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/_interface.py
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import inspect
|
|
4
|
-
|
|
4
|
+
import typing
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import Dict, Generator, Literal, Tuple, Type, TypeVar, Union, cast, get_args, get_origin, get_type_hints
|
|
5
7
|
|
|
6
8
|
from flyte._logging import logger
|
|
7
9
|
|
|
10
|
+
LITERAL_ENUM = "LiteralEnum"
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
def default_output_name(index: int = 0) -> str:
|
|
10
14
|
return f"o{index}"
|
|
@@ -47,6 +51,8 @@ def extract_return_annotation(return_annotation: Union[Type, Tuple, None]) -> Di
|
|
|
47
51
|
Note that Options 1 and 2 are identical, just syntactic sugar. In the NamedTuple case, we'll use the names in the
|
|
48
52
|
definition. In all other cases, we'll automatically generate output names, indexed starting at 0.
|
|
49
53
|
"""
|
|
54
|
+
if isinstance(return_annotation, str):
|
|
55
|
+
raise TypeError("String return annotations are not supported.")
|
|
50
56
|
|
|
51
57
|
# Handle Option 6
|
|
52
58
|
# We can think about whether we should add a default output name with type None in the future.
|
|
@@ -62,16 +68,24 @@ def extract_return_annotation(return_annotation: Union[Type, Tuple, None]) -> Di
|
|
|
62
68
|
# Options 1 and 2
|
|
63
69
|
bases = return_annotation.__bases__ # type: ignore
|
|
64
70
|
if len(bases) == 1 and bases[0] is tuple and hasattr(return_annotation, "_fields"):
|
|
65
|
-
|
|
71
|
+
# Task returns named tuple
|
|
66
72
|
return dict(get_type_hints(cast(Type, return_annotation), include_extras=True))
|
|
67
73
|
|
|
68
74
|
if hasattr(return_annotation, "__origin__") and return_annotation.__origin__ is tuple: # type: ignore
|
|
69
75
|
# Handle option 3
|
|
70
|
-
|
|
76
|
+
# Task returns unnamed typing.Tuple
|
|
71
77
|
if len(return_annotation.__args__) == 1: # type: ignore
|
|
72
78
|
raise TypeError("Tuples should be used to indicate multiple return values, found only one return variable.")
|
|
73
79
|
ra = get_args(return_annotation)
|
|
74
|
-
|
|
80
|
+
annotations = {}
|
|
81
|
+
for i, r in enumerate(ra):
|
|
82
|
+
if r is Ellipsis:
|
|
83
|
+
raise TypeError("Variable length tuples are not supported as return types.")
|
|
84
|
+
if get_origin(r) is Literal:
|
|
85
|
+
annotations[default_output_name(i)] = literal_to_enum(cast(Type, r))
|
|
86
|
+
else:
|
|
87
|
+
annotations[default_output_name(i)] = r
|
|
88
|
+
return annotations
|
|
75
89
|
|
|
76
90
|
elif isinstance(return_annotation, tuple):
|
|
77
91
|
if len(return_annotation) == 1:
|
|
@@ -80,5 +94,26 @@ def extract_return_annotation(return_annotation: Union[Type, Tuple, None]) -> Di
|
|
|
80
94
|
|
|
81
95
|
else:
|
|
82
96
|
# Handle all other single return types
|
|
83
|
-
|
|
97
|
+
# Task returns unnamed native tuple
|
|
98
|
+
if get_origin(return_annotation) is Literal:
|
|
99
|
+
return {default_output_name(): literal_to_enum(cast(Type, return_annotation))}
|
|
84
100
|
return {default_output_name(): cast(Type, return_annotation)}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def literal_to_enum(literal_type: Type) -> Type[Enum | typing.Any]:
|
|
104
|
+
"""Convert a Literal[...] into Union[str, Enum]."""
|
|
105
|
+
|
|
106
|
+
if get_origin(literal_type) is not Literal:
|
|
107
|
+
raise TypeError(f"{literal_type} is not a Literal")
|
|
108
|
+
|
|
109
|
+
values = get_args(literal_type)
|
|
110
|
+
if not all(isinstance(v, str) for v in values):
|
|
111
|
+
logger.warning(f"Literal type {literal_type} contains non-string values, using Any instead of Enum")
|
|
112
|
+
return typing.Any
|
|
113
|
+
# Deduplicate & keep order
|
|
114
|
+
enum_dict = {str(v).upper(): v for v in values}
|
|
115
|
+
|
|
116
|
+
# Dynamically create an Enum
|
|
117
|
+
literal_enum = Enum(LITERAL_ENUM, enum_dict) # type: ignore
|
|
118
|
+
|
|
119
|
+
return literal_enum # type: ignore
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
import concurrent.futures
|
|
1
2
|
import threading
|
|
2
|
-
from typing import Any, Literal, Optional, Protocol, Tuple, TypeVar
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Protocol, Tuple, TypeVar
|
|
3
4
|
|
|
4
|
-
from flyte._datastructures import ActionID, NativeInterface
|
|
5
5
|
from flyte._task import TaskTemplate
|
|
6
|
+
from flyte.models import ActionID, NativeInterface
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from flyte.remote._task import TaskDetails
|
|
6
10
|
|
|
7
11
|
from ._trace import TraceInfo
|
|
8
12
|
|
|
9
13
|
__all__ = ["Controller", "ControllerType", "TraceInfo", "create_controller", "get_controller"]
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
import concurrent.futures
|
|
12
17
|
|
|
13
18
|
ControllerType = Literal["local", "remote"]
|
|
14
19
|
|
|
@@ -28,7 +33,16 @@ class Controller(Protocol):
|
|
|
28
33
|
"""
|
|
29
34
|
...
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
def submit_sync(self, _task: TaskTemplate, *args, **kwargs) -> concurrent.futures.Future:
|
|
37
|
+
"""
|
|
38
|
+
This should call the async submit method above, but return a concurrent Future object that can be
|
|
39
|
+
used in a blocking wait or wrapped in an async future. This is called when
|
|
40
|
+
a) a synchronous task is kicked off locally,
|
|
41
|
+
b) a running task (of either kind) kicks off a downstream synchronous task.
|
|
42
|
+
"""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
async def submit_task_ref(self, _task: "TaskDetails", *args, **kwargs) -> Any:
|
|
32
46
|
"""
|
|
33
47
|
Submit a task reference to the controller asynchronously and wait for the result. This is async and will block
|
|
34
48
|
the current coroutine until the result is available.
|
|
@@ -47,12 +61,12 @@ class Controller(Protocol):
|
|
|
47
61
|
async def watch_for_errors(self): ...
|
|
48
62
|
|
|
49
63
|
async def get_action_outputs(
|
|
50
|
-
self, _interface: NativeInterface,
|
|
64
|
+
self, _interface: NativeInterface, _func: Callable, *args, **kwargs
|
|
51
65
|
) -> Tuple[TraceInfo, bool]:
|
|
52
66
|
"""
|
|
53
67
|
This method returns the outputs of the action, if it is available.
|
|
54
68
|
:param _interface: NativeInterface
|
|
55
|
-
:param
|
|
69
|
+
:param _func: Function name
|
|
56
70
|
:param args: Arguments
|
|
57
71
|
:param kwargs: Keyword arguments
|
|
58
72
|
:return: TraceInfo object and a boolean indicating if the action was found.
|
|
@@ -81,13 +95,13 @@ class _ControllerState:
|
|
|
81
95
|
lock = threading.Lock()
|
|
82
96
|
|
|
83
97
|
|
|
84
|
-
|
|
98
|
+
def get_controller() -> Controller:
|
|
85
99
|
"""
|
|
86
100
|
Get the controller instance. Raise an error if it has not been created.
|
|
87
101
|
"""
|
|
88
102
|
if _ControllerState.controller is not None:
|
|
89
103
|
return _ControllerState.controller
|
|
90
|
-
raise RuntimeError("Controller is not initialized. Please call
|
|
104
|
+
raise RuntimeError("Controller is not initialized. Please call create_controller() first.")
|
|
91
105
|
|
|
92
106
|
|
|
93
107
|
def create_controller(
|
|
@@ -1,26 +1,83 @@
|
|
|
1
|
-
|
|
1
|
+
import asyncio
|
|
2
|
+
import atexit
|
|
3
|
+
import concurrent.futures
|
|
4
|
+
import os
|
|
5
|
+
import pathlib
|
|
6
|
+
import threading
|
|
7
|
+
from typing import Any, Callable, Tuple, TypeVar
|
|
2
8
|
|
|
3
9
|
import flyte.errors
|
|
10
|
+
from flyte._cache.cache import VersionParameters, cache_from_request
|
|
11
|
+
from flyte._cache.local_cache import LocalTaskCache
|
|
4
12
|
from flyte._context import internal_ctx
|
|
5
|
-
from flyte._datastructures import ActionID, NativeInterface, RawDataPath
|
|
6
13
|
from flyte._internal.controllers import TraceInfo
|
|
7
14
|
from flyte._internal.runtime import convert
|
|
8
15
|
from flyte._internal.runtime.entrypoints import direct_dispatch
|
|
16
|
+
from flyte._internal.runtime.types_serde import transform_native_to_typed_interface
|
|
9
17
|
from flyte._logging import log, logger
|
|
10
|
-
from flyte.
|
|
11
|
-
from flyte.
|
|
18
|
+
from flyte._task import AsyncFunctionTaskTemplate, TaskTemplate
|
|
19
|
+
from flyte._utils.helpers import _selector_policy
|
|
20
|
+
from flyte.models import ActionID, NativeInterface
|
|
21
|
+
from flyte.remote._task import TaskDetails
|
|
12
22
|
|
|
13
23
|
R = TypeVar("R")
|
|
14
24
|
|
|
15
25
|
|
|
26
|
+
class _TaskRunner:
|
|
27
|
+
"""A task runner that runs an asyncio event loop on a background thread."""
|
|
28
|
+
|
|
29
|
+
def __init__(self) -> None:
|
|
30
|
+
self.__loop: asyncio.AbstractEventLoop | None = None
|
|
31
|
+
self.__runner_thread: threading.Thread | None = None
|
|
32
|
+
self.__lock = threading.Lock()
|
|
33
|
+
atexit.register(self._close)
|
|
34
|
+
|
|
35
|
+
def _close(self) -> None:
|
|
36
|
+
if self.__loop:
|
|
37
|
+
self.__loop.stop()
|
|
38
|
+
|
|
39
|
+
def _execute(self) -> None:
|
|
40
|
+
loop = self.__loop
|
|
41
|
+
assert loop is not None
|
|
42
|
+
try:
|
|
43
|
+
loop.run_forever()
|
|
44
|
+
finally:
|
|
45
|
+
loop.close()
|
|
46
|
+
|
|
47
|
+
def get_exc_handler(self):
|
|
48
|
+
def exc_handler(loop, context):
|
|
49
|
+
logger.error(
|
|
50
|
+
f"Taskrunner for {self.__runner_thread.name if self.__runner_thread else 'no thread'} caught"
|
|
51
|
+
f" exception in {loop}: {context}"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return exc_handler
|
|
55
|
+
|
|
56
|
+
def get_run_future(self, coro: Any) -> concurrent.futures.Future:
|
|
57
|
+
"""Synchronously run a coroutine on a background thread."""
|
|
58
|
+
name = f"{threading.current_thread().name} : loop-runner"
|
|
59
|
+
with self.__lock:
|
|
60
|
+
if self.__loop is None:
|
|
61
|
+
with _selector_policy():
|
|
62
|
+
self.__loop = asyncio.new_event_loop()
|
|
63
|
+
|
|
64
|
+
exc_handler = self.get_exc_handler()
|
|
65
|
+
self.__loop.set_exception_handler(exc_handler)
|
|
66
|
+
self.__runner_thread = threading.Thread(target=self._execute, daemon=True, name=name)
|
|
67
|
+
self.__runner_thread.start()
|
|
68
|
+
fut = asyncio.run_coroutine_threadsafe(coro, self.__loop)
|
|
69
|
+
return fut
|
|
70
|
+
|
|
71
|
+
|
|
16
72
|
class LocalController:
|
|
17
73
|
def __init__(self):
|
|
18
74
|
logger.debug("LocalController init")
|
|
75
|
+
self._runner_map: dict[str, _TaskRunner] = {}
|
|
19
76
|
|
|
20
77
|
@log
|
|
21
78
|
async def submit(self, _task: TaskTemplate, *args, **kwargs) -> Any:
|
|
22
79
|
"""
|
|
23
|
-
|
|
80
|
+
Main entrypoint for submitting a task to the local controller.
|
|
24
81
|
"""
|
|
25
82
|
ctx = internal_ctx()
|
|
26
83
|
tctx = ctx.data.task_context
|
|
@@ -28,43 +85,100 @@ class LocalController:
|
|
|
28
85
|
raise flyte.errors.RuntimeSystemError("BadContext", "Task context not initialized")
|
|
29
86
|
|
|
30
87
|
inputs = await convert.convert_from_native_to_inputs(_task.native_interface, *args, **kwargs)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
_task,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
88
|
+
inputs_hash = convert.generate_inputs_hash_from_proto(inputs.proto_inputs)
|
|
89
|
+
task_interface = transform_native_to_typed_interface(_task.interface)
|
|
90
|
+
|
|
91
|
+
sub_action_id, sub_action_output_path = convert.generate_sub_action_id_and_output_path(
|
|
92
|
+
tctx, _task.name, inputs_hash, 0
|
|
93
|
+
)
|
|
94
|
+
sub_action_raw_data_path = tctx.raw_data_path
|
|
95
|
+
# Make sure the output path exists
|
|
96
|
+
pathlib.Path(sub_action_output_path).mkdir(parents=True, exist_ok=True)
|
|
97
|
+
pathlib.Path(sub_action_raw_data_path.path).mkdir(parents=True, exist_ok=True)
|
|
98
|
+
|
|
99
|
+
task_cache = cache_from_request(_task.cache)
|
|
100
|
+
cache_enabled = task_cache.is_enabled()
|
|
101
|
+
if isinstance(_task, AsyncFunctionTaskTemplate):
|
|
102
|
+
version_parameters = VersionParameters(func=_task.func, image=_task.image)
|
|
103
|
+
else:
|
|
104
|
+
version_parameters = VersionParameters(func=None, image=_task.image)
|
|
105
|
+
cache_version = task_cache.get_version(version_parameters)
|
|
106
|
+
cache_key = convert.generate_cache_key_hash(
|
|
107
|
+
_task.name,
|
|
108
|
+
inputs_hash,
|
|
109
|
+
task_interface,
|
|
110
|
+
cache_version,
|
|
111
|
+
list(task_cache.get_ignored_inputs()),
|
|
112
|
+
inputs.proto_inputs,
|
|
45
113
|
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
114
|
+
|
|
115
|
+
out = None
|
|
116
|
+
# We only get output from cache if the cache behavior is set to auto
|
|
117
|
+
if task_cache.behavior == "auto":
|
|
118
|
+
out = await LocalTaskCache.get(cache_key)
|
|
119
|
+
if out is not None:
|
|
120
|
+
logger.info(
|
|
121
|
+
f"Cache hit for task '{_task.name}' (version: {cache_version}), getting result from cache..."
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if out is None:
|
|
125
|
+
out, err = await direct_dispatch(
|
|
126
|
+
_task,
|
|
127
|
+
controller=self,
|
|
128
|
+
action=sub_action_id,
|
|
129
|
+
raw_data_path=sub_action_raw_data_path,
|
|
130
|
+
inputs=inputs,
|
|
131
|
+
version=cache_version,
|
|
132
|
+
checkpoints=tctx.checkpoints,
|
|
133
|
+
code_bundle=tctx.code_bundle,
|
|
134
|
+
output_path=sub_action_output_path,
|
|
135
|
+
run_base_dir=tctx.run_base_dir,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
if err:
|
|
139
|
+
exc = convert.convert_error_to_native(err)
|
|
140
|
+
if exc:
|
|
141
|
+
raise exc
|
|
142
|
+
else:
|
|
143
|
+
raise flyte.errors.RuntimeSystemError("BadError", "Unknown error")
|
|
144
|
+
|
|
145
|
+
# store into cache
|
|
146
|
+
if cache_enabled and out is not None:
|
|
147
|
+
await LocalTaskCache.set(cache_key, out)
|
|
148
|
+
|
|
149
|
+
if _task.native_interface.outputs:
|
|
150
|
+
if out is None:
|
|
151
|
+
raise flyte.errors.RuntimeSystemError("BadOutput", "Task output not captured.")
|
|
53
152
|
result = await convert.convert_outputs_to_native(_task.native_interface, out)
|
|
54
153
|
return result
|
|
55
|
-
return
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
def submit_sync(self, _task: TaskTemplate, *args, **kwargs) -> concurrent.futures.Future:
|
|
157
|
+
name = threading.current_thread().name + f"PID:{os.getpid()}"
|
|
158
|
+
coro = self.submit(_task, *args, **kwargs)
|
|
159
|
+
if name not in self._runner_map:
|
|
160
|
+
if len(self._runner_map) > 100:
|
|
161
|
+
logger.warning(
|
|
162
|
+
"More than 100 event loop runners created!!! This could be a case of runaway recursion..."
|
|
163
|
+
)
|
|
164
|
+
self._runner_map[name] = _TaskRunner()
|
|
165
|
+
|
|
166
|
+
return self._runner_map[name].get_run_future(coro)
|
|
56
167
|
|
|
57
168
|
async def finalize_parent_action(self, action: ActionID):
|
|
58
169
|
pass
|
|
59
170
|
|
|
60
171
|
async def stop(self):
|
|
61
|
-
|
|
172
|
+
await LocalTaskCache.close()
|
|
62
173
|
|
|
63
174
|
async def watch_for_errors(self):
|
|
64
|
-
|
|
175
|
+
try:
|
|
176
|
+
await asyncio.Event().wait() # Wait indefinitely until cancelled
|
|
177
|
+
except asyncio.CancelledError:
|
|
178
|
+
return # Return with no errors when cancelled
|
|
65
179
|
|
|
66
180
|
async def get_action_outputs(
|
|
67
|
-
self, _interface: NativeInterface,
|
|
181
|
+
self, _interface: NativeInterface, _func: Callable, *args, **kwargs
|
|
68
182
|
) -> Tuple[TraceInfo, bool]:
|
|
69
183
|
"""
|
|
70
184
|
This method returns the outputs of the action, if it is available.
|
|
@@ -75,16 +189,23 @@ class LocalController:
|
|
|
75
189
|
tctx = ctx.data.task_context
|
|
76
190
|
if not tctx:
|
|
77
191
|
raise flyte.errors.NotInTaskContextError("BadContext", "Task context not initialized")
|
|
192
|
+
|
|
78
193
|
converted_inputs = convert.Inputs.empty()
|
|
79
194
|
if _interface.inputs:
|
|
80
195
|
converted_inputs = await convert.convert_from_native_to_inputs(_interface, *args, **kwargs)
|
|
81
196
|
assert converted_inputs
|
|
197
|
+
|
|
198
|
+
inputs_hash = convert.generate_inputs_hash_from_proto(converted_inputs.proto_inputs)
|
|
82
199
|
action_id, action_output_path = convert.generate_sub_action_id_and_output_path(
|
|
83
|
-
tctx,
|
|
200
|
+
tctx,
|
|
201
|
+
_func.__name__,
|
|
202
|
+
inputs_hash,
|
|
203
|
+
0,
|
|
84
204
|
)
|
|
85
205
|
assert action_output_path
|
|
86
206
|
return (
|
|
87
207
|
TraceInfo(
|
|
208
|
+
name=_func.__name__,
|
|
88
209
|
action=action_id,
|
|
89
210
|
interface=_interface,
|
|
90
211
|
inputs_path=action_output_path,
|
|
@@ -105,14 +226,17 @@ class LocalController:
|
|
|
105
226
|
|
|
106
227
|
if info.interface.outputs and info.output:
|
|
107
228
|
# If the result is not an AsyncGenerator, convert it directly
|
|
108
|
-
converted_outputs = await convert.convert_from_native_to_outputs(info.output, info.interface)
|
|
229
|
+
converted_outputs = await convert.convert_from_native_to_outputs(info.output, info.interface, info.name)
|
|
109
230
|
assert converted_outputs
|
|
110
231
|
elif info.error:
|
|
111
232
|
# If there is an error, convert it to a native error
|
|
112
233
|
converted_error = convert.convert_from_native_to_error(info.error)
|
|
113
234
|
assert converted_error
|
|
114
235
|
assert info.action
|
|
115
|
-
assert info.
|
|
236
|
+
assert info.start_time
|
|
237
|
+
assert info.end_time
|
|
116
238
|
|
|
117
|
-
async def submit_task_ref(self, _task:
|
|
118
|
-
raise flyte.errors.
|
|
239
|
+
async def submit_task_ref(self, _task: TaskDetails, max_inline_io_bytes: int, *args, **kwargs) -> Any:
|
|
240
|
+
raise flyte.errors.RemoteTaskError(
|
|
241
|
+
f"Remote tasks cannot be executed locally, only remotely. Found remote task {_task.name}"
|
|
242
|
+
)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from datetime import timedelta
|
|
1
|
+
from dataclasses import dataclass, field
|
|
3
2
|
from typing import Any, Optional
|
|
4
3
|
|
|
5
|
-
from
|
|
4
|
+
from flyteidl2.core import interface_pb2
|
|
5
|
+
|
|
6
|
+
from flyte.models import ActionID, NativeInterface
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
@dataclass
|
|
@@ -12,29 +13,36 @@ class TraceInfo:
|
|
|
12
13
|
the action is completed.
|
|
13
14
|
"""
|
|
14
15
|
|
|
16
|
+
name: str
|
|
15
17
|
action: ActionID
|
|
16
18
|
interface: NativeInterface
|
|
17
19
|
inputs_path: str
|
|
18
|
-
|
|
20
|
+
start_time: float = field(init=False, default=0.0)
|
|
21
|
+
end_time: float = field(init=False, default=0.0)
|
|
19
22
|
output: Optional[Any] = None
|
|
20
23
|
error: Optional[Exception] = None
|
|
24
|
+
typed_interface: Optional[interface_pb2.TypedInterface] = None
|
|
21
25
|
|
|
22
|
-
def add_outputs(self, output: Any,
|
|
26
|
+
def add_outputs(self, output: Any, start_time: float, end_time: float):
|
|
23
27
|
"""
|
|
24
28
|
Add outputs to the trace information.
|
|
25
29
|
:param output: Output of the action
|
|
26
|
-
:param
|
|
30
|
+
:param start_time: Start time of the action
|
|
31
|
+
:param end_time: End time of the action
|
|
27
32
|
:return:
|
|
28
33
|
"""
|
|
29
34
|
self.output = output
|
|
30
|
-
self.
|
|
35
|
+
self.start_time = start_time
|
|
36
|
+
self.end_time = end_time
|
|
31
37
|
|
|
32
|
-
def add_error(self, error: Exception,
|
|
38
|
+
def add_error(self, error: Exception, start_time: float, end_time: float):
|
|
33
39
|
"""
|
|
34
40
|
Add error to the trace information.
|
|
35
41
|
:param error: Error of the action
|
|
36
|
-
:param
|
|
42
|
+
:param start_time: Start time of the action
|
|
43
|
+
:param end_time: End time of the action
|
|
37
44
|
:return:
|
|
38
45
|
"""
|
|
39
46
|
self.error = error
|
|
40
|
-
self.
|
|
47
|
+
self.start_time = start_time
|
|
48
|
+
self.end_time = end_time
|
|
@@ -10,13 +10,13 @@ __all__ = ["RemoteController", "create_remote_controller"]
|
|
|
10
10
|
def create_remote_controller(
|
|
11
11
|
*,
|
|
12
12
|
api_key: str | None = None,
|
|
13
|
-
|
|
14
|
-
endpoint: str,
|
|
15
|
-
client_config: ClientConfig | None = None,
|
|
16
|
-
headless: bool = False,
|
|
13
|
+
endpoint: str | None = None,
|
|
17
14
|
insecure: bool = False,
|
|
18
15
|
insecure_skip_verify: bool = False,
|
|
19
16
|
ca_cert_file_path: str | None = None,
|
|
17
|
+
client_config: ClientConfig | None = None,
|
|
18
|
+
auth_type: AuthType = "Pkce",
|
|
19
|
+
headless: bool = False,
|
|
20
20
|
command: List[str] | None = None,
|
|
21
21
|
proxy_command: List[str] | None = None,
|
|
22
22
|
client_id: str | None = None,
|
|
@@ -27,14 +27,43 @@ def create_remote_controller(
|
|
|
27
27
|
"""
|
|
28
28
|
Create a new instance of the remote controller.
|
|
29
29
|
"""
|
|
30
|
+
assert endpoint or api_key, "Either endpoint or api_key must be provided when initializing remote controller"
|
|
30
31
|
from ._client import ControllerClient
|
|
31
32
|
from ._controller import RemoteController
|
|
32
33
|
|
|
34
|
+
# https://grpc.io/docs/guides/keepalive/#keepalive-configuration-specification
|
|
35
|
+
channel_options = [
|
|
36
|
+
("grpc.keepalive_permit_without_calls", 1),
|
|
37
|
+
("grpc.keepalive_time_ms", 30000), # Send keepalive ping every 30 seconds
|
|
38
|
+
("grpc.keepalive_timeout_ms", 10000), # Wait 10 seconds for keepalive response
|
|
39
|
+
("grpc.http2.max_pings_without_data", 0), # Allow unlimited pings without data
|
|
40
|
+
("grpc.http2.min_ping_interval_without_data_ms", 30000), # Min 30s between pings
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
if endpoint:
|
|
44
|
+
client_coro = ControllerClient.for_endpoint(
|
|
45
|
+
endpoint,
|
|
46
|
+
insecure=insecure,
|
|
47
|
+
insecure_skip_verify=insecure_skip_verify,
|
|
48
|
+
ca_cert_file_path=ca_cert_file_path,
|
|
49
|
+
client_id=client_id,
|
|
50
|
+
client_credentials_secret=client_credentials_secret,
|
|
51
|
+
auth_type=auth_type,
|
|
52
|
+
grpc_options=channel_options,
|
|
53
|
+
)
|
|
54
|
+
elif api_key:
|
|
55
|
+
client_coro = ControllerClient.for_api_key(
|
|
56
|
+
api_key,
|
|
57
|
+
insecure=insecure,
|
|
58
|
+
insecure_skip_verify=insecure_skip_verify,
|
|
59
|
+
ca_cert_file_path=ca_cert_file_path,
|
|
60
|
+
client_id=client_id,
|
|
61
|
+
client_credentials_secret=client_credentials_secret,
|
|
62
|
+
auth_type=auth_type,
|
|
63
|
+
grpc_options=channel_options,
|
|
64
|
+
)
|
|
65
|
+
|
|
33
66
|
controller = RemoteController(
|
|
34
|
-
client_coro=
|
|
35
|
-
endpoint=endpoint, insecure=insecure, insecure_skip_verify=insecure_skip_verify
|
|
36
|
-
),
|
|
37
|
-
workers=10,
|
|
38
|
-
max_system_retries=5,
|
|
67
|
+
client_coro=client_coro,
|
|
39
68
|
)
|
|
40
69
|
return controller
|