flyte 0.2.0b10__py3-none-any.whl → 0.2.0b12__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.
Potentially problematic release.
This version of flyte might be problematic. Click here for more details.
- flyte/__init__.py +2 -0
- flyte/_bin/runtime.py +17 -5
- flyte/_deploy.py +29 -0
- flyte/_initialize.py +21 -6
- flyte/_internal/controllers/_local_controller.py +2 -1
- flyte/_internal/controllers/_trace.py +1 -0
- flyte/_internal/controllers/remote/_action.py +1 -1
- flyte/_internal/controllers/remote/_informer.py +1 -1
- flyte/_internal/runtime/convert.py +7 -4
- flyte/_internal/runtime/task_serde.py +80 -10
- flyte/_internal/runtime/taskrunner.py +1 -1
- flyte/_logging.py +1 -1
- flyte/_pod.py +19 -0
- flyte/_protos/common/list_pb2.py +3 -3
- flyte/_protos/common/list_pb2.pyi +2 -0
- flyte/_protos/workflow/environment_pb2.py +29 -0
- flyte/_protos/workflow/environment_pb2.pyi +12 -0
- flyte/_protos/workflow/environment_pb2_grpc.py +4 -0
- flyte/_protos/workflow/run_definition_pb2.py +61 -61
- flyte/_protos/workflow/run_definition_pb2.pyi +4 -2
- flyte/_protos/workflow/run_service_pb2.py +20 -24
- flyte/_protos/workflow/run_service_pb2.pyi +2 -6
- flyte/_protos/workflow/task_definition_pb2.py +28 -22
- flyte/_protos/workflow/task_definition_pb2.pyi +16 -4
- flyte/_protos/workflow/task_service_pb2.py +27 -11
- flyte/_protos/workflow/task_service_pb2.pyi +29 -1
- flyte/_protos/workflow/task_service_pb2_grpc.py +34 -0
- flyte/_task.py +2 -13
- flyte/_trace.py +0 -2
- flyte/_utils/__init__.py +4 -0
- flyte/_utils/org_discovery.py +57 -0
- flyte/_version.py +2 -2
- flyte/cli/_abort.py +4 -2
- flyte/cli/_common.py +10 -4
- flyte/cli/_create.py +17 -8
- flyte/cli/_deploy.py +14 -7
- flyte/cli/_get.py +11 -10
- flyte/cli/_params.py +1 -1
- flyte/cli/_run.py +1 -1
- flyte/cli/main.py +3 -7
- flyte/errors.py +11 -0
- flyte/extras/_container.py +0 -7
- flyte/remote/__init__.py +2 -1
- flyte/remote/_client/_protocols.py +2 -0
- flyte/remote/_data.py +2 -1
- flyte/remote/_task.py +141 -9
- flyte/syncify/_api.py +0 -1
- flyte/types/_type_engine.py +3 -1
- {flyte-0.2.0b10.dist-info → flyte-0.2.0b12.dist-info}/METADATA +1 -1
- {flyte-0.2.0b10.dist-info → flyte-0.2.0b12.dist-info}/RECORD +53 -48
- {flyte-0.2.0b10.dist-info → flyte-0.2.0b12.dist-info}/WHEEL +0 -0
- {flyte-0.2.0b10.dist-info → flyte-0.2.0b12.dist-info}/entry_points.txt +0 -0
- {flyte-0.2.0b10.dist-info → flyte-0.2.0b12.dist-info}/top_level.txt +0 -0
|
@@ -25,6 +25,11 @@ class TaskServiceStub(object):
|
|
|
25
25
|
request_serializer=workflow_dot_task__service__pb2.GetTaskDetailsRequest.SerializeToString,
|
|
26
26
|
response_deserializer=workflow_dot_task__service__pb2.GetTaskDetailsResponse.FromString,
|
|
27
27
|
)
|
|
28
|
+
self.ListTasks = channel.unary_unary(
|
|
29
|
+
'/cloudidl.workflow.TaskService/ListTasks',
|
|
30
|
+
request_serializer=workflow_dot_task__service__pb2.ListTasksRequest.SerializeToString,
|
|
31
|
+
response_deserializer=workflow_dot_task__service__pb2.ListTasksResponse.FromString,
|
|
32
|
+
)
|
|
28
33
|
|
|
29
34
|
|
|
30
35
|
class TaskServiceServicer(object):
|
|
@@ -45,6 +50,13 @@ class TaskServiceServicer(object):
|
|
|
45
50
|
context.set_details('Method not implemented!')
|
|
46
51
|
raise NotImplementedError('Method not implemented!')
|
|
47
52
|
|
|
53
|
+
def ListTasks(self, request, context):
|
|
54
|
+
"""Lists tasks, one per task name, returning the latest version and who it was deployed by.
|
|
55
|
+
"""
|
|
56
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
57
|
+
context.set_details('Method not implemented!')
|
|
58
|
+
raise NotImplementedError('Method not implemented!')
|
|
59
|
+
|
|
48
60
|
|
|
49
61
|
def add_TaskServiceServicer_to_server(servicer, server):
|
|
50
62
|
rpc_method_handlers = {
|
|
@@ -58,6 +70,11 @@ def add_TaskServiceServicer_to_server(servicer, server):
|
|
|
58
70
|
request_deserializer=workflow_dot_task__service__pb2.GetTaskDetailsRequest.FromString,
|
|
59
71
|
response_serializer=workflow_dot_task__service__pb2.GetTaskDetailsResponse.SerializeToString,
|
|
60
72
|
),
|
|
73
|
+
'ListTasks': grpc.unary_unary_rpc_method_handler(
|
|
74
|
+
servicer.ListTasks,
|
|
75
|
+
request_deserializer=workflow_dot_task__service__pb2.ListTasksRequest.FromString,
|
|
76
|
+
response_serializer=workflow_dot_task__service__pb2.ListTasksResponse.SerializeToString,
|
|
77
|
+
),
|
|
61
78
|
}
|
|
62
79
|
generic_handler = grpc.method_handlers_generic_handler(
|
|
63
80
|
'cloudidl.workflow.TaskService', rpc_method_handlers)
|
|
@@ -102,3 +119,20 @@ class TaskService(object):
|
|
|
102
119
|
workflow_dot_task__service__pb2.GetTaskDetailsResponse.FromString,
|
|
103
120
|
options, channel_credentials,
|
|
104
121
|
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
122
|
+
|
|
123
|
+
@staticmethod
|
|
124
|
+
def ListTasks(request,
|
|
125
|
+
target,
|
|
126
|
+
options=(),
|
|
127
|
+
channel_credentials=None,
|
|
128
|
+
call_credentials=None,
|
|
129
|
+
insecure=False,
|
|
130
|
+
compression=None,
|
|
131
|
+
wait_for_ready=None,
|
|
132
|
+
timeout=None,
|
|
133
|
+
metadata=None):
|
|
134
|
+
return grpc.experimental.unary_unary(request, target, '/cloudidl.workflow.TaskService/ListTasks',
|
|
135
|
+
workflow_dot_task__service__pb2.ListTasksRequest.SerializeToString,
|
|
136
|
+
workflow_dot_task__service__pb2.ListTasksResponse.FromString,
|
|
137
|
+
options, channel_credentials,
|
|
138
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
flyte/_task.py
CHANGED
|
@@ -23,6 +23,7 @@ from typing import (
|
|
|
23
23
|
|
|
24
24
|
from flyteidl.core.tasks_pb2 import DataLoadingConfig
|
|
25
25
|
|
|
26
|
+
from flyte._pod import PodTemplate
|
|
26
27
|
from flyte.errors import RuntimeSystemError, RuntimeUserError
|
|
27
28
|
|
|
28
29
|
from ._cache import Cache, CacheRequest
|
|
@@ -37,8 +38,6 @@ from ._timeout import TimeoutType
|
|
|
37
38
|
from .models import NativeInterface, SerializationContext
|
|
38
39
|
|
|
39
40
|
if TYPE_CHECKING:
|
|
40
|
-
from kubernetes.client import V1PodTemplate
|
|
41
|
-
|
|
42
41
|
from ._task_environment import TaskEnvironment
|
|
43
42
|
|
|
44
43
|
P = ParamSpec("P") # capture the function's parameters
|
|
@@ -96,8 +95,7 @@ class TaskTemplate(Generic[P, R]):
|
|
|
96
95
|
env: Optional[Dict[str, str]] = None
|
|
97
96
|
secrets: Optional[SecretRequest] = None
|
|
98
97
|
timeout: Optional[TimeoutType] = None
|
|
99
|
-
|
|
100
|
-
pod_template: Optional[Union[str, V1PodTemplate]] = None
|
|
98
|
+
pod_template: Optional[Union[str, PodTemplate]] = None
|
|
101
99
|
report: bool = False
|
|
102
100
|
|
|
103
101
|
parent_env: Optional[weakref.ReferenceType[TaskEnvironment]] = None
|
|
@@ -108,15 +106,6 @@ class TaskTemplate(Generic[P, R]):
|
|
|
108
106
|
_call_as_synchronous: bool = False
|
|
109
107
|
|
|
110
108
|
def __post_init__(self):
|
|
111
|
-
# If pod_template is set to a pod, verify
|
|
112
|
-
if self.pod_template is not None and not isinstance(self.pod_template, str):
|
|
113
|
-
try:
|
|
114
|
-
from kubernetes.client import V1PodTemplate # noqa: F401
|
|
115
|
-
except ImportError as e:
|
|
116
|
-
raise ImportError(
|
|
117
|
-
"kubernetes is not installed, please install kubernetes package to use pod_template"
|
|
118
|
-
) from e
|
|
119
|
-
|
|
120
109
|
# Auto set the image based on the image request
|
|
121
110
|
if self.image == "auto":
|
|
122
111
|
self.image = Image.auto()
|
flyte/_trace.py
CHANGED
|
@@ -112,10 +112,8 @@ def trace(func: Callable[..., T]) -> Callable[..., T]:
|
|
|
112
112
|
# Choose the appropriate wrapper based on the function type
|
|
113
113
|
if inspect.iscoroutinefunction(func):
|
|
114
114
|
# This handles async functions that return normal values
|
|
115
|
-
print(f"Coroutine function {func.__name__}")
|
|
116
115
|
return cast(Callable[..., T], wrapper_async)
|
|
117
116
|
elif inspect.isasyncgenfunction(func):
|
|
118
|
-
print(f"Async generator function {func.__name__}")
|
|
119
117
|
return cast(Callable[..., T], wrapper_async_iterator)
|
|
120
118
|
else:
|
|
121
119
|
# For regular sync functions
|
flyte/_utils/__init__.py
CHANGED
|
@@ -9,14 +9,18 @@ from .coro_management import run_coros
|
|
|
9
9
|
from .file_handling import filehash_update, update_hasher_for_source
|
|
10
10
|
from .helpers import get_cwd_editable_install
|
|
11
11
|
from .lazy_module import lazy_module
|
|
12
|
+
from .org_discovery import hostname_from_url, org_from_endpoint, sanitize_endpoint
|
|
12
13
|
from .uv_script_parser import parse_uv_script_file
|
|
13
14
|
|
|
14
15
|
__all__ = [
|
|
15
16
|
"AsyncLRUCache",
|
|
16
17
|
"filehash_update",
|
|
17
18
|
"get_cwd_editable_install",
|
|
19
|
+
"hostname_from_url",
|
|
18
20
|
"lazy_module",
|
|
21
|
+
"org_from_endpoint",
|
|
19
22
|
"parse_uv_script_file",
|
|
20
23
|
"run_coros",
|
|
24
|
+
"sanitize_endpoint",
|
|
21
25
|
"update_hasher_for_source",
|
|
22
26
|
]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
def hostname_from_url(url: str) -> str:
|
|
2
|
+
"""Parse a URL and return the hostname part."""
|
|
3
|
+
|
|
4
|
+
# Handle dns:/// format specifically (gRPC convention)
|
|
5
|
+
if url.startswith("dns:///"):
|
|
6
|
+
return url[7:] # Skip the "dns:///" prefix
|
|
7
|
+
|
|
8
|
+
# Handle standard URL formats
|
|
9
|
+
import urllib.parse
|
|
10
|
+
|
|
11
|
+
parsed = urllib.parse.urlparse(url)
|
|
12
|
+
return parsed.netloc or parsed.path.lstrip("/").rsplit("/")[0]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def org_from_endpoint(endpoint: str | None) -> str | None:
|
|
16
|
+
"""
|
|
17
|
+
Extracts the organization from the endpoint URL. The organization is assumed to be the first part of the domain.
|
|
18
|
+
This is temporary until we have a proper organization discovery mechanism through APIs.
|
|
19
|
+
|
|
20
|
+
:param endpoint: The endpoint URL
|
|
21
|
+
:return: The organization name or None if not found
|
|
22
|
+
"""
|
|
23
|
+
if not endpoint:
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
hostname = hostname_from_url(endpoint)
|
|
27
|
+
domain_parts = hostname.split(".")
|
|
28
|
+
if len(domain_parts) > 2:
|
|
29
|
+
# Assuming the organization is the first part of the domain
|
|
30
|
+
return domain_parts[0]
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def sanitize_endpoint(endpoint: str | None) -> str | None:
|
|
35
|
+
"""
|
|
36
|
+
Sanitize the endpoint URL by ensuring it has a valid scheme.
|
|
37
|
+
:param endpoint: The endpoint URL to sanitize
|
|
38
|
+
:return: Sanitized endpoint URL or None if the input was None
|
|
39
|
+
"""
|
|
40
|
+
if not endpoint:
|
|
41
|
+
return None
|
|
42
|
+
if "://" not in endpoint:
|
|
43
|
+
endpoint = f"dns:///{endpoint}"
|
|
44
|
+
else:
|
|
45
|
+
if endpoint.startswith("https://"):
|
|
46
|
+
# If the endpoint starts with dns:///, we assume it's a gRPC endpoint
|
|
47
|
+
endpoint = f"dns:///{endpoint[8:]}"
|
|
48
|
+
elif endpoint.startswith("http://"):
|
|
49
|
+
# If the endpoint starts with http://, we assume it's a REST endpoint
|
|
50
|
+
endpoint = f"dns:///{endpoint[7:]}"
|
|
51
|
+
elif not endpoint.startswith("dns:///"):
|
|
52
|
+
raise RuntimeError(
|
|
53
|
+
f"Invalid endpoint {endpoint}, expected format is "
|
|
54
|
+
f"dns:///<hostname> or https://<hostname> or http://<hostname>"
|
|
55
|
+
)
|
|
56
|
+
endpoint = endpoint.removesuffix("/")
|
|
57
|
+
return endpoint
|
flyte/_version.py
CHANGED
|
@@ -17,5 +17,5 @@ __version__: str
|
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
|
18
18
|
version_tuple: VERSION_TUPLE
|
|
19
19
|
|
|
20
|
-
__version__ = version = '0.2.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 2, 0, '
|
|
20
|
+
__version__ = version = '0.2.0b12'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'b12')
|
flyte/cli/_abort.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import rich_click as click
|
|
2
|
+
from rich.console import Console
|
|
2
3
|
|
|
3
4
|
from flyte.cli import _common as common
|
|
4
5
|
|
|
@@ -22,5 +23,6 @@ def run(cfg: common.CLIConfig, run_name: str, project: str | None = None, domain
|
|
|
22
23
|
cfg.init(project=project, domain=domain)
|
|
23
24
|
r = Run.get(name=run_name)
|
|
24
25
|
if r:
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
console = Console()
|
|
27
|
+
r.abort()
|
|
28
|
+
console.print(f"Run '{run_name}' has been aborted.")
|
flyte/cli/_common.py
CHANGED
|
@@ -78,7 +78,7 @@ class CLIConfig:
|
|
|
78
78
|
log_level: int | None = logging.ERROR
|
|
79
79
|
endpoint: str | None = None
|
|
80
80
|
insecure: bool = False
|
|
81
|
-
|
|
81
|
+
org: str | None = None
|
|
82
82
|
|
|
83
83
|
def replace(self, **kwargs) -> CLIConfig:
|
|
84
84
|
"""
|
|
@@ -90,7 +90,7 @@ class CLIConfig:
|
|
|
90
90
|
from flyte.config._config import TaskConfig
|
|
91
91
|
|
|
92
92
|
task_cfg = TaskConfig(
|
|
93
|
-
org=self.
|
|
93
|
+
org=self.org or self.config.task.org,
|
|
94
94
|
project=project or self.config.task.project,
|
|
95
95
|
domain=domain or self.config.task.domain,
|
|
96
96
|
)
|
|
@@ -310,12 +310,18 @@ def get_table(title: str, vals: Iterable[Any]) -> Table:
|
|
|
310
310
|
border_style=PREFERRED_BORDER_COLOR,
|
|
311
311
|
)
|
|
312
312
|
headers = None
|
|
313
|
+
has_rich_repr = False
|
|
313
314
|
for p in vals:
|
|
315
|
+
if hasattr(p, "__rich_repr__"):
|
|
316
|
+
has_rich_repr = True
|
|
317
|
+
elif not isinstance(p, (list, tuple)):
|
|
318
|
+
raise ValueError("Expected a list or tuple of values, or an object with __rich_repr__ method.")
|
|
319
|
+
o = p.__rich_repr__() if has_rich_repr else p
|
|
314
320
|
if headers is None:
|
|
315
|
-
headers = [k for k, _ in
|
|
321
|
+
headers = [k for k, _ in o]
|
|
316
322
|
for h in headers:
|
|
317
323
|
table.add_column(h.capitalize())
|
|
318
|
-
table.add_row(*[str(v) for _, v in
|
|
324
|
+
table.add_row(*[str(v) for _, v in o])
|
|
319
325
|
return table
|
|
320
326
|
|
|
321
327
|
|
flyte/cli/_create.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import Any, Dict, get_args
|
|
|
4
4
|
import rich_click as click
|
|
5
5
|
|
|
6
6
|
import flyte.cli._common as common
|
|
7
|
-
from flyte.remote
|
|
7
|
+
from flyte.remote import SecretTypes
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@click.group(name="create")
|
|
@@ -86,11 +86,9 @@ def secret(
|
|
|
86
86
|
default=False,
|
|
87
87
|
help="Force overwrite of the configuration file if it already exists.",
|
|
88
88
|
show_default=True,
|
|
89
|
-
prompt="Are you sure you want to overwrite the configuration file?",
|
|
90
|
-
confirmation_prompt=True,
|
|
91
89
|
)
|
|
92
90
|
def config(
|
|
93
|
-
output:
|
|
91
|
+
output: str,
|
|
94
92
|
endpoint: str | None = None,
|
|
95
93
|
insecure: bool = False,
|
|
96
94
|
org: str | None = None,
|
|
@@ -105,15 +103,26 @@ def config(
|
|
|
105
103
|
"""
|
|
106
104
|
import yaml
|
|
107
105
|
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
from flyte._utils import org_from_endpoint, sanitize_endpoint
|
|
107
|
+
|
|
108
|
+
output_path = Path(output)
|
|
109
|
+
|
|
110
|
+
if output_path.exists() and not force:
|
|
111
|
+
force = click.confirm(f"Overwrite [{output_path}]?", default=False)
|
|
112
|
+
if not force:
|
|
113
|
+
click.echo(f"Will not overwrite the existing config file at {output_path}")
|
|
114
|
+
return
|
|
110
115
|
|
|
111
116
|
admin: Dict[str, Any] = {}
|
|
112
117
|
if endpoint:
|
|
118
|
+
endpoint = sanitize_endpoint(endpoint)
|
|
113
119
|
admin["endpoint"] = endpoint
|
|
114
120
|
if insecure:
|
|
115
121
|
admin["insecure"] = insecure
|
|
116
122
|
|
|
123
|
+
if not org and endpoint:
|
|
124
|
+
org = org_from_endpoint(endpoint)
|
|
125
|
+
|
|
117
126
|
task: Dict[str, str] = {}
|
|
118
127
|
if org:
|
|
119
128
|
task["org"] = org
|
|
@@ -125,7 +134,7 @@ def config(
|
|
|
125
134
|
if not admin and not task:
|
|
126
135
|
raise click.BadParameter("At least one of --endpoint or --org must be provided.")
|
|
127
136
|
|
|
128
|
-
with open(
|
|
137
|
+
with open(output_path, "w") as f:
|
|
129
138
|
d: Dict[str, Any] = {}
|
|
130
139
|
if admin:
|
|
131
140
|
d["admin"] = admin
|
|
@@ -133,4 +142,4 @@ def config(
|
|
|
133
142
|
d["task"] = task
|
|
134
143
|
yaml.dump(d, f)
|
|
135
144
|
|
|
136
|
-
click.echo(f"Config file
|
|
145
|
+
click.echo(f"Config file written to {output_path}")
|
flyte/cli/_deploy.py
CHANGED
|
@@ -74,15 +74,22 @@ class DeployEnvCommand(click.Command):
|
|
|
74
74
|
super().__init__(*args, **kwargs)
|
|
75
75
|
|
|
76
76
|
def invoke(self, ctx: Context):
|
|
77
|
-
|
|
77
|
+
from rich.console import Console
|
|
78
|
+
|
|
79
|
+
console = Console()
|
|
80
|
+
console.print(f"Deploying root - environment: {self.obj_name}")
|
|
78
81
|
obj: CLIConfig = ctx.obj
|
|
79
82
|
obj.init(self.deploy_args.project, self.deploy_args.domain)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
with console.status("Deploying...", spinner="dots"):
|
|
84
|
+
deployment = flyte.deploy(
|
|
85
|
+
self.obj,
|
|
86
|
+
dryrun=self.deploy_args.dry_run,
|
|
87
|
+
copy_style=self.deploy_args.copy_style,
|
|
88
|
+
version=self.deploy_args.version,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
console.print(common.get_table("Environments", deployment.env_repr()))
|
|
92
|
+
console.print(common.get_table("Tasks", deployment.task_repr()))
|
|
86
93
|
|
|
87
94
|
|
|
88
95
|
class EnvPerFileGroup(common.ObjectsPerFileGroup):
|
flyte/cli/_get.py
CHANGED
|
@@ -40,7 +40,6 @@ def project(cfg: common.CLIConfig, name: str | None = None):
|
|
|
40
40
|
"""
|
|
41
41
|
from flyte.remote import Project
|
|
42
42
|
|
|
43
|
-
print(cfg)
|
|
44
43
|
cfg.init()
|
|
45
44
|
|
|
46
45
|
console = Console()
|
|
@@ -76,10 +75,12 @@ def run(cfg: common.CLIConfig, name: str | None = None, project: str | None = No
|
|
|
76
75
|
@get.command(cls=common.CommandBase)
|
|
77
76
|
@click.argument("name", type=str, required=False)
|
|
78
77
|
@click.argument("version", type=str, required=False)
|
|
78
|
+
@click.option("--limit", type=int, default=100, help="Limit the number of tasks to show.")
|
|
79
79
|
@click.pass_obj
|
|
80
80
|
def task(
|
|
81
81
|
cfg: common.CLIConfig,
|
|
82
82
|
name: str | None = None,
|
|
83
|
+
limit: int = 100,
|
|
83
84
|
version: str | None = None,
|
|
84
85
|
project: str | None = None,
|
|
85
86
|
domain: str | None = None,
|
|
@@ -95,16 +96,16 @@ def task(
|
|
|
95
96
|
|
|
96
97
|
console = Console()
|
|
97
98
|
if name:
|
|
98
|
-
if
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
if version:
|
|
100
|
+
v = Task.get(name=name, version=version)
|
|
101
|
+
if v is None:
|
|
102
|
+
raise click.BadParameter(f"Task {name} not found.")
|
|
103
|
+
t = v.fetch()
|
|
104
|
+
console.print(pretty_repr(t))
|
|
105
|
+
else:
|
|
106
|
+
console.print(common.get_table("Tasks", Task.listall(by_task_name=name, limit=limit)))
|
|
105
107
|
else:
|
|
106
|
-
|
|
107
|
-
# console.print(common.get_table("Tasks", Task.listall()))
|
|
108
|
+
console.print(common.get_table("Tasks", Task.listall(limit=limit)))
|
|
108
109
|
|
|
109
110
|
|
|
110
111
|
@get.command(cls=common.CommandBase)
|
flyte/cli/_params.py
CHANGED
|
@@ -110,7 +110,7 @@ class FileParamType(click.ParamType):
|
|
|
110
110
|
p = pathlib.Path(value)
|
|
111
111
|
if not p.exists() or not p.is_file():
|
|
112
112
|
raise click.BadParameter(f"parameter should be a valid file path, {value}")
|
|
113
|
-
return File(
|
|
113
|
+
return File.from_existing_remote(value)
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
class PickleParamType(click.ParamType):
|
flyte/cli/_run.py
CHANGED
|
@@ -97,7 +97,7 @@ class RunTaskCommand(click.Command):
|
|
|
97
97
|
if obj is None:
|
|
98
98
|
import flyte.config
|
|
99
99
|
|
|
100
|
-
obj = CLIConfig(flyte.config.auto())
|
|
100
|
+
obj = CLIConfig(flyte.config.auto(), ctx)
|
|
101
101
|
|
|
102
102
|
if not self.run_args.local:
|
|
103
103
|
assert obj.endpoint, "CLI Config should have an endpoint"
|
flyte/cli/main.py
CHANGED
|
@@ -146,15 +146,11 @@ def main(
|
|
|
146
146
|
cfg = config.auto(config_file=config_file)
|
|
147
147
|
logger.debug(f"Using config file discovered at location {cfg.source}")
|
|
148
148
|
|
|
149
|
-
final_insecure = cfg.platform.insecure
|
|
150
|
-
if insecure is not None:
|
|
151
|
-
final_insecure = insecure
|
|
152
|
-
|
|
153
149
|
ctx.obj = CLIConfig(
|
|
154
150
|
log_level=log_level,
|
|
155
|
-
endpoint=endpoint
|
|
156
|
-
insecure=
|
|
157
|
-
|
|
151
|
+
endpoint=endpoint,
|
|
152
|
+
insecure=insecure,
|
|
153
|
+
org=org,
|
|
158
154
|
config=cfg,
|
|
159
155
|
ctx=ctx,
|
|
160
156
|
)
|
flyte/errors.py
CHANGED
|
@@ -150,3 +150,14 @@ class LogsNotYetAvailableError(BaseRuntimeError):
|
|
|
150
150
|
|
|
151
151
|
def __init__(self, message: str):
|
|
152
152
|
super().__init__("LogsNotYetAvailable", "system", message, None)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class RuntimeDataValidationError(RuntimeUserError):
|
|
156
|
+
"""
|
|
157
|
+
This error is raised when the user tries to access a resource that does not exist or is invalid.
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
def __init__(self, var: str, e: Exception, task_name: str = ""):
|
|
161
|
+
super().__init__(
|
|
162
|
+
"DataValiationError", f"In task {task_name} variable {var}, failed to serialize/deserialize because {e}"
|
|
163
|
+
)
|
flyte/extras/_container.py
CHANGED
|
@@ -9,8 +9,6 @@ from flyte._logging import logger
|
|
|
9
9
|
from flyte._task import TaskTemplate
|
|
10
10
|
from flyte.models import NativeInterface, SerializationContext
|
|
11
11
|
|
|
12
|
-
_PRIMARY_CONTAINER_NAME_FIELD = "primary_container_name"
|
|
13
|
-
|
|
14
12
|
|
|
15
13
|
def _extract_command_key(cmd: str, **kwargs) -> List[Any] | None:
|
|
16
14
|
"""
|
|
@@ -263,8 +261,3 @@ class ContainerTask(TaskTemplate):
|
|
|
263
261
|
|
|
264
262
|
def container_args(self, sctx: SerializationContext) -> List[str]:
|
|
265
263
|
return self._cmd + (self._args if self._args else [])
|
|
266
|
-
|
|
267
|
-
def config(self, sctx: SerializationContext) -> Dict[str, str]:
|
|
268
|
-
if self.pod_template is None:
|
|
269
|
-
return {}
|
|
270
|
-
return {_PRIMARY_CONTAINER_NAME_FIELD: self.primary_container_name}
|
flyte/remote/__init__.py
CHANGED
|
@@ -11,6 +11,7 @@ __all__ = [
|
|
|
11
11
|
"Run",
|
|
12
12
|
"RunDetails",
|
|
13
13
|
"Secret",
|
|
14
|
+
"SecretTypes",
|
|
14
15
|
"Task",
|
|
15
16
|
"create_channel",
|
|
16
17
|
"upload_dir",
|
|
@@ -21,5 +22,5 @@ from ._client.auth import create_channel
|
|
|
21
22
|
from ._data import upload_dir, upload_file
|
|
22
23
|
from ._project import Project
|
|
23
24
|
from ._run import Action, ActionDetails, ActionInputs, ActionOutputs, Run, RunDetails
|
|
24
|
-
from ._secret import Secret
|
|
25
|
+
from ._secret import Secret, SecretTypes
|
|
25
26
|
from ._task import Task
|
|
@@ -58,6 +58,8 @@ class TaskService(Protocol):
|
|
|
58
58
|
self, request: task_service_pb2.GetTaskDetailsRequest
|
|
59
59
|
) -> task_service_pb2.GetTaskDetailsResponse: ...
|
|
60
60
|
|
|
61
|
+
async def ListTasks(self, request: task_service_pb2.ListTasksRequest) -> task_service_pb2.ListTasksResponse: ...
|
|
62
|
+
|
|
61
63
|
|
|
62
64
|
class RunService(Protocol):
|
|
63
65
|
async def CreateRun(self, request: run_service_pb2.CreateRunRequest) -> run_service_pb2.CreateRunResponse: ...
|
flyte/remote/_data.py
CHANGED
|
@@ -100,7 +100,8 @@ async def _upload_single_file(
|
|
|
100
100
|
if put_resp.status_code != 200:
|
|
101
101
|
raise RuntimeSystemError(
|
|
102
102
|
"UploadFailed",
|
|
103
|
-
f"Failed to upload {fp} to {resp.signed_url}, status code: {put_resp.status_code}"
|
|
103
|
+
f"Failed to upload {fp} to {resp.signed_url}, status code: {put_resp.status_code}, "
|
|
104
|
+
f"response: {put_resp.text}",
|
|
104
105
|
)
|
|
105
106
|
# TODO in old code we did this
|
|
106
107
|
# if self._config.platform.insecure_skip_verify is True
|