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
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
import dataclasses
|
|
3
2
|
import datetime
|
|
4
3
|
import enum
|
|
@@ -7,6 +6,7 @@ import importlib.util
|
|
|
7
6
|
import json
|
|
8
7
|
import os
|
|
9
8
|
import pathlib
|
|
9
|
+
import re
|
|
10
10
|
import sys
|
|
11
11
|
import typing
|
|
12
12
|
import typing as t
|
|
@@ -14,24 +14,16 @@ from typing import get_args
|
|
|
14
14
|
|
|
15
15
|
import rich_click as click
|
|
16
16
|
import yaml
|
|
17
|
-
from
|
|
18
|
-
from
|
|
19
|
-
|
|
20
|
-
from
|
|
21
|
-
from
|
|
22
|
-
from
|
|
23
|
-
from union.storage._remote_fs import RemoteFSPathResolver
|
|
24
|
-
from union.types import TypeEngine
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# ---------------------------------------------------
|
|
28
|
-
# TODO replace these
|
|
29
|
-
class ArtifactQuery:
|
|
30
|
-
pass
|
|
31
|
-
|
|
17
|
+
from click import Context, Parameter
|
|
18
|
+
from flyteidl2.core.interface_pb2 import Variable
|
|
19
|
+
from flyteidl2.core.literals_pb2 import Literal
|
|
20
|
+
from flyteidl2.core.types_pb2 import BlobType, LiteralType, SimpleType
|
|
21
|
+
from google.protobuf.json_format import MessageToDict
|
|
22
|
+
from mashumaro.codecs.json import JSONEncoder
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
from flyte._logging import logger
|
|
25
|
+
from flyte.io import Dir, File
|
|
26
|
+
from flyte.types._pickle import FlytePickleTransformer
|
|
35
27
|
|
|
36
28
|
|
|
37
29
|
class StructuredDataset:
|
|
@@ -43,26 +35,6 @@ class StructuredDataset:
|
|
|
43
35
|
# ---------------------------------------------------
|
|
44
36
|
|
|
45
37
|
|
|
46
|
-
def is_pydantic_basemodel(python_type: typing.Type) -> bool:
|
|
47
|
-
"""
|
|
48
|
-
Checks if the python type is a pydantic BaseModel
|
|
49
|
-
"""
|
|
50
|
-
try:
|
|
51
|
-
import pydantic # noqa: F401
|
|
52
|
-
except ImportError:
|
|
53
|
-
return False
|
|
54
|
-
else:
|
|
55
|
-
try:
|
|
56
|
-
from pydantic import BaseModel as BaseModelV2
|
|
57
|
-
from pydantic.v1 import BaseModel as BaseModelV1
|
|
58
|
-
|
|
59
|
-
return issubclass(python_type, BaseModelV1) or issubclass(python_type, BaseModelV2)
|
|
60
|
-
except ImportError:
|
|
61
|
-
from pydantic import BaseModel
|
|
62
|
-
|
|
63
|
-
return issubclass(python_type, BaseModel)
|
|
64
|
-
|
|
65
|
-
|
|
66
38
|
def key_value_callback(_: typing.Any, param: str, values: typing.List[str]) -> typing.Optional[typing.Dict[str, str]]:
|
|
67
39
|
"""
|
|
68
40
|
Callback for click to parse key-value pairs.
|
|
@@ -97,20 +69,19 @@ def labels_callback(_: typing.Any, param: str, values: typing.List[str]) -> typi
|
|
|
97
69
|
class DirParamType(click.ParamType):
|
|
98
70
|
name = "directory path"
|
|
99
71
|
|
|
72
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
|
73
|
+
return "Remote Dir Path"
|
|
74
|
+
|
|
100
75
|
def convert(
|
|
101
76
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
102
77
|
) -> typing.Any:
|
|
103
|
-
|
|
104
|
-
return value
|
|
78
|
+
from flyte.storage import is_remote
|
|
105
79
|
|
|
106
|
-
# set remote_directory to false if running pyflyte run locally. This makes sure that the original
|
|
107
|
-
# directory is used and not a random one.
|
|
108
|
-
remote_directory = None if getattr(ctx.obj, "is_remote", False) else False
|
|
109
80
|
if not is_remote(value):
|
|
110
81
|
p = pathlib.Path(value)
|
|
111
82
|
if not p.exists() or not p.is_dir():
|
|
112
83
|
raise click.BadParameter(f"parameter should be a valid flytedirectory path, {value}")
|
|
113
|
-
return Dir(path=value
|
|
84
|
+
return Dir(path=value)
|
|
114
85
|
|
|
115
86
|
|
|
116
87
|
class StructuredDatasetParamType(click.ParamType):
|
|
@@ -120,11 +91,12 @@ class StructuredDatasetParamType(click.ParamType):
|
|
|
120
91
|
|
|
121
92
|
name = "structured dataset path (dir/file)"
|
|
122
93
|
|
|
94
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
|
95
|
+
return "Remote parquet URI"
|
|
96
|
+
|
|
123
97
|
def convert(
|
|
124
98
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
125
99
|
) -> typing.Any:
|
|
126
|
-
if isinstance(value, ArtifactQuery):
|
|
127
|
-
return value
|
|
128
100
|
if isinstance(value, str):
|
|
129
101
|
return StructuredDataset(uri=value)
|
|
130
102
|
elif isinstance(value, StructuredDataset):
|
|
@@ -135,26 +107,27 @@ class StructuredDatasetParamType(click.ParamType):
|
|
|
135
107
|
class FileParamType(click.ParamType):
|
|
136
108
|
name = "file path"
|
|
137
109
|
|
|
110
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
|
111
|
+
return "Remote File Path"
|
|
112
|
+
|
|
138
113
|
def convert(
|
|
139
114
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
140
115
|
) -> typing.Any:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# set remote_directory to false if running pyflyte run locally. This makes sure that the original
|
|
144
|
-
# file is used and not a random one.
|
|
145
|
-
remote_path = None if getattr(ctx.obj, "is_remote", False) else False
|
|
116
|
+
from flyte.storage import is_remote
|
|
117
|
+
|
|
146
118
|
if not is_remote(value):
|
|
147
119
|
p = pathlib.Path(value)
|
|
148
120
|
if not p.exists() or not p.is_file():
|
|
149
121
|
raise click.BadParameter(f"parameter should be a valid file path, {value}")
|
|
150
|
-
|
|
122
|
+
raise click.BadParameter(f"Only remote paths are supported currently, {value}")
|
|
123
|
+
return File.from_existing_remote(value)
|
|
151
124
|
|
|
152
125
|
|
|
153
126
|
class PickleParamType(click.ParamType):
|
|
154
127
|
name = "pickle"
|
|
155
128
|
|
|
156
|
-
def get_metavar(self, param:
|
|
157
|
-
return "Python Object <Module>:<Object>"
|
|
129
|
+
def get_metavar(self, param: "Parameter", ctx) -> t.Optional[str]:
|
|
130
|
+
return "Python Object Instance <Module>:<Object>"
|
|
158
131
|
|
|
159
132
|
def convert(
|
|
160
133
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
@@ -163,7 +136,7 @@ class PickleParamType(click.ParamType):
|
|
|
163
136
|
return value
|
|
164
137
|
parts = value.split(":")
|
|
165
138
|
if len(parts) != 2:
|
|
166
|
-
if ctx and ctx.obj and ctx.obj.
|
|
139
|
+
if ctx and ctx.obj and ctx.obj.log_level >= 10: # DEBUG level
|
|
167
140
|
click.echo(f"Did not receive a string in the expected format <MODULE>:<VAR>, falling back to: {value}")
|
|
168
141
|
return value
|
|
169
142
|
try:
|
|
@@ -179,15 +152,15 @@ class PickleParamType(click.ParamType):
|
|
|
179
152
|
class JSONIteratorParamType(click.ParamType):
|
|
180
153
|
name = "json iterator"
|
|
181
154
|
|
|
155
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
|
156
|
+
return "JSON Value"
|
|
157
|
+
|
|
182
158
|
def convert(
|
|
183
159
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
184
160
|
) -> typing.Any:
|
|
185
161
|
return value
|
|
186
162
|
|
|
187
163
|
|
|
188
|
-
import re
|
|
189
|
-
|
|
190
|
-
|
|
191
164
|
def parse_iso8601_duration(iso_duration: str) -> datetime.timedelta:
|
|
192
165
|
pattern = re.compile(
|
|
193
166
|
r"^P" # Starts with 'P'
|
|
@@ -211,10 +184,10 @@ def parse_human_durations(text: str) -> list[datetime.timedelta]:
|
|
|
211
184
|
durations = []
|
|
212
185
|
|
|
213
186
|
for part in raw_parts:
|
|
214
|
-
|
|
187
|
+
new_part = part.strip().lower()
|
|
215
188
|
|
|
216
189
|
# Match 1:24 or :45
|
|
217
|
-
m_colon = re.match(r"^(?:(\d+):)?(\d+)$",
|
|
190
|
+
m_colon = re.match(r"^(?:(\d+):)?(\d+)$", new_part)
|
|
218
191
|
if m_colon:
|
|
219
192
|
minutes = int(m_colon.group(1)) if m_colon.group(1) else 0
|
|
220
193
|
seconds = int(m_colon.group(2))
|
|
@@ -222,7 +195,7 @@ def parse_human_durations(text: str) -> list[datetime.timedelta]:
|
|
|
222
195
|
continue
|
|
223
196
|
|
|
224
197
|
# Match "10 days", "1 minute", etc.
|
|
225
|
-
m_units = re.match(r"^(\d+)\s*(day|hour|minute|second)s?$",
|
|
198
|
+
m_units = re.match(r"^(\d+)\s*(day|hour|minute|second)s?$", new_part)
|
|
226
199
|
if m_units:
|
|
227
200
|
value = int(m_units.group(1))
|
|
228
201
|
unit = m_units.group(2)
|
|
@@ -270,9 +243,6 @@ class DateTimeType(click.DateTime):
|
|
|
270
243
|
def convert(
|
|
271
244
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
272
245
|
) -> typing.Any:
|
|
273
|
-
if isinstance(value, ArtifactQuery):
|
|
274
|
-
return value
|
|
275
|
-
|
|
276
246
|
if isinstance(value, str) and " " in value:
|
|
277
247
|
import re
|
|
278
248
|
|
|
@@ -300,11 +270,12 @@ class DateTimeType(click.DateTime):
|
|
|
300
270
|
class DurationParamType(click.ParamType):
|
|
301
271
|
name = "[1:24 | :22 | 1 minute | 10 days | ...]"
|
|
302
272
|
|
|
273
|
+
def get_metavar(self, param: Parameter, ctx: Context) -> str | None:
|
|
274
|
+
return "ISO8601 duration"
|
|
275
|
+
|
|
303
276
|
def convert(
|
|
304
277
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
305
278
|
) -> typing.Any:
|
|
306
|
-
if isinstance(value, ArtifactQuery):
|
|
307
|
-
return value
|
|
308
279
|
if value is None:
|
|
309
280
|
raise click.BadParameter("None value cannot be converted to a Duration type.")
|
|
310
281
|
return parse_duration(value)
|
|
@@ -318,8 +289,6 @@ class EnumParamType(click.Choice):
|
|
|
318
289
|
def convert(
|
|
319
290
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
320
291
|
) -> enum.Enum:
|
|
321
|
-
if isinstance(value, ArtifactQuery):
|
|
322
|
-
return value
|
|
323
292
|
if isinstance(value, self._enum_type):
|
|
324
293
|
return value
|
|
325
294
|
return self._enum_type(super().convert(value, param, ctx))
|
|
@@ -330,16 +299,20 @@ class UnionParamType(click.ParamType):
|
|
|
330
299
|
A composite type that allows for multiple types to be specified. This is used for union types.
|
|
331
300
|
"""
|
|
332
301
|
|
|
333
|
-
def __init__(self, types: typing.List[click.ParamType]):
|
|
302
|
+
def __init__(self, types: typing.List[click.ParamType | None]):
|
|
334
303
|
super().__init__()
|
|
335
304
|
self._types = self._sort_precedence(types)
|
|
305
|
+
self.name = "|".join([t.name for t in self._types if t is not None])
|
|
306
|
+
self.optional = False
|
|
307
|
+
if None in types:
|
|
308
|
+
self.name = f"Optional[{self.name}]"
|
|
309
|
+
self.optional = True
|
|
336
310
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
return "|".join([t.name for t in self._types])
|
|
311
|
+
def get_metavar(self, param: Parameter, ctx: typing.Optional[click.Context]) -> str | None:
|
|
312
|
+
return self.name
|
|
340
313
|
|
|
341
314
|
@staticmethod
|
|
342
|
-
def _sort_precedence(tp: typing.List[click.ParamType]) -> typing.List[click.ParamType]:
|
|
315
|
+
def _sort_precedence(tp: typing.List[click.ParamType | None]) -> typing.List[click.ParamType]:
|
|
343
316
|
unprocessed = []
|
|
344
317
|
str_types = []
|
|
345
318
|
others = []
|
|
@@ -350,7 +323,7 @@ class UnionParamType(click.ParamType):
|
|
|
350
323
|
str_types.append(p)
|
|
351
324
|
else:
|
|
352
325
|
others.append(p)
|
|
353
|
-
return others + str_types + unprocessed
|
|
326
|
+
return others + str_types + unprocessed # type: ignore
|
|
354
327
|
|
|
355
328
|
def convert(
|
|
356
329
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
@@ -359,10 +332,10 @@ class UnionParamType(click.ParamType):
|
|
|
359
332
|
Important to implement NoneType / Optional.
|
|
360
333
|
Also could we just determine the click types from the python types
|
|
361
334
|
"""
|
|
362
|
-
if isinstance(value, ArtifactQuery):
|
|
363
|
-
return value
|
|
364
335
|
for p in self._types:
|
|
365
336
|
try:
|
|
337
|
+
if p is None and value is None:
|
|
338
|
+
return None
|
|
366
339
|
return p.convert(value, param, ctx)
|
|
367
340
|
except Exception as e:
|
|
368
341
|
logger.debug(f"Ignoring conversion error for type {p} trying other variants in Union. Error: {e}")
|
|
@@ -386,7 +359,7 @@ class JsonParamType(click.ParamType):
|
|
|
386
359
|
# We failed to load the json, so we'll try to load it as a file
|
|
387
360
|
if os.path.exists(value):
|
|
388
361
|
# if the value is a yaml file, we'll try to load it as yaml
|
|
389
|
-
if value.endswith(".yaml"
|
|
362
|
+
if value.endswith((".yaml", "yml")):
|
|
390
363
|
with open(value, "r") as f:
|
|
391
364
|
return yaml.safe_load(f)
|
|
392
365
|
with open(value, "r") as f:
|
|
@@ -398,8 +371,6 @@ class JsonParamType(click.ParamType):
|
|
|
398
371
|
def convert(
|
|
399
372
|
self, value: typing.Any, param: typing.Optional[click.Parameter], ctx: typing.Optional[click.Context]
|
|
400
373
|
) -> typing.Any:
|
|
401
|
-
if isinstance(value, ArtifactQuery):
|
|
402
|
-
return value
|
|
403
374
|
if value is None:
|
|
404
375
|
raise click.BadParameter("None value cannot be converted to a Json type.")
|
|
405
376
|
|
|
@@ -407,68 +378,38 @@ class JsonParamType(click.ParamType):
|
|
|
407
378
|
|
|
408
379
|
# We compare the origin type because the json parsed value for list or dict is always a list or dict without
|
|
409
380
|
# the covariant type information.
|
|
410
|
-
if type(parsed_value)
|
|
381
|
+
if type(parsed_value) is typing.get_origin(self._python_type) or type(parsed_value) is self._python_type:
|
|
411
382
|
# Indexing the return value of get_args will raise an error for native dict and list types.
|
|
412
383
|
# We don't support native list/dict types with nested dataclasses.
|
|
413
384
|
if get_args(self._python_type) == ():
|
|
414
385
|
return parsed_value
|
|
415
386
|
elif isinstance(parsed_value, list) and dataclasses.is_dataclass(get_args(self._python_type)[0]):
|
|
416
387
|
j = JsonParamType(get_args(self._python_type)[0])
|
|
417
|
-
|
|
388
|
+
# turn object back into json string
|
|
389
|
+
return [j.convert(json.dumps(v), param, ctx) for v in parsed_value]
|
|
418
390
|
elif isinstance(parsed_value, dict) and dataclasses.is_dataclass(get_args(self._python_type)[1]):
|
|
419
391
|
j = JsonParamType(get_args(self._python_type)[1])
|
|
420
|
-
|
|
392
|
+
# turn object back into json string
|
|
393
|
+
return {k: j.convert(json.dumps(v), param, ctx) for k, v in parsed_value.items()}
|
|
421
394
|
|
|
422
395
|
return parsed_value
|
|
423
396
|
|
|
424
|
-
|
|
425
|
-
"""
|
|
426
|
-
This function supports backward compatibility for the Pydantic v1 plugin.
|
|
427
|
-
If the class is a Pydantic BaseModel, it attempts to parse JSON input using
|
|
428
|
-
the appropriate version of Pydantic (v1 or v2).
|
|
429
|
-
"""
|
|
430
|
-
try:
|
|
431
|
-
if importlib.util.find_spec("pydantic.v1") is not None:
|
|
432
|
-
from pydantic import BaseModel as BaseModelV2
|
|
433
|
-
|
|
434
|
-
if issubclass(self._python_type, BaseModelV2):
|
|
435
|
-
return self._python_type.model_validate_json(
|
|
436
|
-
json.dumps(parsed_value), strict=False, context={"deserialize": True}
|
|
437
|
-
)
|
|
438
|
-
except ImportError:
|
|
439
|
-
pass
|
|
440
|
-
|
|
441
|
-
# The behavior of the Pydantic v1 plugin.
|
|
442
|
-
return self._python_type.parse_raw(json.dumps(parsed_value))
|
|
443
|
-
return None
|
|
444
|
-
|
|
397
|
+
from pydantic import BaseModel
|
|
445
398
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
"""
|
|
450
|
-
if lit.collection:
|
|
451
|
-
for l in lit.collection.literals:
|
|
452
|
-
modify_literal_uris(l)
|
|
453
|
-
elif lit.map:
|
|
454
|
-
for k, v in lit.map.literals.items():
|
|
455
|
-
modify_literal_uris(v)
|
|
456
|
-
elif lit.scalar:
|
|
457
|
-
if lit.scalar.blob and lit.scalar.blob.uri and lit.scalar.blob.uri.startswith(RemoteFSPathResolver.protocol):
|
|
458
|
-
lit.scalar.blob._uri = RemoteFSPathResolver.resolve_remote_path(lit.scalar.blob.uri)
|
|
459
|
-
elif lit.scalar.union:
|
|
460
|
-
modify_literal_uris(lit.scalar.union.value)
|
|
461
|
-
elif (
|
|
462
|
-
lit.scalar.structured_dataset
|
|
463
|
-
and lit.scalar.structured_dataset.uri
|
|
464
|
-
and lit.scalar.structured_dataset.uri.startswith(RemoteFSPathResolver.protocol)
|
|
465
|
-
):
|
|
466
|
-
lit.scalar.structured_dataset._uri = RemoteFSPathResolver.resolve_remote_path(
|
|
467
|
-
lit.scalar.structured_dataset.uri
|
|
399
|
+
if issubclass(self._python_type, BaseModel):
|
|
400
|
+
return typing.cast(BaseModel, self._python_type).model_validate_json(
|
|
401
|
+
json.dumps(parsed_value), strict=False, context={"deserialize": True}
|
|
468
402
|
)
|
|
403
|
+
elif dataclasses.is_dataclass(self._python_type):
|
|
404
|
+
from mashumaro.codecs.json import JSONDecoder
|
|
469
405
|
|
|
406
|
+
decoder = JSONDecoder(self._python_type)
|
|
407
|
+
return decoder.decode(value)
|
|
470
408
|
|
|
471
|
-
|
|
409
|
+
return parsed_value
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
SIMPLE_TYPE_CONVERTER = {
|
|
472
413
|
SimpleType.FLOAT: click.FLOAT,
|
|
473
414
|
SimpleType.INTEGER: click.INT,
|
|
474
415
|
SimpleType.STRING: click.STRING,
|
|
@@ -482,47 +423,53 @@ def literal_type_to_click_type(lt: LiteralType, python_type: typing.Type) -> cli
|
|
|
482
423
|
"""
|
|
483
424
|
Converts a Flyte LiteralType given a python_type to a click.ParamType
|
|
484
425
|
"""
|
|
485
|
-
if lt.simple:
|
|
426
|
+
if lt.HasField("simple"):
|
|
486
427
|
if lt.simple == SimpleType.STRUCT:
|
|
487
428
|
ct = JsonParamType(python_type)
|
|
488
429
|
ct.name = f"JSON object {python_type.__name__}"
|
|
489
430
|
return ct
|
|
490
431
|
if lt.simple in SIMPLE_TYPE_CONVERTER:
|
|
491
432
|
return SIMPLE_TYPE_CONVERTER[lt.simple]
|
|
492
|
-
raise NotImplementedError(f"Type {lt.simple} is not supported in
|
|
493
|
-
|
|
494
|
-
if lt.enum_type:
|
|
495
|
-
return EnumParamType(python_type) # type: ignore
|
|
433
|
+
raise NotImplementedError(f"Type {lt.simple} is not supported in `flyte run`")
|
|
496
434
|
|
|
497
|
-
if lt.structured_dataset_type:
|
|
435
|
+
if lt.HasField("structured_dataset_type"):
|
|
498
436
|
return StructuredDatasetParamType()
|
|
499
437
|
|
|
500
|
-
if lt.collection_type or lt.map_value_type:
|
|
438
|
+
if lt.HasField("collection_type") or lt.HasField("map_value_type"):
|
|
501
439
|
ct = JsonParamType(python_type)
|
|
502
|
-
if lt.collection_type:
|
|
440
|
+
if lt.HasField("collection_type"):
|
|
503
441
|
ct.name = "json list"
|
|
504
442
|
else:
|
|
505
443
|
ct.name = "json dictionary"
|
|
506
444
|
return ct
|
|
507
445
|
|
|
508
|
-
if lt.blob:
|
|
446
|
+
if lt.HasField("blob"):
|
|
509
447
|
if lt.blob.dimensionality == BlobType.BlobDimensionality.SINGLE:
|
|
510
448
|
if lt.blob.format == FlytePickleTransformer.PYTHON_PICKLE_FORMAT:
|
|
511
449
|
return PickleParamType()
|
|
450
|
+
# TODO: Add JSONIteratorTransformer
|
|
512
451
|
# elif lt.blob.format == JSONIteratorTransformer.JSON_ITERATOR_FORMAT:
|
|
513
452
|
# return JSONIteratorParamType()
|
|
514
453
|
return FileParamType()
|
|
515
454
|
return DirParamType()
|
|
516
455
|
|
|
517
|
-
if lt.union_type:
|
|
456
|
+
if lt.HasField("union_type"):
|
|
457
|
+
python_args = typing.get_args(python_type)
|
|
458
|
+
if len(python_args) == 0:
|
|
459
|
+
return PickleParamType()
|
|
518
460
|
cts = []
|
|
519
461
|
for i in range(len(lt.union_type.variants)):
|
|
520
462
|
variant = lt.union_type.variants[i]
|
|
521
|
-
variant_python_type =
|
|
522
|
-
|
|
523
|
-
|
|
463
|
+
variant_python_type = python_args[i]
|
|
464
|
+
if variant_python_type is type(None):
|
|
465
|
+
cts.append(None)
|
|
466
|
+
else:
|
|
467
|
+
cts.append(literal_type_to_click_type(variant, variant_python_type))
|
|
524
468
|
return UnionParamType(cts)
|
|
525
469
|
|
|
470
|
+
if lt.HasField("enum_type"):
|
|
471
|
+
return EnumParamType(python_type) # type: ignore
|
|
472
|
+
|
|
526
473
|
return click.UNPROCESSED
|
|
527
474
|
|
|
528
475
|
|
|
@@ -533,9 +480,7 @@ class FlyteLiteralConverter(object):
|
|
|
533
480
|
self,
|
|
534
481
|
literal_type: LiteralType,
|
|
535
482
|
python_type: typing.Type,
|
|
536
|
-
is_remote: bool,
|
|
537
483
|
):
|
|
538
|
-
self._is_remote = is_remote
|
|
539
484
|
self._literal_type = literal_type
|
|
540
485
|
self._python_type = python_type
|
|
541
486
|
self._click_type = literal_type_to_click_type(literal_type, python_type)
|
|
@@ -547,29 +492,24 @@ class FlyteLiteralConverter(object):
|
|
|
547
492
|
def is_bool(self) -> bool:
|
|
548
493
|
return self.click_type == click.BOOL
|
|
549
494
|
|
|
495
|
+
def is_optional(self) -> bool:
|
|
496
|
+
return isinstance(self.click_type, UnionParamType) and self.click_type.optional
|
|
497
|
+
|
|
550
498
|
def convert(
|
|
551
499
|
self, ctx: click.Context, param: typing.Optional[click.Parameter], value: typing.Any
|
|
552
500
|
) -> typing.Union[Literal, typing.Any]:
|
|
553
501
|
"""
|
|
554
|
-
Convert the value to a
|
|
502
|
+
Convert the value to a python native type. This is used by click to convert the input.
|
|
555
503
|
"""
|
|
556
|
-
if isinstance(value, ArtifactQuery):
|
|
557
|
-
return value
|
|
558
504
|
try:
|
|
559
505
|
# If the expected Python type is datetime.date, adjust the value to date
|
|
560
506
|
if self._python_type is datetime.date:
|
|
507
|
+
if value is None:
|
|
508
|
+
return None
|
|
561
509
|
# Click produces datetime, so converting to date to avoid type mismatch error
|
|
562
510
|
value = value.date()
|
|
563
|
-
# If the input matches the default value in the launch plan, serialization can be skipped.
|
|
564
|
-
if param and value == param.default:
|
|
565
|
-
return None
|
|
566
511
|
|
|
567
|
-
|
|
568
|
-
if not self._is_remote:
|
|
569
|
-
return value
|
|
570
|
-
|
|
571
|
-
lit = asyncio.run(TypeEngine.to_literal(value, self._python_type, self._literal_type))
|
|
572
|
-
return lit
|
|
512
|
+
return value
|
|
573
513
|
except click.BadParameter:
|
|
574
514
|
raise
|
|
575
515
|
except Exception as e:
|
|
@@ -577,3 +517,62 @@ class FlyteLiteralConverter(object):
|
|
|
577
517
|
f"Failed to convert param: {param if param else 'NA'}, value: {value} to type: {self._python_type}."
|
|
578
518
|
f" Reason {e}"
|
|
579
519
|
) from e
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def to_click_option(
|
|
523
|
+
input_name: str,
|
|
524
|
+
literal_var: Variable,
|
|
525
|
+
python_type: typing.Type,
|
|
526
|
+
default_val: typing.Any,
|
|
527
|
+
) -> click.Option:
|
|
528
|
+
"""
|
|
529
|
+
This handles converting workflow input types to supported click parameters with callbacks to initialize
|
|
530
|
+
the input values to their expected types.
|
|
531
|
+
"""
|
|
532
|
+
from flyteidl2.core.types_pb2 import SimpleType
|
|
533
|
+
|
|
534
|
+
if input_name != input_name.lower():
|
|
535
|
+
# Click does not support uppercase option names: https://github.com/pallets/click/issues/837
|
|
536
|
+
raise ValueError(f"Workflow input name must be lowercase: {input_name!r}")
|
|
537
|
+
|
|
538
|
+
literal_converter = FlyteLiteralConverter(
|
|
539
|
+
literal_type=literal_var.type,
|
|
540
|
+
python_type=python_type,
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
if literal_converter.is_bool() and not default_val:
|
|
544
|
+
default_val = False
|
|
545
|
+
|
|
546
|
+
description_extra = ""
|
|
547
|
+
if literal_var.type.simple == SimpleType.STRUCT:
|
|
548
|
+
if default_val:
|
|
549
|
+
# pydantic v2
|
|
550
|
+
if hasattr(default_val, "model_dump_json"):
|
|
551
|
+
default_val = default_val.model_dump_json()
|
|
552
|
+
else:
|
|
553
|
+
encoder = JSONEncoder(python_type)
|
|
554
|
+
default_val = encoder.encode(default_val)
|
|
555
|
+
if literal_var.type.metadata:
|
|
556
|
+
description_extra = f": {MessageToDict(literal_var.type.metadata)}"
|
|
557
|
+
|
|
558
|
+
required = False if default_val is not None else True
|
|
559
|
+
is_flag: typing.Optional[bool] = None
|
|
560
|
+
param_decls = [f"--{input_name}"]
|
|
561
|
+
if literal_converter.is_bool():
|
|
562
|
+
required = False
|
|
563
|
+
is_flag = True
|
|
564
|
+
if default_val is True:
|
|
565
|
+
param_decls = [f"--{input_name}/--no-{input_name}"]
|
|
566
|
+
if literal_converter.is_optional():
|
|
567
|
+
required = False
|
|
568
|
+
|
|
569
|
+
return click.Option(
|
|
570
|
+
param_decls=param_decls,
|
|
571
|
+
type=literal_converter.click_type,
|
|
572
|
+
is_flag=is_flag,
|
|
573
|
+
default=default_val,
|
|
574
|
+
show_default=True,
|
|
575
|
+
required=required,
|
|
576
|
+
help=literal_var.description + description_extra,
|
|
577
|
+
callback=literal_converter.convert,
|
|
578
|
+
)
|