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/_utils/uv_script_parser.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pathlib
|
|
2
2
|
import re
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
+
from functools import lru_cache
|
|
4
5
|
from typing import Dict, List, Optional
|
|
5
6
|
|
|
6
7
|
import toml
|
|
@@ -15,6 +16,7 @@ class ToolUVConfig:
|
|
|
15
16
|
class UVScriptMetadata:
|
|
16
17
|
requires_python: Optional[str] = None
|
|
17
18
|
dependencies: List[str] = field(default_factory=list)
|
|
19
|
+
pyprojects: List[str] = field(default_factory=list)
|
|
18
20
|
tool: Optional[Dict[str, ToolUVConfig]] = None
|
|
19
21
|
|
|
20
22
|
|
|
@@ -27,6 +29,7 @@ def _extract_uv_metadata_block(text: str) -> str | None:
|
|
|
27
29
|
return "\n".join(lines)
|
|
28
30
|
|
|
29
31
|
|
|
32
|
+
@lru_cache
|
|
30
33
|
def parse_uv_script_file(path: pathlib.Path) -> UVScriptMetadata:
|
|
31
34
|
if not path.exists() or not path.is_file():
|
|
32
35
|
raise FileNotFoundError(f"File not found: {path}")
|
|
@@ -42,8 +45,12 @@ def parse_uv_script_file(path: pathlib.Path) -> UVScriptMetadata:
|
|
|
42
45
|
raise ValueError(f"Invalid TOML in metadata block: {e}")
|
|
43
46
|
|
|
44
47
|
tool_data = data.get("tool", {}).get("uv", {})
|
|
48
|
+
dependencies = data.get("dependencies", [])
|
|
49
|
+
py_dependencies = [dep for dep in dependencies if "file://" not in dep]
|
|
50
|
+
pyprojects = [dep.split("file://")[-1] for dep in dependencies if "file://" in dep]
|
|
45
51
|
return UVScriptMetadata(
|
|
46
52
|
requires_python=data.get("requires-python"),
|
|
47
|
-
dependencies=
|
|
53
|
+
dependencies=py_dependencies,
|
|
54
|
+
pyprojects=pyprojects,
|
|
48
55
|
tool={"uv": ToolUVConfig(exclude_newer=tool_data.get("exclude-newer"))} if tool_data else None,
|
|
49
56
|
)
|
flyte/_version.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '
|
|
21
|
-
__version_tuple__ = version_tuple = (
|
|
31
|
+
__version__ = version = '2.0.0b46'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 0, 0, 'b46')
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'g9b41862a0'
|
flyte/app/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from flyte.app._app_environment import AppEnvironment
|
|
2
|
+
from flyte.app._connector_environment import ConnectorEnvironment
|
|
3
|
+
from flyte.app._parameter import AppEndpoint, Parameter, RunOutput, get_parameter
|
|
4
|
+
from flyte.app._types import Domain, Link, Port, Scaling
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"AppEndpoint",
|
|
8
|
+
"AppEnvironment",
|
|
9
|
+
"ConnectorEnvironment",
|
|
10
|
+
"Domain",
|
|
11
|
+
"Link",
|
|
12
|
+
"Parameter",
|
|
13
|
+
"Port",
|
|
14
|
+
"RunOutput",
|
|
15
|
+
"Scaling",
|
|
16
|
+
"get_parameter",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def register_app_deployer():
|
|
21
|
+
from flyte import _deployer as deployer
|
|
22
|
+
from flyte.app._deploy import _deploy_app_env
|
|
23
|
+
|
|
24
|
+
deployer.register_deployer(AppEnvironment, _deploy_app_env)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
register_app_deployer()
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import shlex
|
|
7
|
+
from dataclasses import dataclass, field, replace
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Callable, List, Literal, Optional, Union
|
|
9
|
+
|
|
10
|
+
import rich.repr
|
|
11
|
+
|
|
12
|
+
from flyte import Environment, Image, Resources, SecretRequest
|
|
13
|
+
from flyte.app._parameter import Parameter
|
|
14
|
+
from flyte.app._types import Domain, Link, Port, Scaling
|
|
15
|
+
from flyte.models import SerializationContext
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
APP_NAME_RE = re.compile(r"[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*")
|
|
22
|
+
INVALID_APP_PORTS = [8012, 8022, 8112, 9090, 9091]
|
|
23
|
+
INTERNAL_APP_ENDPOINT_PATTERN_ENV_VAR = "INTERNAL_APP_ENDPOINT_PATTERN"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@rich.repr.auto
|
|
27
|
+
@dataclass(init=True, repr=True)
|
|
28
|
+
class AppEnvironment(Environment):
|
|
29
|
+
"""
|
|
30
|
+
:param type: Type of the environment.
|
|
31
|
+
:param port: Port to use for the app server.
|
|
32
|
+
:param args: Arguments to pass to app.
|
|
33
|
+
:param command: Command to run in the app.
|
|
34
|
+
:param requires_auth: Whether the app requires authentication.
|
|
35
|
+
:param scaling: Scaling configuration for the app environment.
|
|
36
|
+
:param domain: Domain to use for the app.
|
|
37
|
+
:param links: Links to other environments.
|
|
38
|
+
:param include: Files to include in the environment to run the app.
|
|
39
|
+
:param parameters: Parameters to pass to the app environment.
|
|
40
|
+
:param cluster_pool: Cluster pool to use for the app environment.
|
|
41
|
+
:param name: Name of the app environment
|
|
42
|
+
:param image: Docker image to use for the environment. If set to "auto", will use the default image.
|
|
43
|
+
:param resources: Resources to allocate for the environment.
|
|
44
|
+
:param env_vars: Environment variables to set for the environment.
|
|
45
|
+
:param secrets: Secrets to inject into the environment.
|
|
46
|
+
:param depends_on: Environment dependencies to hint, so when you deploy the environment, the dependencies are
|
|
47
|
+
also deployed. This is useful when you have a set of environments that depend on each other.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
type: Optional[str] = None
|
|
51
|
+
port: int | Port = 8080
|
|
52
|
+
args: Optional[Union[List[str], str]] = None
|
|
53
|
+
command: Optional[Union[List[str], str]] = None
|
|
54
|
+
requires_auth: bool = True
|
|
55
|
+
scaling: Scaling = field(default_factory=Scaling)
|
|
56
|
+
domain: Domain | None = field(default_factory=Domain)
|
|
57
|
+
# Integration
|
|
58
|
+
links: List[Link] = field(default_factory=list)
|
|
59
|
+
|
|
60
|
+
# Code
|
|
61
|
+
include: List[str] = field(default_factory=list)
|
|
62
|
+
parameters: List[Parameter] = field(default_factory=list)
|
|
63
|
+
|
|
64
|
+
# queue / cluster_pool
|
|
65
|
+
cluster_pool: str = "default"
|
|
66
|
+
|
|
67
|
+
# private field
|
|
68
|
+
_server: Callable[[], None] | None = field(init=False, default=None)
|
|
69
|
+
_on_startup: Callable[[], None] | None = field(init=False, default=None)
|
|
70
|
+
_on_shutdown: Callable[[], None] | None = field(init=False, default=None)
|
|
71
|
+
|
|
72
|
+
def _validate_name(self):
|
|
73
|
+
if not APP_NAME_RE.fullmatch(self.name):
|
|
74
|
+
raise ValueError(
|
|
75
|
+
f"App name '{self.name}' must consist of lower case alphanumeric characters or '-', "
|
|
76
|
+
"and must start and end with an alphanumeric character."
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def _get_app_filename(self) -> str:
|
|
80
|
+
"""
|
|
81
|
+
Get the filename of the file that declares this app environment.
|
|
82
|
+
|
|
83
|
+
Returns the actual file path instead of <string>, skipping flyte SDK internal files.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def is_user_file(filename: str) -> bool:
|
|
87
|
+
"""Check if a file is a user file (not part of flyte SDK)."""
|
|
88
|
+
if filename in ("<string>", "<stdin>"):
|
|
89
|
+
return False
|
|
90
|
+
if not os.path.exists(filename):
|
|
91
|
+
return False
|
|
92
|
+
# Skip files that are part of the flyte SDK
|
|
93
|
+
abs_path = os.path.abspath(filename)
|
|
94
|
+
# Check if file is in flyte package
|
|
95
|
+
return ("site-packages/flyte" not in abs_path and "/flyte/" not in abs_path) or "/examples/" in abs_path
|
|
96
|
+
|
|
97
|
+
# Try frame inspection first - walk up the stack to find user file
|
|
98
|
+
frame = inspect.currentframe()
|
|
99
|
+
while frame is not None:
|
|
100
|
+
filename = frame.f_code.co_filename
|
|
101
|
+
if is_user_file(filename):
|
|
102
|
+
return os.path.abspath(filename)
|
|
103
|
+
frame = frame.f_back
|
|
104
|
+
|
|
105
|
+
# Fallback: Inspect the full stack to find the first user file
|
|
106
|
+
stack = inspect.stack()
|
|
107
|
+
for frame_info in stack:
|
|
108
|
+
filename = frame_info.filename
|
|
109
|
+
if is_user_file(filename):
|
|
110
|
+
return os.path.abspath(filename)
|
|
111
|
+
|
|
112
|
+
# Last fallback: Try to get from __main__ module
|
|
113
|
+
import sys
|
|
114
|
+
|
|
115
|
+
if hasattr(sys.modules.get("__main__"), "__file__"):
|
|
116
|
+
main_file = sys.modules["__main__"].__file__
|
|
117
|
+
if main_file and os.path.exists(main_file):
|
|
118
|
+
return os.path.abspath(main_file)
|
|
119
|
+
|
|
120
|
+
# Last resort: return the current working directory with a placeholder
|
|
121
|
+
# This shouldn't happen in normal usage
|
|
122
|
+
return os.path.join(os.getcwd(), "app.py")
|
|
123
|
+
|
|
124
|
+
def __post_init__(self):
|
|
125
|
+
super().__post_init__()
|
|
126
|
+
if self.args is not None and not isinstance(self.args, (list, str)):
|
|
127
|
+
raise TypeError(f"Expected args to be of type List[str] or str, got {type(self.args)}")
|
|
128
|
+
if isinstance(self.port, int):
|
|
129
|
+
self.port = Port(port=self.port) # Name should be blank can be h2c / http1
|
|
130
|
+
if self.port.port in INVALID_APP_PORTS:
|
|
131
|
+
raise ValueError(f"Port {self.port.port} is reserved and cannot be used for AppEnvironment")
|
|
132
|
+
if self.command is not None and not isinstance(self.command, (list, str)):
|
|
133
|
+
raise TypeError(f"Expected command to be of type List[str] or str, got {type(self.command)}")
|
|
134
|
+
if not isinstance(self.scaling, Scaling):
|
|
135
|
+
raise TypeError(f"Expected scaling to be of type Scaling, got {type(self.scaling)}")
|
|
136
|
+
if not isinstance(self.domain, (Domain, type(None))):
|
|
137
|
+
raise TypeError(f"Expected domain to be of type Domain or None, got {type(self.domain)}")
|
|
138
|
+
for link in self.links:
|
|
139
|
+
if not isinstance(link, Link):
|
|
140
|
+
raise TypeError(f"Expected links to be of type List[Link], got {type(link)}")
|
|
141
|
+
|
|
142
|
+
self._validate_name()
|
|
143
|
+
|
|
144
|
+
# get instantiated file to keep track of app root directory
|
|
145
|
+
self._app_filename = self._get_app_filename()
|
|
146
|
+
|
|
147
|
+
# Capture the frame where this environment was instantiated
|
|
148
|
+
# This helps us find the module where the app variable is defined
|
|
149
|
+
frame = inspect.currentframe()
|
|
150
|
+
if frame and frame.f_back:
|
|
151
|
+
# Go up the call stack to find the user's module
|
|
152
|
+
# Skip the dataclass __init__ frame
|
|
153
|
+
caller_frame = frame.f_back
|
|
154
|
+
if caller_frame and caller_frame.f_back:
|
|
155
|
+
self._caller_frame = inspect.getframeinfo(caller_frame.f_back)
|
|
156
|
+
|
|
157
|
+
def container_args(self, serialize_context: SerializationContext) -> List[str]:
|
|
158
|
+
if self.args is None:
|
|
159
|
+
return []
|
|
160
|
+
elif isinstance(self.args, str):
|
|
161
|
+
return shlex.split(self.args)
|
|
162
|
+
else:
|
|
163
|
+
# args is a list
|
|
164
|
+
return self.args
|
|
165
|
+
|
|
166
|
+
def _serialize_parameters(self, parameter_overrides: list[Parameter] | None) -> str:
|
|
167
|
+
if not self.parameters:
|
|
168
|
+
return ""
|
|
169
|
+
from ._parameter import SerializableParameterCollection
|
|
170
|
+
|
|
171
|
+
serialized_parameters = SerializableParameterCollection.from_parameters(parameter_overrides or self.parameters)
|
|
172
|
+
return serialized_parameters.to_transport
|
|
173
|
+
|
|
174
|
+
def on_startup(self, fn: Callable[..., None]) -> Callable[..., None]:
|
|
175
|
+
"""
|
|
176
|
+
Decorator to define the startup function for the app environment.
|
|
177
|
+
|
|
178
|
+
This function is called before the server function is called.
|
|
179
|
+
|
|
180
|
+
The decorated function can be a sync or async function, and accepts input
|
|
181
|
+
parameters based on the Parameters defined in the AppEnvironment
|
|
182
|
+
definition.
|
|
183
|
+
"""
|
|
184
|
+
self._on_startup = fn
|
|
185
|
+
return self._on_startup
|
|
186
|
+
|
|
187
|
+
def server(self, fn: Callable[..., None]) -> Callable[..., None]:
|
|
188
|
+
"""
|
|
189
|
+
Decorator to define the server function for the app environment.
|
|
190
|
+
|
|
191
|
+
This decorated function can be a sync or async function, and accepts input
|
|
192
|
+
parameters based on the Parameters defined in the AppEnvironment
|
|
193
|
+
definition.
|
|
194
|
+
"""
|
|
195
|
+
self._server = fn
|
|
196
|
+
return self._server
|
|
197
|
+
|
|
198
|
+
def on_shutdown(self, fn: Callable[..., None]) -> Callable[..., None]:
|
|
199
|
+
"""
|
|
200
|
+
Decorator to define the shutdown function for the app environment.
|
|
201
|
+
|
|
202
|
+
This function is called after the server function is called.
|
|
203
|
+
|
|
204
|
+
This decorated function can be a sync or async function, and accepts input
|
|
205
|
+
parameters based on the Parameters defined in the AppEnvironment
|
|
206
|
+
definition.
|
|
207
|
+
"""
|
|
208
|
+
self._on_shutdown = fn
|
|
209
|
+
return self._on_shutdown
|
|
210
|
+
|
|
211
|
+
def container_cmd(
|
|
212
|
+
self, serialize_context: SerializationContext, parameter_overrides: list[Parameter] | None = None
|
|
213
|
+
) -> List[str]:
|
|
214
|
+
from flyte._internal.resolvers.app_env import AppEnvResolver
|
|
215
|
+
|
|
216
|
+
if self.command is None:
|
|
217
|
+
# Default command
|
|
218
|
+
version = serialize_context.version
|
|
219
|
+
if version is None and serialize_context.code_bundle is not None:
|
|
220
|
+
version = serialize_context.code_bundle.computed_version
|
|
221
|
+
|
|
222
|
+
cmd: list[str] = [
|
|
223
|
+
"fserve",
|
|
224
|
+
"--version",
|
|
225
|
+
version or "",
|
|
226
|
+
"--project",
|
|
227
|
+
serialize_context.project or "",
|
|
228
|
+
"--domain",
|
|
229
|
+
serialize_context.domain or "",
|
|
230
|
+
"--org",
|
|
231
|
+
serialize_context.org or "",
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
if serialize_context.image_cache and serialize_context.image_cache.serialized_form:
|
|
235
|
+
cmd = [*cmd, "--image-cache", serialize_context.image_cache.serialized_form]
|
|
236
|
+
else:
|
|
237
|
+
if serialize_context.image_cache:
|
|
238
|
+
cmd = [*cmd, "--image-cache", serialize_context.image_cache.to_transport]
|
|
239
|
+
|
|
240
|
+
if serialize_context.code_bundle:
|
|
241
|
+
if serialize_context.code_bundle.tgz:
|
|
242
|
+
cmd = [*cmd, *["--tgz", f"{serialize_context.code_bundle.tgz}"]]
|
|
243
|
+
elif serialize_context.code_bundle.pkl:
|
|
244
|
+
cmd = [*cmd, *["--pkl", f"{serialize_context.code_bundle.pkl}"]]
|
|
245
|
+
cmd = [*cmd, *["--dest", f"{serialize_context.code_bundle.destination or '.'}"]]
|
|
246
|
+
|
|
247
|
+
if self.parameters:
|
|
248
|
+
cmd.append("--parameters")
|
|
249
|
+
cmd.append(self._serialize_parameters(parameter_overrides))
|
|
250
|
+
|
|
251
|
+
# Only add resolver args if _caller_frame is set and we can extract the module
|
|
252
|
+
# (i.e., app was created in a module and can be found)
|
|
253
|
+
if self._caller_frame is not None:
|
|
254
|
+
assert serialize_context.root_dir is not None
|
|
255
|
+
try:
|
|
256
|
+
_app_env_resolver = AppEnvResolver()
|
|
257
|
+
loader_args = _app_env_resolver.loader_args(self, serialize_context.root_dir)
|
|
258
|
+
cmd = [
|
|
259
|
+
*cmd,
|
|
260
|
+
*[
|
|
261
|
+
"--resolver",
|
|
262
|
+
_app_env_resolver.import_path,
|
|
263
|
+
"--resolver-args",
|
|
264
|
+
loader_args,
|
|
265
|
+
],
|
|
266
|
+
]
|
|
267
|
+
except RuntimeError as e:
|
|
268
|
+
# If we can't find the app in the module (e.g., in tests), skip resolver args
|
|
269
|
+
from flyte._logging import logger
|
|
270
|
+
|
|
271
|
+
logger.warning(f"Failed to extract app resolver args: {e}. Skipping resolver args.")
|
|
272
|
+
return [*cmd, "--"]
|
|
273
|
+
elif isinstance(self.command, str):
|
|
274
|
+
return shlex.split(self.command)
|
|
275
|
+
else:
|
|
276
|
+
# command is a list
|
|
277
|
+
return self.command
|
|
278
|
+
|
|
279
|
+
def get_port(self) -> Port:
|
|
280
|
+
if isinstance(self.port, int):
|
|
281
|
+
self.port = Port(port=self.port)
|
|
282
|
+
return self.port
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def endpoint(self) -> str:
|
|
286
|
+
endpoint_pattern = os.getenv(INTERNAL_APP_ENDPOINT_PATTERN_ENV_VAR)
|
|
287
|
+
if endpoint_pattern is not None:
|
|
288
|
+
return endpoint_pattern.format(app_fqdn=self.name)
|
|
289
|
+
|
|
290
|
+
import flyte.remote
|
|
291
|
+
from flyte._initialize import ensure_client
|
|
292
|
+
|
|
293
|
+
ensure_client()
|
|
294
|
+
app = flyte.remote.App.get(name=self.name)
|
|
295
|
+
return app.endpoint
|
|
296
|
+
|
|
297
|
+
def clone_with(
|
|
298
|
+
self,
|
|
299
|
+
name: str,
|
|
300
|
+
image: Optional[Union[str, Image, Literal["auto"]]] = None,
|
|
301
|
+
resources: Optional[Resources] = None,
|
|
302
|
+
env_vars: Optional[dict[str, str]] = None,
|
|
303
|
+
secrets: Optional[SecretRequest] = None,
|
|
304
|
+
depends_on: Optional[List[Environment]] = None,
|
|
305
|
+
description: Optional[str] = None,
|
|
306
|
+
interruptible: Optional[bool] = None,
|
|
307
|
+
**kwargs: Any,
|
|
308
|
+
) -> AppEnvironment:
|
|
309
|
+
# validate unknown kwargs if needed
|
|
310
|
+
|
|
311
|
+
type = kwargs.pop("type", None)
|
|
312
|
+
port = kwargs.pop("port", None)
|
|
313
|
+
args = kwargs.pop("args", None)
|
|
314
|
+
command = kwargs.pop("command", None)
|
|
315
|
+
requires_auth = kwargs.pop("requires_auth", None)
|
|
316
|
+
scaling = kwargs.pop("scaling", None)
|
|
317
|
+
domain = kwargs.pop("domain", None)
|
|
318
|
+
links = kwargs.pop("links", None)
|
|
319
|
+
include = kwargs.pop("include", None)
|
|
320
|
+
parameters = kwargs.pop("parameters", None)
|
|
321
|
+
cluster_pool = kwargs.pop("cluster_pool", None)
|
|
322
|
+
|
|
323
|
+
if kwargs:
|
|
324
|
+
raise TypeError(f"Unexpected keyword arguments: {list(kwargs.keys())}")
|
|
325
|
+
|
|
326
|
+
kwargs = self._get_kwargs()
|
|
327
|
+
kwargs["name"] = name
|
|
328
|
+
if image is not None:
|
|
329
|
+
kwargs["image"] = image
|
|
330
|
+
if resources is not None:
|
|
331
|
+
kwargs["resources"] = resources
|
|
332
|
+
if env_vars is not None:
|
|
333
|
+
kwargs["env_vars"] = env_vars
|
|
334
|
+
if secrets is not None:
|
|
335
|
+
kwargs["secrets"] = secrets
|
|
336
|
+
if depends_on is not None:
|
|
337
|
+
kwargs["depends_on"] = depends_on
|
|
338
|
+
if description is not None:
|
|
339
|
+
kwargs["description"] = description
|
|
340
|
+
if type is not None:
|
|
341
|
+
kwargs["type"] = type
|
|
342
|
+
if port is not None:
|
|
343
|
+
kwargs["port"] = port
|
|
344
|
+
if args is not None:
|
|
345
|
+
kwargs["args"] = args
|
|
346
|
+
if command is not None:
|
|
347
|
+
kwargs["command"] = command
|
|
348
|
+
if requires_auth is not None:
|
|
349
|
+
kwargs["requires_auth"] = requires_auth
|
|
350
|
+
if scaling is not None:
|
|
351
|
+
kwargs["scaling"] = scaling
|
|
352
|
+
if domain is not None:
|
|
353
|
+
kwargs["domain"] = domain
|
|
354
|
+
if links is not None:
|
|
355
|
+
kwargs["links"] = links
|
|
356
|
+
if include is not None:
|
|
357
|
+
kwargs["include"] = include
|
|
358
|
+
if parameters is not None:
|
|
359
|
+
kwargs["parameters"] = parameters
|
|
360
|
+
if cluster_pool is not None:
|
|
361
|
+
kwargs["cluster_pool"] = cluster_pool
|
|
362
|
+
return replace(self, **kwargs)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import shlex
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
import rich.repr
|
|
6
|
+
|
|
7
|
+
from flyte.app import AppEnvironment
|
|
8
|
+
from flyte.app._parameter import Parameter
|
|
9
|
+
from flyte.app._types import Port
|
|
10
|
+
from flyte.models import SerializationContext
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@rich.repr.auto
|
|
14
|
+
@dataclass(init=True, repr=True)
|
|
15
|
+
class ConnectorEnvironment(AppEnvironment):
|
|
16
|
+
type: str = "Connector"
|
|
17
|
+
port: int | Port = field(default=Port(port=8080, name="h2c"))
|
|
18
|
+
|
|
19
|
+
def __post_init__(self):
|
|
20
|
+
super().__post_init__()
|
|
21
|
+
|
|
22
|
+
def container_args(self, serialize_context: SerializationContext) -> List[str]:
|
|
23
|
+
if self.args is None:
|
|
24
|
+
if isinstance(self.port, Port):
|
|
25
|
+
port = self.port.port
|
|
26
|
+
else:
|
|
27
|
+
port = self.port
|
|
28
|
+
return ["c0", "--port", str(port), "--prometheus_port", "9092"]
|
|
29
|
+
return super().container_args(serialize_context)
|
|
30
|
+
|
|
31
|
+
def container_cmd(
|
|
32
|
+
self, serialize_context: SerializationContext, parameter_overrides: list[Parameter] | None = None
|
|
33
|
+
) -> List[str]:
|
|
34
|
+
if isinstance(self.command, str):
|
|
35
|
+
return shlex.split(self.command)
|
|
36
|
+
elif isinstance(self.command, list):
|
|
37
|
+
return self.command
|
|
38
|
+
else:
|
|
39
|
+
# command is None, use default from parent class
|
|
40
|
+
return super().container_cmd(serialize_context, parameter_overrides)
|
flyte/app/_deploy.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import flyte._deployer as deployer
|
|
8
|
+
from flyte import Image
|
|
9
|
+
from flyte._code_bundle.bundle import build_code_bundle_from_relative_paths
|
|
10
|
+
from flyte._initialize import ensure_client
|
|
11
|
+
from flyte._logging import logger
|
|
12
|
+
from flyte.models import SerializationContext
|
|
13
|
+
|
|
14
|
+
from ._app_environment import AppEnvironment
|
|
15
|
+
from ._parameter import Parameter
|
|
16
|
+
|
|
17
|
+
if typing.TYPE_CHECKING:
|
|
18
|
+
from flyte._deployer import DeployedEnvironment
|
|
19
|
+
from flyte.remote import App
|
|
20
|
+
|
|
21
|
+
FILES_TAR_FILE_NAME = "code_bundle.tgz"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class DeployedAppEnvironment:
|
|
26
|
+
env: AppEnvironment
|
|
27
|
+
deployed_app: "App"
|
|
28
|
+
|
|
29
|
+
def get_name(self) -> str:
|
|
30
|
+
"""
|
|
31
|
+
Returns the name of the deployed environment.
|
|
32
|
+
"""
|
|
33
|
+
return self.env.name
|
|
34
|
+
|
|
35
|
+
def env_repr(self) -> typing.List[typing.Tuple[str, ...]]:
|
|
36
|
+
return [
|
|
37
|
+
("environment", self.env.name),
|
|
38
|
+
("image", self.env.image.uri if isinstance(self.env.image, Image) else self.env.image or ""),
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
def table_repr(self) -> typing.List[typing.List[typing.Tuple[str, ...]]]:
|
|
42
|
+
from flyteidl2.app import app_definition_pb2
|
|
43
|
+
|
|
44
|
+
return [
|
|
45
|
+
[
|
|
46
|
+
("type", "App"),
|
|
47
|
+
("name", f"[link={self.deployed_app.url}]{self.deployed_app.name}[/link]"),
|
|
48
|
+
("revision", str(self.deployed_app.revision)),
|
|
49
|
+
(
|
|
50
|
+
"desired state",
|
|
51
|
+
app_definition_pb2.Spec.DesiredState.Name(self.deployed_app.desired_state),
|
|
52
|
+
),
|
|
53
|
+
(
|
|
54
|
+
"current state",
|
|
55
|
+
app_definition_pb2.Status.DeploymentStatus.Name(self.deployed_app.deployment_status),
|
|
56
|
+
),
|
|
57
|
+
(
|
|
58
|
+
"public_url",
|
|
59
|
+
self.deployed_app.endpoint,
|
|
60
|
+
),
|
|
61
|
+
],
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
def summary_repr(self) -> str:
|
|
65
|
+
return f"Deployed App[{self.deployed_app.name}] in environment {self.env.name}"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async def _deploy_app(
|
|
69
|
+
app: AppEnvironment,
|
|
70
|
+
serialization_context: SerializationContext,
|
|
71
|
+
parameter_overrides: list[Parameter] | None = None,
|
|
72
|
+
dryrun: bool = False,
|
|
73
|
+
) -> "App":
|
|
74
|
+
"""
|
|
75
|
+
Deploy the given app.
|
|
76
|
+
"""
|
|
77
|
+
import flyte.errors
|
|
78
|
+
from flyte.app._runtime import translate_app_env_to_idl
|
|
79
|
+
from flyte.remote import App
|
|
80
|
+
|
|
81
|
+
is_pkl = serialization_context.code_bundle and serialization_context.code_bundle.pkl
|
|
82
|
+
if app.include and not is_pkl:
|
|
83
|
+
# Only bundle when not pickling. If this is a pkl bundle, assume that
|
|
84
|
+
# the AppEnvironment has a server function that will be used to serve
|
|
85
|
+
# the app. This function should contain all of the code needed to serve the app.
|
|
86
|
+
app_file = Path(app._app_filename)
|
|
87
|
+
app_root_dir = app_file.parent
|
|
88
|
+
_preexisting_code_bundle_files = []
|
|
89
|
+
if serialization_context.code_bundle is not None:
|
|
90
|
+
_preexisting_code_bundle_files = serialization_context.code_bundle.files or []
|
|
91
|
+
files = (*_preexisting_code_bundle_files, *[f for f in app.include if f not in _preexisting_code_bundle_files])
|
|
92
|
+
code_bundle = await build_code_bundle_from_relative_paths(files, from_dir=app_root_dir)
|
|
93
|
+
serialization_context.code_bundle = code_bundle
|
|
94
|
+
|
|
95
|
+
if serialization_context.code_bundle and serialization_context.code_bundle.pkl:
|
|
96
|
+
assert app._server is not None, (
|
|
97
|
+
"Server function is required for pkl code bundles, use the app_env.server() decorator to define the "
|
|
98
|
+
"server function."
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
image_uri = app.image.uri if isinstance(app.image, Image) else app.image
|
|
102
|
+
try:
|
|
103
|
+
app_idl = await translate_app_env_to_idl.aio(
|
|
104
|
+
app, serialization_context, parameter_overrides=parameter_overrides
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
if dryrun:
|
|
108
|
+
return app_idl
|
|
109
|
+
ensure_client()
|
|
110
|
+
msg = f"Deploying app {app.name}, with image {image_uri} version {serialization_context.version}"
|
|
111
|
+
if app_idl.spec.HasField("container") and app_idl.spec.container.args:
|
|
112
|
+
msg += f" with args {app_idl.spec.container.args}"
|
|
113
|
+
logger.info(msg)
|
|
114
|
+
|
|
115
|
+
return await App.create.aio(app_idl)
|
|
116
|
+
except Exception as exc:
|
|
117
|
+
logger.error(f"Failed to deploy app {app.name} with image {image_uri}: {exc}")
|
|
118
|
+
raise flyte.errors.DeploymentError(
|
|
119
|
+
f"Failed to deploy app {app.name} with image {image_uri}, Error: {exc!s}"
|
|
120
|
+
) from exc
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
async def _deploy_app_env(context: deployer.DeploymentContext) -> DeployedEnvironment:
|
|
124
|
+
if not isinstance(context.environment, AppEnvironment):
|
|
125
|
+
raise TypeError(f"Expected AppEnvironment, got {type(context.environment)}")
|
|
126
|
+
|
|
127
|
+
app_env = context.environment
|
|
128
|
+
deployed_app = await _deploy_app(app_env, context.serialization_context, dryrun=context.dryrun)
|
|
129
|
+
|
|
130
|
+
return DeployedAppEnvironment(env=app_env, deployed_app=deployed_app)
|