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/remote/_run.py
CHANGED
|
@@ -1,92 +1,25 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import asyncio
|
|
4
3
|
from dataclasses import dataclass, field
|
|
5
|
-
from
|
|
6
|
-
from typing import AsyncGenerator, AsyncIterator, Iterator, Literal, Tuple, Union, cast
|
|
4
|
+
from typing import AsyncGenerator, AsyncIterator, Literal, Tuple
|
|
7
5
|
|
|
8
6
|
import grpc
|
|
9
7
|
import rich.repr
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
|
|
8
|
+
from flyteidl2.common import identifier_pb2, list_pb2, phase_pb2
|
|
9
|
+
from flyteidl2.workflow import run_definition_pb2, run_service_pb2
|
|
13
10
|
|
|
14
|
-
from flyte.
|
|
15
|
-
from flyte.
|
|
16
|
-
from flyte.
|
|
17
|
-
from flyte.
|
|
11
|
+
from flyte._initialize import ensure_client, get_client, get_init_config
|
|
12
|
+
from flyte._logging import logger
|
|
13
|
+
from flyte.models import ActionPhase
|
|
14
|
+
from flyte.syncify import syncify
|
|
18
15
|
|
|
19
|
-
from
|
|
20
|
-
from .
|
|
21
|
-
from .
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def _action_time_phase(action: run_definition_pb2.Action | run_definition_pb2.ActionDetails) -> rich.repr.Result:
|
|
25
|
-
"""
|
|
26
|
-
Rich representation of the action time and phase.
|
|
27
|
-
"""
|
|
28
|
-
start_time = timestamp.to_datetime(action.status.start_time, timezone.utc)
|
|
29
|
-
yield "start_time", start_time.isoformat()
|
|
30
|
-
if action.status.phase in [
|
|
31
|
-
run_definition_pb2.PHASE_FAILED,
|
|
32
|
-
run_definition_pb2.PHASE_SUCCEEDED,
|
|
33
|
-
run_definition_pb2.PHASE_ABORTED,
|
|
34
|
-
run_definition_pb2.PHASE_TIMED_OUT,
|
|
35
|
-
]:
|
|
36
|
-
end_time = timestamp.to_datetime(action.status.end_time, timezone.utc)
|
|
37
|
-
yield "end_time", end_time.isoformat()
|
|
38
|
-
yield "run_time", f"{(end_time - start_time).seconds} secs"
|
|
39
|
-
else:
|
|
40
|
-
yield "end_time", None
|
|
41
|
-
yield "run_time", f"{(datetime.now(timezone.utc) - start_time).seconds} secs"
|
|
42
|
-
yield "phase", run_definition_pb2.Phase.Name(action.status.phase)
|
|
43
|
-
if isinstance(action, run_definition_pb2.ActionDetails):
|
|
44
|
-
yield "error", action.error_info if action.HasField("error_info") else "NA"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def _action_rich_repr(action: run_definition_pb2.Action, root: bool = False) -> rich.repr.Result:
|
|
48
|
-
"""
|
|
49
|
-
Rich representation of the action.
|
|
50
|
-
"""
|
|
51
|
-
yield "run-name", action.id.run.name
|
|
52
|
-
yield "name", action.id.name
|
|
53
|
-
yield from _action_time_phase(action)
|
|
54
|
-
yield "task", action.metadata.task.id.name
|
|
55
|
-
if not root:
|
|
56
|
-
yield "group", action.metadata.group
|
|
57
|
-
yield "parent", action.metadata.parent
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def _action_details_rich_repr(action: run_definition_pb2.ActionDetails, root: bool = False) -> rich.repr.Result:
|
|
61
|
-
"""
|
|
62
|
-
Rich representation of the action details.
|
|
63
|
-
"""
|
|
64
|
-
yield "name", action.id.run.name
|
|
65
|
-
yield from _action_time_phase(action)
|
|
66
|
-
# yield "task", action.metadata.task.id.name
|
|
67
|
-
yield "task", action.resolved_task_spec.task_template.id.name
|
|
68
|
-
yield "task_type", action.resolved_task_spec.task_template.type
|
|
69
|
-
yield "task_version", action.resolved_task_spec.task_template.id.version
|
|
70
|
-
if not root:
|
|
71
|
-
yield "group", action.metadata.group
|
|
72
|
-
yield "parent", action.metadata.parent
|
|
73
|
-
# TODO attempt info
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def _action_done_check(phase: run_definition_pb2.Phase) -> bool:
|
|
77
|
-
"""
|
|
78
|
-
Check if the action is done.
|
|
79
|
-
"""
|
|
80
|
-
return phase in [
|
|
81
|
-
run_definition_pb2.PHASE_FAILED,
|
|
82
|
-
run_definition_pb2.PHASE_SUCCEEDED,
|
|
83
|
-
run_definition_pb2.PHASE_ABORTED,
|
|
84
|
-
run_definition_pb2.PHASE_TIMED_OUT,
|
|
85
|
-
]
|
|
16
|
+
from . import Action, ActionDetails, ActionInputs, ActionOutputs
|
|
17
|
+
from ._action import _action_details_rich_repr, _action_rich_repr
|
|
18
|
+
from ._common import ToJSONMixin, filtering, sorting
|
|
86
19
|
|
|
87
20
|
|
|
88
21
|
@dataclass
|
|
89
|
-
class Run:
|
|
22
|
+
class Run(ToJSONMixin):
|
|
90
23
|
"""
|
|
91
24
|
A class representing a run of a task. It is used to manage the run of a task and its state on the remote
|
|
92
25
|
Union API.
|
|
@@ -104,32 +37,84 @@ class Run:
|
|
|
104
37
|
raise RuntimeError("Run does not have an action")
|
|
105
38
|
self.action = Action(self.pb2.action)
|
|
106
39
|
|
|
40
|
+
@syncify
|
|
107
41
|
@classmethod
|
|
108
|
-
@requires_client
|
|
109
|
-
@syncer.wrap
|
|
110
42
|
async def listall(
|
|
111
43
|
cls,
|
|
112
|
-
|
|
44
|
+
in_phase: Tuple[ActionPhase | str, ...] | None = None,
|
|
45
|
+
task_name: str | None = None,
|
|
46
|
+
task_version: str | None = None,
|
|
47
|
+
created_by_subject: str | None = None,
|
|
113
48
|
sort_by: Tuple[str, Literal["asc", "desc"]] | None = None,
|
|
114
|
-
|
|
49
|
+
limit: int = 100,
|
|
50
|
+
) -> AsyncIterator[Run]:
|
|
115
51
|
"""
|
|
116
52
|
Get all runs for the current project and domain.
|
|
117
53
|
|
|
118
|
-
:param
|
|
119
|
-
:param
|
|
54
|
+
:param in_phase: Filter runs by one or more phases.
|
|
55
|
+
:param task_name: Filter runs by task name.
|
|
56
|
+
:param task_version: Filter runs by task version.
|
|
57
|
+
:param created_by_subject: Filter runs by the subject that created them. (this is not username, but the subject)
|
|
58
|
+
:param sort_by: The sorting criteria for the Run list, in the format (field, order).
|
|
59
|
+
:param limit: The maximum number of runs to return.
|
|
120
60
|
:return: An iterator of runs.
|
|
121
61
|
"""
|
|
62
|
+
ensure_client()
|
|
122
63
|
token = None
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
64
|
+
sort_pb2 = sorting(sort_by)
|
|
65
|
+
filters = []
|
|
66
|
+
if in_phase:
|
|
67
|
+
phases = [
|
|
68
|
+
str(p.to_protobuf_value())
|
|
69
|
+
if isinstance(p, ActionPhase)
|
|
70
|
+
else str(phase_pb2.ActionPhase.Value(f"ACTION_PHASE_{p.upper()}"))
|
|
71
|
+
for p in in_phase
|
|
72
|
+
]
|
|
73
|
+
logger.debug(f"Fetching run phases: {phases}")
|
|
74
|
+
if len(phases) > 1:
|
|
75
|
+
filters.append(
|
|
76
|
+
list_pb2.Filter(
|
|
77
|
+
function=list_pb2.Filter.Function.VALUE_IN,
|
|
78
|
+
field="phase",
|
|
79
|
+
values=phases,
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
else:
|
|
83
|
+
filters.append(
|
|
84
|
+
list_pb2.Filter(
|
|
85
|
+
function=list_pb2.Filter.Function.EQUAL,
|
|
86
|
+
field="phase",
|
|
87
|
+
values=phases[0],
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if task_name:
|
|
92
|
+
filters.append(
|
|
93
|
+
list_pb2.Filter(
|
|
94
|
+
function=list_pb2.Filter.Function.EQUAL,
|
|
95
|
+
field="task_name",
|
|
96
|
+
values=[task_name],
|
|
97
|
+
),
|
|
98
|
+
)
|
|
99
|
+
if task_version:
|
|
100
|
+
filters.append(
|
|
101
|
+
list_pb2.Filter(
|
|
102
|
+
function=list_pb2.Filter.Function.EQUAL,
|
|
103
|
+
field="task_version",
|
|
104
|
+
values=[task_version],
|
|
105
|
+
),
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
filters = filtering(created_by_subject, *filters)
|
|
109
|
+
|
|
110
|
+
cfg = get_init_config()
|
|
111
|
+
i = 0
|
|
128
112
|
while True:
|
|
129
113
|
req = list_pb2.ListRequest(
|
|
130
|
-
limit=100,
|
|
114
|
+
limit=min(100, limit),
|
|
131
115
|
token=token,
|
|
132
116
|
sort_by=sort_pb2,
|
|
117
|
+
filters=filters,
|
|
133
118
|
)
|
|
134
119
|
resp = await get_client().run_service.ListRuns(
|
|
135
120
|
run_service_pb2.ListRunsRequest(
|
|
@@ -144,20 +129,23 @@ class Run:
|
|
|
144
129
|
)
|
|
145
130
|
token = resp.token
|
|
146
131
|
for r in resp.runs:
|
|
132
|
+
i += 1
|
|
133
|
+
if i > limit:
|
|
134
|
+
return
|
|
147
135
|
yield cls(r)
|
|
148
136
|
if not token:
|
|
149
137
|
break
|
|
150
138
|
|
|
139
|
+
@syncify
|
|
151
140
|
@classmethod
|
|
152
|
-
@requires_client
|
|
153
|
-
@syncer.wrap
|
|
154
141
|
async def get(cls, name: str) -> Run:
|
|
155
142
|
"""
|
|
156
143
|
Get the current run.
|
|
157
144
|
|
|
158
145
|
:return: The current run.
|
|
159
146
|
"""
|
|
160
|
-
|
|
147
|
+
ensure_client()
|
|
148
|
+
run_details: RunDetails = await RunDetails.get.aio(name=name)
|
|
161
149
|
run = run_definition_pb2.Run(
|
|
162
150
|
action=run_definition_pb2.Action(
|
|
163
151
|
id=run_details.action_id,
|
|
@@ -179,112 +167,104 @@ class Run:
|
|
|
179
167
|
"""
|
|
180
168
|
Get the phase of the run.
|
|
181
169
|
"""
|
|
182
|
-
return
|
|
170
|
+
return self.action.phase
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def raw_phase(self) -> phase_pb2.ActionPhase:
|
|
174
|
+
"""
|
|
175
|
+
Get the raw phase of the run.
|
|
176
|
+
"""
|
|
177
|
+
return self.action.raw_phase
|
|
183
178
|
|
|
184
|
-
@
|
|
185
|
-
async def wait(self, quiet: bool = False) -> None:
|
|
179
|
+
@syncify
|
|
180
|
+
async def wait(self, quiet: bool = False, wait_for: Literal["terminal", "running"] = "terminal") -> None:
|
|
186
181
|
"""
|
|
187
182
|
Wait for the run to complete, displaying a rich progress panel with status transitions,
|
|
188
183
|
time elapsed, and error details in case of failure.
|
|
189
|
-
"""
|
|
190
|
-
console = Console()
|
|
191
|
-
if self.done():
|
|
192
|
-
if not quiet:
|
|
193
|
-
console.print(f"[bold green]Run '{self.name}' is already completed.[/bold green]")
|
|
194
|
-
return
|
|
195
184
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
transient=True,
|
|
203
|
-
disable=quiet,
|
|
204
|
-
) as progress:
|
|
205
|
-
task_id = progress.add_task(f"Waiting for run '{self.name}'...", start=False)
|
|
206
|
-
|
|
207
|
-
async for ad in self.watch(cache_data_on_done=True):
|
|
208
|
-
if ad is None:
|
|
209
|
-
break
|
|
210
|
-
|
|
211
|
-
# Update progress description with the current phase
|
|
212
|
-
progress.update(
|
|
213
|
-
task_id,
|
|
214
|
-
description=f"Run: {self.name} in {ad.phase}, Runtime: {ad.runtime} secs "
|
|
215
|
-
f"Attempts[{ad.attempts}]",
|
|
216
|
-
)
|
|
217
|
-
progress.start_task(task_id)
|
|
218
|
-
|
|
219
|
-
# If the action is done, handle the final state
|
|
220
|
-
if ad.done():
|
|
221
|
-
progress.stop_task(task_id)
|
|
222
|
-
if ad.pb2.status.phase == run_definition_pb2.PHASE_SUCCEEDED:
|
|
223
|
-
console.print(f"[bold green]Run '{self.name}' completed successfully.[/bold green]")
|
|
224
|
-
else:
|
|
225
|
-
console.print(
|
|
226
|
-
f"[bold red]Run '{self.name}' exited unsuccessfully in state {ad.phase}"
|
|
227
|
-
f"with error: {ad.error_info}[/bold red]"
|
|
228
|
-
)
|
|
229
|
-
break
|
|
230
|
-
except asyncio.CancelledError:
|
|
231
|
-
# Handle cancellation gracefully
|
|
232
|
-
pass
|
|
233
|
-
except KeyboardInterrupt:
|
|
234
|
-
# Handle keyboard interrupt gracefully
|
|
235
|
-
console.print(f"\n[bold yellow]Run '{self.name}' was interrupted.[/bold yellow]")
|
|
185
|
+
This method updates the Run's internal state, ensuring that properties like
|
|
186
|
+
`run.action.phase` reflect the final state after waiting completes.
|
|
187
|
+
"""
|
|
188
|
+
await self.action.wait(quiet=quiet, wait_for=wait_for)
|
|
189
|
+
# Update the Run's pb2.action to keep it in sync after waiting
|
|
190
|
+
self.pb2.action.CopyFrom(self.action.pb2)
|
|
236
191
|
|
|
237
192
|
async def watch(self, cache_data_on_done: bool = False) -> AsyncGenerator[ActionDetails, None]:
|
|
238
193
|
"""
|
|
239
|
-
|
|
194
|
+
Watch the run for updates, updating the internal Run state with latest details.
|
|
195
|
+
|
|
196
|
+
This method updates the Run's action state, ensuring that properties like
|
|
197
|
+
`run.action.phase` reflect the current state after watching.
|
|
240
198
|
"""
|
|
241
|
-
async for ad in self.action.
|
|
242
|
-
|
|
243
|
-
|
|
199
|
+
async for ad in self.action.watch(cache_data_on_done=cache_data_on_done):
|
|
200
|
+
# The action's pb2 is already updated by Action.watch()
|
|
201
|
+
# Update the Run's pb2.action to keep it in sync
|
|
202
|
+
self.pb2.action.CopyFrom(self.action.pb2)
|
|
244
203
|
yield ad
|
|
245
204
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
205
|
+
@syncify
|
|
206
|
+
async def show_logs(
|
|
207
|
+
self,
|
|
208
|
+
attempt: int | None = None,
|
|
209
|
+
max_lines: int = 100,
|
|
210
|
+
show_ts: bool = False,
|
|
211
|
+
raw: bool = False,
|
|
212
|
+
filter_system: bool = False,
|
|
213
|
+
):
|
|
214
|
+
await self.action.show_logs.aio(attempt, max_lines, show_ts, raw, filter_system=filter_system)
|
|
254
215
|
|
|
216
|
+
@syncify
|
|
255
217
|
async def details(self) -> RunDetails:
|
|
256
218
|
"""
|
|
257
219
|
Get the details of the run. This is a placeholder for getting the run details.
|
|
258
220
|
"""
|
|
259
|
-
if self._details is None:
|
|
260
|
-
self._details = await RunDetails.get_details(
|
|
221
|
+
if self._details is None or not self._details.done():
|
|
222
|
+
self._details = await RunDetails.get_details.aio(self.pb2.action.id.run)
|
|
261
223
|
return self._details
|
|
262
224
|
|
|
225
|
+
@syncify
|
|
226
|
+
async def inputs(self) -> ActionInputs:
|
|
227
|
+
"""
|
|
228
|
+
Get the inputs of the run. This is a placeholder for getting the run inputs.
|
|
229
|
+
"""
|
|
230
|
+
details = await self.details.aio()
|
|
231
|
+
return await details.inputs()
|
|
232
|
+
|
|
233
|
+
@syncify
|
|
234
|
+
async def outputs(self) -> ActionOutputs:
|
|
235
|
+
"""
|
|
236
|
+
Get the outputs of the run. This is a placeholder for getting the run outputs.
|
|
237
|
+
"""
|
|
238
|
+
details = await self.details.aio()
|
|
239
|
+
return await details.outputs()
|
|
240
|
+
|
|
263
241
|
@property
|
|
264
|
-
@requires_client
|
|
265
242
|
def url(self) -> str:
|
|
266
243
|
"""
|
|
267
244
|
Get the URL of the run.
|
|
268
245
|
"""
|
|
269
246
|
client = get_client()
|
|
270
|
-
return
|
|
271
|
-
client.endpoint,
|
|
272
|
-
insecure=client.insecure,
|
|
247
|
+
return client.console.run_url(
|
|
273
248
|
project=self.pb2.action.id.run.project,
|
|
274
249
|
domain=self.pb2.action.id.run.domain,
|
|
275
250
|
run_name=self.name,
|
|
276
251
|
)
|
|
277
252
|
|
|
278
|
-
@
|
|
279
|
-
async def
|
|
253
|
+
@syncify
|
|
254
|
+
async def abort(self):
|
|
280
255
|
"""
|
|
281
|
-
|
|
256
|
+
Aborts / Terminates the run.
|
|
282
257
|
"""
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
258
|
+
try:
|
|
259
|
+
await get_client().run_service.AbortRun(
|
|
260
|
+
run_service_pb2.AbortRunRequest(
|
|
261
|
+
run_id=self.pb2.action.id.run,
|
|
262
|
+
)
|
|
286
263
|
)
|
|
287
|
-
|
|
264
|
+
except grpc.aio.AioRpcError as e:
|
|
265
|
+
if e.code() == grpc.StatusCode.NOT_FOUND:
|
|
266
|
+
return
|
|
267
|
+
raise
|
|
288
268
|
|
|
289
269
|
def done(self) -> bool:
|
|
290
270
|
"""
|
|
@@ -304,7 +284,8 @@ class Run:
|
|
|
304
284
|
"""
|
|
305
285
|
Rich representation of the Run object.
|
|
306
286
|
"""
|
|
307
|
-
yield
|
|
287
|
+
yield "url", f"[blue bold][link={self.url}]link[/link][/blue bold]"
|
|
288
|
+
yield from _action_rich_repr(self.pb2.action)
|
|
308
289
|
|
|
309
290
|
def __repr__(self) -> str:
|
|
310
291
|
"""
|
|
@@ -316,7 +297,7 @@ class Run:
|
|
|
316
297
|
|
|
317
298
|
|
|
318
299
|
@dataclass
|
|
319
|
-
class RunDetails:
|
|
300
|
+
class RunDetails(ToJSONMixin):
|
|
320
301
|
"""
|
|
321
302
|
A class representing a run of a task. It is used to manage the run of a task and its state on the remote
|
|
322
303
|
Union API.
|
|
@@ -331,13 +312,13 @@ class RunDetails:
|
|
|
331
312
|
"""
|
|
332
313
|
self.action_details = ActionDetails(self.pb2.action)
|
|
333
314
|
|
|
315
|
+
@syncify
|
|
334
316
|
@classmethod
|
|
335
|
-
|
|
336
|
-
@syncer.wrap
|
|
337
|
-
async def get_details(cls, run_id: run_definition_pb2.RunIdentifier) -> RunDetails:
|
|
317
|
+
async def get_details(cls, run_id: identifier_pb2.RunIdentifier) -> RunDetails:
|
|
338
318
|
"""
|
|
339
319
|
Get the details of the run. This is a placeholder for getting the run details.
|
|
340
320
|
"""
|
|
321
|
+
ensure_client()
|
|
341
322
|
resp = await get_client().run_service.GetRunDetails(
|
|
342
323
|
run_service_pb2.GetRunDetailsRequest(
|
|
343
324
|
run_id=run_id,
|
|
@@ -345,9 +326,8 @@ class RunDetails:
|
|
|
345
326
|
)
|
|
346
327
|
return cls(resp.details)
|
|
347
328
|
|
|
329
|
+
@syncify
|
|
348
330
|
@classmethod
|
|
349
|
-
@requires_client
|
|
350
|
-
@syncer.wrap
|
|
351
331
|
async def get(cls, name: str | None = None) -> RunDetails:
|
|
352
332
|
"""
|
|
353
333
|
Get a run by its ID or name. If both are provided, the ID will take precedence.
|
|
@@ -355,10 +335,10 @@ class RunDetails:
|
|
|
355
335
|
:param uri: The URI of the run.
|
|
356
336
|
:param name: The name of the run.
|
|
357
337
|
"""
|
|
358
|
-
|
|
338
|
+
ensure_client()
|
|
339
|
+
cfg = get_init_config()
|
|
359
340
|
return await RunDetails.get_details.aio(
|
|
360
|
-
|
|
361
|
-
run_id=run_definition_pb2.RunIdentifier(
|
|
341
|
+
run_id=identifier_pb2.RunIdentifier(
|
|
362
342
|
org=cfg.org,
|
|
363
343
|
project=cfg.project,
|
|
364
344
|
domain=cfg.domain,
|
|
@@ -381,7 +361,7 @@ class RunDetails:
|
|
|
381
361
|
return self.action_details.task_name
|
|
382
362
|
|
|
383
363
|
@property
|
|
384
|
-
def action_id(self) ->
|
|
364
|
+
def action_id(self) -> identifier_pb2.ActionIdentifier:
|
|
385
365
|
"""
|
|
386
366
|
Get the action ID.
|
|
387
367
|
"""
|
|
@@ -410,196 +390,12 @@ class RunDetails:
|
|
|
410
390
|
"""
|
|
411
391
|
Rich representation of the Run object.
|
|
412
392
|
"""
|
|
413
|
-
yield
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
""
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
import rich.pretty
|
|
420
|
-
|
|
421
|
-
return rich.pretty.pretty_repr(self)
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
@dataclass
|
|
425
|
-
class Action:
|
|
426
|
-
"""
|
|
427
|
-
A class representing an action. It is used to manage the run of a task and its state on the remote Union API.
|
|
428
|
-
"""
|
|
429
|
-
|
|
430
|
-
pb2: run_definition_pb2.Action
|
|
431
|
-
_details: ActionDetails | None = None
|
|
432
|
-
|
|
433
|
-
@classmethod
|
|
434
|
-
@requires_client
|
|
435
|
-
@syncer.wrap
|
|
436
|
-
async def listall(
|
|
437
|
-
cls,
|
|
438
|
-
for_run_name: str,
|
|
439
|
-
filters: str | None = None,
|
|
440
|
-
sort_by: Tuple[str, Literal["asc", "desc"]] | None = None,
|
|
441
|
-
) -> Union[Iterator[Action], AsyncGenerator[Action, None]]:
|
|
442
|
-
"""
|
|
443
|
-
Get all actions for a given run.
|
|
444
|
-
|
|
445
|
-
:param for_run_name: The name of the run.
|
|
446
|
-
:param filters: The filters to apply to the project list.
|
|
447
|
-
:param sort_by: The sorting criteria for the project list, in the format (field, order).
|
|
448
|
-
:return: An iterator of projects.
|
|
449
|
-
"""
|
|
450
|
-
token = None
|
|
451
|
-
sort_by = sort_by or ("created_at", "asc")
|
|
452
|
-
sort_pb2 = list_pb2.Sort(
|
|
453
|
-
key=sort_by[0], direction=list_pb2.Sort.ASCENDING if sort_by[1] == "asc" else list_pb2.Sort.DESCENDING
|
|
454
|
-
)
|
|
455
|
-
cfg = get_common_config()
|
|
456
|
-
while True:
|
|
457
|
-
req = list_pb2.ListRequest(
|
|
458
|
-
limit=100,
|
|
459
|
-
token=token,
|
|
460
|
-
sort_by=sort_pb2,
|
|
461
|
-
)
|
|
462
|
-
resp = await get_client().run_service.ListActions(
|
|
463
|
-
run_service_pb2.ListActionsRequest(
|
|
464
|
-
request=req,
|
|
465
|
-
run_id=run_definition_pb2.RunIdentifier(
|
|
466
|
-
org=cfg.org,
|
|
467
|
-
project=cfg.project,
|
|
468
|
-
domain=cfg.domain,
|
|
469
|
-
name=for_run_name,
|
|
470
|
-
),
|
|
471
|
-
)
|
|
472
|
-
)
|
|
473
|
-
token = resp.token
|
|
474
|
-
for r in resp.actions:
|
|
475
|
-
yield cls(r)
|
|
476
|
-
if not token:
|
|
477
|
-
break
|
|
478
|
-
|
|
479
|
-
@classmethod
|
|
480
|
-
@requires_client
|
|
481
|
-
@syncer.wrap
|
|
482
|
-
async def get(cls, uri: str | None = None, /, run_name: str | None = None, name: str | None = None) -> Action:
|
|
483
|
-
"""
|
|
484
|
-
Get a run by its ID or name. If both are provided, the ID will take precedence.
|
|
485
|
-
|
|
486
|
-
:param uri: The URI of the action.
|
|
487
|
-
:param run_name: The name of the action.
|
|
488
|
-
:param name: The name of the action.
|
|
489
|
-
"""
|
|
490
|
-
cfg = get_common_config()
|
|
491
|
-
details: ActionDetails = await ActionDetails.get_details.aio(
|
|
492
|
-
cls,
|
|
493
|
-
run_definition_pb2.ActionIdentifier(
|
|
494
|
-
run=run_definition_pb2.RunIdentifier(
|
|
495
|
-
org=cfg.org,
|
|
496
|
-
project=cfg.project,
|
|
497
|
-
domain=cfg.domain,
|
|
498
|
-
name=run_name,
|
|
499
|
-
),
|
|
500
|
-
name=name,
|
|
501
|
-
),
|
|
502
|
-
)
|
|
503
|
-
return cls(
|
|
504
|
-
pb2=run_definition_pb2.Action(
|
|
505
|
-
id=details.action_id,
|
|
506
|
-
metadata=details.pb2.metadata,
|
|
507
|
-
status=details.pb2.status,
|
|
508
|
-
),
|
|
509
|
-
_details=details,
|
|
510
|
-
)
|
|
511
|
-
|
|
512
|
-
@property
|
|
513
|
-
def phase(self) -> str:
|
|
514
|
-
"""
|
|
515
|
-
Get the phase of the action.
|
|
516
|
-
"""
|
|
517
|
-
return run_definition_pb2.Phase.Name(self.pb2.status.phase)
|
|
518
|
-
|
|
519
|
-
@property
|
|
520
|
-
def name(self) -> str:
|
|
521
|
-
"""
|
|
522
|
-
Get the name of the action.
|
|
523
|
-
"""
|
|
524
|
-
return self.action_id.name
|
|
525
|
-
|
|
526
|
-
@property
|
|
527
|
-
def run_name(self) -> str:
|
|
528
|
-
"""
|
|
529
|
-
Get the name of the run.
|
|
530
|
-
"""
|
|
531
|
-
return self.action_id.run.name
|
|
532
|
-
|
|
533
|
-
@property
|
|
534
|
-
def task_name(self) -> str | None:
|
|
535
|
-
"""
|
|
536
|
-
Get the name of the task.
|
|
537
|
-
"""
|
|
538
|
-
if self.pb2.metadata.HasField("task") and self.pb2.metadata.task.HasField("id"):
|
|
539
|
-
return self.pb2.metadata.task.id.name
|
|
540
|
-
return None
|
|
541
|
-
|
|
542
|
-
@property
|
|
543
|
-
def action_id(self) -> run_definition_pb2.ActionIdentifier:
|
|
544
|
-
"""
|
|
545
|
-
Get the action ID.
|
|
546
|
-
"""
|
|
547
|
-
return self.pb2.id
|
|
548
|
-
|
|
549
|
-
async def show_logs(
|
|
550
|
-
self, attempt: int | None = None, max_lines: int = 30, show_ts: bool = False, raw: bool = False
|
|
551
|
-
):
|
|
552
|
-
details = await self.details()
|
|
553
|
-
if not attempt:
|
|
554
|
-
attempt = details.attempts
|
|
555
|
-
if details.phase in [
|
|
556
|
-
run_definition_pb2.PHASE_QUEUED,
|
|
557
|
-
run_definition_pb2.PHASE_INITIALIZING,
|
|
558
|
-
run_definition_pb2.PHASE_WAITING_FOR_RESOURCES,
|
|
559
|
-
]:
|
|
560
|
-
raise RuntimeError("Action has not yet started, so logs are not available.")
|
|
561
|
-
return await Logs.create_viewer(
|
|
562
|
-
action_id=self.action_id, attempt=attempt, max_lines=max_lines, show_ts=show_ts, raw=raw
|
|
563
|
-
)
|
|
564
|
-
|
|
565
|
-
async def details(self) -> ActionDetails:
|
|
566
|
-
"""
|
|
567
|
-
Get the details of the action. This is a placeholder for getting the action details.
|
|
568
|
-
"""
|
|
569
|
-
if not self._details:
|
|
570
|
-
self._details = await ActionDetails.get_details.aio(ActionDetails, self.action_id)
|
|
571
|
-
return cast(ActionDetails, self._details)
|
|
572
|
-
|
|
573
|
-
async def watch_details(self, cache_data_on_done: bool = False) -> AsyncGenerator[ActionDetails, None]:
|
|
574
|
-
"""
|
|
575
|
-
Watch the action for updates. This is a placeholder for watching the action.
|
|
576
|
-
"""
|
|
577
|
-
ad = None
|
|
578
|
-
async for ad in ActionDetails.watch.aio(ActionDetails, self.action_id):
|
|
579
|
-
if ad is None:
|
|
580
|
-
return
|
|
581
|
-
self._details = ad
|
|
582
|
-
yield ad
|
|
583
|
-
if cache_data_on_done and ad and ad.done():
|
|
584
|
-
await cast(ActionDetails, self._details).outputs()
|
|
585
|
-
|
|
586
|
-
def done(self) -> bool:
|
|
587
|
-
"""
|
|
588
|
-
Check if the action is done.
|
|
589
|
-
"""
|
|
590
|
-
return _action_done_check(self.pb2.status.phase)
|
|
591
|
-
|
|
592
|
-
async def sync(self) -> Action:
|
|
593
|
-
"""
|
|
594
|
-
Sync the action with the remote server. This is a placeholder for syncing the action.
|
|
595
|
-
"""
|
|
596
|
-
return self
|
|
597
|
-
|
|
598
|
-
def __rich_repr__(self) -> rich.repr.Result:
|
|
599
|
-
"""
|
|
600
|
-
Rich representation of the Action object.
|
|
601
|
-
"""
|
|
602
|
-
yield from _action_rich_repr(self.pb2, root=True)
|
|
393
|
+
yield "labels", str(self.pb2.run_spec.labels)
|
|
394
|
+
yield "annotations", str(self.pb2.run_spec.annotations)
|
|
395
|
+
yield "env-vars", str(self.pb2.run_spec.envs)
|
|
396
|
+
yield "is-interruptible", str(self.pb2.run_spec.interruptible)
|
|
397
|
+
yield "cache-overwrite", self.pb2.run_spec.overwrite_cache
|
|
398
|
+
yield from _action_details_rich_repr(self.pb2.action)
|
|
603
399
|
|
|
604
400
|
def __repr__(self) -> str:
|
|
605
401
|
"""
|
|
@@ -608,266 +404,3 @@ class Action:
|
|
|
608
404
|
import rich.pretty
|
|
609
405
|
|
|
610
406
|
return rich.pretty.pretty_repr(self)
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
@dataclass
|
|
614
|
-
class ActionDetails:
|
|
615
|
-
"""
|
|
616
|
-
A class representing an action. It is used to manage the run of a task and its state on the remote Union API.
|
|
617
|
-
"""
|
|
618
|
-
|
|
619
|
-
pb2: run_definition_pb2.ActionDetails
|
|
620
|
-
_inputs: ActionInputs | None = None
|
|
621
|
-
_outputs: ActionOutputs | None = None
|
|
622
|
-
|
|
623
|
-
@classmethod
|
|
624
|
-
@requires_client
|
|
625
|
-
@syncer.wrap
|
|
626
|
-
async def get_details(cls, action_id: run_definition_pb2.ActionIdentifier) -> ActionDetails:
|
|
627
|
-
"""
|
|
628
|
-
Get the details of the action. This is a placeholder for getting the action details.
|
|
629
|
-
"""
|
|
630
|
-
resp = await get_client().run_service.GetActionDetails(
|
|
631
|
-
run_service_pb2.GetActionDetailsRequest(
|
|
632
|
-
action_id=action_id,
|
|
633
|
-
)
|
|
634
|
-
)
|
|
635
|
-
return ActionDetails(resp.details)
|
|
636
|
-
|
|
637
|
-
@classmethod
|
|
638
|
-
@requires_client
|
|
639
|
-
@syncer.wrap
|
|
640
|
-
async def get(
|
|
641
|
-
cls, uri: str | None = None, /, run_name: str | None = None, name: str | None = None
|
|
642
|
-
) -> ActionDetails:
|
|
643
|
-
"""
|
|
644
|
-
Get a run by its ID or name. If both are provided, the ID will take precedence.
|
|
645
|
-
|
|
646
|
-
:param uri: The URI of the action.
|
|
647
|
-
:param name: The name of the action.
|
|
648
|
-
:param run_name: The name of the run.
|
|
649
|
-
"""
|
|
650
|
-
if not uri:
|
|
651
|
-
assert name is not None and run_name is not None, "Either uri or name and run_name must be provided"
|
|
652
|
-
cfg = get_common_config()
|
|
653
|
-
return await cls.get_details.aio(
|
|
654
|
-
cls,
|
|
655
|
-
run_definition_pb2.ActionIdentifier(
|
|
656
|
-
run=run_definition_pb2.RunIdentifier(
|
|
657
|
-
org=cfg.org,
|
|
658
|
-
project=cfg.project,
|
|
659
|
-
domain=cfg.domain,
|
|
660
|
-
name=run_name,
|
|
661
|
-
),
|
|
662
|
-
name=name,
|
|
663
|
-
),
|
|
664
|
-
)
|
|
665
|
-
|
|
666
|
-
@classmethod
|
|
667
|
-
@requires_client
|
|
668
|
-
@syncer.wrap
|
|
669
|
-
async def watch(cls, action_id: run_definition_pb2.ActionIdentifier) -> AsyncGenerator[ActionDetails, None]:
|
|
670
|
-
"""
|
|
671
|
-
Watch the action for updates. This is a placeholder for watching the action.
|
|
672
|
-
"""
|
|
673
|
-
if not action_id:
|
|
674
|
-
raise ValueError("Action ID is required")
|
|
675
|
-
|
|
676
|
-
call = cast(
|
|
677
|
-
AsyncIterator[WatchActionDetailsResponse],
|
|
678
|
-
get_client().run_service.WatchActionDetails(
|
|
679
|
-
request=run_service_pb2.WatchActionDetailsRequest(
|
|
680
|
-
action_id=action_id,
|
|
681
|
-
)
|
|
682
|
-
),
|
|
683
|
-
)
|
|
684
|
-
try:
|
|
685
|
-
async for resp in call:
|
|
686
|
-
v = cls(resp.details)
|
|
687
|
-
yield v
|
|
688
|
-
if v.done():
|
|
689
|
-
return
|
|
690
|
-
except grpc.aio.AioRpcError as e:
|
|
691
|
-
if e.code() == grpc.StatusCode.CANCELLED:
|
|
692
|
-
pass
|
|
693
|
-
else:
|
|
694
|
-
raise e
|
|
695
|
-
|
|
696
|
-
async def watch_updates(self, cache_data_on_done: bool = False) -> AsyncGenerator[ActionDetails, None]:
|
|
697
|
-
async for d in self.watch.aio(action_id=self.pb2.id):
|
|
698
|
-
yield d
|
|
699
|
-
if d.done():
|
|
700
|
-
self.pb2 = d.pb2
|
|
701
|
-
break
|
|
702
|
-
|
|
703
|
-
if cache_data_on_done and self.done():
|
|
704
|
-
await self._cache_data.aio(self)
|
|
705
|
-
|
|
706
|
-
@property
|
|
707
|
-
def phase(self) -> str:
|
|
708
|
-
"""
|
|
709
|
-
Get the phase of the action.
|
|
710
|
-
"""
|
|
711
|
-
return run_definition_pb2.Phase.Name(self.status.phase)
|
|
712
|
-
|
|
713
|
-
@property
|
|
714
|
-
def name(self) -> str:
|
|
715
|
-
"""
|
|
716
|
-
Get the name of the action.
|
|
717
|
-
"""
|
|
718
|
-
return self.action_id.name
|
|
719
|
-
|
|
720
|
-
@property
|
|
721
|
-
def run_name(self) -> str:
|
|
722
|
-
"""
|
|
723
|
-
Get the name of the run.
|
|
724
|
-
"""
|
|
725
|
-
return self.action_id.run.name
|
|
726
|
-
|
|
727
|
-
@property
|
|
728
|
-
def task_name(self) -> str | None:
|
|
729
|
-
"""
|
|
730
|
-
Get the name of the task.
|
|
731
|
-
"""
|
|
732
|
-
if self.pb2.metadata.HasField("task") and self.pb2.metadata.task.HasField("id"):
|
|
733
|
-
return self.pb2.metadata.task.id.name
|
|
734
|
-
return None
|
|
735
|
-
|
|
736
|
-
@property
|
|
737
|
-
def action_id(self) -> run_definition_pb2.ActionIdentifier:
|
|
738
|
-
"""
|
|
739
|
-
Get the action ID.
|
|
740
|
-
"""
|
|
741
|
-
return self.pb2.id
|
|
742
|
-
|
|
743
|
-
@property
|
|
744
|
-
def metadata(self) -> run_definition_pb2.ActionMetadata:
|
|
745
|
-
return self.pb2.metadata
|
|
746
|
-
|
|
747
|
-
@property
|
|
748
|
-
def status(self) -> run_definition_pb2.ActionStatus:
|
|
749
|
-
return self.pb2.status
|
|
750
|
-
|
|
751
|
-
@property
|
|
752
|
-
def error_info(self) -> run_definition_pb2.ErrorInfo | None:
|
|
753
|
-
if self.pb2.HasField("error_info"):
|
|
754
|
-
return self.pb2.error_info
|
|
755
|
-
return None
|
|
756
|
-
|
|
757
|
-
@property
|
|
758
|
-
def abort_info(self) -> run_definition_pb2.AbortInfo | None:
|
|
759
|
-
if self.pb2.HasField("abort_info"):
|
|
760
|
-
return self.pb2.abort_info
|
|
761
|
-
return None
|
|
762
|
-
|
|
763
|
-
@property
|
|
764
|
-
def runtime(self) -> timedelta:
|
|
765
|
-
"""
|
|
766
|
-
Get the runtime of the action.
|
|
767
|
-
"""
|
|
768
|
-
start_time = timestamp.to_datetime(self.pb2.status.start_time, timezone.utc)
|
|
769
|
-
if self.pb2.status.HasField("end_time"):
|
|
770
|
-
end_time = timestamp.to_datetime(self.pb2.status.end_time, timezone.utc)
|
|
771
|
-
return end_time - start_time
|
|
772
|
-
return datetime.now(timezone.utc) - start_time
|
|
773
|
-
|
|
774
|
-
@property
|
|
775
|
-
def attempts(self) -> int:
|
|
776
|
-
"""
|
|
777
|
-
Get the number of attempts of the action.
|
|
778
|
-
"""
|
|
779
|
-
return self.pb2.status.attempts
|
|
780
|
-
|
|
781
|
-
@syncer.wrap
|
|
782
|
-
async def _cache_data(self) -> bool:
|
|
783
|
-
"""
|
|
784
|
-
Cache the inputs and outputs of the action.
|
|
785
|
-
:return: Returns True if Action is terminal and all data is cached else False.
|
|
786
|
-
"""
|
|
787
|
-
if self._inputs and self._outputs:
|
|
788
|
-
return True
|
|
789
|
-
if self._inputs and not self.done():
|
|
790
|
-
return False
|
|
791
|
-
resp = await get_client().run_service.GetActionData(
|
|
792
|
-
request=run_service_pb2.GetActionDataRequest(
|
|
793
|
-
action_id=self.pb2.id,
|
|
794
|
-
)
|
|
795
|
-
)
|
|
796
|
-
self._inputs = ActionInputs(resp.inputs)
|
|
797
|
-
self._outputs = ActionOutputs(resp.outputs) if resp.HasField("outputs") else None
|
|
798
|
-
return self._outputs is not None
|
|
799
|
-
|
|
800
|
-
async def inputs(self) -> ActionInputs:
|
|
801
|
-
"""
|
|
802
|
-
Placeholder for inputs. This can be extended to handle inputs from the run context.
|
|
803
|
-
"""
|
|
804
|
-
if not self._inputs:
|
|
805
|
-
await self._cache_data.aio(self)
|
|
806
|
-
return cast(ActionInputs, self._inputs)
|
|
807
|
-
|
|
808
|
-
async def outputs(self) -> ActionOutputs:
|
|
809
|
-
"""
|
|
810
|
-
Placeholder for outputs. This can be extended to handle outputs from the run context.
|
|
811
|
-
"""
|
|
812
|
-
if not self._outputs:
|
|
813
|
-
if not await self._cache_data.aio(self):
|
|
814
|
-
raise RuntimeError(
|
|
815
|
-
"Action is not in a terminal state, outputs are not available. "
|
|
816
|
-
"Please wait for the action to complete."
|
|
817
|
-
)
|
|
818
|
-
return cast(ActionOutputs, self._outputs)
|
|
819
|
-
|
|
820
|
-
def done(self) -> bool:
|
|
821
|
-
"""
|
|
822
|
-
Check if the action is in a terminal state (completed or failed). This is a placeholder for checking the
|
|
823
|
-
action state.
|
|
824
|
-
"""
|
|
825
|
-
return _action_done_check(self.pb2.status.phase)
|
|
826
|
-
|
|
827
|
-
def __rich_repr__(self) -> rich.repr.Result:
|
|
828
|
-
"""
|
|
829
|
-
Rich representation of the Action object.
|
|
830
|
-
"""
|
|
831
|
-
yield from _action_details_rich_repr(self.pb2, root=True)
|
|
832
|
-
|
|
833
|
-
def __repr__(self) -> str:
|
|
834
|
-
"""
|
|
835
|
-
String representation of the Action object.
|
|
836
|
-
"""
|
|
837
|
-
import rich.pretty
|
|
838
|
-
|
|
839
|
-
return rich.pretty.pretty_repr(self)
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
@dataclass
|
|
843
|
-
class ActionInputs:
|
|
844
|
-
"""
|
|
845
|
-
A class representing the inputs of an action. It is used to manage the inputs of a task and its state on the
|
|
846
|
-
remote Union API.
|
|
847
|
-
"""
|
|
848
|
-
|
|
849
|
-
pb2: run_definition_pb2.Inputs
|
|
850
|
-
|
|
851
|
-
def __repr__(self):
|
|
852
|
-
import rich.pretty
|
|
853
|
-
|
|
854
|
-
import flyte.types as types
|
|
855
|
-
|
|
856
|
-
return rich.pretty.pretty_repr(types.literal_string_repr(self.pb2))
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
@dataclass
|
|
860
|
-
class ActionOutputs:
|
|
861
|
-
"""
|
|
862
|
-
A class representing the outputs of an action. It is used to manage the outputs of a task and its state on the
|
|
863
|
-
remote Union API.
|
|
864
|
-
"""
|
|
865
|
-
|
|
866
|
-
pb2: run_definition_pb2.Outputs
|
|
867
|
-
|
|
868
|
-
def __repr__(self):
|
|
869
|
-
import rich.pretty
|
|
870
|
-
|
|
871
|
-
import flyte.types as types
|
|
872
|
-
|
|
873
|
-
return rich.pretty.pretty_repr(types.literal_string_repr(self.pb2))
|