flyte 0.2.0b1__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 -231
- flyte/_initialize.py +456 -316
- 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 +319 -36
- 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 +462 -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
- flyte/{_cli → cli}/_params.py +57 -17
- 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 +2 -167
- flyte/config/_config.py +215 -163
- flyte/config/_internal.py +10 -1
- 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 +226 -126
- 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 -299
- 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 -174
- flyte/_cli/main.py +0 -98
- 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.2.0b1.dist-info/METADATA +0 -179
- flyte-0.2.0b1.dist-info/RECORD +0 -204
- flyte-0.2.0b1.dist-info/entry_points.txt +0 -3
- /flyte/{_cli → _debug}/__init__.py +0 -0
- /flyte/{_protos → _keyring}/__init__.py +0 -0
- {flyte-0.2.0b1.dist-info → flyte-2.0.0b46.dist-info}/WHEEL +0 -0
- {flyte-0.2.0b1.dist-info → flyte-2.0.0b46.dist-info}/top_level.txt +0 -0
flyte/cli/_run.py
ADDED
|
@@ -0,0 +1,690 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import inspect
|
|
5
|
+
from dataclasses import dataclass, field, fields
|
|
6
|
+
from functools import lru_cache
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from types import ModuleType
|
|
9
|
+
from typing import Any, Dict, List, cast
|
|
10
|
+
|
|
11
|
+
import rich_click as click
|
|
12
|
+
from typing_extensions import get_args
|
|
13
|
+
|
|
14
|
+
from .._code_bundle._utils import CopyFiles
|
|
15
|
+
from .._task import TaskTemplate
|
|
16
|
+
from ..remote import Run
|
|
17
|
+
from . import _common as common
|
|
18
|
+
from ._params import to_click_option
|
|
19
|
+
|
|
20
|
+
RUN_REMOTE_CMD = "deployed-task"
|
|
21
|
+
initialize_config = common.initialize_config
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@lru_cache()
|
|
25
|
+
def _list_tasks(
|
|
26
|
+
ctx: click.Context,
|
|
27
|
+
project: str,
|
|
28
|
+
domain: str,
|
|
29
|
+
by_task_name: str | None = None,
|
|
30
|
+
by_task_env: str | None = None,
|
|
31
|
+
) -> list[str]:
|
|
32
|
+
import flyte.remote
|
|
33
|
+
|
|
34
|
+
common.initialize_config(ctx, project, domain)
|
|
35
|
+
return [task.name for task in flyte.remote.Task.listall(by_task_name=by_task_name, by_task_env=by_task_env)]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class RunArguments:
|
|
40
|
+
project: str = field(
|
|
41
|
+
default=cast(str, common.PROJECT_OPTION.default), metadata={"click.option": common.PROJECT_OPTION}
|
|
42
|
+
)
|
|
43
|
+
domain: str = field(
|
|
44
|
+
default=cast(str, common.DOMAIN_OPTION.default), metadata={"click.option": common.DOMAIN_OPTION}
|
|
45
|
+
)
|
|
46
|
+
local: bool = field(
|
|
47
|
+
default=False,
|
|
48
|
+
metadata={
|
|
49
|
+
"click.option": click.Option(
|
|
50
|
+
["--local"],
|
|
51
|
+
is_flag=True,
|
|
52
|
+
help="Run the task locally",
|
|
53
|
+
)
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
copy_style: CopyFiles = field(
|
|
57
|
+
default="loaded_modules",
|
|
58
|
+
metadata={
|
|
59
|
+
"click.option": click.Option(
|
|
60
|
+
["--copy-style"],
|
|
61
|
+
type=click.Choice(get_args(CopyFiles)),
|
|
62
|
+
default="loaded_modules",
|
|
63
|
+
help="Copy style to use when running the task",
|
|
64
|
+
)
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
root_dir: str | None = field(
|
|
68
|
+
default=None,
|
|
69
|
+
metadata={
|
|
70
|
+
"click.option": click.Option(
|
|
71
|
+
["--root-dir"],
|
|
72
|
+
type=str,
|
|
73
|
+
help="Override the root source directory, helpful when working with monorepos.",
|
|
74
|
+
)
|
|
75
|
+
},
|
|
76
|
+
)
|
|
77
|
+
raw_data_path: str | None = field(
|
|
78
|
+
default=None,
|
|
79
|
+
metadata={
|
|
80
|
+
"click.option": click.Option(
|
|
81
|
+
["--raw-data-path"],
|
|
82
|
+
type=str,
|
|
83
|
+
help="Override the output prefix used to store offloaded data types. e.g. s3://bucket/",
|
|
84
|
+
)
|
|
85
|
+
},
|
|
86
|
+
)
|
|
87
|
+
service_account: str | None = field(
|
|
88
|
+
default=None,
|
|
89
|
+
metadata={
|
|
90
|
+
"click.option": click.Option(
|
|
91
|
+
["--service-account"],
|
|
92
|
+
type=str,
|
|
93
|
+
help="Kubernetes service account. If not provided, the configured default will be used",
|
|
94
|
+
)
|
|
95
|
+
},
|
|
96
|
+
)
|
|
97
|
+
name: str | None = field(
|
|
98
|
+
default=None,
|
|
99
|
+
metadata={
|
|
100
|
+
"click.option": click.Option(
|
|
101
|
+
["--name"],
|
|
102
|
+
type=str,
|
|
103
|
+
help="Name of the run. If not provided, a random name will be generated.",
|
|
104
|
+
)
|
|
105
|
+
},
|
|
106
|
+
)
|
|
107
|
+
follow: bool = field(
|
|
108
|
+
default=False,
|
|
109
|
+
metadata={
|
|
110
|
+
"click.option": click.Option(
|
|
111
|
+
["--follow", "-f"],
|
|
112
|
+
is_flag=True,
|
|
113
|
+
default=False,
|
|
114
|
+
help="Wait and watch logs for the parent action. If not provided, the CLI will exit after "
|
|
115
|
+
"successfully launching a remote execution with a link to the UI.",
|
|
116
|
+
)
|
|
117
|
+
},
|
|
118
|
+
)
|
|
119
|
+
image: List[str] = field(
|
|
120
|
+
default_factory=list,
|
|
121
|
+
metadata={
|
|
122
|
+
"click.option": click.Option(
|
|
123
|
+
["--image"],
|
|
124
|
+
type=str,
|
|
125
|
+
multiple=True,
|
|
126
|
+
help="Image to be used in the run. Format: imagename=imageuri. Can be specified multiple times.",
|
|
127
|
+
)
|
|
128
|
+
},
|
|
129
|
+
)
|
|
130
|
+
no_sync_local_sys_paths: bool = field(
|
|
131
|
+
default=True,
|
|
132
|
+
metadata={
|
|
133
|
+
"click.option": click.Option(
|
|
134
|
+
["--no-sync-local-sys-paths"],
|
|
135
|
+
is_flag=True,
|
|
136
|
+
flag_value=True,
|
|
137
|
+
default=False,
|
|
138
|
+
help="Disable synchronization of local sys.path entries under the root directory "
|
|
139
|
+
"to the remote container.",
|
|
140
|
+
)
|
|
141
|
+
},
|
|
142
|
+
)
|
|
143
|
+
run_project: str | None = field(
|
|
144
|
+
default=None,
|
|
145
|
+
metadata={
|
|
146
|
+
"click.option": click.Option(
|
|
147
|
+
param_decls=["--run-project"],
|
|
148
|
+
required=False,
|
|
149
|
+
type=str,
|
|
150
|
+
default=None,
|
|
151
|
+
help="Run the remote task in this project, only applicable when using `deployed-task` subcommand.",
|
|
152
|
+
show_default=True,
|
|
153
|
+
)
|
|
154
|
+
},
|
|
155
|
+
)
|
|
156
|
+
run_domain: str | None = field(
|
|
157
|
+
default=None,
|
|
158
|
+
metadata={
|
|
159
|
+
"click.option": click.Option(
|
|
160
|
+
["--run-domain"],
|
|
161
|
+
required=False,
|
|
162
|
+
type=str,
|
|
163
|
+
default=None,
|
|
164
|
+
help="Run the remote task in this domain, only applicable when using `deployed-task` subcommand.",
|
|
165
|
+
show_default=True,
|
|
166
|
+
)
|
|
167
|
+
},
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
@classmethod
|
|
171
|
+
def from_dict(cls, d: Dict[str, Any]) -> RunArguments:
|
|
172
|
+
modified = {k: v for k, v in d.items() if k in {f.name for f in fields(cls)}}
|
|
173
|
+
return cls(**modified)
|
|
174
|
+
|
|
175
|
+
@classmethod
|
|
176
|
+
def options(cls) -> List[click.Option]:
|
|
177
|
+
"""
|
|
178
|
+
Return the set of base parameters added to run subcommand.
|
|
179
|
+
"""
|
|
180
|
+
return [common.get_option_from_metadata(f.metadata) for f in fields(cls) if f.metadata]
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class RunTaskCommand(click.RichCommand):
|
|
184
|
+
def __init__(self, obj_name: str, obj: Any, run_args: RunArguments, *args, **kwargs):
|
|
185
|
+
self.obj_name = obj_name
|
|
186
|
+
self.obj = cast(TaskTemplate, obj)
|
|
187
|
+
self.run_args = run_args
|
|
188
|
+
kwargs.pop("name", None)
|
|
189
|
+
super().__init__(obj_name, *args, **kwargs)
|
|
190
|
+
|
|
191
|
+
def _validate_required_params(self, ctx: click.Context) -> None:
|
|
192
|
+
"""
|
|
193
|
+
Validate that all required parameters are provided.
|
|
194
|
+
"""
|
|
195
|
+
missing_params = []
|
|
196
|
+
for param in self.params:
|
|
197
|
+
if isinstance(param, click.Option) and param.required:
|
|
198
|
+
param_name = param.name
|
|
199
|
+
if param_name not in ctx.params or ctx.params[param_name] is None:
|
|
200
|
+
missing_params.append(
|
|
201
|
+
(param_name, param.type.get_metavar(param, ctx) or param.type.name.upper() or param.type)
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
if missing_params:
|
|
205
|
+
raise click.UsageError(
|
|
206
|
+
f"Missing required parameter(s): {', '.join(f'--{p[0]} (type: {p[1]})' for p in missing_params)}"
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
async def _execute_and_render(self, ctx: click.Context, config: common.CLIConfig):
|
|
210
|
+
"""Separate execution logic from the Click entry point for better testability."""
|
|
211
|
+
import flyte
|
|
212
|
+
|
|
213
|
+
console = common.get_console()
|
|
214
|
+
|
|
215
|
+
# 2. Execute with a UX Status Spinner
|
|
216
|
+
try:
|
|
217
|
+
with console.status(
|
|
218
|
+
f"[bold blue]Launching {'local' if self.run_args.local else 'remote'} execution...", spinner="dots"
|
|
219
|
+
):
|
|
220
|
+
execution_context = flyte.with_runcontext(
|
|
221
|
+
copy_style=self.run_args.copy_style,
|
|
222
|
+
mode="local" if self.run_args.local else "remote",
|
|
223
|
+
name=self.run_args.name,
|
|
224
|
+
raw_data_path=self.run_args.raw_data_path,
|
|
225
|
+
service_account=self.run_args.service_account,
|
|
226
|
+
log_format=config.log_format,
|
|
227
|
+
reset_root_logger=config.reset_root_logger,
|
|
228
|
+
)
|
|
229
|
+
result = await execution_context.run.aio(self.obj, **ctx.params)
|
|
230
|
+
except Exception as e:
|
|
231
|
+
console.print(common.get_panel("Exception", f"[red]✕ Execution failed:[/red] {e}", config.output_format))
|
|
232
|
+
return
|
|
233
|
+
|
|
234
|
+
# 3. UI Branching
|
|
235
|
+
if self.run_args.local:
|
|
236
|
+
self._render_local_success(console, result, config)
|
|
237
|
+
else:
|
|
238
|
+
await self._render_remote_success(console, result, config)
|
|
239
|
+
|
|
240
|
+
def _render_local_success(self, console, result, config):
|
|
241
|
+
content = f"[green]Completed Local Run[/green]\nPath: {result.url}\n➡️ Outputs: {result.outputs()}"
|
|
242
|
+
console.print(common.get_panel("Local Success", content, config.output_format))
|
|
243
|
+
|
|
244
|
+
async def _render_remote_success(self, console, result, config):
|
|
245
|
+
if not (isinstance(result, Run) and result.action):
|
|
246
|
+
return
|
|
247
|
+
|
|
248
|
+
run_info = (
|
|
249
|
+
f"[green bold]Created Run: {result.name}[/green bold]\n"
|
|
250
|
+
f"URL: [blue bold][link={result.url}]{result.url}[/link][/blue bold]"
|
|
251
|
+
)
|
|
252
|
+
console.print(common.get_panel("Remote Run", run_info, config.output_format))
|
|
253
|
+
|
|
254
|
+
if self.run_args.follow:
|
|
255
|
+
console.print("[dim]Waiting for log stream...[/dim]")
|
|
256
|
+
await result.show_logs.aio(max_lines=30, show_ts=True, raw=False)
|
|
257
|
+
|
|
258
|
+
def invoke(self, ctx: click.Context):
|
|
259
|
+
config: common.CLIConfig = common.initialize_config(
|
|
260
|
+
ctx,
|
|
261
|
+
self.run_args.project,
|
|
262
|
+
self.run_args.domain,
|
|
263
|
+
self.run_args.root_dir,
|
|
264
|
+
tuple(self.run_args.image) or None,
|
|
265
|
+
not self.run_args.no_sync_local_sys_paths,
|
|
266
|
+
)
|
|
267
|
+
self._validate_required_params(ctx)
|
|
268
|
+
# Main entry point remains very thin
|
|
269
|
+
asyncio.run(self._execute_and_render(ctx, config))
|
|
270
|
+
|
|
271
|
+
def get_params(self, ctx: click.Context) -> List[click.Parameter]:
|
|
272
|
+
# Note this function may be called multiple times by click.
|
|
273
|
+
task = self.obj
|
|
274
|
+
from .._internal.runtime.types_serde import transform_native_to_typed_interface
|
|
275
|
+
|
|
276
|
+
interface = transform_native_to_typed_interface(task.native_interface)
|
|
277
|
+
if interface is None:
|
|
278
|
+
return super().get_params(ctx)
|
|
279
|
+
inputs_interface = task.native_interface.inputs
|
|
280
|
+
|
|
281
|
+
params: List[click.Parameter] = []
|
|
282
|
+
for name, var in interface.inputs.variables.items():
|
|
283
|
+
default_val = None
|
|
284
|
+
if inputs_interface[name][1] is not inspect._empty:
|
|
285
|
+
default_val = inputs_interface[name][1]
|
|
286
|
+
params.append(to_click_option(name, var, inputs_interface[name][0], default_val))
|
|
287
|
+
|
|
288
|
+
self.params = params
|
|
289
|
+
return super().get_params(ctx)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class TaskPerFileGroup(common.ObjectsPerFileGroup):
|
|
293
|
+
"""
|
|
294
|
+
Group that creates a command for each task in the current directory that is not __init__.py.
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
def __init__(self, filename: Path, run_args: RunArguments, *args, **kwargs):
|
|
298
|
+
if filename.is_absolute():
|
|
299
|
+
filename = filename.relative_to(Path.cwd())
|
|
300
|
+
super().__init__(*(filename, *args), **kwargs)
|
|
301
|
+
self.run_args = run_args
|
|
302
|
+
|
|
303
|
+
def _filter_objects(self, module: ModuleType) -> Dict[str, Any]:
|
|
304
|
+
return {k: v for k, v in module.__dict__.items() if isinstance(v, TaskTemplate)}
|
|
305
|
+
|
|
306
|
+
def list_commands(self, ctx):
|
|
307
|
+
common.initialize_config(
|
|
308
|
+
ctx,
|
|
309
|
+
self.run_args.project,
|
|
310
|
+
self.run_args.domain,
|
|
311
|
+
self.run_args.root_dir,
|
|
312
|
+
sync_local_sys_paths=not self.run_args.no_sync_local_sys_paths,
|
|
313
|
+
)
|
|
314
|
+
return super().list_commands(ctx)
|
|
315
|
+
|
|
316
|
+
def get_command(self, ctx, obj_name):
|
|
317
|
+
common.initialize_config(
|
|
318
|
+
ctx,
|
|
319
|
+
self.run_args.project,
|
|
320
|
+
self.run_args.domain,
|
|
321
|
+
self.run_args.root_dir,
|
|
322
|
+
sync_local_sys_paths=not self.run_args.no_sync_local_sys_paths,
|
|
323
|
+
)
|
|
324
|
+
return super().get_command(ctx, obj_name)
|
|
325
|
+
|
|
326
|
+
def _get_command_for_obj(self, ctx: click.Context, obj_name: str, obj: Any) -> click.Command:
|
|
327
|
+
obj = cast(TaskTemplate, obj)
|
|
328
|
+
return RunTaskCommand(
|
|
329
|
+
obj_name=obj_name,
|
|
330
|
+
obj=obj,
|
|
331
|
+
help=obj.docs.__help__str__() if obj.docs else None,
|
|
332
|
+
run_args=self.run_args,
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class RunRemoteTaskCommand(click.RichCommand):
|
|
337
|
+
def __init__(self, task_name: str, run_args: RunArguments, version: str | None, *args, **kwargs):
|
|
338
|
+
self.task_name = task_name
|
|
339
|
+
self.run_args = run_args
|
|
340
|
+
self.version = version
|
|
341
|
+
|
|
342
|
+
super().__init__(*args, **kwargs)
|
|
343
|
+
|
|
344
|
+
def _validate_required_params(self, ctx: click.Context) -> None:
|
|
345
|
+
"""
|
|
346
|
+
Validate that all required parameters are provided.
|
|
347
|
+
"""
|
|
348
|
+
missing_params = []
|
|
349
|
+
for param in self.params:
|
|
350
|
+
if isinstance(param, click.Option) and param.required:
|
|
351
|
+
param_name = param.name
|
|
352
|
+
if param_name not in ctx.params or ctx.params[param_name] is None:
|
|
353
|
+
missing_params.append(
|
|
354
|
+
(param_name, param.type.get_metavar(param, ctx) or param.type.name.upper() or param.type)
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
if missing_params:
|
|
358
|
+
raise click.UsageError(
|
|
359
|
+
f"Missing required parameter(s): {', '.join(f'--{p[0]} (type: {p[1]})' for p in missing_params)}"
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
async def _execute_and_render(self, ctx: click.Context, config: common.CLIConfig):
|
|
363
|
+
"""Separate execution logic from the Click entry point for better testability."""
|
|
364
|
+
import flyte.remote
|
|
365
|
+
|
|
366
|
+
task = flyte.remote.Task.get(self.task_name, version=self.version, auto_version="latest")
|
|
367
|
+
console = common.get_console()
|
|
368
|
+
if self.run_args.run_project or self.run_args.run_domain:
|
|
369
|
+
console.print(
|
|
370
|
+
f"Separate Run project/domain set, using {self.run_args.run_project} and {self.run_args.run_domain}"
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
# 2. Execute with a UX Status Spinner
|
|
374
|
+
try:
|
|
375
|
+
with console.status(
|
|
376
|
+
f"[bold blue]Launching {'local' if self.run_args.local else 'remote'} execution...", spinner="dots"
|
|
377
|
+
):
|
|
378
|
+
execution_context = flyte.with_runcontext(
|
|
379
|
+
copy_style=self.run_args.copy_style,
|
|
380
|
+
mode="local" if self.run_args.local else "remote",
|
|
381
|
+
name=self.run_args.name,
|
|
382
|
+
project=self.run_args.run_project,
|
|
383
|
+
domain=self.run_args.run_domain,
|
|
384
|
+
)
|
|
385
|
+
result = await execution_context.run.aio(task, **ctx.params)
|
|
386
|
+
except Exception as e:
|
|
387
|
+
console.print(f"[red]✕ Execution failed:[/red] {e}")
|
|
388
|
+
return
|
|
389
|
+
|
|
390
|
+
# 3. UI Branching
|
|
391
|
+
if self.run_args.local:
|
|
392
|
+
self._render_local_success(console, result, config)
|
|
393
|
+
else:
|
|
394
|
+
await self._render_remote_success(console, result, config)
|
|
395
|
+
|
|
396
|
+
def _render_local_success(self, console, result, config):
|
|
397
|
+
content = f"[green]Completed Local Run[/green]\nPath: {result.url}\n➡️ Outputs: {result.outputs()}"
|
|
398
|
+
console.print(common.get_panel("Local Success", content, config.output_format))
|
|
399
|
+
|
|
400
|
+
async def _render_remote_success(self, console, result, config):
|
|
401
|
+
if not (isinstance(result, Run) and result.action):
|
|
402
|
+
return
|
|
403
|
+
|
|
404
|
+
run_info = (
|
|
405
|
+
f"[green bold]Created Run: {result.name}[/green bold]\n"
|
|
406
|
+
f"(Project: {result.action.action_id.run.project}, Domain: {result.action.action_id.run.domain})\n"
|
|
407
|
+
f"➡️ [blue bold][link={result.url}]{result.url}[/link][/blue bold]",
|
|
408
|
+
)
|
|
409
|
+
console.print(common.get_panel("Remote Run", run_info, config.output_format))
|
|
410
|
+
|
|
411
|
+
if self.run_args.follow:
|
|
412
|
+
console.print(
|
|
413
|
+
"[dim]Log streaming enabled, will wait for task to start running and log stream to be available[/dim]"
|
|
414
|
+
)
|
|
415
|
+
await result.show_logs.aio(max_lines=30, show_ts=True, raw=False)
|
|
416
|
+
|
|
417
|
+
def invoke(self, ctx: click.Context):
|
|
418
|
+
config: common.CLIConfig = common.initialize_config(
|
|
419
|
+
ctx,
|
|
420
|
+
project=self.run_args.project,
|
|
421
|
+
domain=self.run_args.domain,
|
|
422
|
+
root_dir=self.run_args.root_dir,
|
|
423
|
+
images=tuple(self.run_args.image) or None,
|
|
424
|
+
sync_local_sys_paths=not self.run_args.no_sync_local_sys_paths,
|
|
425
|
+
)
|
|
426
|
+
self._validate_required_params(ctx)
|
|
427
|
+
# Main entry point remains very thin
|
|
428
|
+
asyncio.run(self._execute_and_render(ctx, config))
|
|
429
|
+
|
|
430
|
+
def get_params(self, ctx: click.Context) -> List[click.Parameter]:
|
|
431
|
+
# Note this function may be called multiple times by click.
|
|
432
|
+
import flyte.remote
|
|
433
|
+
from flyte._internal.runtime.types_serde import transform_native_to_typed_interface
|
|
434
|
+
|
|
435
|
+
common.initialize_config(
|
|
436
|
+
ctx,
|
|
437
|
+
self.run_args.project,
|
|
438
|
+
self.run_args.domain,
|
|
439
|
+
sync_local_sys_paths=not self.run_args.no_sync_local_sys_paths,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
task = flyte.remote.Task.get(self.task_name, auto_version="latest")
|
|
443
|
+
task_details = task.fetch()
|
|
444
|
+
|
|
445
|
+
interface = transform_native_to_typed_interface(task_details.interface)
|
|
446
|
+
if interface is None:
|
|
447
|
+
return super().get_params(ctx)
|
|
448
|
+
inputs_interface = task_details.interface.inputs
|
|
449
|
+
|
|
450
|
+
params: List[click.Parameter] = []
|
|
451
|
+
for name, var in interface.inputs.variables.items():
|
|
452
|
+
default_val = None
|
|
453
|
+
if inputs_interface[name][1] is not inspect._empty:
|
|
454
|
+
default_val = inputs_interface[name][1]
|
|
455
|
+
params.append(to_click_option(name, var, inputs_interface[name][0], default_val))
|
|
456
|
+
|
|
457
|
+
self.params = params
|
|
458
|
+
return super().get_params(ctx)
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
class RemoteEnvGroup(common.GroupBase):
|
|
462
|
+
def __init__(self, name: str, *args, run_args, env: str, **kwargs):
|
|
463
|
+
super().__init__(*args, **kwargs)
|
|
464
|
+
self.name = name
|
|
465
|
+
self.env = env
|
|
466
|
+
self.run_args = run_args
|
|
467
|
+
|
|
468
|
+
def list_commands(self, ctx):
|
|
469
|
+
return _list_tasks(ctx, self.run_args.project, self.run_args.domain, by_task_env=self.env)
|
|
470
|
+
|
|
471
|
+
def get_command(self, ctx, name):
|
|
472
|
+
return RunRemoteTaskCommand(
|
|
473
|
+
task_name=name,
|
|
474
|
+
run_args=self.run_args,
|
|
475
|
+
name=name,
|
|
476
|
+
version=None,
|
|
477
|
+
help=f"Run deployed task '{name}' from the Flyte backend",
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
class RemoteTaskGroup(common.GroupBase):
|
|
482
|
+
"""
|
|
483
|
+
Group that creates a command for each remote task in the current directory that is not __init__.py.
|
|
484
|
+
"""
|
|
485
|
+
|
|
486
|
+
def __init__(self, name: str, *args, run_args, tasks: list[str] | None = None, **kwargs):
|
|
487
|
+
super().__init__(*args, **kwargs)
|
|
488
|
+
self.name = name
|
|
489
|
+
self.run_args = run_args
|
|
490
|
+
|
|
491
|
+
def list_commands(self, ctx):
|
|
492
|
+
# list envs of all remote tasks
|
|
493
|
+
envs = []
|
|
494
|
+
for task in _list_tasks(ctx, self.run_args.project, self.run_args.domain):
|
|
495
|
+
env = task.split(".")[0]
|
|
496
|
+
if env not in envs:
|
|
497
|
+
envs.append(env)
|
|
498
|
+
return envs
|
|
499
|
+
|
|
500
|
+
@staticmethod
|
|
501
|
+
def _parse_task_name(task_name: str) -> tuple[str, str | None, str | None]:
|
|
502
|
+
import re
|
|
503
|
+
|
|
504
|
+
pattern = r"^([^.:]+)(?:\.([^:]+))?(?::(.+))?$"
|
|
505
|
+
match = re.match(pattern, task_name)
|
|
506
|
+
if not match:
|
|
507
|
+
raise click.BadParameter(f"Invalid task name format: {task_name}")
|
|
508
|
+
return match.group(1), match.group(2), match.group(3)
|
|
509
|
+
|
|
510
|
+
def _env_is_task(self, ctx: click.Context, env: str) -> bool:
|
|
511
|
+
# check if the env name is the full task name, since sometimes task
|
|
512
|
+
# names don't have an environment prefix
|
|
513
|
+
tasks = [*_list_tasks(ctx, self.run_args.project, self.run_args.domain, by_task_name=env)]
|
|
514
|
+
return len(tasks) > 0
|
|
515
|
+
|
|
516
|
+
def get_command(self, ctx, name):
|
|
517
|
+
env, task, version = self._parse_task_name(name)
|
|
518
|
+
match env, task, version:
|
|
519
|
+
case env, None, None:
|
|
520
|
+
if self._env_is_task(ctx, env):
|
|
521
|
+
# this handles cases where task names do not have a environment prefix
|
|
522
|
+
task_name = env
|
|
523
|
+
return RunRemoteTaskCommand(
|
|
524
|
+
task_name=task_name,
|
|
525
|
+
run_args=self.run_args,
|
|
526
|
+
name=task_name,
|
|
527
|
+
version=None,
|
|
528
|
+
help=f"Run remote task `{task_name}` from the Flyte backend",
|
|
529
|
+
)
|
|
530
|
+
else:
|
|
531
|
+
return RemoteEnvGroup(
|
|
532
|
+
name=name,
|
|
533
|
+
run_args=self.run_args,
|
|
534
|
+
env=env,
|
|
535
|
+
help=f"Run remote tasks in the `{env}` environment from the Flyte backend",
|
|
536
|
+
)
|
|
537
|
+
case env, task, None:
|
|
538
|
+
task_name = f"{env}.{task}"
|
|
539
|
+
return RunRemoteTaskCommand(
|
|
540
|
+
task_name=task_name,
|
|
541
|
+
run_args=self.run_args,
|
|
542
|
+
name=task_name,
|
|
543
|
+
version=None,
|
|
544
|
+
help=f"Run remote task '{task_name}' from the Flyte backend",
|
|
545
|
+
)
|
|
546
|
+
case env, task, version:
|
|
547
|
+
task_name = f"{env}.{task}"
|
|
548
|
+
return RunRemoteTaskCommand(
|
|
549
|
+
task_name=task_name,
|
|
550
|
+
run_args=self.run_args,
|
|
551
|
+
version=version,
|
|
552
|
+
name=f"{task_name}:{version}",
|
|
553
|
+
help=f"Run remote task '{task_name}' from the Flyte backend",
|
|
554
|
+
)
|
|
555
|
+
case _:
|
|
556
|
+
raise click.BadParameter(f"Invalid task name format: {task_name}")
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
class TaskFiles(common.FileGroup):
|
|
560
|
+
"""
|
|
561
|
+
Group that creates a command for each file in the current directory that is not __init__.py.
|
|
562
|
+
"""
|
|
563
|
+
|
|
564
|
+
common_options_enabled = False
|
|
565
|
+
|
|
566
|
+
def __init__(
|
|
567
|
+
self,
|
|
568
|
+
*args,
|
|
569
|
+
directory: Path | None = None,
|
|
570
|
+
**kwargs,
|
|
571
|
+
):
|
|
572
|
+
if "params" not in kwargs:
|
|
573
|
+
kwargs["params"] = []
|
|
574
|
+
kwargs["params"].extend(RunArguments.options())
|
|
575
|
+
super().__init__(*args, directory=directory, **kwargs)
|
|
576
|
+
|
|
577
|
+
def list_commands(self, ctx):
|
|
578
|
+
v = [
|
|
579
|
+
RUN_REMOTE_CMD,
|
|
580
|
+
*super().list_commands(ctx),
|
|
581
|
+
]
|
|
582
|
+
return v
|
|
583
|
+
|
|
584
|
+
def get_command(self, ctx, cmd_name):
|
|
585
|
+
run_args = RunArguments.from_dict(ctx.params)
|
|
586
|
+
if cmd_name == RUN_REMOTE_CMD:
|
|
587
|
+
return RemoteTaskGroup(
|
|
588
|
+
name=cmd_name,
|
|
589
|
+
run_args=run_args,
|
|
590
|
+
help="Run remote task from the Flyte backend",
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
fp = Path(cmd_name)
|
|
594
|
+
if not fp.exists():
|
|
595
|
+
raise click.BadParameter(f"File {cmd_name} does not exist")
|
|
596
|
+
if fp.is_dir():
|
|
597
|
+
return TaskFiles(
|
|
598
|
+
directory=fp,
|
|
599
|
+
help=f"Run `*.py` file inside the {fp} directory",
|
|
600
|
+
)
|
|
601
|
+
return TaskPerFileGroup(
|
|
602
|
+
filename=fp,
|
|
603
|
+
run_args=run_args,
|
|
604
|
+
name=cmd_name,
|
|
605
|
+
help=f"Run functions decorated with `env.task` in {cmd_name}",
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
run = TaskFiles(
|
|
610
|
+
name="run",
|
|
611
|
+
help=f"""
|
|
612
|
+
Run a task from a python file or deployed task.
|
|
613
|
+
|
|
614
|
+
Example usage:
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
flyte run hello.py my_task --arg1 value1 --arg2 value2
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
Arguments to the run command are provided right after the `run` command and before the file name.
|
|
621
|
+
Arguments for the task itself are provided after the task name.
|
|
622
|
+
|
|
623
|
+
To run a task locally, use the `--local` flag. This will run the task in the local environment instead of the remote
|
|
624
|
+
Flyte environment:
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
flyte run --local hello.py my_task --arg1 value1 --arg2 value2
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
You can provide image mappings with `--image` flag. This allows you to specify
|
|
631
|
+
the image URI for the task environment during CLI execution without changing
|
|
632
|
+
the code. Any images defined with `Image.from_ref_name("name")` will resolve to the
|
|
633
|
+
corresponding URIs you specify here.
|
|
634
|
+
|
|
635
|
+
```bash
|
|
636
|
+
flyte run --image my_image=ghcr.io/myorg/my-image:v1.0 hello.py my_task
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
If the image name is not provided, it is regarded as a default image and will
|
|
640
|
+
be used when no image is specified in TaskEnvironment:
|
|
641
|
+
|
|
642
|
+
```bash
|
|
643
|
+
flyte run --image ghcr.io/myorg/default-image:latest hello.py my_task
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
You can specify multiple image arguments:
|
|
647
|
+
|
|
648
|
+
```bash
|
|
649
|
+
flyte run --image ghcr.io/org/default:latest --image gpu=ghcr.io/org/gpu:v2.0 hello.py my_task
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
To run tasks that you've already deployed to Flyte, use the {RUN_REMOTE_CMD} command:
|
|
653
|
+
|
|
654
|
+
```bash
|
|
655
|
+
flyte run {RUN_REMOTE_CMD} my_env.my_task --arg1 value1 --arg2 value2
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
To run a specific version of a deployed task, use the `env.task:version` syntax:
|
|
659
|
+
|
|
660
|
+
```bash
|
|
661
|
+
flyte run {RUN_REMOTE_CMD} my_env.my_task:xyz123 --arg1 value1 --arg2 value2
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
You can specify the `--config` flag to point to a specific Flyte cluster:
|
|
665
|
+
|
|
666
|
+
```bash
|
|
667
|
+
flyte run --config my-config.yaml {RUN_REMOTE_CMD} ...
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
You can override the default configured project and domain:
|
|
671
|
+
|
|
672
|
+
```bash
|
|
673
|
+
flyte run --project my-project --domain development hello.py my_task
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
You can discover what deployed tasks are available by running:
|
|
677
|
+
|
|
678
|
+
```bash
|
|
679
|
+
flyte run {RUN_REMOTE_CMD}
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
Other arguments to the run command are listed below.
|
|
683
|
+
|
|
684
|
+
Arguments for the task itself are provided after the task name and can be retrieved using `--help`. For example:
|
|
685
|
+
|
|
686
|
+
```bash
|
|
687
|
+
flyte run hello.py my_task --help
|
|
688
|
+
```
|
|
689
|
+
""",
|
|
690
|
+
)
|