flyte 0.0.1b3__py3-none-any.whl → 0.2.0b0__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/_cli/_common.py +12 -0
- {union → flyte}/_cli/_params.py +106 -147
- flyte/_cli/_run.py +24 -2
- flyte/_cli/main.py +28 -2
- flyte/_image.py +1 -2
- flyte/_initialize.py +24 -15
- flyte/_internal/runtime/convert.py +6 -0
- flyte/_run.py +0 -1
- flyte/_version.py +2 -2
- flyte/config/__init__.py +168 -0
- flyte/config/_config.py +196 -0
- flyte/config/_internal.py +64 -0
- flyte/remote/_console.py +1 -1
- flyte/types/_type_engine.py +4 -3
- {flyte-0.0.1b3.dist-info → flyte-0.2.0b0.dist-info}/METADATA +1 -1
- flyte-0.2.0b0.dist-info/RECORD +204 -0
- flyte-0.0.1b3.dist-info/RECORD +0 -390
- union/__init__.py +0 -54
- union/_api_commons.py +0 -3
- union/_bin/__init__.py +0 -0
- union/_bin/runtime.py +0 -113
- union/_build.py +0 -25
- union/_cache/__init__.py +0 -12
- union/_cache/cache.py +0 -141
- union/_cache/defaults.py +0 -9
- union/_cache/policy_function_body.py +0 -42
- union/_cli/__init__.py +0 -0
- union/_cli/_common.py +0 -263
- union/_cli/_create.py +0 -40
- union/_cli/_delete.py +0 -23
- union/_cli/_deploy.py +0 -120
- union/_cli/_get.py +0 -162
- union/_cli/_run.py +0 -150
- union/_cli/main.py +0 -72
- union/_code_bundle/__init__.py +0 -8
- union/_code_bundle/_ignore.py +0 -113
- union/_code_bundle/_packaging.py +0 -187
- union/_code_bundle/_utils.py +0 -342
- union/_code_bundle/bundle.py +0 -176
- union/_context.py +0 -146
- union/_datastructures.py +0 -295
- union/_deploy.py +0 -185
- union/_doc.py +0 -29
- union/_docstring.py +0 -26
- union/_environment.py +0 -43
- union/_group.py +0 -31
- union/_hash.py +0 -23
- union/_image.py +0 -760
- union/_initialize.py +0 -585
- union/_interface.py +0 -84
- union/_internal/__init__.py +0 -3
- union/_internal/controllers/__init__.py +0 -77
- union/_internal/controllers/_local_controller.py +0 -77
- union/_internal/controllers/pbhash.py +0 -39
- union/_internal/controllers/remote/__init__.py +0 -40
- union/_internal/controllers/remote/_action.py +0 -131
- union/_internal/controllers/remote/_client.py +0 -43
- union/_internal/controllers/remote/_controller.py +0 -169
- union/_internal/controllers/remote/_core.py +0 -341
- union/_internal/controllers/remote/_informer.py +0 -260
- union/_internal/controllers/remote/_service_protocol.py +0 -44
- union/_internal/imagebuild/__init__.py +0 -11
- union/_internal/imagebuild/docker_builder.py +0 -416
- union/_internal/imagebuild/image_builder.py +0 -243
- union/_internal/imagebuild/remote_builder.py +0 -0
- union/_internal/resolvers/__init__.py +0 -0
- union/_internal/resolvers/_task_module.py +0 -31
- union/_internal/resolvers/common.py +0 -24
- union/_internal/resolvers/default.py +0 -27
- union/_internal/runtime/__init__.py +0 -0
- union/_internal/runtime/convert.py +0 -163
- union/_internal/runtime/entrypoints.py +0 -121
- union/_internal/runtime/io.py +0 -136
- union/_internal/runtime/resources_serde.py +0 -134
- union/_internal/runtime/task_serde.py +0 -202
- union/_internal/runtime/taskrunner.py +0 -179
- union/_internal/runtime/types_serde.py +0 -53
- union/_logging.py +0 -124
- union/_protos/__init__.py +0 -0
- union/_protos/common/authorization_pb2.py +0 -66
- union/_protos/common/authorization_pb2.pyi +0 -106
- union/_protos/common/authorization_pb2_grpc.py +0 -4
- union/_protos/common/identifier_pb2.py +0 -71
- union/_protos/common/identifier_pb2.pyi +0 -82
- union/_protos/common/identifier_pb2_grpc.py +0 -4
- union/_protos/common/identity_pb2.py +0 -48
- union/_protos/common/identity_pb2.pyi +0 -72
- union/_protos/common/identity_pb2_grpc.py +0 -4
- union/_protos/common/list_pb2.py +0 -36
- union/_protos/common/list_pb2.pyi +0 -69
- union/_protos/common/list_pb2_grpc.py +0 -4
- union/_protos/common/policy_pb2.py +0 -37
- union/_protos/common/policy_pb2.pyi +0 -27
- union/_protos/common/policy_pb2_grpc.py +0 -4
- union/_protos/common/role_pb2.py +0 -37
- union/_protos/common/role_pb2.pyi +0 -51
- union/_protos/common/role_pb2_grpc.py +0 -4
- union/_protos/common/runtime_version_pb2.py +0 -28
- union/_protos/common/runtime_version_pb2.pyi +0 -24
- union/_protos/common/runtime_version_pb2_grpc.py +0 -4
- union/_protos/logs/dataplane/payload_pb2.py +0 -96
- union/_protos/logs/dataplane/payload_pb2.pyi +0 -168
- union/_protos/logs/dataplane/payload_pb2_grpc.py +0 -4
- union/_protos/secret/definition_pb2.py +0 -49
- union/_protos/secret/definition_pb2.pyi +0 -93
- union/_protos/secret/definition_pb2_grpc.py +0 -4
- union/_protos/secret/payload_pb2.py +0 -62
- union/_protos/secret/payload_pb2.pyi +0 -94
- union/_protos/secret/payload_pb2_grpc.py +0 -4
- union/_protos/secret/secret_pb2.py +0 -38
- union/_protos/secret/secret_pb2.pyi +0 -6
- union/_protos/secret/secret_pb2_grpc.py +0 -198
- union/_protos/validate/validate/validate_pb2.py +0 -76
- union/_protos/workflow/node_execution_service_pb2.py +0 -26
- union/_protos/workflow/node_execution_service_pb2.pyi +0 -4
- union/_protos/workflow/node_execution_service_pb2_grpc.py +0 -32
- union/_protos/workflow/queue_service_pb2.py +0 -75
- union/_protos/workflow/queue_service_pb2.pyi +0 -103
- union/_protos/workflow/queue_service_pb2_grpc.py +0 -172
- union/_protos/workflow/run_definition_pb2.py +0 -100
- union/_protos/workflow/run_definition_pb2.pyi +0 -256
- union/_protos/workflow/run_definition_pb2_grpc.py +0 -4
- union/_protos/workflow/run_logs_service_pb2.py +0 -41
- union/_protos/workflow/run_logs_service_pb2.pyi +0 -28
- union/_protos/workflow/run_logs_service_pb2_grpc.py +0 -69
- union/_protos/workflow/run_service_pb2.py +0 -133
- union/_protos/workflow/run_service_pb2.pyi +0 -173
- union/_protos/workflow/run_service_pb2_grpc.py +0 -412
- union/_protos/workflow/state_service_pb2.py +0 -58
- union/_protos/workflow/state_service_pb2.pyi +0 -69
- union/_protos/workflow/state_service_pb2_grpc.py +0 -138
- union/_protos/workflow/task_definition_pb2.py +0 -72
- union/_protos/workflow/task_definition_pb2.pyi +0 -65
- union/_protos/workflow/task_definition_pb2_grpc.py +0 -4
- union/_protos/workflow/task_service_pb2.py +0 -44
- union/_protos/workflow/task_service_pb2.pyi +0 -31
- union/_protos/workflow/task_service_pb2_grpc.py +0 -104
- union/_resources.py +0 -226
- union/_retry.py +0 -32
- union/_reusable_environment.py +0 -25
- union/_run.py +0 -374
- union/_secret.py +0 -61
- union/_task.py +0 -354
- union/_task_environment.py +0 -186
- union/_timeout.py +0 -47
- union/_tools.py +0 -27
- union/_utils/__init__.py +0 -11
- union/_utils/asyn.py +0 -119
- union/_utils/file_handling.py +0 -71
- union/_utils/helpers.py +0 -46
- union/_utils/lazy_module.py +0 -54
- union/_utils/uv_script_parser.py +0 -49
- union/_version.py +0 -21
- union/connectors/__init__.py +0 -0
- union/errors.py +0 -128
- union/extras/__init__.py +0 -5
- union/extras/_container.py +0 -263
- union/io/__init__.py +0 -11
- union/io/_dataframe.py +0 -0
- union/io/_dir.py +0 -425
- union/io/_file.py +0 -418
- union/io/pickle/__init__.py +0 -0
- union/io/pickle/transformer.py +0 -117
- union/io/structured_dataset/__init__.py +0 -122
- union/io/structured_dataset/basic_dfs.py +0 -219
- union/io/structured_dataset/structured_dataset.py +0 -1057
- union/py.typed +0 -0
- union/remote/__init__.py +0 -23
- union/remote/_client/__init__.py +0 -0
- union/remote/_client/_protocols.py +0 -129
- union/remote/_client/auth/__init__.py +0 -12
- union/remote/_client/auth/_authenticators/__init__.py +0 -0
- union/remote/_client/auth/_authenticators/base.py +0 -391
- union/remote/_client/auth/_authenticators/client_credentials.py +0 -73
- union/remote/_client/auth/_authenticators/device_code.py +0 -120
- union/remote/_client/auth/_authenticators/external_command.py +0 -77
- union/remote/_client/auth/_authenticators/factory.py +0 -200
- union/remote/_client/auth/_authenticators/pkce.py +0 -515
- union/remote/_client/auth/_channel.py +0 -184
- union/remote/_client/auth/_client_config.py +0 -83
- union/remote/_client/auth/_default_html.py +0 -32
- union/remote/_client/auth/_grpc_utils/__init__.py +0 -0
- union/remote/_client/auth/_grpc_utils/auth_interceptor.py +0 -204
- union/remote/_client/auth/_grpc_utils/default_metadata_interceptor.py +0 -144
- union/remote/_client/auth/_keyring.py +0 -154
- union/remote/_client/auth/_token_client.py +0 -258
- union/remote/_client/auth/errors.py +0 -16
- union/remote/_client/controlplane.py +0 -86
- union/remote/_data.py +0 -149
- union/remote/_logs.py +0 -74
- union/remote/_project.py +0 -86
- union/remote/_run.py +0 -820
- union/remote/_secret.py +0 -132
- union/remote/_task.py +0 -193
- union/report/__init__.py +0 -3
- union/report/_report.py +0 -178
- union/report/_template.html +0 -124
- union/storage/__init__.py +0 -24
- union/storage/_remote_fs.py +0 -34
- union/storage/_storage.py +0 -247
- union/storage/_utils.py +0 -5
- union/types/__init__.py +0 -11
- union/types/_renderer.py +0 -162
- union/types/_string_literals.py +0 -120
- union/types/_type_engine.py +0 -2131
- union/types/_utils.py +0 -80
- {flyte-0.0.1b3.dist-info → flyte-0.2.0b0.dist-info}/WHEEL +0 -0
- {flyte-0.0.1b3.dist-info → flyte-0.2.0b0.dist-info}/entry_points.txt +0 -0
- {flyte-0.0.1b3.dist-info → flyte-0.2.0b0.dist-info}/top_level.txt +0 -0
union/remote/_secret.py
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from typing import AsyncGenerator, Iterator, Literal, Union
|
|
5
|
-
|
|
6
|
-
import rich.repr
|
|
7
|
-
|
|
8
|
-
from union._api_commons import syncer
|
|
9
|
-
from union._initialize import get_client, get_common_config, requires_client
|
|
10
|
-
from union._protos.secret import definition_pb2, payload_pb2
|
|
11
|
-
|
|
12
|
-
SecretTypes = Literal["regular", "image_pull"]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@dataclass
|
|
16
|
-
class Secret:
|
|
17
|
-
pb2: definition_pb2.Secret
|
|
18
|
-
|
|
19
|
-
@classmethod
|
|
20
|
-
@requires_client
|
|
21
|
-
@syncer.wrap
|
|
22
|
-
async def create(cls, name: str, value: Union[str, bytes], type: SecretTypes = "regular"):
|
|
23
|
-
cfg = get_common_config()
|
|
24
|
-
secret_type = (
|
|
25
|
-
definition_pb2.SecretType.SECRET_TYPE_GENERIC
|
|
26
|
-
if type == "regular"
|
|
27
|
-
else definition_pb2.SecretType.SECRET_TYPE_IMAGE_PULL_SECRET
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
if isinstance(value, str):
|
|
31
|
-
secret = definition_pb2.SecretSpec(
|
|
32
|
-
type=secret_type,
|
|
33
|
-
string_value=value,
|
|
34
|
-
)
|
|
35
|
-
else:
|
|
36
|
-
secret = definition_pb2.SecretSpec(
|
|
37
|
-
type=secret_type,
|
|
38
|
-
binary_value=value,
|
|
39
|
-
)
|
|
40
|
-
await get_client().secrets_service.CreateSecret(
|
|
41
|
-
request=payload_pb2.CreateSecretRequest(
|
|
42
|
-
id=definition_pb2.SecretIdentifier(
|
|
43
|
-
organization=cfg.org,
|
|
44
|
-
project=cfg.project,
|
|
45
|
-
domain=cfg.domain,
|
|
46
|
-
name=name,
|
|
47
|
-
),
|
|
48
|
-
secret_spec=secret,
|
|
49
|
-
),
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
@classmethod
|
|
53
|
-
@requires_client
|
|
54
|
-
@syncer.wrap
|
|
55
|
-
async def get(cls, name: str) -> Secret:
|
|
56
|
-
cfg = get_common_config()
|
|
57
|
-
resp = await get_client().secrets_service.GetSecret(
|
|
58
|
-
request=payload_pb2.GetSecretRequest(
|
|
59
|
-
id=definition_pb2.SecretIdentifier(
|
|
60
|
-
organization=cfg.org,
|
|
61
|
-
project=cfg.project,
|
|
62
|
-
domain=cfg.domain,
|
|
63
|
-
name=name,
|
|
64
|
-
)
|
|
65
|
-
)
|
|
66
|
-
)
|
|
67
|
-
return Secret(pb2=resp.secret)
|
|
68
|
-
|
|
69
|
-
@classmethod
|
|
70
|
-
@requires_client
|
|
71
|
-
@syncer.wrap
|
|
72
|
-
async def listall(cls, limit: int = 100) -> Union[Iterator[Secret], AsyncGenerator[Secret, None]]:
|
|
73
|
-
cfg = get_common_config()
|
|
74
|
-
token = None
|
|
75
|
-
while True:
|
|
76
|
-
resp = await get_client().secrets_service.ListSecrets(
|
|
77
|
-
request=payload_pb2.ListSecretsRequest(
|
|
78
|
-
organization=cfg.org,
|
|
79
|
-
project=cfg.project,
|
|
80
|
-
domain=cfg.domain,
|
|
81
|
-
token=token,
|
|
82
|
-
limit=limit,
|
|
83
|
-
),
|
|
84
|
-
)
|
|
85
|
-
token = resp.token
|
|
86
|
-
for r in resp.secrets:
|
|
87
|
-
yield cls(r)
|
|
88
|
-
if not token:
|
|
89
|
-
break
|
|
90
|
-
|
|
91
|
-
@classmethod
|
|
92
|
-
@requires_client
|
|
93
|
-
@syncer.wrap
|
|
94
|
-
async def delete(cls, name):
|
|
95
|
-
cfg = get_common_config()
|
|
96
|
-
await get_client().secrets_service.DeleteSecret(
|
|
97
|
-
request=payload_pb2.DeleteSecretRequest(
|
|
98
|
-
id=definition_pb2.SecretIdentifier(
|
|
99
|
-
organization=cfg.org,
|
|
100
|
-
project=cfg.project,
|
|
101
|
-
domain=cfg.domain,
|
|
102
|
-
name=name,
|
|
103
|
-
)
|
|
104
|
-
)
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
@property
|
|
108
|
-
def name(self) -> str:
|
|
109
|
-
return self.pb2.id.name
|
|
110
|
-
|
|
111
|
-
@property
|
|
112
|
-
def type(self) -> str:
|
|
113
|
-
if self.pb2.secret_metadata.type == definition_pb2.SecretType.SECRET_TYPE_GENERIC:
|
|
114
|
-
return "regular"
|
|
115
|
-
elif self.pb2.secret_metadata.type == definition_pb2.SecretType.SECRET_TYPE_IMAGE_PULL_SECRET:
|
|
116
|
-
return "image_pull"
|
|
117
|
-
raise ValueError("unknown type")
|
|
118
|
-
|
|
119
|
-
def __rich_repr__(self) -> rich.repr.Result:
|
|
120
|
-
yield "project", self.pb2.id.project or "-"
|
|
121
|
-
yield "domain", self.pb2.id.domain or "-"
|
|
122
|
-
yield "name", self.name
|
|
123
|
-
yield "type", self.type
|
|
124
|
-
yield "created_time", self.pb2.secret_metadata.created_time.ToDatetime().isoformat()
|
|
125
|
-
yield "status", definition_pb2.OverallStatus.Name(self.pb2.secret_metadata.secret_status.overall_status)
|
|
126
|
-
yield (
|
|
127
|
-
"cluster_status",
|
|
128
|
-
{
|
|
129
|
-
s.cluster.name: definition_pb2.SecretPresenceStatus.Name(s.presence_status)
|
|
130
|
-
for s in self.pb2.secret_metadata.secret_status.cluster_status
|
|
131
|
-
},
|
|
132
|
-
)
|
union/remote/_task.py
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from threading import Lock
|
|
4
|
-
from typing import Any, Callable, Coroutine, Dict, Literal, Optional, Union
|
|
5
|
-
|
|
6
|
-
import rich.repr
|
|
7
|
-
from flyteidl.core import interface_pb2
|
|
8
|
-
|
|
9
|
-
from union import CacheRequest, Resources, ReusePolicy
|
|
10
|
-
from union._api_commons import syncer
|
|
11
|
-
from union._initialize import get_client, get_common_config, requires_client
|
|
12
|
-
from union._protos.workflow import task_definition_pb2, task_service_pb2
|
|
13
|
-
from union._retry import RetryStrategy
|
|
14
|
-
from union._secret import SecretRequest
|
|
15
|
-
from union._timeout import TimeoutType
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class LazyEntity:
|
|
19
|
-
"""
|
|
20
|
-
Fetches the entity when the entity is called or when the entity is retrieved.
|
|
21
|
-
The entity is derived from RemoteEntity so that it behaves exactly like the mimicked entity.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def __init__(self, name: str, getter: Callable[[], Coroutine[Any, Any, Task]], *args, **kwargs):
|
|
25
|
-
self._task = None
|
|
26
|
-
self._getter = getter
|
|
27
|
-
self._name = name
|
|
28
|
-
if not self._getter:
|
|
29
|
-
raise ValueError("getter method is required to create a Lazy loadable Remote Entity.")
|
|
30
|
-
self._mutex = Lock()
|
|
31
|
-
|
|
32
|
-
@property
|
|
33
|
-
def name(self) -> str:
|
|
34
|
-
return self._name
|
|
35
|
-
|
|
36
|
-
@requires_client
|
|
37
|
-
@syncer.wrap
|
|
38
|
-
async def fetch(self) -> Task:
|
|
39
|
-
"""
|
|
40
|
-
Forwards all other attributes to task, causing the task to be fetched!
|
|
41
|
-
"""
|
|
42
|
-
with self._mutex:
|
|
43
|
-
if self._task is None:
|
|
44
|
-
try:
|
|
45
|
-
self._task = await self._getter()
|
|
46
|
-
except AttributeError as e:
|
|
47
|
-
raise RuntimeError(
|
|
48
|
-
f"Error downloading the entity {self._name}, (check original exception...)"
|
|
49
|
-
) from e
|
|
50
|
-
return self._task
|
|
51
|
-
|
|
52
|
-
@requires_client
|
|
53
|
-
async def __call__(self, *args, **kwargs):
|
|
54
|
-
"""
|
|
55
|
-
Forwards the call to the underlying task. The entity will be fetched if not already present
|
|
56
|
-
"""
|
|
57
|
-
tk = await self.fetch.aio()
|
|
58
|
-
return await tk(*args, **kwargs)
|
|
59
|
-
|
|
60
|
-
def __repr__(self) -> str:
|
|
61
|
-
return str(self)
|
|
62
|
-
|
|
63
|
-
def __str__(self) -> str:
|
|
64
|
-
return f"Future for task with name {self._name}"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def _interface_repr(name: str, interface: interface_pb2.TypedInterface) -> str:
|
|
68
|
-
"""
|
|
69
|
-
Returns a string representation of the task interface.
|
|
70
|
-
"""
|
|
71
|
-
i = f"{name}("
|
|
72
|
-
if interface.inputs:
|
|
73
|
-
initial = True
|
|
74
|
-
for key, tpe in interface.inputs.variables.items():
|
|
75
|
-
if not initial:
|
|
76
|
-
i += ", "
|
|
77
|
-
i += f"{key}"
|
|
78
|
-
i += ")"
|
|
79
|
-
if interface.outputs:
|
|
80
|
-
initial = True
|
|
81
|
-
multi = len(interface.outputs.variables) > 1
|
|
82
|
-
i += " -> "
|
|
83
|
-
if multi:
|
|
84
|
-
i += "("
|
|
85
|
-
for key, tpe in interface.outputs.variables.items():
|
|
86
|
-
if not initial:
|
|
87
|
-
i += ", "
|
|
88
|
-
i += f"{key}"
|
|
89
|
-
if multi:
|
|
90
|
-
i += ")"
|
|
91
|
-
i += ":"
|
|
92
|
-
return i
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
class Task:
|
|
96
|
-
@classmethod
|
|
97
|
-
def _parse_task_url(cls, task_url) -> task_definition_pb2.TaskIdentifier:
|
|
98
|
-
if not task_url.startswith("task://"):
|
|
99
|
-
raise ValueError("Invalid task URL: must start with 'task://'")
|
|
100
|
-
|
|
101
|
-
parts = task_url[len("task://") :].split("/")
|
|
102
|
-
|
|
103
|
-
if len(parts) != 5:
|
|
104
|
-
raise ValueError("Invalid task URL: must have 5 parts after 'task://'")
|
|
105
|
-
|
|
106
|
-
org, project, domain, name, version = parts
|
|
107
|
-
return task_definition_pb2.TaskIdentifier(
|
|
108
|
-
org=org,
|
|
109
|
-
project=project,
|
|
110
|
-
domain=domain,
|
|
111
|
-
name=name,
|
|
112
|
-
version=version,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
@classmethod
|
|
116
|
-
def get(cls, uri: str | None = None, *, name: str | None = None, version: str | None = None) -> LazyEntity:
|
|
117
|
-
"""
|
|
118
|
-
Get a task by its ID or name. If both are provided, the ID will take precedence.
|
|
119
|
-
|
|
120
|
-
:param uri: The URI of the task. If provided, do not provide the rest of the parameters.
|
|
121
|
-
:param name: The name of the task.
|
|
122
|
-
:param version: The version of the task.
|
|
123
|
-
|
|
124
|
-
"""
|
|
125
|
-
if uri:
|
|
126
|
-
task_id = cls._parse_task_url(uri)
|
|
127
|
-
else:
|
|
128
|
-
cfg = get_common_config()
|
|
129
|
-
task_id = task_definition_pb2.TaskIdentifier(
|
|
130
|
-
org=cfg.org,
|
|
131
|
-
project=cfg.project,
|
|
132
|
-
domain=cfg.domain,
|
|
133
|
-
name=name,
|
|
134
|
-
version=version,
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
@requires_client
|
|
138
|
-
async def deferred_get() -> Task:
|
|
139
|
-
resp = await get_client().task_service.GetTaskDetails(
|
|
140
|
-
task_service_pb2.GetTaskDetailsRequest(
|
|
141
|
-
task_id=task_id,
|
|
142
|
-
)
|
|
143
|
-
)
|
|
144
|
-
return cls(resp.details)
|
|
145
|
-
|
|
146
|
-
return LazyEntity(name=name, getter=deferred_get)
|
|
147
|
-
|
|
148
|
-
def __init__(self, task: task_definition_pb2.TaskDetails):
|
|
149
|
-
self._task = task
|
|
150
|
-
|
|
151
|
-
@requires_client
|
|
152
|
-
def __call__(self, *args, **kwargs):
|
|
153
|
-
"""
|
|
154
|
-
Forwards the call to the underlying task. The entity will be fetched if not already present
|
|
155
|
-
"""
|
|
156
|
-
raise NotImplementedError
|
|
157
|
-
|
|
158
|
-
def __getattr__(self, item: str) -> Any:
|
|
159
|
-
"""
|
|
160
|
-
Forwards all other attributes to task, causing the task to be fetched!
|
|
161
|
-
"""
|
|
162
|
-
return getattr(self._task, item)
|
|
163
|
-
|
|
164
|
-
def override(
|
|
165
|
-
self,
|
|
166
|
-
*,
|
|
167
|
-
local: Optional[bool] = None,
|
|
168
|
-
ref: Optional[bool] = None,
|
|
169
|
-
resources: Optional[Resources] = None,
|
|
170
|
-
cache: CacheRequest = "auto",
|
|
171
|
-
retries: Union[int, RetryStrategy] = 0,
|
|
172
|
-
timeout: Optional[TimeoutType] = None,
|
|
173
|
-
reusable: Union[ReusePolicy, Literal["auto"], None] = None,
|
|
174
|
-
env: Optional[Dict[str, str]] = None,
|
|
175
|
-
secrets: Optional[SecretRequest] = None,
|
|
176
|
-
**kwargs: Any,
|
|
177
|
-
) -> Task:
|
|
178
|
-
raise NotImplementedError
|
|
179
|
-
|
|
180
|
-
def __rich_repr__(self) -> rich.repr.Result:
|
|
181
|
-
"""
|
|
182
|
-
Rich representation of the task.
|
|
183
|
-
"""
|
|
184
|
-
yield "project", self._task.task_id.project
|
|
185
|
-
yield "domain", self._task.task_id.domain
|
|
186
|
-
yield "name", self._task.task_id.name
|
|
187
|
-
yield "version", self._task.task_id.version
|
|
188
|
-
yield "deployed by", self._task.metadata.deployed_by
|
|
189
|
-
yield "interface", _interface_repr(self._task.task_id.name, self._task.spec.task_template.interface)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if __name__ == "__main__":
|
|
193
|
-
tk = Task.get(name="example_task")
|
union/report/__init__.py
DELETED
union/report/_report.py
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import html
|
|
2
|
-
import pathlib
|
|
3
|
-
import string
|
|
4
|
-
from dataclasses import dataclass, field
|
|
5
|
-
from typing import TYPE_CHECKING, Dict, List, Union
|
|
6
|
-
|
|
7
|
-
from union._api_commons import syncer
|
|
8
|
-
from union._internal.runtime import io
|
|
9
|
-
from union._logging import logger
|
|
10
|
-
from union._tools import ipython_check
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from IPython.core.display import HTML
|
|
14
|
-
|
|
15
|
-
_MAIN_TAB_NAME = "main"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@dataclass
|
|
19
|
-
class Tab:
|
|
20
|
-
name: str
|
|
21
|
-
content: List[str] = field(default_factory=list, init=False)
|
|
22
|
-
|
|
23
|
-
def log(self, content: str):
|
|
24
|
-
"""
|
|
25
|
-
Add content to the tab.
|
|
26
|
-
The content should be a valid HTML string, but not a complete HTML document, as it will be inserted into a div.
|
|
27
|
-
|
|
28
|
-
:param content: The content to add.
|
|
29
|
-
"""
|
|
30
|
-
self.content.append(content)
|
|
31
|
-
|
|
32
|
-
def replace(self, content: str):
|
|
33
|
-
"""
|
|
34
|
-
Replace the content of the tab.
|
|
35
|
-
The content should be a valid HTML string, but not a complete HTML document, as it will be inserted into a div.
|
|
36
|
-
|
|
37
|
-
:param content: The content to replace.
|
|
38
|
-
"""
|
|
39
|
-
self.content = [content]
|
|
40
|
-
|
|
41
|
-
def get_html(self) -> str:
|
|
42
|
-
"""
|
|
43
|
-
Get the HTML representation of the tab.
|
|
44
|
-
|
|
45
|
-
:return: The HTML representation of the tab.
|
|
46
|
-
"""
|
|
47
|
-
return "\n".join(self.content)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
@dataclass
|
|
51
|
-
class Report:
|
|
52
|
-
name: str
|
|
53
|
-
tabs: Dict[str, Tab] = field(default_factory=dict)
|
|
54
|
-
template_path: pathlib.Path = field(default_factory=lambda: pathlib.Path(__file__).parent / "_template.html")
|
|
55
|
-
|
|
56
|
-
def __post_init__(self):
|
|
57
|
-
self.tabs[_MAIN_TAB_NAME] = Tab(_MAIN_TAB_NAME)
|
|
58
|
-
|
|
59
|
-
def get_tab(self, name: str, create_if_missing: bool = True) -> Tab:
|
|
60
|
-
"""
|
|
61
|
-
Get a tab by name. If the tab does not exist, create it.
|
|
62
|
-
|
|
63
|
-
:param name: The name of the tab.
|
|
64
|
-
:param create_if_missing: Whether to create the tab if it does not exist.
|
|
65
|
-
:return: The tab.
|
|
66
|
-
"""
|
|
67
|
-
if name not in self.tabs:
|
|
68
|
-
if create_if_missing:
|
|
69
|
-
self.tabs[name] = Tab(name)
|
|
70
|
-
else:
|
|
71
|
-
raise ValueError(f"Tab {name} does not exist.")
|
|
72
|
-
return self.tabs[name]
|
|
73
|
-
|
|
74
|
-
def get_final_report(self) -> Union[str, "HTML"]:
|
|
75
|
-
"""
|
|
76
|
-
Get the final report as a string.
|
|
77
|
-
|
|
78
|
-
:return: The final report.
|
|
79
|
-
"""
|
|
80
|
-
tabs = {n: t.get_html() for n, t in self.tabs.items()}
|
|
81
|
-
nav_htmls = []
|
|
82
|
-
body_htmls = []
|
|
83
|
-
|
|
84
|
-
for key, value in tabs.items():
|
|
85
|
-
nav_htmls.append(f'<li onclick="handleLinkClick(this)">{html.escape(key)}</li>')
|
|
86
|
-
# Can not escape here because this is HTML. Escaping it will present the HTML as text.
|
|
87
|
-
# The renderer must ensure that the HTML is safe.
|
|
88
|
-
body_htmls.append(f"<div>{value}</div>")
|
|
89
|
-
|
|
90
|
-
template = string.Template(self.template_path.open("r").read())
|
|
91
|
-
|
|
92
|
-
raw_html = template.substitute(NAV_HTML="".join(nav_htmls), BODY_HTML="".join(body_htmls))
|
|
93
|
-
if ipython_check():
|
|
94
|
-
try:
|
|
95
|
-
from IPython.core.display import HTML
|
|
96
|
-
|
|
97
|
-
return HTML(raw_html)
|
|
98
|
-
except ImportError:
|
|
99
|
-
...
|
|
100
|
-
return raw_html
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def get_tab(name: str, /, create_if_missing: bool = True) -> Tab:
|
|
104
|
-
"""
|
|
105
|
-
Get a tab by name. If the tab does not exist, create it.
|
|
106
|
-
|
|
107
|
-
:param name: The name of the tab.
|
|
108
|
-
:param create_if_missing: Whether to create the tab if it does not exist.
|
|
109
|
-
:return: The tab.
|
|
110
|
-
"""
|
|
111
|
-
report = current_report()
|
|
112
|
-
return report.get_tab(name, create_if_missing=create_if_missing)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
@syncer.wrap
|
|
116
|
-
async def log(content: str, do_flush: bool = False):
|
|
117
|
-
"""
|
|
118
|
-
Log content to the main tab. The content should be a valid HTML string, but not a complete HTML document,
|
|
119
|
-
as it will be inserted into a div.
|
|
120
|
-
|
|
121
|
-
:param content: The content to log.
|
|
122
|
-
:param do_flush: flush the report after logging.
|
|
123
|
-
"""
|
|
124
|
-
get_tab(_MAIN_TAB_NAME).log(content)
|
|
125
|
-
if do_flush:
|
|
126
|
-
await flush.aio()
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@syncer.wrap
|
|
130
|
-
async def flush():
|
|
131
|
-
"""
|
|
132
|
-
Flush the report.
|
|
133
|
-
"""
|
|
134
|
-
import union.storage as storage
|
|
135
|
-
from union._context import internal_ctx
|
|
136
|
-
|
|
137
|
-
if not internal_ctx().is_task_context():
|
|
138
|
-
return
|
|
139
|
-
|
|
140
|
-
report = internal_ctx().get_report()
|
|
141
|
-
if report is None:
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
report_html = report.get_final_report()
|
|
145
|
-
assert report_html is not None
|
|
146
|
-
assert isinstance(report_html, str)
|
|
147
|
-
report_path = io.report_path(internal_ctx().data.task_context.output_path)
|
|
148
|
-
final_path = await storage.put_stream(report_html.encode("utf-8"), to_path=report_path)
|
|
149
|
-
logger.debug(f"Report flushed to {final_path}")
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
@syncer.wrap
|
|
153
|
-
async def replace(content: str, do_flush: bool = False):
|
|
154
|
-
"""
|
|
155
|
-
Get the report. Replaces the content of the main tab.
|
|
156
|
-
|
|
157
|
-
:return: The report.
|
|
158
|
-
"""
|
|
159
|
-
report = current_report()
|
|
160
|
-
if report is None:
|
|
161
|
-
return
|
|
162
|
-
report.get_tab(_MAIN_TAB_NAME).replace(content)
|
|
163
|
-
if do_flush:
|
|
164
|
-
await flush.aio()
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def current_report() -> Report:
|
|
168
|
-
"""
|
|
169
|
-
Get the current report. This is a dummy report if not in a task context.
|
|
170
|
-
|
|
171
|
-
:return: The current report.
|
|
172
|
-
"""
|
|
173
|
-
from union._context import internal_ctx
|
|
174
|
-
|
|
175
|
-
report = internal_ctx().get_report()
|
|
176
|
-
if report is None:
|
|
177
|
-
report = Report("dummy")
|
|
178
|
-
return report
|
union/report/_template.html
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>User Content</title>
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
-
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,700%7COpen+Sans:400,700" rel="stylesheet">
|
|
8
|
-
<style>
|
|
9
|
-
ol, ul {
|
|
10
|
-
list-style: none;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
table {
|
|
14
|
-
border-collapse: collapse;
|
|
15
|
-
border-spacing: 0;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
#flyte-frame-nav {
|
|
19
|
-
display: flex;
|
|
20
|
-
width: 100%;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
#flyte-frame-tabs {
|
|
24
|
-
display: flex;
|
|
25
|
-
width: 100%;
|
|
26
|
-
justify-content: center;
|
|
27
|
-
margin-block: 0;
|
|
28
|
-
padding-inline-start: 0;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
#flyte-frame-tabs li {
|
|
32
|
-
cursor: pointer;
|
|
33
|
-
padding: 8px;
|
|
34
|
-
margin: 0;
|
|
35
|
-
margin-right: 12px;
|
|
36
|
-
font-size: 14px;
|
|
37
|
-
line-height: 20px;
|
|
38
|
-
font-weight: 700;
|
|
39
|
-
font-style: normal;
|
|
40
|
-
font-family: Open Sans, helvetica, arial, sans-serif;
|
|
41
|
-
color: #666666;
|
|
42
|
-
width: 126px;
|
|
43
|
-
text-align: center;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
#flyte-frame-tabs li:last-child {
|
|
47
|
-
margin-right: 0;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
#flyte-frame-tabs li.active {
|
|
51
|
-
border-bottom: 4px solid rgb(163, 26, 255);
|
|
52
|
-
color: #333333;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
#flyte-frame-container {
|
|
56
|
-
width: auto;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
#flyte-frame-container > div {
|
|
60
|
-
display: None;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
#flyte-frame-container > div.active {
|
|
64
|
-
display: block;
|
|
65
|
-
padding: 2rem 2rem;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
</style>
|
|
69
|
-
|
|
70
|
-
</head>
|
|
71
|
-
<body>
|
|
72
|
-
<nav id="flyte-frame-nav">
|
|
73
|
-
<ul id="flyte-frame-tabs">
|
|
74
|
-
$NAV_HTML
|
|
75
|
-
</ul>
|
|
76
|
-
</nav>
|
|
77
|
-
<div id="flyte-frame-container">
|
|
78
|
-
$BODY_HTML
|
|
79
|
-
</div>
|
|
80
|
-
</body>
|
|
81
|
-
<script>
|
|
82
|
-
const setTabs = index => {
|
|
83
|
-
const container = document.getElementById('flyte-frame-tabs')
|
|
84
|
-
for (let i = 0; i < container.children.length; i++) {
|
|
85
|
-
const tabIndex = container.children[i].getAttribute('link_index')
|
|
86
|
-
if (tabIndex === index) {
|
|
87
|
-
container.children[i].classList.add('active')
|
|
88
|
-
} else {
|
|
89
|
-
container.children[i].className = ''
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
const setContent = index => {
|
|
94
|
-
const container = document.getElementById('flyte-frame-container')
|
|
95
|
-
for (let i = 0; i < container.children.length; i++) {
|
|
96
|
-
const tabIndex = container.children[i].getAttribute('link_index')
|
|
97
|
-
if (tabIndex === index) {
|
|
98
|
-
container.children[i].classList.add('active')
|
|
99
|
-
} else {
|
|
100
|
-
container.children[i].className = ''
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
const setLinkIndex = index => {
|
|
105
|
-
setTabs(index)
|
|
106
|
-
setContent(index)
|
|
107
|
-
}
|
|
108
|
-
const handleLinkClick = e => {
|
|
109
|
-
const linkIndex = e.getAttribute('link_index');
|
|
110
|
-
setLinkIndex(linkIndex)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const tabs = document.getElementById('flyte-frame-tabs');
|
|
114
|
-
const containers = document.getElementById('flyte-frame-container');
|
|
115
|
-
for(var i = 0; i < tabs.children.length; i++) {
|
|
116
|
-
if (i === 0) {
|
|
117
|
-
tabs.children[i].classList.add('active')
|
|
118
|
-
containers.children[i].classList.add('active')
|
|
119
|
-
}
|
|
120
|
-
tabs.children[i].setAttribute("link_index", i+1)
|
|
121
|
-
containers.children[i].setAttribute("link_index", i+1)
|
|
122
|
-
}
|
|
123
|
-
</script>
|
|
124
|
-
</html>
|
union/storage/__init__.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
__all__ = [
|
|
2
|
-
"get",
|
|
3
|
-
"get_random_local_directory",
|
|
4
|
-
"get_random_local_path",
|
|
5
|
-
"get_stream",
|
|
6
|
-
"get_underlying_filesystem",
|
|
7
|
-
"is_remote",
|
|
8
|
-
"join",
|
|
9
|
-
"put",
|
|
10
|
-
"put_stream",
|
|
11
|
-
"put_stream",
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
from ._storage import (
|
|
15
|
-
get,
|
|
16
|
-
get_random_local_directory,
|
|
17
|
-
get_random_local_path,
|
|
18
|
-
get_stream,
|
|
19
|
-
get_underlying_filesystem,
|
|
20
|
-
is_remote,
|
|
21
|
-
join,
|
|
22
|
-
put,
|
|
23
|
-
put_stream,
|
|
24
|
-
)
|
union/storage/_remote_fs.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import threading
|
|
4
|
-
import typing
|
|
5
|
-
|
|
6
|
-
# This file system is not really a filesystem, so users aren't really able to specify the remote path,
|
|
7
|
-
# at least not yet.
|
|
8
|
-
REMOTE_PLACEHOLDER = "flyte://data"
|
|
9
|
-
|
|
10
|
-
HashStructure = typing.Dict[str, typing.Tuple[bytes, int]]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class RemoteFSPathResolver:
|
|
14
|
-
protocol = "flyte://"
|
|
15
|
-
_flyte_path_to_remote_map: typing.ClassVar[typing.Dict[str, str]] = {}
|
|
16
|
-
_lock = threading.Lock()
|
|
17
|
-
|
|
18
|
-
@classmethod
|
|
19
|
-
def resolve_remote_path(cls, flyte_uri: str) -> typing.Optional[str]:
|
|
20
|
-
"""
|
|
21
|
-
Given a flyte uri, return the remote path if it exists or was created in current session, otherwise return None
|
|
22
|
-
"""
|
|
23
|
-
with cls._lock:
|
|
24
|
-
if flyte_uri in cls._flyte_path_to_remote_map:
|
|
25
|
-
return cls._flyte_path_to_remote_map[flyte_uri]
|
|
26
|
-
return None
|
|
27
|
-
|
|
28
|
-
@classmethod
|
|
29
|
-
def add_mapping(cls, flyte_uri: str, remote_path: str):
|
|
30
|
-
"""
|
|
31
|
-
Thread safe method to dd a mapping from a flyte uri to a remote path
|
|
32
|
-
"""
|
|
33
|
-
with cls._lock:
|
|
34
|
-
cls._flyte_path_to_remote_map[flyte_uri] = remote_path
|