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/__init__.py
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Union SDK for authoring Compound AI applications, services and workflows.
|
|
3
|
-
|
|
4
|
-
## Environments
|
|
5
|
-
|
|
6
|
-
TaskEnvironment class to define a new environment for a set of tasks.
|
|
7
|
-
|
|
8
|
-
Example usage:
|
|
9
|
-
|
|
10
|
-
```python
|
|
11
|
-
env = union.TaskEnvironment(name="my_env", image="my_image", resources=Resources(cpu="1", memory="1Gi"))
|
|
12
|
-
|
|
13
|
-
@env.task
|
|
14
|
-
async def my_task():
|
|
15
|
-
pass
|
|
16
|
-
```
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
__all__ = [
|
|
20
|
-
"ABFS",
|
|
21
|
-
"GCS",
|
|
22
|
-
"GPU",
|
|
23
|
-
"S3",
|
|
24
|
-
"TPU",
|
|
25
|
-
"Cache",
|
|
26
|
-
"CachePolicy",
|
|
27
|
-
"CacheRequest",
|
|
28
|
-
"Device",
|
|
29
|
-
"Image",
|
|
30
|
-
"Resources",
|
|
31
|
-
"ReusePolicy",
|
|
32
|
-
"Secret",
|
|
33
|
-
"TaskEnvironment",
|
|
34
|
-
"__version__",
|
|
35
|
-
"ctx",
|
|
36
|
-
"deploy",
|
|
37
|
-
"group",
|
|
38
|
-
"init",
|
|
39
|
-
"run",
|
|
40
|
-
"with_runcontext",
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
from ._cache import Cache, CachePolicy, CacheRequest
|
|
44
|
-
from ._context import ctx
|
|
45
|
-
from ._deploy import deploy
|
|
46
|
-
from ._group import group
|
|
47
|
-
from ._image import Image
|
|
48
|
-
from ._initialize import ABFS, GCS, S3, init
|
|
49
|
-
from ._resources import GPU, TPU, Device, Resources
|
|
50
|
-
from ._reusable_environment import ReusePolicy
|
|
51
|
-
from ._run import run, with_runcontext
|
|
52
|
-
from ._secret import Secret
|
|
53
|
-
from ._task_environment import TaskEnvironment
|
|
54
|
-
from ._version import __version__
|
union/_api_commons.py
DELETED
union/_bin/__init__.py
DELETED
|
File without changes
|
union/_bin/runtime.py
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Union runtime module, this is the entrypoint script for the Union runtime.
|
|
3
|
-
|
|
4
|
-
Caution: Startup time for this module is very important, as it is the entrypoint for the Union runtime.
|
|
5
|
-
Refrain from importing any modules here. If you need to import any modules, do it inside the main function.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import asyncio
|
|
9
|
-
import os
|
|
10
|
-
import sys
|
|
11
|
-
from typing import List
|
|
12
|
-
|
|
13
|
-
import click
|
|
14
|
-
|
|
15
|
-
# Todo: work with pvditt to make these the names
|
|
16
|
-
# ACTION_NAME = "_U_ACTION_NAME"
|
|
17
|
-
# RUN_NAME = "_U_RUN_NAME"
|
|
18
|
-
# PROJECT_NAME = "_U_PROJECT_NAME"
|
|
19
|
-
# DOMAIN_NAME = "_U_DOMAIN_NAME"
|
|
20
|
-
# ORG_NAME = "_U_ORG_NAME"
|
|
21
|
-
|
|
22
|
-
ACTION_NAME = "ACTION_NAME"
|
|
23
|
-
RUN_NAME = "RUN_NAME"
|
|
24
|
-
PROJECT_NAME = "FLYTE_INTERNAL_TASK_PROJECT"
|
|
25
|
-
DOMAIN_NAME = "FLYTE_INTERNAL_TASK_DOMAIN"
|
|
26
|
-
ORG_NAME = "_U_ORG_NAME"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@click.command("urun")
|
|
30
|
-
@click.option("--inputs", "-i", required=True)
|
|
31
|
-
@click.option("--outputs-path", "-o", required=True)
|
|
32
|
-
@click.option("--version", "-v", required=True)
|
|
33
|
-
@click.option("--raw-data-path", "-r", required=False)
|
|
34
|
-
@click.option("--checkpoint-path", "-c", required=False)
|
|
35
|
-
@click.option("--prev-checkpoint", "-p", required=False)
|
|
36
|
-
@click.option("--name", envvar=ACTION_NAME, required=False)
|
|
37
|
-
@click.option("--run-name", envvar=RUN_NAME, required=False)
|
|
38
|
-
@click.option("--project", envvar=PROJECT_NAME, required=False)
|
|
39
|
-
@click.option("--domain", envvar=DOMAIN_NAME, required=False)
|
|
40
|
-
@click.option("--org", envvar=ORG_NAME, required=False)
|
|
41
|
-
@click.option("--image-cache", required=False)
|
|
42
|
-
@click.option("--tgz", required=False)
|
|
43
|
-
@click.option("--pkl", required=False)
|
|
44
|
-
@click.option("--dest", required=False)
|
|
45
|
-
@click.option("--resolver", required=False)
|
|
46
|
-
@click.argument(
|
|
47
|
-
"resolver-args",
|
|
48
|
-
type=click.UNPROCESSED,
|
|
49
|
-
nargs=-1,
|
|
50
|
-
)
|
|
51
|
-
def main(
|
|
52
|
-
run_name: str,
|
|
53
|
-
name: str,
|
|
54
|
-
project: str,
|
|
55
|
-
domain: str,
|
|
56
|
-
org: str,
|
|
57
|
-
image_cache: str,
|
|
58
|
-
version: str,
|
|
59
|
-
inputs: str,
|
|
60
|
-
outputs_path: str,
|
|
61
|
-
raw_data_path: str,
|
|
62
|
-
checkpoint_path: str,
|
|
63
|
-
prev_checkpoint: str,
|
|
64
|
-
tgz: str,
|
|
65
|
-
pkl: str,
|
|
66
|
-
dest: str,
|
|
67
|
-
resolver: str,
|
|
68
|
-
resolver_args: List[str],
|
|
69
|
-
):
|
|
70
|
-
sys.path.insert(0, ".")
|
|
71
|
-
|
|
72
|
-
from union._datastructures import ActionID, Checkpoints, CodeBundle, RawDataPath
|
|
73
|
-
from union._initialize import S3, initialize_in_cluster
|
|
74
|
-
from union._internal.controllers import create_controller
|
|
75
|
-
from union._internal.imagebuild.image_builder import ImageCache
|
|
76
|
-
from union._internal.runtime.entrypoints import load_and_run_task
|
|
77
|
-
|
|
78
|
-
if not org:
|
|
79
|
-
org = "testorg"
|
|
80
|
-
|
|
81
|
-
assert org, "Org is required for now"
|
|
82
|
-
assert project, "Project is required"
|
|
83
|
-
assert domain, "Domain is required"
|
|
84
|
-
assert run_name, "Run name is required"
|
|
85
|
-
assert name, "Action name is required"
|
|
86
|
-
|
|
87
|
-
if run_name.startswith("{{"):
|
|
88
|
-
run_name = os.environ.get("RUN_NAME")
|
|
89
|
-
if name.startswith("{{"):
|
|
90
|
-
name = os.environ.get("ACTION_NAME")
|
|
91
|
-
|
|
92
|
-
bundle = CodeBundle(tgz=tgz, pkl=pkl, destination=dest, computed_version=version)
|
|
93
|
-
# TODO configure storage correctly for cluster
|
|
94
|
-
initialize_in_cluster(storage=S3.auto())
|
|
95
|
-
controller = create_controller(ct="remote", endpoint="host.docker.internal:8090", insecure=True)
|
|
96
|
-
|
|
97
|
-
ic = ImageCache.from_transport(image_cache) if image_cache else None
|
|
98
|
-
|
|
99
|
-
asyncio.run(
|
|
100
|
-
load_and_run_task(
|
|
101
|
-
resolver=resolver,
|
|
102
|
-
resolver_args=resolver_args,
|
|
103
|
-
action=ActionID(name=name, run_name=run_name, project=project, domain=domain, org=org),
|
|
104
|
-
raw_data_path=RawDataPath(path=raw_data_path),
|
|
105
|
-
checkpoints=Checkpoints(checkpoint_path, prev_checkpoint),
|
|
106
|
-
code_bundle=bundle,
|
|
107
|
-
input_path=inputs,
|
|
108
|
-
output_path=outputs_path,
|
|
109
|
-
version=version,
|
|
110
|
-
controller=controller,
|
|
111
|
-
image_cache=ic,
|
|
112
|
-
)
|
|
113
|
-
)
|
union/_build.py
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from ._api_commons import syncer
|
|
4
|
-
from ._image import Image
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@syncer.wrap
|
|
8
|
-
async def build(image: Image) -> str:
|
|
9
|
-
"""
|
|
10
|
-
Build an image. The existing async context will be used.
|
|
11
|
-
|
|
12
|
-
Example:
|
|
13
|
-
```
|
|
14
|
-
import union
|
|
15
|
-
image = union.Image("example_image")
|
|
16
|
-
if __name__ == "__main__":
|
|
17
|
-
asyncio.run(union.build.aio(image))
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
:param image: The image(s) to build.
|
|
21
|
-
:return: The image URI.
|
|
22
|
-
"""
|
|
23
|
-
from union._internal.imagebuild.image_builder import ImageBuildEngine
|
|
24
|
-
|
|
25
|
-
return await ImageBuildEngine.build(image)
|
union/_cache/__init__.py
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from .cache import Cache, CacheBehavior, CachePolicy, CacheRequest
|
|
2
|
-
from .defaults import get_default_policies
|
|
3
|
-
from .policy_function_body import FunctionBodyPolicy
|
|
4
|
-
|
|
5
|
-
__all__ = [
|
|
6
|
-
"Cache",
|
|
7
|
-
"CacheBehavior",
|
|
8
|
-
"CachePolicy",
|
|
9
|
-
"CacheRequest",
|
|
10
|
-
"FunctionBodyPolicy",
|
|
11
|
-
"get_default_policies",
|
|
12
|
-
]
|
union/_cache/cache.py
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import hashlib
|
|
2
|
-
from dataclasses import dataclass, field
|
|
3
|
-
from typing import (
|
|
4
|
-
Callable,
|
|
5
|
-
Generic,
|
|
6
|
-
List,
|
|
7
|
-
Optional,
|
|
8
|
-
Protocol,
|
|
9
|
-
Tuple,
|
|
10
|
-
Union,
|
|
11
|
-
runtime_checkable,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
from typing_extensions import Literal, ParamSpec, TypeVar
|
|
15
|
-
|
|
16
|
-
from union._datastructures import CodeBundle
|
|
17
|
-
|
|
18
|
-
# if TYPE_CHECKING:
|
|
19
|
-
from union._image import Image
|
|
20
|
-
|
|
21
|
-
P = ParamSpec("P")
|
|
22
|
-
FuncOut = TypeVar("FuncOut")
|
|
23
|
-
|
|
24
|
-
CacheBehavior = Literal["auto", "override", "disable"]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclass
|
|
28
|
-
class VersionParameters(Generic[P, FuncOut]):
|
|
29
|
-
"""
|
|
30
|
-
Parameters used for cache version hash generation.
|
|
31
|
-
|
|
32
|
-
:param func: The function to generate a version for. This is a required parameter but can be any callable
|
|
33
|
-
:type func: Callable[P, FuncOut]
|
|
34
|
-
:param image: The container image to generate a version for. This can be a string representing the
|
|
35
|
-
image name or an Image object.
|
|
36
|
-
:type image: Optional[Union[str, Image]]
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
func: Callable[P, FuncOut]
|
|
40
|
-
image: Optional[Union[str, Image]] = None
|
|
41
|
-
code_bundle: Optional[CodeBundle] = None
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@runtime_checkable
|
|
45
|
-
class CachePolicy(Protocol):
|
|
46
|
-
def get_version(self, salt: str, params: VersionParameters) -> str: ...
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@dataclass
|
|
50
|
-
class Cache:
|
|
51
|
-
"""
|
|
52
|
-
Cache configuration for a task.
|
|
53
|
-
:param behavior: The behavior of the cache. Can be "auto", "override" or "disable".
|
|
54
|
-
:param version_override: The version of the cache. If not provided, the version will be
|
|
55
|
-
generated based on the cache policies
|
|
56
|
-
:type version_override: Optional[str]
|
|
57
|
-
:param serialize: Boolean that indicates if identical (ie. same inputs) instances of this task should be executed in
|
|
58
|
-
serial when caching is enabled. This means that given multiple concurrent executions over identical inputs,
|
|
59
|
-
only a single instance executes and the rest wait to reuse the cached results.
|
|
60
|
-
:type serialize: bool
|
|
61
|
-
:param ignored_inputs: A tuple of input names to ignore when generating the version hash.
|
|
62
|
-
:type ignored_inputs: Union[Tuple[str, ...], str]
|
|
63
|
-
:param salt: A salt used in the hash generation.
|
|
64
|
-
:type salt: str
|
|
65
|
-
:param policies: A list of cache policies to generate the version hash.
|
|
66
|
-
:type policies: Optional[Union[List[CachePolicy], CachePolicy]]
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
behavior: CacheBehavior
|
|
70
|
-
version_override: Optional[str] = None
|
|
71
|
-
serialize: bool = False
|
|
72
|
-
ignored_inputs: Union[Tuple[str, ...], str] = field(default_factory=tuple)
|
|
73
|
-
salt: str = ""
|
|
74
|
-
policies: Optional[Union[List[CachePolicy], CachePolicy]] = None
|
|
75
|
-
|
|
76
|
-
def __post_init__(self):
|
|
77
|
-
if self.behavior not in ["auto", "override", "disable"]:
|
|
78
|
-
raise ValueError(f"Invalid cache behavior: {self.behavior}. Must be one of ['auto', 'override', 'disable']")
|
|
79
|
-
if self.behavior == "disable":
|
|
80
|
-
return
|
|
81
|
-
|
|
82
|
-
if isinstance(self.ignored_inputs, str):
|
|
83
|
-
self._ignored_inputs = (self.ignored_inputs,)
|
|
84
|
-
else:
|
|
85
|
-
self._ignored_inputs = self.ignored_inputs
|
|
86
|
-
|
|
87
|
-
# Normalize policies so that self._policies is always a list
|
|
88
|
-
if self.policies is None:
|
|
89
|
-
from union._cache.defaults import get_default_policies
|
|
90
|
-
|
|
91
|
-
self.policies = get_default_policies()
|
|
92
|
-
elif isinstance(self.policies, CachePolicy):
|
|
93
|
-
self.policies = [self.policies]
|
|
94
|
-
|
|
95
|
-
if self.version_override is None and not self.policies:
|
|
96
|
-
raise ValueError("If version is not defined then at least one cache policy needs to be set")
|
|
97
|
-
|
|
98
|
-
def is_enabled(self) -> bool:
|
|
99
|
-
"""
|
|
100
|
-
Check if the cache policy is enabled.
|
|
101
|
-
"""
|
|
102
|
-
return self.behavior in ["auto", "override"]
|
|
103
|
-
|
|
104
|
-
def get_ignored_inputs(self) -> Tuple[str, ...]:
|
|
105
|
-
return self._ignored_inputs
|
|
106
|
-
|
|
107
|
-
def get_version(self, params: Optional[VersionParameters] = None) -> str:
|
|
108
|
-
if not self.is_enabled():
|
|
109
|
-
return ""
|
|
110
|
-
|
|
111
|
-
if self.version_override is not None:
|
|
112
|
-
return self.version_override
|
|
113
|
-
|
|
114
|
-
if params is None:
|
|
115
|
-
raise ValueError("Version parameters must be provided when version_override is not set.")
|
|
116
|
-
|
|
117
|
-
if params.code_bundle is not None:
|
|
118
|
-
if params.code_bundle.pkl is not None:
|
|
119
|
-
return params.code_bundle.computed_version
|
|
120
|
-
|
|
121
|
-
task_hash = ""
|
|
122
|
-
for policy in self.policies:
|
|
123
|
-
try:
|
|
124
|
-
task_hash += policy.get_version(self.salt, params)
|
|
125
|
-
except Exception as e:
|
|
126
|
-
raise ValueError(f"Failed to generate version for cache policy {policy}.") from e
|
|
127
|
-
|
|
128
|
-
hash_obj = hashlib.sha256(task_hash.encode())
|
|
129
|
-
return hash_obj.hexdigest()
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
CacheRequest = CacheBehavior | Cache
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def cache_from_request(cache: CacheRequest) -> Cache:
|
|
136
|
-
"""
|
|
137
|
-
Coerce user input into a cache object.
|
|
138
|
-
"""
|
|
139
|
-
if isinstance(cache, Cache):
|
|
140
|
-
return cache
|
|
141
|
-
return Cache(behavior=cache)
|
union/_cache/defaults.py
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import ast
|
|
2
|
-
import hashlib
|
|
3
|
-
import inspect
|
|
4
|
-
import textwrap
|
|
5
|
-
|
|
6
|
-
from .cache import CachePolicy, VersionParameters
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class FunctionBodyPolicy(CachePolicy):
|
|
10
|
-
"""
|
|
11
|
-
A class that implements a versioning mechanism for functions by generating
|
|
12
|
-
a SHA-256 hash of the function's source code combined with a salt.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
def get_version(self, salt: str, params: VersionParameters) -> str:
|
|
16
|
-
"""
|
|
17
|
-
This method generates a version string for a function by hashing the function's source code
|
|
18
|
-
combined with a salt.
|
|
19
|
-
|
|
20
|
-
:param salt: A string that is used to salt the hash.
|
|
21
|
-
:param params: VersionParameters object that contains the parameters (e.g. function, ImageSpec, etc.) that are
|
|
22
|
-
used to generate the version.
|
|
23
|
-
|
|
24
|
-
:return: A string that represents the version of the function.
|
|
25
|
-
"""
|
|
26
|
-
if params.func is None:
|
|
27
|
-
return ""
|
|
28
|
-
|
|
29
|
-
source = inspect.getsource(params.func)
|
|
30
|
-
dedented_source = textwrap.dedent(source)
|
|
31
|
-
|
|
32
|
-
# Parse the source code into an Abstract Syntax Tree (AST)
|
|
33
|
-
parsed_ast = ast.parse(dedented_source)
|
|
34
|
-
|
|
35
|
-
# Convert the AST into a string representation
|
|
36
|
-
ast_bytes = ast.dump(parsed_ast, include_attributes=False).encode("utf-8")
|
|
37
|
-
|
|
38
|
-
# Combine the AST bytes with the salt (encoded into bytes)
|
|
39
|
-
combined_data = ast_bytes + salt.encode("utf-8")
|
|
40
|
-
|
|
41
|
-
# Return the SHA-256 hash of the combined data (AST + salt)
|
|
42
|
-
return hashlib.sha256(combined_data).hexdigest()
|
union/_cli/__init__.py
DELETED
|
File without changes
|
union/_cli/_common.py
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import importlib.util
|
|
4
|
-
import logging
|
|
5
|
-
import os
|
|
6
|
-
import sys
|
|
7
|
-
from abc import abstractmethod
|
|
8
|
-
from dataclasses import Field, dataclass, field, replace
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
from types import MappingProxyType, ModuleType
|
|
11
|
-
from typing import Any, Dict, Iterable, List, Optional
|
|
12
|
-
|
|
13
|
-
import rich_click as click
|
|
14
|
-
from rich.table import Table
|
|
15
|
-
|
|
16
|
-
import union.errors
|
|
17
|
-
|
|
18
|
-
PROJECT_OPTION = click.Option(
|
|
19
|
-
param_decls=["-p", "--project"],
|
|
20
|
-
required=False,
|
|
21
|
-
type=str,
|
|
22
|
-
default="default",
|
|
23
|
-
help="Project to operate on",
|
|
24
|
-
show_default=True,
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
DOMAIN_OPTION = click.Option(
|
|
28
|
-
param_decls=["-d", "--domain"],
|
|
29
|
-
required=False,
|
|
30
|
-
type=str,
|
|
31
|
-
default="development",
|
|
32
|
-
help="Domain to operate on",
|
|
33
|
-
show_default=True,
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
DRY_RUN_OPTION = click.Option(
|
|
37
|
-
param_decls=["--dry-run", "--dryrun"],
|
|
38
|
-
required=False,
|
|
39
|
-
type=bool,
|
|
40
|
-
is_flag=True,
|
|
41
|
-
default=False,
|
|
42
|
-
help="Dry run, do not actually call the backend service.",
|
|
43
|
-
show_default=True,
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def _common_options() -> List[click.Option]:
|
|
48
|
-
"""
|
|
49
|
-
Common options for that will be added to all commands and groups that inherit from CommandBase or GroupBase.
|
|
50
|
-
"""
|
|
51
|
-
return [PROJECT_OPTION, DOMAIN_OPTION]
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# This is global state for the CLI, it is manipulated by the main command
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@dataclass(frozen=True)
|
|
58
|
-
class CLIConfig:
|
|
59
|
-
"""
|
|
60
|
-
This is the global state for the CLI. It is manipulated by the main command.
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
log_level: int = logging.ERROR
|
|
64
|
-
endpoint: str = "dns:///dogfood.cloud-staging.union.ai"
|
|
65
|
-
insecure: bool = False
|
|
66
|
-
org_override: str | None = None
|
|
67
|
-
|
|
68
|
-
def replace(self, **kwargs) -> CLIConfig:
|
|
69
|
-
"""
|
|
70
|
-
Replace the global state with a new one.
|
|
71
|
-
"""
|
|
72
|
-
return replace(self, **kwargs)
|
|
73
|
-
|
|
74
|
-
def init(self, project: str | None = None, domain: str | None = None):
|
|
75
|
-
import union
|
|
76
|
-
|
|
77
|
-
union.init(
|
|
78
|
-
endpoint=self.endpoint,
|
|
79
|
-
project=project,
|
|
80
|
-
domain=domain,
|
|
81
|
-
log_level=self.log_level,
|
|
82
|
-
insecure=self.insecure,
|
|
83
|
-
org=self.org_override,
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
class InvokeBaseMixin:
|
|
88
|
-
"""
|
|
89
|
-
Mixin to catch grpc.RpcError, union.RpcError, other errors and other exceptions and raise them as
|
|
90
|
-
gclick.ClickException.
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
def invoke(self, ctx):
|
|
94
|
-
import grpc
|
|
95
|
-
|
|
96
|
-
try:
|
|
97
|
-
return super().invoke(ctx) # type: ignore
|
|
98
|
-
except grpc.aio.AioRpcError as e:
|
|
99
|
-
if e.code() == grpc.StatusCode.UNAUTHENTICATED:
|
|
100
|
-
raise click.ClickException(f"Authentication failed. Please check your credentials. {e!s}")
|
|
101
|
-
if e.code() == grpc.StatusCode.NOT_FOUND:
|
|
102
|
-
raise click.ClickException(f"Requested object NOT FOUND. Please check your input. Error: {e!s}")
|
|
103
|
-
if e.code() == grpc.StatusCode.ALREADY_EXISTS:
|
|
104
|
-
raise click.ClickException("Resource already exists.")
|
|
105
|
-
raise click.ClickException(f"Error invoking command: {e!s}") from e
|
|
106
|
-
except union.errors.InitializationError:
|
|
107
|
-
raise click.ClickException("Initialize the CLI with a remote configuration. For example, pass --endpoint")
|
|
108
|
-
except Exception as e:
|
|
109
|
-
raise click.ClickException(f"Error invoking command: {e}") from e
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
class CommandBase(InvokeBaseMixin, click.RichCommand):
|
|
113
|
-
"""
|
|
114
|
-
Base class for all commands, that adds common options to all commands if enabled.
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
common_options_enabled = True
|
|
118
|
-
|
|
119
|
-
def __init__(self, *args, **kwargs):
|
|
120
|
-
if "params" not in kwargs:
|
|
121
|
-
kwargs["params"] = []
|
|
122
|
-
if self.common_options_enabled:
|
|
123
|
-
kwargs["params"].extend(_common_options())
|
|
124
|
-
super().__init__(*args, **kwargs)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
class GroupBase(InvokeBaseMixin, click.RichGroup):
|
|
128
|
-
"""
|
|
129
|
-
Base class for all commands, that adds common options to all commands if enabled.
|
|
130
|
-
"""
|
|
131
|
-
|
|
132
|
-
common_options_enabled = True
|
|
133
|
-
|
|
134
|
-
def __init__(self, *args, **kwargs):
|
|
135
|
-
if "params" not in kwargs:
|
|
136
|
-
kwargs["params"] = []
|
|
137
|
-
if self.common_options_enabled:
|
|
138
|
-
kwargs["params"].extend(_common_options())
|
|
139
|
-
super().__init__(*args, **kwargs)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
class GroupBaseNoOptions(GroupBase):
|
|
143
|
-
common_options_enabled = False
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def make_click_option_field(o: click.Option) -> Field:
|
|
147
|
-
if o.multiple:
|
|
148
|
-
o.help = click.style("Multiple values allowed.", bold=True) + f"{o.help}"
|
|
149
|
-
return field(default_factory=lambda: o.default, metadata={"click.option": o})
|
|
150
|
-
return field(default=o.default, metadata={"click.option": o})
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def get_option_from_metadata(metadata: MappingProxyType) -> click.Option:
|
|
154
|
-
return metadata["click.option"]
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def key_value_callback(_: Any, param: str, values: List[str]) -> Optional[Dict[str, str]]:
|
|
158
|
-
"""
|
|
159
|
-
Callback for click to parse key-value pairs.
|
|
160
|
-
"""
|
|
161
|
-
if not values:
|
|
162
|
-
return None
|
|
163
|
-
result = {}
|
|
164
|
-
for v in values:
|
|
165
|
-
if "=" not in v:
|
|
166
|
-
raise click.BadParameter(f"Expected key-value pair of the form key=value, got {v}")
|
|
167
|
-
k, v_ = v.split("=", 1)
|
|
168
|
-
result[k.strip()] = v_.strip()
|
|
169
|
-
return result
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
class ObjectsPerFileGroup(GroupBase):
|
|
173
|
-
"""
|
|
174
|
-
Group that creates a command for each object in a python file.
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
-
def __init__(self, filename: Path, *args, **kwargs):
|
|
178
|
-
super().__init__(*args, **kwargs)
|
|
179
|
-
if not filename.exists():
|
|
180
|
-
raise click.ClickException(f"{filename} does not exists")
|
|
181
|
-
self.filename = filename
|
|
182
|
-
self._objs = None
|
|
183
|
-
|
|
184
|
-
@abstractmethod
|
|
185
|
-
def _filter_objects(self, module: ModuleType) -> Dict[str, Any]:
|
|
186
|
-
raise NotImplementedError
|
|
187
|
-
|
|
188
|
-
@property
|
|
189
|
-
def objs(self) -> Dict[str, Any]:
|
|
190
|
-
if self._objs is not None:
|
|
191
|
-
return self._objs
|
|
192
|
-
|
|
193
|
-
module_name = os.path.splitext(os.path.basename(self.filename))[0]
|
|
194
|
-
module_path = os.path.dirname(os.path.abspath(self.filename))
|
|
195
|
-
|
|
196
|
-
spec = importlib.util.spec_from_file_location(module_name, self.filename)
|
|
197
|
-
module = importlib.util.module_from_spec(spec)
|
|
198
|
-
sys.modules[module_name] = module
|
|
199
|
-
|
|
200
|
-
sys.path.append(module_path)
|
|
201
|
-
spec.loader.exec_module(module)
|
|
202
|
-
|
|
203
|
-
self._objs = self._filter_objects(module)
|
|
204
|
-
return self._objs
|
|
205
|
-
|
|
206
|
-
def list_commands(self, ctx):
|
|
207
|
-
m = list(self.objs.keys())
|
|
208
|
-
return sorted(m)
|
|
209
|
-
|
|
210
|
-
@abstractmethod
|
|
211
|
-
def _get_command_for_obj(self, ctx: click.Context, obj_name: str, obj: Any) -> click.Command: ...
|
|
212
|
-
|
|
213
|
-
def get_command(self, ctx, obj_name):
|
|
214
|
-
obj = self.objs[obj_name]
|
|
215
|
-
return self._get_command_for_obj(ctx, obj_name, obj)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
class FileGroup(GroupBase):
|
|
219
|
-
"""
|
|
220
|
-
Group that creates a command for each file in the current directory that is not __init__.py.
|
|
221
|
-
"""
|
|
222
|
-
|
|
223
|
-
common_options_enabled = False
|
|
224
|
-
|
|
225
|
-
def __init__(
|
|
226
|
-
self,
|
|
227
|
-
*args,
|
|
228
|
-
directory: Path | None = None,
|
|
229
|
-
**kwargs,
|
|
230
|
-
):
|
|
231
|
-
if "params" not in kwargs:
|
|
232
|
-
kwargs["params"] = []
|
|
233
|
-
super().__init__(*args, **kwargs)
|
|
234
|
-
self._files = None
|
|
235
|
-
self._dir = directory
|
|
236
|
-
|
|
237
|
-
@property
|
|
238
|
-
def files(self):
|
|
239
|
-
if self._files is None:
|
|
240
|
-
directory = self._dir or Path(".").absolute()
|
|
241
|
-
self._files = [os.fspath(p) for p in directory.glob("*.py") if p.name != "__init__.py"]
|
|
242
|
-
return self._files
|
|
243
|
-
|
|
244
|
-
def list_commands(self, ctx):
|
|
245
|
-
return self.files
|
|
246
|
-
|
|
247
|
-
def get_command(self, ctx, filename):
|
|
248
|
-
raise NotImplementedError
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
def get_table(title: str, vals: Iterable[Any]) -> Table:
|
|
252
|
-
"""
|
|
253
|
-
Get a table from a list of values.
|
|
254
|
-
"""
|
|
255
|
-
table = Table(title=title)
|
|
256
|
-
headers = None
|
|
257
|
-
for p in vals:
|
|
258
|
-
if headers is None:
|
|
259
|
-
headers = [k for k, _ in p.__rich_repr__()]
|
|
260
|
-
for h in headers:
|
|
261
|
-
table.add_column(h.capitalize())
|
|
262
|
-
table.add_row(*[str(v) for _, v in p.__rich_repr__()])
|
|
263
|
-
return table
|