flyte 0.2.0b7__py3-none-any.whl → 0.2.0b8__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/_environment.py +42 -1
- flyte/_image.py +1 -2
- flyte/_internal/controllers/__init__.py +2 -0
- flyte/_internal/controllers/_local_controller.py +3 -0
- flyte/_internal/controllers/remote/_controller.py +3 -0
- flyte/_internal/controllers/remote/_informer.py +3 -3
- flyte/_task.py +51 -12
- flyte/_task_environment.py +48 -66
- flyte/_utils/coro_management.py +0 -2
- flyte/_version.py +2 -2
- flyte/cli/_common.py +1 -0
- flyte/cli/_create.py +39 -8
- flyte/cli/_delete.py +2 -2
- flyte/cli/_deploy.py +4 -1
- flyte/cli/_gen.py +155 -0
- flyte/cli/_get.py +53 -7
- flyte/cli/_run.py +22 -2
- flyte/cli/main.py +55 -8
- flyte/extras/_container.py +1 -1
- flyte/remote/_run.py +1 -0
- flyte/syncify/__init__.py +51 -0
- flyte/syncify/_api.py +5 -6
- {flyte-0.2.0b7.dist-info → flyte-0.2.0b8.dist-info}/METADATA +28 -4
- {flyte-0.2.0b7.dist-info → flyte-0.2.0b8.dist-info}/RECORD +27 -26
- {flyte-0.2.0b7.dist-info → flyte-0.2.0b8.dist-info}/WHEEL +0 -0
- {flyte-0.2.0b7.dist-info → flyte-0.2.0b8.dist-info}/entry_points.txt +0 -0
- {flyte-0.2.0b7.dist-info → flyte-0.2.0b8.dist-info}/top_level.txt +0 -0
flyte/_environment.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import re
|
|
3
4
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Union
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Union
|
|
5
6
|
|
|
6
7
|
import rich.repr
|
|
7
8
|
|
|
@@ -14,6 +15,10 @@ if TYPE_CHECKING:
|
|
|
14
15
|
from kubernetes.client import V1PodTemplate
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
def is_snake_or_kebab_with_numbers(s: str) -> bool:
|
|
19
|
+
return re.fullmatch(r"^[a-z0-9]+([_-][a-z0-9]+)*$", s) is not None
|
|
20
|
+
|
|
21
|
+
|
|
17
22
|
@rich.repr.auto
|
|
18
23
|
@dataclass(init=True, repr=True)
|
|
19
24
|
class Environment:
|
|
@@ -36,8 +41,44 @@ class Environment:
|
|
|
36
41
|
resources: Optional[Resources] = None
|
|
37
42
|
image: Union[str, Image, Literal["auto"]] = "auto"
|
|
38
43
|
|
|
44
|
+
def __post_init__(self):
|
|
45
|
+
if not is_snake_or_kebab_with_numbers(self.name):
|
|
46
|
+
raise ValueError(f"Environment name '{self.name}' must be in snake_case or kebab-case format.")
|
|
47
|
+
|
|
39
48
|
def add_dependency(self, *env: Environment):
|
|
40
49
|
"""
|
|
41
50
|
Add a dependency to the environment.
|
|
42
51
|
"""
|
|
43
52
|
self.env_dep_hints.extend(env)
|
|
53
|
+
|
|
54
|
+
def clone_with(
|
|
55
|
+
self,
|
|
56
|
+
name: str,
|
|
57
|
+
image: Optional[Union[str, Image, Literal["auto"]]] = None,
|
|
58
|
+
resources: Optional[Resources] = None,
|
|
59
|
+
env: Optional[Dict[str, str]] = None,
|
|
60
|
+
secrets: Optional[SecretRequest] = None,
|
|
61
|
+
env_dep_hints: Optional[List[Environment]] = None,
|
|
62
|
+
**kwargs: Any,
|
|
63
|
+
) -> Environment:
|
|
64
|
+
raise NotImplementedError
|
|
65
|
+
|
|
66
|
+
def _get_kwargs(self) -> Dict[str, Any]:
|
|
67
|
+
"""
|
|
68
|
+
Get the keyword arguments for the environment.
|
|
69
|
+
"""
|
|
70
|
+
kwargs: Dict[str, Any] = {
|
|
71
|
+
"env_dep_hints": self.env_dep_hints,
|
|
72
|
+
"image": self.image,
|
|
73
|
+
}
|
|
74
|
+
if self.resources is not None:
|
|
75
|
+
kwargs["resources"] = self.resources
|
|
76
|
+
if self.secrets is not None:
|
|
77
|
+
kwargs["secrets"] = self.secrets
|
|
78
|
+
if self.env is not None:
|
|
79
|
+
kwargs["env"] = self.env
|
|
80
|
+
if self.pod_template is not None:
|
|
81
|
+
kwargs["pod_template"] = self.pod_template
|
|
82
|
+
if self.description is not None:
|
|
83
|
+
kwargs["description"] = self.description
|
|
84
|
+
return kwargs
|
flyte/_image.py
CHANGED
|
@@ -444,8 +444,7 @@ class Image:
|
|
|
444
444
|
```
|
|
445
445
|
|
|
446
446
|
For more information on the uv script format, see the documentation:
|
|
447
|
-
|
|
448
|
-
UV: Declaring script dependencies</href>
|
|
447
|
+
[UV: Declaring script dependencies](https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies)
|
|
449
448
|
|
|
450
449
|
:param name: name of the image
|
|
451
450
|
:param registry: registry to use for the image
|
|
@@ -28,6 +28,8 @@ class Controller(Protocol):
|
|
|
28
28
|
"""
|
|
29
29
|
...
|
|
30
30
|
|
|
31
|
+
def submit_sync(self, _task: TaskTemplate, *args, **kwargs) -> Any: ...
|
|
32
|
+
|
|
31
33
|
async def submit_task_ref(self, _task: task_definition_pb2.TaskDetails, *args, **kwargs) -> Any:
|
|
32
34
|
"""
|
|
33
35
|
Submit a task reference to the controller asynchronously and wait for the result. This is async and will block
|
|
@@ -8,6 +8,7 @@ from flyte._internal.runtime.entrypoints import direct_dispatch
|
|
|
8
8
|
from flyte._logging import log, logger
|
|
9
9
|
from flyte._protos.workflow import task_definition_pb2
|
|
10
10
|
from flyte._task import TaskTemplate
|
|
11
|
+
from flyte._utils.asyn import loop_manager
|
|
11
12
|
from flyte.models import ActionID, NativeInterface, RawDataPath
|
|
12
13
|
|
|
13
14
|
R = TypeVar("R")
|
|
@@ -58,6 +59,8 @@ class LocalController:
|
|
|
58
59
|
return result
|
|
59
60
|
return out
|
|
60
61
|
|
|
62
|
+
submit_sync = loop_manager.synced(submit)
|
|
63
|
+
|
|
61
64
|
async def finalize_parent_action(self, action: ActionID):
|
|
62
65
|
pass
|
|
63
66
|
|
|
@@ -21,6 +21,7 @@ from flyte._internal.runtime.task_serde import translate_task_to_wire
|
|
|
21
21
|
from flyte._logging import logger
|
|
22
22
|
from flyte._protos.workflow import run_definition_pb2, task_definition_pb2
|
|
23
23
|
from flyte._task import TaskTemplate
|
|
24
|
+
from flyte._utils.asyn import loop_manager
|
|
24
25
|
from flyte.models import ActionID, NativeInterface, SerializationContext
|
|
25
26
|
|
|
26
27
|
R = TypeVar("R")
|
|
@@ -235,6 +236,8 @@ class RemoteController(Controller):
|
|
|
235
236
|
async with self._parent_action_semaphore[unique_action_name(current_action_id)]:
|
|
236
237
|
return await self._submit(task_call_seq, _task, *args, **kwargs)
|
|
237
238
|
|
|
239
|
+
submit_sync = loop_manager.synced(submit)
|
|
240
|
+
|
|
238
241
|
async def finalize_parent_action(self, action_id: ActionID):
|
|
239
242
|
"""
|
|
240
243
|
This method is invoked when the parent action is finished. It will finalize the run and upload the outputs
|
|
@@ -38,11 +38,11 @@ class ActionCache:
|
|
|
38
38
|
"""
|
|
39
39
|
Add an action to the cache if it doesn't exist. This is invoked by the watch.
|
|
40
40
|
"""
|
|
41
|
-
logger.
|
|
41
|
+
logger.debug(f"Observing phase {run_definition_pb2.Phase.Name(state.phase)} for {state.action_id.name}")
|
|
42
42
|
if state.output_uri:
|
|
43
|
-
logger.
|
|
43
|
+
logger.debug(f"Output URI: {state.output_uri}")
|
|
44
44
|
else:
|
|
45
|
-
logger.
|
|
45
|
+
logger.warning(f"{state.action_id.name} has no output URI")
|
|
46
46
|
if state.phase == run_definition_pb2.Phase.PHASE_FAILED:
|
|
47
47
|
logger.error(
|
|
48
48
|
f"Action {state.action_id.name} failed with error (msg):"
|
flyte/_task.py
CHANGED
|
@@ -3,10 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
import weakref
|
|
4
4
|
from dataclasses import dataclass, field, replace
|
|
5
5
|
from functools import cached_property
|
|
6
|
+
from inspect import iscoroutinefunction
|
|
6
7
|
from typing import (
|
|
7
8
|
TYPE_CHECKING,
|
|
8
9
|
Any,
|
|
9
|
-
Awaitable,
|
|
10
10
|
Callable,
|
|
11
11
|
Coroutine,
|
|
12
12
|
Dict,
|
|
@@ -15,6 +15,7 @@ from typing import (
|
|
|
15
15
|
Literal,
|
|
16
16
|
Optional,
|
|
17
17
|
ParamSpec,
|
|
18
|
+
TypeAlias,
|
|
18
19
|
TypeVar,
|
|
19
20
|
Union,
|
|
20
21
|
)
|
|
@@ -42,6 +43,10 @@ if TYPE_CHECKING:
|
|
|
42
43
|
P = ParamSpec("P") # capture the function's parameters
|
|
43
44
|
R = TypeVar("R") # return type
|
|
44
45
|
|
|
46
|
+
AsyncFunctionType: TypeAlias = Callable[P, Coroutine[Any, Any, R]]
|
|
47
|
+
SyncFunctionType: TypeAlias = Callable[P, R]
|
|
48
|
+
FunctionTypes: TypeAlias = Union[AsyncFunctionType, SyncFunctionType]
|
|
49
|
+
|
|
45
50
|
|
|
46
51
|
@dataclass(kw_only=True)
|
|
47
52
|
class TaskTemplate(Generic[P, R]):
|
|
@@ -98,6 +103,9 @@ class TaskTemplate(Generic[P, R]):
|
|
|
98
103
|
local: bool = field(default=False, init=False)
|
|
99
104
|
ref: bool = field(default=False, init=False, repr=False, compare=False)
|
|
100
105
|
|
|
106
|
+
# Only used in python 3.10 and 3.11, where we cannot use markcoroutinefunction
|
|
107
|
+
_call_as_synchronous: bool = False
|
|
108
|
+
|
|
101
109
|
def __post_init__(self):
|
|
102
110
|
# If pod_template is set to a pod, verify
|
|
103
111
|
if self.pod_template is not None and not isinstance(self.pod_template, str):
|
|
@@ -208,13 +216,15 @@ class TaskTemplate(Generic[P, R]):
|
|
|
208
216
|
def native_interface(self) -> NativeInterface:
|
|
209
217
|
return self.interface
|
|
210
218
|
|
|
211
|
-
|
|
219
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, R] | R:
|
|
212
220
|
"""
|
|
213
221
|
This is the entrypoint for an async function task at runtime. It will be called during an execution.
|
|
214
222
|
Please do not override this method, if you simply want to modify the execution behavior, override the
|
|
215
223
|
execute method.
|
|
216
224
|
|
|
217
|
-
|
|
225
|
+
This needs to be overridable to maybe be async.
|
|
226
|
+
The returned thing from here needs to be an awaitable if the underlying task is async, and a regular object
|
|
227
|
+
if the task is not.
|
|
218
228
|
"""
|
|
219
229
|
try:
|
|
220
230
|
ctx = internal_ctx()
|
|
@@ -226,8 +236,14 @@ class TaskTemplate(Generic[P, R]):
|
|
|
226
236
|
|
|
227
237
|
controller = get_controller()
|
|
228
238
|
if controller:
|
|
229
|
-
|
|
230
|
-
|
|
239
|
+
if self._call_as_synchronous:
|
|
240
|
+
return controller.submit_sync(self, *args, **kwargs)
|
|
241
|
+
else:
|
|
242
|
+
return controller.submit(self, *args, **kwargs)
|
|
243
|
+
else:
|
|
244
|
+
raise RuntimeSystemError("BadContext", "Controller is not initialized.")
|
|
245
|
+
|
|
246
|
+
return self.forward(*args, **kwargs)
|
|
231
247
|
except RuntimeSystemError:
|
|
232
248
|
raise
|
|
233
249
|
except RuntimeUserError:
|
|
@@ -235,6 +251,17 @@ class TaskTemplate(Generic[P, R]):
|
|
|
235
251
|
except Exception as e:
|
|
236
252
|
raise RuntimeUserError(type(e).__name__, str(e)) from e
|
|
237
253
|
|
|
254
|
+
def forward(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, R] | R:
|
|
255
|
+
"""
|
|
256
|
+
Think of this as a local execute method for your task. This function will be invoked by the __call__ method
|
|
257
|
+
when not in a Flyte task execution context. See the implementation below for an example.
|
|
258
|
+
|
|
259
|
+
:param args:
|
|
260
|
+
:param kwargs:
|
|
261
|
+
:return:
|
|
262
|
+
"""
|
|
263
|
+
raise NotImplementedError
|
|
264
|
+
|
|
238
265
|
def override(
|
|
239
266
|
self,
|
|
240
267
|
*,
|
|
@@ -290,26 +317,38 @@ class AsyncFunctionTaskTemplate(TaskTemplate[P, R]):
|
|
|
290
317
|
is decorated with the task decorator.
|
|
291
318
|
"""
|
|
292
319
|
|
|
293
|
-
func:
|
|
320
|
+
func: FunctionTypes
|
|
321
|
+
|
|
322
|
+
def __post_init__(self):
|
|
323
|
+
super().__post_init__()
|
|
324
|
+
if not iscoroutinefunction(self.func):
|
|
325
|
+
self._call_as_synchronous = True
|
|
294
326
|
|
|
295
327
|
@cached_property
|
|
296
328
|
def native_interface(self) -> NativeInterface:
|
|
297
329
|
return NativeInterface.from_callable(self.func)
|
|
298
330
|
|
|
331
|
+
def forward(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, R] | R:
|
|
332
|
+
# In local execution, we want to just call the function. Note we're not awaiting anything here.
|
|
333
|
+
# If the function was a coroutine function, the coroutine is returned and the await that the caller has
|
|
334
|
+
# in front of the task invocation will handle the awaiting.
|
|
335
|
+
return self.func(*args, **kwargs)
|
|
336
|
+
|
|
299
337
|
async def execute(self, *args: P.args, **kwargs: P.kwargs) -> R:
|
|
300
338
|
"""
|
|
301
339
|
This is the execute method that will be called when the task is invoked. It will call the actual function.
|
|
302
340
|
# TODO We may need to keep this as the bare func execute, and need a pre and post execute some other func.
|
|
303
341
|
"""
|
|
342
|
+
|
|
304
343
|
ctx = internal_ctx()
|
|
344
|
+
assert ctx.data.task_context is not None, "Function should have already returned if not in a task context"
|
|
305
345
|
ctx_data = await self.pre(*args, **kwargs)
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
346
|
+
tctx = ctx.data.task_context.replace(data=ctx_data)
|
|
347
|
+
with ctx.replace_task_context(tctx):
|
|
348
|
+
if iscoroutinefunction(self.func):
|
|
309
349
|
v = await self.func(*args, **kwargs)
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
v = await self.func(*args, **kwargs)
|
|
350
|
+
else:
|
|
351
|
+
v = self.func(*args, **kwargs)
|
|
313
352
|
await self.post(v)
|
|
314
353
|
return v
|
|
315
354
|
|
flyte/_task_environment.py
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import asyncio
|
|
4
3
|
import weakref
|
|
5
4
|
from dataclasses import dataclass, field, replace
|
|
6
5
|
from datetime import timedelta
|
|
7
|
-
from
|
|
8
|
-
|
|
6
|
+
from typing import (
|
|
7
|
+
TYPE_CHECKING,
|
|
8
|
+
Any,
|
|
9
|
+
Callable,
|
|
10
|
+
Dict,
|
|
11
|
+
List,
|
|
12
|
+
Literal,
|
|
13
|
+
Optional,
|
|
14
|
+
Union,
|
|
15
|
+
cast,
|
|
16
|
+
)
|
|
9
17
|
|
|
10
18
|
import rich.repr
|
|
11
19
|
|
|
@@ -23,8 +31,7 @@ from .models import NativeInterface
|
|
|
23
31
|
if TYPE_CHECKING:
|
|
24
32
|
from kubernetes.client import V1PodTemplate
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
R = TypeVar("R") # return type
|
|
34
|
+
from ._task import FunctionTypes, P, R
|
|
28
35
|
|
|
29
36
|
|
|
30
37
|
@rich.repr.auto
|
|
@@ -54,7 +61,7 @@ class TaskEnvironment(Environment):
|
|
|
54
61
|
"""
|
|
55
62
|
|
|
56
63
|
cache: Union[CacheRequest] = "auto"
|
|
57
|
-
reusable:
|
|
64
|
+
reusable: ReusePolicy | None = None
|
|
58
65
|
# TODO Shall we make this union of string or env? This way we can lookup the env by module/file:name
|
|
59
66
|
# TODO also we could add list of files that are used by this environment
|
|
60
67
|
|
|
@@ -65,32 +72,42 @@ class TaskEnvironment(Environment):
|
|
|
65
72
|
name: str,
|
|
66
73
|
image: Optional[Union[str, Image, Literal["auto"]]] = None,
|
|
67
74
|
resources: Optional[Resources] = None,
|
|
68
|
-
cache: Union[CacheRequest, None] = None,
|
|
69
75
|
env: Optional[Dict[str, str]] = None,
|
|
70
|
-
reusable: Union[ReusePolicy, None] = None,
|
|
71
76
|
secrets: Optional[SecretRequest] = None,
|
|
72
77
|
env_dep_hints: Optional[List[Environment]] = None,
|
|
78
|
+
**kwargs: Any,
|
|
73
79
|
) -> TaskEnvironment:
|
|
74
80
|
"""
|
|
75
|
-
Clone the
|
|
81
|
+
Clone the TaskEnvironment with new parameters.
|
|
82
|
+
besides the base environment parameters, you can override, kwargs like `cache`, `reusable`, etc.
|
|
83
|
+
|
|
76
84
|
"""
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
cache = kwargs.pop("cache", None)
|
|
86
|
+
reusable = kwargs.pop("reusable", None)
|
|
87
|
+
|
|
88
|
+
# validate unknown kwargs if needed
|
|
89
|
+
if kwargs:
|
|
90
|
+
raise TypeError(f"Unexpected keyword arguments: {list(kwargs.keys())}")
|
|
91
|
+
|
|
92
|
+
kwargs = self._get_kwargs()
|
|
93
|
+
kwargs["name"] = name
|
|
94
|
+
if image is not None:
|
|
95
|
+
kwargs["image"] = image
|
|
96
|
+
if resources is not None:
|
|
97
|
+
kwargs["resources"] = resources
|
|
98
|
+
if cache is not None:
|
|
99
|
+
kwargs["cache"] = cache
|
|
100
|
+
if env is not None:
|
|
101
|
+
kwargs["env"] = env
|
|
102
|
+
if reusable is not None:
|
|
103
|
+
kwargs["reusable"] = reusable
|
|
104
|
+
if secrets is not None:
|
|
105
|
+
kwargs["secrets"] = secrets
|
|
106
|
+
if env_dep_hints is not None:
|
|
107
|
+
kwargs["env_dep_hints"] = env_dep_hints
|
|
108
|
+
return replace(self, **kwargs)
|
|
109
|
+
|
|
110
|
+
def task(
|
|
94
111
|
self,
|
|
95
112
|
_func=None,
|
|
96
113
|
*,
|
|
@@ -104,6 +121,7 @@ class TaskEnvironment(Environment):
|
|
|
104
121
|
report: bool = False,
|
|
105
122
|
) -> Union[AsyncFunctionTaskTemplate, Callable[P, R]]:
|
|
106
123
|
"""
|
|
124
|
+
:param _func: Optional The function to decorate. If not provided, the decorator will return a callable that
|
|
107
125
|
:param name: Optional The name of the task (defaults to the function name)
|
|
108
126
|
:param cache: Optional The cache policy for the task, defaults to auto, which will cache the results of the
|
|
109
127
|
task.
|
|
@@ -119,25 +137,12 @@ class TaskEnvironment(Environment):
|
|
|
119
137
|
if pod_template is not None:
|
|
120
138
|
raise ValueError("Cannot set pod_template when environment is reusable.")
|
|
121
139
|
|
|
122
|
-
def decorator(func:
|
|
140
|
+
def decorator(func: FunctionTypes) -> AsyncFunctionTaskTemplate[P, R]:
|
|
123
141
|
task_name = name or func.__name__
|
|
124
142
|
task_name = self.name + "." + task_name
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@wraps(func)
|
|
130
|
-
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
131
|
-
return await func(*args, **kwargs)
|
|
132
|
-
|
|
133
|
-
if not asyncio.iscoroutinefunction(func):
|
|
134
|
-
raise TypeError(
|
|
135
|
-
f"Function {func.__name__} is not a coroutine function. Use @env.task decorator for async tasks."
|
|
136
|
-
f"You can simply mark your function as async def {func.__name__} to make it a coroutine function, "
|
|
137
|
-
f"it is ok to write sync code in async functions, but not the other way around."
|
|
138
|
-
)
|
|
139
|
-
tmpl = AsyncFunctionTaskTemplate(
|
|
140
|
-
func=wrapper,
|
|
143
|
+
|
|
144
|
+
tmpl: AsyncFunctionTaskTemplate = AsyncFunctionTaskTemplate(
|
|
145
|
+
func=func,
|
|
141
146
|
name=task_name,
|
|
142
147
|
image=self.image,
|
|
143
148
|
resources=self.resources,
|
|
@@ -160,29 +165,6 @@ class TaskEnvironment(Environment):
|
|
|
160
165
|
return cast(AsyncFunctionTaskTemplate, decorator)
|
|
161
166
|
return cast(AsyncFunctionTaskTemplate, decorator(_func))
|
|
162
167
|
|
|
163
|
-
@property
|
|
164
|
-
def task(self) -> Callable:
|
|
165
|
-
"""
|
|
166
|
-
Decorator to create a new task with the environment settings.
|
|
167
|
-
The task will be executed in its own container with the specified image, resources, and environment variables,
|
|
168
|
-
unless reusePolicy is set, in which case the same container will be reused for all tasks with the same
|
|
169
|
-
environment settings.
|
|
170
|
-
|
|
171
|
-
:param name: Optional The name of the task (defaults to the function name)
|
|
172
|
-
:param cache: Optional The cache policy for the task, defaults to auto, which will cache the results of the
|
|
173
|
-
task.
|
|
174
|
-
:param retries: Optional The number of retries for the task, defaults to 0, which means no retries.
|
|
175
|
-
:param docs: Optional The documentation for the task, if not provided the function docstring will be used.
|
|
176
|
-
:param secrets: Optional The secrets that will be injected into the task at runtime.
|
|
177
|
-
:param timeout: Optional The timeout for the task.
|
|
178
|
-
:param pod_template: Optional The pod template for the task, if not provided the default pod template will be
|
|
179
|
-
used.
|
|
180
|
-
:param report: Optional Whether to generate the html report for the task, defaults to False.
|
|
181
|
-
|
|
182
|
-
:return: New Task instance or Task decorator
|
|
183
|
-
"""
|
|
184
|
-
return self._task
|
|
185
|
-
|
|
186
168
|
@property
|
|
187
169
|
def tasks(self) -> Dict[str, TaskTemplate]:
|
|
188
170
|
"""
|
flyte/_utils/coro_management.py
CHANGED
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.0b8'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 2, 0, 'b8')
|
flyte/cli/_common.py
CHANGED
flyte/cli/_create.py
CHANGED
|
@@ -10,7 +10,7 @@ from flyte.remote._secret import SecretTypes
|
|
|
10
10
|
@click.group(name="create")
|
|
11
11
|
def create():
|
|
12
12
|
"""
|
|
13
|
-
|
|
13
|
+
The create subcommand allows you to create resources in a Flyte deployment.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
|
|
@@ -32,7 +32,23 @@ def secret(
|
|
|
32
32
|
domain: str | None = None,
|
|
33
33
|
):
|
|
34
34
|
"""
|
|
35
|
-
Create a new secret.
|
|
35
|
+
Create a new secret, the name of the secret is required.
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
```bash
|
|
39
|
+
flyte create secret my_secret --value my_value
|
|
40
|
+
```
|
|
41
|
+
If `--from-file` is specified, the value will be read from the file instead of being provided directly.
|
|
42
|
+
Example:
|
|
43
|
+
```bash
|
|
44
|
+
flyte create secret my_secret --from-file /path/to/secret_file
|
|
45
|
+
```
|
|
46
|
+
Secret types can be used to create specific types of secrets. Some secrets are useful for image pull, while some
|
|
47
|
+
are `regular` / general purpose secrets.
|
|
48
|
+
Example:
|
|
49
|
+
```bash
|
|
50
|
+
flyte create secret my_secret --type image_pull
|
|
51
|
+
```
|
|
36
52
|
"""
|
|
37
53
|
from flyte.remote import Secret
|
|
38
54
|
|
|
@@ -55,9 +71,19 @@ def secret(
|
|
|
55
71
|
@click.option(
|
|
56
72
|
"-o",
|
|
57
73
|
"--output",
|
|
58
|
-
type=click.Path(),
|
|
59
|
-
default=Path.cwd(),
|
|
74
|
+
type=click.Path(exists=False, writable=True),
|
|
75
|
+
default=Path.cwd() / "config.yaml",
|
|
60
76
|
help="Path to the output dir where the config will be saved, defaults to current directory.",
|
|
77
|
+
show_default=True,
|
|
78
|
+
)
|
|
79
|
+
@click.option(
|
|
80
|
+
"--force",
|
|
81
|
+
is_flag=True,
|
|
82
|
+
default=False,
|
|
83
|
+
help="Force overwrite the config file if it already exists.",
|
|
84
|
+
show_default=True,
|
|
85
|
+
prompt="Are you sure you want to overwrite the config file?",
|
|
86
|
+
confirmation_prompt=True,
|
|
61
87
|
)
|
|
62
88
|
def config(
|
|
63
89
|
output: Path,
|
|
@@ -66,14 +92,19 @@ def config(
|
|
|
66
92
|
org: str | None = None,
|
|
67
93
|
project: str | None = None,
|
|
68
94
|
domain: str | None = None,
|
|
95
|
+
force: bool = False,
|
|
69
96
|
):
|
|
70
97
|
"""
|
|
71
|
-
|
|
98
|
+
This command creates a configuration file for Flyte CLI.
|
|
99
|
+
If the `--output` option is not specified, it will create a file named `config.yaml` in the current directory.
|
|
100
|
+
If the file already exists, it will raise an error unless the `--force` option is used.
|
|
72
101
|
"""
|
|
73
102
|
import yaml
|
|
74
103
|
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
if output.exists() and not force:
|
|
105
|
+
raise click.BadParameter(f"Output file {output} already exists. Use --force to overwrite.")
|
|
106
|
+
|
|
107
|
+
with open(output, "w") as f:
|
|
77
108
|
d = {
|
|
78
109
|
"admin": {
|
|
79
110
|
"endpoint": endpoint,
|
|
@@ -87,4 +118,4 @@ def config(
|
|
|
87
118
|
}
|
|
88
119
|
yaml.dump(d, f)
|
|
89
120
|
|
|
90
|
-
click.echo(f"Config file created at {
|
|
121
|
+
click.echo(f"Config file created at {output}")
|
flyte/cli/_delete.py
CHANGED
|
@@ -6,7 +6,7 @@ import flyte.cli._common as common
|
|
|
6
6
|
@click.group(name="delete")
|
|
7
7
|
def delete():
|
|
8
8
|
"""
|
|
9
|
-
|
|
9
|
+
The delete subcommand allows you to remove resources from a Flyte deployment.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ def delete():
|
|
|
15
15
|
@click.pass_obj
|
|
16
16
|
def secret(cfg: common.CLIConfig, name: str, project: str | None = None, domain: str | None = None):
|
|
17
17
|
"""
|
|
18
|
-
Delete a secret.
|
|
18
|
+
Delete a secret, the name of the secret is required.
|
|
19
19
|
"""
|
|
20
20
|
from flyte.remote import Secret
|
|
21
21
|
|
flyte/cli/_deploy.py
CHANGED
|
@@ -138,5 +138,8 @@ class EnvFiles(common.FileGroup):
|
|
|
138
138
|
|
|
139
139
|
deploy = EnvFiles(
|
|
140
140
|
name="deploy",
|
|
141
|
-
help="
|
|
141
|
+
help="""
|
|
142
|
+
Deploy one or more environments from a python file.
|
|
143
|
+
The deploy command will create or update environments in the Flyte system.
|
|
144
|
+
""",
|
|
142
145
|
)
|
flyte/cli/_gen.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from os import getcwd
|
|
2
|
+
from typing import Generator, Tuple
|
|
3
|
+
|
|
4
|
+
import rich_click as click
|
|
5
|
+
|
|
6
|
+
import flyte.cli._common as common
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.group(name="gen")
|
|
10
|
+
def gen():
|
|
11
|
+
"""
|
|
12
|
+
Generate documentation
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@gen.command(cls=common.CommandBase)
|
|
17
|
+
@click.option("--type", "doc_type", type=str, required=True, help="Type of documentation (valid: markdown)")
|
|
18
|
+
@click.pass_obj
|
|
19
|
+
def docs(cfg: common.CLIConfig, doc_type: str, project: str | None = None, domain: str | None = None):
|
|
20
|
+
"""
|
|
21
|
+
Generate documentation
|
|
22
|
+
"""
|
|
23
|
+
if doc_type == "markdown":
|
|
24
|
+
markdown(cfg)
|
|
25
|
+
else:
|
|
26
|
+
raise click.ClickException("Invalid documentation type: {}".format(doc_type))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def walk_commands(ctx: click.Context) -> Generator[Tuple[str, click.Command], None, None]:
|
|
30
|
+
"""
|
|
31
|
+
Recursively walk a Click command tree, starting from the given context.
|
|
32
|
+
|
|
33
|
+
Yields:
|
|
34
|
+
(full_command_path, command_object)
|
|
35
|
+
"""
|
|
36
|
+
command = ctx.command
|
|
37
|
+
|
|
38
|
+
if not isinstance(command, click.Group):
|
|
39
|
+
yield ctx.command_path, command
|
|
40
|
+
else:
|
|
41
|
+
for name in command.list_commands(ctx):
|
|
42
|
+
subcommand = command.get_command(ctx, name)
|
|
43
|
+
if subcommand is None:
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
full_name = f"{ctx.command_path} {name}".strip()
|
|
47
|
+
yield full_name, subcommand
|
|
48
|
+
|
|
49
|
+
# Recurse if subcommand is a MultiCommand (i.e., has its own subcommands)
|
|
50
|
+
if isinstance(subcommand, click.Group):
|
|
51
|
+
sub_ctx = click.Context(subcommand, info_name=name, parent=ctx)
|
|
52
|
+
yield from walk_commands(sub_ctx)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def markdown(cfg: common.CLIConfig):
|
|
56
|
+
"""
|
|
57
|
+
Generate documentation in Markdown format
|
|
58
|
+
"""
|
|
59
|
+
ctx = cfg.ctx
|
|
60
|
+
|
|
61
|
+
output = []
|
|
62
|
+
output_verb_groups: dict[str, list[str]] = {}
|
|
63
|
+
output_noun_groups: dict[str, list[str]] = {}
|
|
64
|
+
|
|
65
|
+
commands = [*[("flyte", ctx.command)], *walk_commands(ctx)]
|
|
66
|
+
for cmd_path, cmd in commands:
|
|
67
|
+
output.append("")
|
|
68
|
+
|
|
69
|
+
cmd_path_parts = cmd_path.split(" ")
|
|
70
|
+
|
|
71
|
+
if len(cmd_path_parts) > 1:
|
|
72
|
+
if cmd_path_parts[1] not in output_verb_groups:
|
|
73
|
+
output_verb_groups[cmd_path_parts[1]] = []
|
|
74
|
+
if len(cmd_path_parts) > 2:
|
|
75
|
+
output_verb_groups[cmd_path_parts[1]].append(cmd_path_parts[2])
|
|
76
|
+
|
|
77
|
+
if len(cmd_path_parts) == 3:
|
|
78
|
+
if cmd_path_parts[2] not in output_noun_groups:
|
|
79
|
+
output_noun_groups[cmd_path_parts[2]] = []
|
|
80
|
+
output_noun_groups[cmd_path_parts[2]].append(cmd_path_parts[1])
|
|
81
|
+
|
|
82
|
+
output.append(f"{'#' * (len(cmd_path_parts) + 1)} {cmd_path}")
|
|
83
|
+
if cmd.help:
|
|
84
|
+
output.append("")
|
|
85
|
+
output.append(f"{cmd.help.strip()}")
|
|
86
|
+
|
|
87
|
+
if not cmd.params:
|
|
88
|
+
continue
|
|
89
|
+
|
|
90
|
+
params = cmd.get_params(click.Context(cmd))
|
|
91
|
+
|
|
92
|
+
# Collect all data first to calculate column widths
|
|
93
|
+
table_data = []
|
|
94
|
+
for param in params:
|
|
95
|
+
if isinstance(param, click.Option):
|
|
96
|
+
# Format each option with backticks before joining
|
|
97
|
+
all_opts = param.opts + param.secondary_opts
|
|
98
|
+
if len(all_opts) == 1:
|
|
99
|
+
opts = f"`{all_opts[0]}`"
|
|
100
|
+
else:
|
|
101
|
+
opts = "".join(
|
|
102
|
+
[
|
|
103
|
+
"{{< multiline >}}",
|
|
104
|
+
"\n".join([f"`{opt}`" for opt in all_opts]),
|
|
105
|
+
"{{< /multiline >}}",
|
|
106
|
+
]
|
|
107
|
+
)
|
|
108
|
+
default_value = ""
|
|
109
|
+
if param.default is not None:
|
|
110
|
+
default_value = f"`{param.default}`"
|
|
111
|
+
default_value = default_value.replace(f"{getcwd()}/", "")
|
|
112
|
+
help_text = param.help.strip() if param.help else ""
|
|
113
|
+
table_data.append([opts, f"`{param.type.name}`", default_value, help_text])
|
|
114
|
+
|
|
115
|
+
if not table_data:
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
# Add table header with proper alignment
|
|
119
|
+
output.append("")
|
|
120
|
+
output.append("| Option | Type | Default | Description |")
|
|
121
|
+
output.append("|--------|------|---------|-------------|")
|
|
122
|
+
|
|
123
|
+
# Add table rows with proper alignment
|
|
124
|
+
for row in table_data:
|
|
125
|
+
output.append(f"| {row[0]} | {row[1]} | {row[2]} | {row[3]} |")
|
|
126
|
+
|
|
127
|
+
output_verb_index = []
|
|
128
|
+
|
|
129
|
+
if len(output_verb_groups) > 0:
|
|
130
|
+
output_verb_index.append("| Action | On |")
|
|
131
|
+
output_verb_index.append("| ------ | -- |")
|
|
132
|
+
for verb, nouns in output_verb_groups.items():
|
|
133
|
+
entries = [f"[`{noun}`](#flyte-{verb}-{noun})" for noun in nouns]
|
|
134
|
+
output_verb_index.append(f"| `{verb}` | {', '.join(entries)} |")
|
|
135
|
+
|
|
136
|
+
output_noun_index = []
|
|
137
|
+
|
|
138
|
+
if len(output_noun_groups) > 0:
|
|
139
|
+
output_noun_index.append("| Object | Action |")
|
|
140
|
+
output_noun_index.append("| ------ | -- |")
|
|
141
|
+
for obj, actions in output_noun_groups.items():
|
|
142
|
+
entries = [f"[`{action}`](#flyte-{action}-{obj})" for action in actions]
|
|
143
|
+
output_noun_index.append(f"| `{obj}` | {', '.join(entries)} |")
|
|
144
|
+
|
|
145
|
+
print()
|
|
146
|
+
print("{{< grid >}}")
|
|
147
|
+
print("{{< markdown >}}")
|
|
148
|
+
print("\n".join(output_noun_index))
|
|
149
|
+
print("{{< /markdown >}}")
|
|
150
|
+
print("{{< markdown >}}")
|
|
151
|
+
print("\n".join(output_verb_index))
|
|
152
|
+
print("{{< /markdown >}}")
|
|
153
|
+
print("{{< /grid >}}")
|
|
154
|
+
print()
|
|
155
|
+
print("\n".join(output))
|
flyte/cli/_get.py
CHANGED
|
@@ -11,7 +11,16 @@ from . import _common as common
|
|
|
11
11
|
@click.group(name="get")
|
|
12
12
|
def get():
|
|
13
13
|
"""
|
|
14
|
-
|
|
14
|
+
The `get` subcommand allows you to retrieve various resources from a Flyte deployment.
|
|
15
|
+
|
|
16
|
+
You can get information about projects, runs, tasks, actions, secrets, and more.
|
|
17
|
+
Each command supports optional parameters to filter or specify the resource you want to retrieve.
|
|
18
|
+
|
|
19
|
+
Every `get` subcommand for example ``get project` without any arguments will list all projects.
|
|
20
|
+
`get project my_project` will return the details of the project named `my_project`.
|
|
21
|
+
|
|
22
|
+
In some cases `get action my_run` will return all actions for the run named `my_run` and
|
|
23
|
+
`get action my_run my_action` will return the details of the action named `my_action` for the run `my_run`.
|
|
15
24
|
"""
|
|
16
25
|
|
|
17
26
|
|
|
@@ -20,7 +29,7 @@ def get():
|
|
|
20
29
|
@click.pass_obj
|
|
21
30
|
def project(cfg: common.CLIConfig, name: str | None = None):
|
|
22
31
|
"""
|
|
23
|
-
|
|
32
|
+
Retrieve a list of all projects or details of a specific project by name.
|
|
24
33
|
"""
|
|
25
34
|
from flyte.remote import Project
|
|
26
35
|
|
|
@@ -39,7 +48,11 @@ def project(cfg: common.CLIConfig, name: str | None = None):
|
|
|
39
48
|
@click.pass_obj
|
|
40
49
|
def run(cfg: common.CLIConfig, name: str | None = None, project: str | None = None, domain: str | None = None):
|
|
41
50
|
"""
|
|
42
|
-
Get
|
|
51
|
+
Get list of all runs or details of a specific run by name.
|
|
52
|
+
|
|
53
|
+
The run details will include information about the run, its status, but only the root action will be shown.
|
|
54
|
+
|
|
55
|
+
If you want to see the actions for a run, use `get action <run_name>`.
|
|
43
56
|
"""
|
|
44
57
|
from flyte.remote import Run, RunDetails
|
|
45
58
|
|
|
@@ -65,7 +78,9 @@ def task(
|
|
|
65
78
|
domain: str | None = None,
|
|
66
79
|
):
|
|
67
80
|
"""
|
|
68
|
-
|
|
81
|
+
Retrieve a list of all tasks or details of a specific task by name and version.
|
|
82
|
+
|
|
83
|
+
Currently name+version are required to get a specific task.
|
|
69
84
|
"""
|
|
70
85
|
from flyte.remote import Task
|
|
71
86
|
|
|
@@ -140,8 +155,24 @@ def logs(
|
|
|
140
155
|
filter_system: bool = False,
|
|
141
156
|
):
|
|
142
157
|
"""
|
|
143
|
-
Stream logs for the provided run or action.
|
|
144
|
-
streamed.
|
|
158
|
+
Stream logs for the provided run or action.
|
|
159
|
+
If only the run is provided, only the logs for the parent action will be streamed.
|
|
160
|
+
|
|
161
|
+
Example:
|
|
162
|
+
```bash
|
|
163
|
+
flyte get logs my_run
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
But, if you want to see the logs for a specific action, you can provide the action name as well:
|
|
167
|
+
```bash
|
|
168
|
+
flyte get logs my_run my_action
|
|
169
|
+
```
|
|
170
|
+
By default logs will be shown in the raw format, will scroll on the terminal. If automatic scrolling and only
|
|
171
|
+
tailing --lines lines is desired, use the `--pretty` flag:
|
|
172
|
+
```bash
|
|
173
|
+
flyte get logs my_run my_action --pretty --lines 50
|
|
174
|
+
```
|
|
175
|
+
|
|
145
176
|
"""
|
|
146
177
|
import flyte.remote as remote
|
|
147
178
|
|
|
@@ -175,7 +206,7 @@ def secret(
|
|
|
175
206
|
domain: str | None = None,
|
|
176
207
|
):
|
|
177
208
|
"""
|
|
178
|
-
|
|
209
|
+
Retrieve a list of all secrets or details of a specific secret by name.
|
|
179
210
|
"""
|
|
180
211
|
import flyte.remote as remote
|
|
181
212
|
|
|
@@ -205,6 +236,19 @@ def io(
|
|
|
205
236
|
):
|
|
206
237
|
"""
|
|
207
238
|
Get the inputs and outputs of a run or action.
|
|
239
|
+
if only the run name is provided, it will show the inputs and outputs of the root action of that run.
|
|
240
|
+
If an action name is provided, it will show the inputs and outputs for that action.
|
|
241
|
+
|
|
242
|
+
If `--inputs-only` or `--outputs-only` is specified, it will only show the inputs or outputs respectively.
|
|
243
|
+
|
|
244
|
+
Example:
|
|
245
|
+
```bash
|
|
246
|
+
flyte get io my_run
|
|
247
|
+
```
|
|
248
|
+
or
|
|
249
|
+
```bash
|
|
250
|
+
flyte get io my_run my_action
|
|
251
|
+
```
|
|
208
252
|
"""
|
|
209
253
|
if inputs_only and outputs_only:
|
|
210
254
|
raise click.BadParameter("Cannot use both --inputs-only and --outputs-only")
|
|
@@ -250,6 +294,8 @@ def io(
|
|
|
250
294
|
def config(cfg: common.CLIConfig):
|
|
251
295
|
"""
|
|
252
296
|
Shows the automatically detected configuration to connect with remote Flyte services.
|
|
297
|
+
|
|
298
|
+
The configuration will include the endpoint, organization, and other settings that are used by the CLI.
|
|
253
299
|
"""
|
|
254
300
|
console = Console()
|
|
255
301
|
console.print(cfg)
|
flyte/cli/_run.py
CHANGED
|
@@ -204,11 +204,31 @@ class TaskFiles(common.FileGroup):
|
|
|
204
204
|
filename=Path(filename),
|
|
205
205
|
run_args=run_args,
|
|
206
206
|
name=filename,
|
|
207
|
-
help=f"Run, functions decorated `env.task` {filename}",
|
|
207
|
+
help=f"Run, functions decorated with `env.task` in {filename}",
|
|
208
208
|
)
|
|
209
209
|
|
|
210
210
|
|
|
211
211
|
run = TaskFiles(
|
|
212
212
|
name="run",
|
|
213
|
-
help="
|
|
213
|
+
help="""
|
|
214
|
+
Run a task from a python file.
|
|
215
|
+
|
|
216
|
+
Example usage:
|
|
217
|
+
```bash
|
|
218
|
+
flyte run --name examples/basics/hello.py my_task --arg1 value1 --arg2 value2
|
|
219
|
+
```
|
|
220
|
+
Note: all arguments for the run command are provided right after the `run` command and before the file name.
|
|
221
|
+
|
|
222
|
+
You can also specify the project and domain using the `--project` and `--domain` options, respectively. These
|
|
223
|
+
options can be set in the config file or passed as command line arguments.
|
|
224
|
+
|
|
225
|
+
Note: The arguments for the task are provided after the task name and can be retrieved using `--help`
|
|
226
|
+
Example:
|
|
227
|
+
```bash
|
|
228
|
+
flyte run --name examples/basics/hello.py my_task --help
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
To run a task locally, use the `--local` flag. This will run the task in the local environment instead of the remote
|
|
232
|
+
Flyte environment.
|
|
233
|
+
""",
|
|
214
234
|
)
|
flyte/cli/main.py
CHANGED
|
@@ -6,9 +6,32 @@ from ._abort import abort
|
|
|
6
6
|
from ._common import CLIConfig
|
|
7
7
|
from ._create import create
|
|
8
8
|
from ._deploy import deploy
|
|
9
|
+
from ._gen import gen
|
|
9
10
|
from ._get import get
|
|
10
11
|
from ._run import run
|
|
11
12
|
|
|
13
|
+
click.rich_click.COMMAND_GROUPS = {
|
|
14
|
+
"flyte": [
|
|
15
|
+
{
|
|
16
|
+
"name": "Running Workflows",
|
|
17
|
+
"commands": ["run", "abort"],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "Management",
|
|
21
|
+
"commands": ["create", "deploy", "get"],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "Documentation Generation",
|
|
25
|
+
"commands": ["gen"],
|
|
26
|
+
},
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
help_config = click.RichHelpConfiguration(
|
|
31
|
+
use_markdown=True,
|
|
32
|
+
use_markdown_emoji=True,
|
|
33
|
+
)
|
|
34
|
+
|
|
12
35
|
|
|
13
36
|
def _verbosity_to_loglevel(verbosity: int) -> int | None:
|
|
14
37
|
"""
|
|
@@ -41,7 +64,7 @@ def _verbosity_to_loglevel(verbosity: int) -> int | None:
|
|
|
41
64
|
"--insecure/--secure",
|
|
42
65
|
is_flag=True,
|
|
43
66
|
required=False,
|
|
44
|
-
help="Use insecure connection to the endpoint. If secure is specified, the CLI will use TLS",
|
|
67
|
+
help="Use insecure connection to the endpoint. If secure is specified, the CLI will use TLS.",
|
|
45
68
|
type=bool,
|
|
46
69
|
default=None,
|
|
47
70
|
show_default=True,
|
|
@@ -50,7 +73,7 @@ def _verbosity_to_loglevel(verbosity: int) -> int | None:
|
|
|
50
73
|
"-v",
|
|
51
74
|
"--verbose",
|
|
52
75
|
required=False,
|
|
53
|
-
help="Show verbose messages and exception traces",
|
|
76
|
+
help="Show verbose messages and exception traces, multiple times increases verbosity (e.g., -vvv).",
|
|
54
77
|
count=True,
|
|
55
78
|
default=0,
|
|
56
79
|
type=int,
|
|
@@ -70,6 +93,7 @@ def _verbosity_to_loglevel(verbosity: int) -> int | None:
|
|
|
70
93
|
help="Path to config file (YAML format) to use for the CLI. If not specified,"
|
|
71
94
|
" the default config file will be used.",
|
|
72
95
|
)
|
|
96
|
+
@click.rich_config(help_config=help_config)
|
|
73
97
|
@click.pass_context
|
|
74
98
|
def main(
|
|
75
99
|
ctx: click.Context,
|
|
@@ -80,14 +104,35 @@ def main(
|
|
|
80
104
|
config_file: str | None,
|
|
81
105
|
):
|
|
82
106
|
"""
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
( __)( ) ( \\/ )(_ _)( __) / )( \\(___ \\ / \
|
|
86
|
-
) _) / (_/\\ ) / )( ) _) \\ \\/ / / __/ _( 0 )
|
|
87
|
-
(__) \\____/(__/ (__) (____) \\__/ (____)(_)\\__/
|
|
107
|
+
### Flyte entrypoint for the CLI
|
|
108
|
+
The Flyte CLI is a command line interface for interacting with Flyte.
|
|
88
109
|
|
|
89
110
|
The flyte cli follows a simple verb based structure, where the top-level commands are verbs that describe the action
|
|
90
|
-
to be taken, and the subcommands are nouns that describe the object of the action.
|
|
111
|
+
to be taken, and the subcommands are nouns that describe the object of the action.
|
|
112
|
+
|
|
113
|
+
The root command can be used to configure the CLI for most commands, such as setting the endpoint,
|
|
114
|
+
organization, and verbosity level.
|
|
115
|
+
|
|
116
|
+
Example: Set endpoint and organization
|
|
117
|
+
```bash
|
|
118
|
+
flyte --endpoint <endpoint> --org <org> get project <project_name>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Example: Increase verbosity level (This is useful for debugging, this will show more logs and exception traces)
|
|
122
|
+
```bash
|
|
123
|
+
flyte -vvv get logs <run-name>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Example: Override the default config file
|
|
127
|
+
```bash
|
|
128
|
+
flyte --config /path/to/config.yaml run ...
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
👉 [Documentation](https://www.union.ai/docs/flyte/user-guide/) \n
|
|
132
|
+
👉 [GitHub](https://github.com/flyteorg/flyte) - Please leave a ⭐. \n
|
|
133
|
+
👉 [Slack](https://slack.flyte.org) - Join the community and ask questions.
|
|
134
|
+
👉 [Issues](https://github.com/flyteorg/flyte/issues)
|
|
135
|
+
|
|
91
136
|
"""
|
|
92
137
|
import flyte.config as config
|
|
93
138
|
|
|
@@ -108,6 +153,7 @@ to be taken, and the subcommands are nouns that describe the object of the actio
|
|
|
108
153
|
insecure=final_insecure,
|
|
109
154
|
org_override=org or cfg.task.org,
|
|
110
155
|
config=cfg,
|
|
156
|
+
ctx=ctx,
|
|
111
157
|
)
|
|
112
158
|
logger.debug(f"Final materialized Cli config: {ctx.obj}")
|
|
113
159
|
|
|
@@ -117,3 +163,4 @@ main.add_command(deploy)
|
|
|
117
163
|
main.add_command(get) # type: ignore
|
|
118
164
|
main.add_command(create) # type: ignore
|
|
119
165
|
main.add_command(abort) # type: ignore
|
|
166
|
+
main.add_command(gen) # type: ignore
|
flyte/extras/_container.py
CHANGED
|
@@ -215,7 +215,7 @@ class ContainerTask(TaskTemplate):
|
|
|
215
215
|
output_dict[k] = self._convert_output_val_to_correct_type(output_val, output_type)
|
|
216
216
|
return output_dict
|
|
217
217
|
|
|
218
|
-
def execute(self, **kwargs) -> Any:
|
|
218
|
+
async def execute(self, **kwargs) -> Any:
|
|
219
219
|
try:
|
|
220
220
|
import docker
|
|
221
221
|
except ImportError:
|
flyte/remote/_run.py
CHANGED
|
@@ -50,6 +50,7 @@ def _action_rich_repr(action: run_definition_pb2.Action) -> rich.repr.Result:
|
|
|
50
50
|
"""
|
|
51
51
|
Rich representation of the action.
|
|
52
52
|
"""
|
|
53
|
+
yield "run", action.id.run.name
|
|
53
54
|
if action.metadata.HasField("task"):
|
|
54
55
|
yield "task", action.metadata.task.id.name
|
|
55
56
|
yield "type", "task"
|
flyte/syncify/__init__.py
CHANGED
|
@@ -1,3 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
# Syncify Module
|
|
3
|
+
This module provides the `syncify` decorator and the `Syncify` class.
|
|
4
|
+
The decorator can be used to convert asynchronous functions or methods into synchronous ones.
|
|
5
|
+
This is useful for integrating async code into synchronous contexts.
|
|
6
|
+
|
|
7
|
+
Every asynchronous function or method wrapped with `syncify` can be called synchronously using the
|
|
8
|
+
parenthesis `()` operator, or asynchronously using the `.aio()` method.
|
|
9
|
+
|
|
10
|
+
Example::
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from flyte.syncify import syncify
|
|
14
|
+
|
|
15
|
+
@syncify
|
|
16
|
+
async def async_function(x: str) -> str:
|
|
17
|
+
return f"Hello, Async World {x}!"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# now you can call it synchronously
|
|
21
|
+
result = async_function("Async World") # Note: no .aio() needed for sync calls
|
|
22
|
+
print(result)
|
|
23
|
+
# Output: Hello, Async World Async World!
|
|
24
|
+
|
|
25
|
+
# or call it asynchronously
|
|
26
|
+
async def main():
|
|
27
|
+
result = await async_function.aio("World") # Note the use of .aio() for async calls
|
|
28
|
+
print(result)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Creating a Syncify Instance
|
|
32
|
+
```python
|
|
33
|
+
from flyte.syncify. import Syncify
|
|
34
|
+
|
|
35
|
+
syncer = Syncify("my_syncer")
|
|
36
|
+
|
|
37
|
+
# Now you can use `syncer` to decorate your async functions or methods
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## How does it work?
|
|
42
|
+
The Syncify class wraps asynchronous functions, classmethods, instance methods, and static methods to
|
|
43
|
+
provide a synchronous interface. The wrapped methods are always executed in the context of a background loop,
|
|
44
|
+
whether they are called synchronously or asynchronously. This allows for seamless integration of async code, as
|
|
45
|
+
certain async libraries capture the event loop. An example is grpc.aio, which captures the event loop.
|
|
46
|
+
In such a case, the Syncify class ensures that the async function is executed in the context of the background loop.
|
|
47
|
+
|
|
48
|
+
To use it correctly with grpc.aio, you should wrap every grpc.aio channel creation, and client invocation
|
|
49
|
+
with the same `Syncify` instance. This ensures that the async code runs in the correct event loop context.
|
|
50
|
+
"""
|
|
51
|
+
|
|
1
52
|
from flyte.syncify._api import Syncify
|
|
2
53
|
|
|
3
54
|
syncify = Syncify()
|
flyte/syncify/_api.py
CHANGED
|
@@ -54,14 +54,13 @@ class _BackgroundLoop:
|
|
|
54
54
|
functions or methods synchronously.
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
|
-
def __init__(self):
|
|
58
|
-
self.loop =
|
|
59
|
-
self.thread = threading.Thread(name=
|
|
57
|
+
def __init__(self, name: str):
|
|
58
|
+
self.loop = asyncio.new_event_loop()
|
|
59
|
+
self.thread = threading.Thread(name=name, target=self._run, daemon=True)
|
|
60
60
|
self.thread.start()
|
|
61
61
|
atexit.register(self.stop)
|
|
62
62
|
|
|
63
63
|
def _run(self):
|
|
64
|
-
self.loop = asyncio.new_event_loop()
|
|
65
64
|
asyncio.set_event_loop(self.loop)
|
|
66
65
|
self.loop.run_forever()
|
|
67
66
|
|
|
@@ -242,8 +241,8 @@ class Syncify:
|
|
|
242
241
|
|
|
243
242
|
"""
|
|
244
243
|
|
|
245
|
-
def __init__(self):
|
|
246
|
-
self._bg_loop = _BackgroundLoop()
|
|
244
|
+
def __init__(self, name: str = "flyte_syncify"):
|
|
245
|
+
self._bg_loop = _BackgroundLoop(name=name)
|
|
247
246
|
|
|
248
247
|
@overload
|
|
249
248
|
def __call__(self, func: Callable[P, Awaitable[R_co]]) -> Any: ...
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flyte
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.0b8
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Author-email: Ketan Umare <kumare3@users.noreply.github.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -24,11 +24,35 @@ Requires-Dist: async-lru>=2.0.5
|
|
|
24
24
|
Requires-Dist: mashumaro
|
|
25
25
|
Requires-Dist: dataclasses_json
|
|
26
26
|
|
|
27
|
-
# Flyte 2
|
|
27
|
+
# Flyte 2 SDK
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
The next-generation SDK for Flyte.
|
|
30
30
|
|
|
31
|
-
##
|
|
31
|
+
## Quickstart
|
|
32
|
+
1. Clone this repo and set `unionv2` to working directory.
|
|
33
|
+
2. Run `uv venv`, and `source .venv/bin/activate` to create a new virtualenv
|
|
34
|
+
3. Install the latest version of the SDK by running the following:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
uv pip install --no-cache --prerelease=allow --upgrade flyte
|
|
38
|
+
```
|
|
39
|
+
4. Create the config and point it to the Dogfood GCP cluster by running the following:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
flyte create config --endpoint dns:///dogfood-gcp.cloud-staging.union.ai --org dogfood-gcp --project andrew --domain development
|
|
43
|
+
```
|
|
44
|
+
This will create a `config.yaml` file in the current directory which will be referenced ahead of any other `config.yaml`s found in your system.
|
|
45
|
+
|
|
46
|
+
5. Now you can run stuff with the CLI:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
flyte run --follow examples/basics/devbox_one.py say_hello_nested
|
|
50
|
+
```
|
|
51
|
+
Note that the `--follow` command is optional. Use this to stream updates to the terminal!
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## Hello World Example
|
|
32
56
|
|
|
33
57
|
1. Only async tasks are supported right now. Style recommended, `import flyte` and then `flyte.TaskEnvironment` etc
|
|
34
58
|
2. You have to create environment for even a single task
|
|
@@ -4,10 +4,10 @@ flyte/_context.py,sha256=pYa43ut8gp6i-Y_zOy1WW_N2IbP9Vd-zIORO11vqK1E,4995
|
|
|
4
4
|
flyte/_deploy.py,sha256=hHZKLU3U7t1ZF_8x6LykkPu_KSDyaHL3f2WzyjLj9BQ,7723
|
|
5
5
|
flyte/_doc.py,sha256=_OPCf3t_git6UT7kSJISFaWO9cfNzJhhoe6JjVdyCJo,706
|
|
6
6
|
flyte/_docstring.py,sha256=SsG0Ab_YMAwy2ABJlEo3eBKlyC3kwPdnDJ1FIms-ZBQ,1127
|
|
7
|
-
flyte/_environment.py,sha256=
|
|
7
|
+
flyte/_environment.py,sha256=BkChtdVhWB3SwMSvetDZ-KiNBgRFlAXgq69PHT4zyG0,2942
|
|
8
8
|
flyte/_group.py,sha256=64q2GFDp3koIkx3IV4GBeGEbu4v-GPUxTlxU_sV2fPk,743
|
|
9
9
|
flyte/_hash.py,sha256=Of_Zl_DzzzF2jp4ZsLm-3o-xJFCCJ8_GubmLI1htx78,504
|
|
10
|
-
flyte/_image.py,sha256=
|
|
10
|
+
flyte/_image.py,sha256=NeBvjCdwFAVGd666ufi1q-YOvhwdTEzAeJl5YBfl0bI,29043
|
|
11
11
|
flyte/_initialize.py,sha256=ihTIvoMHs67UKbtFLR_zy9M1e7OK26ywoc_yMfLYwMw,16499
|
|
12
12
|
flyte/_interface.py,sha256=MP5o_qpIwfBNtAc7zo_cLSjMugsPyanuO6EgUSk4fBE,3644
|
|
13
13
|
flyte/_logging.py,sha256=FQvF3W1kkFypbARcOQ7WZVXO0XJasXp8EhozF6E6-aQ,3379
|
|
@@ -16,12 +16,12 @@ flyte/_retry.py,sha256=rfLv0MvWxzPByKESTglEmjPsytEAKiIvvmzlJxXwsfE,941
|
|
|
16
16
|
flyte/_reusable_environment.py,sha256=P4FBATVKAYcIKpdFN98sI8acPyKy8eIGx6V0kUb9YdM,1289
|
|
17
17
|
flyte/_run.py,sha256=2ugAk4tpvSAnNAlfhx4YysSrdFoce-hZHQ6XMHYxp0A,17783
|
|
18
18
|
flyte/_secret.py,sha256=SqIHs6mi8hEkIIBZe3bI9jJsPt65Mt6dV5uh9_op1ME,2392
|
|
19
|
-
flyte/_task.py,sha256=
|
|
20
|
-
flyte/_task_environment.py,sha256=
|
|
19
|
+
flyte/_task.py,sha256=UDsnSs0lYXZe-0HvZHk4FQ5X9DGRyy1qldm7zpUEXT4,16373
|
|
20
|
+
flyte/_task_environment.py,sha256=J1LFH9Zz1nPhlsrc_rYny1SS3QC1b55X7tRYoTG7Vk4,6815
|
|
21
21
|
flyte/_timeout.py,sha256=zx5sFcbYmjJAJbZWSGzzX-BpC9HC7Jfs35T7vVhKwkk,1571
|
|
22
22
|
flyte/_tools.py,sha256=JewkQZBR_M85tS6QY8e4xXue75jbOE48nID4ZHnc9jY,632
|
|
23
23
|
flyte/_trace.py,sha256=7OQtQNosIlycTwaMjdc3GW4h3T3N0bYTsY6og4clPl8,5234
|
|
24
|
-
flyte/_version.py,sha256=
|
|
24
|
+
flyte/_version.py,sha256=vlbuxWySGV761QhtXKWRtZJy0eos4BpfR3ZShXEd4sQ,519
|
|
25
25
|
flyte/errors.py,sha256=m2JUNqLC6anVW6UiDK_ihuA06q_Hkw1mIUMDskb2OW8,4289
|
|
26
26
|
flyte/models.py,sha256=GTRuR6GXc0RAbLmPEnnH54oRF7__2TNFhmYjFoYMjZA,12660
|
|
27
27
|
flyte/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -37,15 +37,15 @@ flyte/_code_bundle/_packaging.py,sha256=_wEozcQTYgqvAAaKQYna9ptvShIMlXk3vEdccwAO
|
|
|
37
37
|
flyte/_code_bundle/_utils.py,sha256=b0s3ZVKSRwaa_2CMTCqt2iRrUvTTW3FmlyqCD9k5BS0,12028
|
|
38
38
|
flyte/_code_bundle/bundle.py,sha256=8T0gcXck6dmg-8L2-0G3B2iNjC-Xwydu806iyKneMMY,8789
|
|
39
39
|
flyte/_internal/__init__.py,sha256=vjXgGzAAjy609YFkAy9_RVPuUlslsHSJBXCLNTVnqOY,136
|
|
40
|
-
flyte/_internal/controllers/__init__.py,sha256=
|
|
41
|
-
flyte/_internal/controllers/_local_controller.py,sha256=
|
|
40
|
+
flyte/_internal/controllers/__init__.py,sha256=wPugf6_9BUVqwCXClnmScwyKVaGYIo0PTd-sdYjxVWA,3827
|
|
41
|
+
flyte/_internal/controllers/_local_controller.py,sha256=fT-mFBs05vxHf43U24AKGJg5NuSTO5F8LBRcZAfgX2g,4798
|
|
42
42
|
flyte/_internal/controllers/_trace.py,sha256=Ga2b65sn9q2IoOwHBZV2inMYyO6-CSDwzN7E3pDxsEI,1126
|
|
43
43
|
flyte/_internal/controllers/remote/__init__.py,sha256=9_azH1eHLqY6VULpDugXi7Kf1kK1ODqEnsQ_3wM6IqU,1919
|
|
44
44
|
flyte/_internal/controllers/remote/_action.py,sha256=w6vE1vPz1BwxvwfotDWjTNbDXfGEPrRBA8N3UVQ6P0w,4905
|
|
45
45
|
flyte/_internal/controllers/remote/_client.py,sha256=HPbzbfaWZVv5wpOvKNtFXR6COiZDwd1cUJQqi60A7oU,1421
|
|
46
|
-
flyte/_internal/controllers/remote/_controller.py,sha256=
|
|
46
|
+
flyte/_internal/controllers/remote/_controller.py,sha256=5jhm6UG3DLCUiwQMkVGeIF4pIx_cZkR9it6tLMK7DRw,17477
|
|
47
47
|
flyte/_internal/controllers/remote/_core.py,sha256=2dka1rDnA8Ui_qhfE1ymZuN8E2BYQPn123h_eMixSiM,18091
|
|
48
|
-
flyte/_internal/controllers/remote/_informer.py,sha256=
|
|
48
|
+
flyte/_internal/controllers/remote/_informer.py,sha256=JC35aHbEdwBN7cwDKbQj6koPUypTapYyK0wKxOBRBCo,14191
|
|
49
49
|
flyte/_internal/controllers/remote/_service_protocol.py,sha256=B9qbIg6DiGeac-iSccLmX_AL2xUgX4ezNUOiAbSy4V0,1357
|
|
50
50
|
flyte/_internal/imagebuild/__init__.py,sha256=cLXVxkAyFpbdC1y-k3Rb6FRW9f_xpoRQWVn__G9IqKs,354
|
|
51
51
|
flyte/_internal/imagebuild/docker_builder.py,sha256=bkr2fs9jInTq8jqU8ka7NGvp0RPfYhbTfX1RqtqTvvs,13986
|
|
@@ -129,28 +129,29 @@ flyte/_protos/workflow/task_service_pb2_grpc.py,sha256=PdhEfPraBIeN-UQulZsA2D0on
|
|
|
129
129
|
flyte/_utils/__init__.py,sha256=ZlVA1bLeAEnzwbkK7eEVAVmeVQnbBCuGqfd2UIk-yNc,599
|
|
130
130
|
flyte/_utils/asyn.py,sha256=KeJKarXNIyD16g6oPM0T9cH7JDmh1KY7JLbwo7i0IlQ,3673
|
|
131
131
|
flyte/_utils/async_cache.py,sha256=JtZJmWO62OowJ0QFNl6wryWqh-kuDi76aAASMie87QY,4596
|
|
132
|
-
flyte/_utils/coro_management.py,sha256=
|
|
132
|
+
flyte/_utils/coro_management.py,sha256=_JTt9x9fOc_1OSe03DSheYoKOvlonBB_4WNCS9XSaoU,698
|
|
133
133
|
flyte/_utils/file_handling.py,sha256=iU4TxW--fCho_Eg5xTMODn96P03SxzF-V-5f-7bZAZY,2233
|
|
134
134
|
flyte/_utils/helpers.py,sha256=Ntrs1WilJS7a4oLmcIPLXMi0cuzRDiCr_wwgtpV30uk,3953
|
|
135
135
|
flyte/_utils/lazy_module.py,sha256=fvXPjvZLzCfcI8Vzs4pKedUDdY0U_RQ1ZVrp9b8qBQY,1994
|
|
136
136
|
flyte/_utils/uv_script_parser.py,sha256=PxqD8lSMi6xv0uDd1s8LKB2IPZr4ttZJCUweqlyMTKk,1483
|
|
137
137
|
flyte/cli/__init__.py,sha256=Hx_mrERToVkrvORPB56ZnUED86T4S50ac1nwLQfvsgo,278
|
|
138
138
|
flyte/cli/_abort.py,sha256=WkXmjAOcrBU9NXXndcwF7YW7QcUTJzyUrvIRW0fjpSE,580
|
|
139
|
-
flyte/cli/_common.py,sha256=
|
|
140
|
-
flyte/cli/_create.py,sha256=
|
|
141
|
-
flyte/cli/_delete.py,sha256=
|
|
142
|
-
flyte/cli/_deploy.py,sha256=
|
|
143
|
-
flyte/cli/
|
|
139
|
+
flyte/cli/_common.py,sha256=KSn6MxJng_WJDrA20Wl_RKWiCcqZ7ZS68UFlqYyR7xs,10771
|
|
140
|
+
flyte/cli/_create.py,sha256=bB_kkM54LLWVBaAy8LKPJGfLjC3NSIDELB8niQlG50c,3667
|
|
141
|
+
flyte/cli/_delete.py,sha256=WnHn9m_1b3nAXaD772bOirsN73ICUi-BVzjFP8s_Hyg,581
|
|
142
|
+
flyte/cli/_deploy.py,sha256=zCHvy88UPYz_iXXG7b9Pi61GFdB52-niYw2pVIum2b4,4464
|
|
143
|
+
flyte/cli/_gen.py,sha256=onJIXj2PiJxxHCOFo5A9LNwjt-rRo-a_SojdtuvQ5is,5302
|
|
144
|
+
flyte/cli/_get.py,sha256=f5e8h6P6LBBPNZKHEx8aYeoym_Bih7eIsxqiAqAHtso,9641
|
|
144
145
|
flyte/cli/_params.py,sha256=X3GpuftXmtfIsYQ7vBilD4kmlkXTc7_AxpaxohRjSuY,19458
|
|
145
|
-
flyte/cli/_run.py,sha256=
|
|
146
|
-
flyte/cli/main.py,sha256=
|
|
146
|
+
flyte/cli/_run.py,sha256=zRu4DTO__BVsLgpSLUbYR1Twvzc_2zivUhcviymCRf0,7884
|
|
147
|
+
flyte/cli/main.py,sha256=PhH8RgpNFP9owpjN8purGvM41qlm9VcR2QF2oLi_6FA,4480
|
|
147
148
|
flyte/config/__init__.py,sha256=MiwEYK5Iv7MRR22z61nzbsbvZ9Q6MdmAU_g9If1Pmb8,144
|
|
148
149
|
flyte/config/_config.py,sha256=QE3T0W8xOULjJaqDMdMF90f9gFVjGR6h8QPOLsyqjYw,9831
|
|
149
150
|
flyte/config/_internal.py,sha256=Bj0uzn3PYgxKbzM-q2GKXxp7Y6cyzhPzUB-Y2i6cQKo,2836
|
|
150
151
|
flyte/config/_reader.py,sha256=c16jm0_IYxwEAjXENtllLeO_sT5Eg2RNLG4UjnAv_x4,7157
|
|
151
152
|
flyte/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
152
153
|
flyte/extras/__init__.py,sha256=FhB0uK7H1Yo5De9vOuF7UGnezTKncj3u2Wo5uQdWN0g,74
|
|
153
|
-
flyte/extras/_container.py,sha256=
|
|
154
|
+
flyte/extras/_container.py,sha256=R7tMIy2EuprEGowYhjPMwnszSutgWIzAeKPeXNc2nmI,11255
|
|
154
155
|
flyte/io/__init__.py,sha256=e2wHVEoZ84TGOtOPrtTg6hJpeuxiYI56Sg011yq6nUQ,236
|
|
155
156
|
flyte/io/_dataframe.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
156
157
|
flyte/io/_dir.py,sha256=rih9CY1YjNX05bcAu5LG62Xoyij5GXAlv7jLyVF0je8,15310
|
|
@@ -165,7 +166,7 @@ flyte/remote/_console.py,sha256=avmELJPx8nQMAVPrHlh6jEIRPjrMwFpdZjJsWOOa9rE,660
|
|
|
165
166
|
flyte/remote/_data.py,sha256=DPK85gB6M71RjxqIh1Q5PdZ9xcJ0m1w_3cT2lAO0r7w,5795
|
|
166
167
|
flyte/remote/_logs.py,sha256=EOXg4OS8yYclsT6NASgOLMo0TA2sZpKb2MWZXpWBPuI,6404
|
|
167
168
|
flyte/remote/_project.py,sha256=dTBYqORDAbLvh9WnPO1Ytuzw2vxNYZwwNsKE2_b0o14,2807
|
|
168
|
-
flyte/remote/_run.py,sha256=
|
|
169
|
+
flyte/remote/_run.py,sha256=9euHjYRX-xyxXuhn0MunYb9dmgl0FMU3a-FZNjJA4F8,31057
|
|
169
170
|
flyte/remote/_secret.py,sha256=l5xeMS83uMcWWeSSTRsSZUNhS0N--1Dze09C-thSOQs,4341
|
|
170
171
|
flyte/remote/_task.py,sha256=6TBdjPWgxHmdY9OJMMPGZax8h7Qs7q9dprNktjnZ77E,7904
|
|
171
172
|
flyte/remote/_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -197,16 +198,16 @@ flyte/storage/_config.py,sha256=xVibWJaioOnkeTb_M30azgiUe1jvmQaOWRZEkpdoTao,8680
|
|
|
197
198
|
flyte/storage/_remote_fs.py,sha256=kM_iszbccjVD5VtVdgfkl1FHS8NPnY__JOo_CPQUE4c,1124
|
|
198
199
|
flyte/storage/_storage.py,sha256=mBy7MKII2M1UTVm_EUUDwVb7uT1_AOPzQr2wCJ-fgW0,9873
|
|
199
200
|
flyte/storage/_utils.py,sha256=8oLCM-7D7JyJhzUi1_Q1NFx8GBUPRfou0T_5tPBmPbE,309
|
|
200
|
-
flyte/syncify/__init__.py,sha256=
|
|
201
|
-
flyte/syncify/_api.py,sha256=
|
|
201
|
+
flyte/syncify/__init__.py,sha256=WgTk-v-SntULnI55CsVy71cxGJ9Q6pxpTrhbPFuouJ0,1974
|
|
202
|
+
flyte/syncify/_api.py,sha256=Jek0sIpu6RyOCAYQZFxuW-xv_lpr6DBOjs2kGA8tfvc,9815
|
|
202
203
|
flyte/types/__init__.py,sha256=xMIYOolT3Vq0qXy7unw90IVdYztdMDpKg0oG0XAPC9o,364
|
|
203
204
|
flyte/types/_interface.py,sha256=mY7mb8v2hJPGk7AU99gdOWl4_jArA1VFtjYGlE31SK0,953
|
|
204
205
|
flyte/types/_renderer.py,sha256=ygcCo5l60lHufyQISFddZfWwLlQ8kJAKxUT_XnR_6dY,4818
|
|
205
206
|
flyte/types/_string_literals.py,sha256=NlG1xV8RSA-sZ-n-IFQCAsdB6jXJOAKkHWtnopxVVDk,4231
|
|
206
207
|
flyte/types/_type_engine.py,sha256=QxyoDWRG_whfLCz88YqEVVoTTnca0FZv9eHeLLT0_-s,93645
|
|
207
208
|
flyte/types/_utils.py,sha256=pbts9E1_2LTdLygAY0UYTLYJ8AsN3BZyviSXvrtcutc,2626
|
|
208
|
-
flyte-0.2.
|
|
209
|
-
flyte-0.2.
|
|
210
|
-
flyte-0.2.
|
|
211
|
-
flyte-0.2.
|
|
212
|
-
flyte-0.2.
|
|
209
|
+
flyte-0.2.0b8.dist-info/METADATA,sha256=143TeXr4H7BtrVp2r0GwVQ0jviOe8S5fXn3t1s439wY,4636
|
|
210
|
+
flyte-0.2.0b8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
211
|
+
flyte-0.2.0b8.dist-info/entry_points.txt,sha256=MIq2z5dBurdCJfpXfMKzgBv7sJOakKRYxr8G0cMiTrg,75
|
|
212
|
+
flyte-0.2.0b8.dist-info/top_level.txt,sha256=7dkyFbikvA12LEZEqawx8oDG1CMod6hTliPj7iWzgYo,6
|
|
213
|
+
flyte-0.2.0b8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|