flyte 0.0.1b3__py3-none-any.whl → 0.2.0a0__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.

Files changed (319) hide show
  1. flyte/__init__.py +20 -4
  2. flyte/_bin/runtime.py +33 -7
  3. flyte/_build.py +3 -2
  4. flyte/_cache/cache.py +1 -2
  5. flyte/_code_bundle/_packaging.py +1 -1
  6. flyte/_code_bundle/_utils.py +0 -16
  7. flyte/_code_bundle/bundle.py +43 -12
  8. flyte/_context.py +8 -2
  9. flyte/_deploy.py +56 -15
  10. flyte/_environment.py +45 -4
  11. flyte/_excepthook.py +37 -0
  12. flyte/_group.py +2 -1
  13. flyte/_image.py +8 -4
  14. flyte/_initialize.py +112 -254
  15. flyte/_interface.py +3 -3
  16. flyte/_internal/controllers/__init__.py +19 -6
  17. flyte/_internal/controllers/_local_controller.py +83 -8
  18. flyte/_internal/controllers/_trace.py +2 -1
  19. flyte/_internal/controllers/remote/__init__.py +27 -7
  20. flyte/_internal/controllers/remote/_action.py +7 -2
  21. flyte/_internal/controllers/remote/_client.py +5 -1
  22. flyte/_internal/controllers/remote/_controller.py +159 -26
  23. flyte/_internal/controllers/remote/_core.py +13 -5
  24. flyte/_internal/controllers/remote/_informer.py +4 -4
  25. flyte/_internal/controllers/remote/_service_protocol.py +6 -6
  26. flyte/_internal/imagebuild/docker_builder.py +12 -1
  27. flyte/_internal/imagebuild/image_builder.py +16 -11
  28. flyte/_internal/runtime/convert.py +164 -21
  29. flyte/_internal/runtime/entrypoints.py +1 -1
  30. flyte/_internal/runtime/io.py +3 -3
  31. flyte/_internal/runtime/task_serde.py +140 -20
  32. flyte/_internal/runtime/taskrunner.py +4 -3
  33. flyte/_internal/runtime/types_serde.py +1 -1
  34. flyte/_logging.py +12 -1
  35. flyte/_map.py +215 -0
  36. flyte/_pod.py +19 -0
  37. flyte/_protos/common/list_pb2.py +3 -3
  38. flyte/_protos/common/list_pb2.pyi +2 -0
  39. flyte/_protos/logs/dataplane/payload_pb2.py +28 -24
  40. flyte/_protos/logs/dataplane/payload_pb2.pyi +11 -2
  41. flyte/_protos/workflow/common_pb2.py +27 -0
  42. flyte/_protos/workflow/common_pb2.pyi +14 -0
  43. flyte/_protos/workflow/environment_pb2.py +29 -0
  44. flyte/_protos/workflow/environment_pb2.pyi +12 -0
  45. flyte/_protos/workflow/queue_service_pb2.py +40 -41
  46. flyte/_protos/workflow/queue_service_pb2.pyi +35 -30
  47. flyte/_protos/workflow/queue_service_pb2_grpc.py +15 -15
  48. flyte/_protos/workflow/run_definition_pb2.py +61 -61
  49. flyte/_protos/workflow/run_definition_pb2.pyi +8 -4
  50. flyte/_protos/workflow/run_service_pb2.py +20 -24
  51. flyte/_protos/workflow/run_service_pb2.pyi +2 -6
  52. flyte/_protos/workflow/state_service_pb2.py +36 -28
  53. flyte/_protos/workflow/state_service_pb2.pyi +19 -15
  54. flyte/_protos/workflow/state_service_pb2_grpc.py +28 -28
  55. flyte/_protos/workflow/task_definition_pb2.py +29 -22
  56. flyte/_protos/workflow/task_definition_pb2.pyi +21 -5
  57. flyte/_protos/workflow/task_service_pb2.py +27 -11
  58. flyte/_protos/workflow/task_service_pb2.pyi +29 -1
  59. flyte/_protos/workflow/task_service_pb2_grpc.py +34 -0
  60. flyte/_run.py +166 -95
  61. flyte/_task.py +110 -28
  62. flyte/_task_environment.py +55 -72
  63. flyte/_trace.py +6 -14
  64. flyte/_utils/__init__.py +6 -0
  65. flyte/_utils/async_cache.py +139 -0
  66. flyte/_utils/coro_management.py +0 -2
  67. flyte/_utils/helpers.py +45 -19
  68. flyte/_utils/org_discovery.py +57 -0
  69. flyte/_version.py +2 -2
  70. flyte/cli/__init__.py +3 -0
  71. flyte/cli/_abort.py +28 -0
  72. flyte/{_cli → cli}/_common.py +73 -23
  73. flyte/cli/_create.py +145 -0
  74. flyte/{_cli → cli}/_delete.py +4 -4
  75. flyte/{_cli → cli}/_deploy.py +26 -14
  76. flyte/cli/_gen.py +163 -0
  77. flyte/{_cli → cli}/_get.py +98 -23
  78. {union/_cli → flyte/cli}/_params.py +106 -147
  79. flyte/{_cli → cli}/_run.py +99 -20
  80. flyte/cli/main.py +166 -0
  81. flyte/config/__init__.py +3 -0
  82. flyte/config/_config.py +216 -0
  83. flyte/config/_internal.py +64 -0
  84. flyte/config/_reader.py +207 -0
  85. flyte/errors.py +29 -0
  86. flyte/extras/_container.py +33 -43
  87. flyte/io/__init__.py +17 -1
  88. flyte/io/_dir.py +2 -2
  89. flyte/io/_file.py +3 -4
  90. flyte/io/{structured_dataset → _structured_dataset}/basic_dfs.py +1 -1
  91. flyte/io/{structured_dataset → _structured_dataset}/structured_dataset.py +1 -1
  92. flyte/{_datastructures.py → models.py} +56 -7
  93. flyte/remote/__init__.py +2 -1
  94. flyte/remote/_client/_protocols.py +2 -0
  95. flyte/remote/_client/auth/_auth_utils.py +14 -0
  96. flyte/remote/_client/auth/_channel.py +34 -3
  97. flyte/remote/_client/auth/_token_client.py +3 -3
  98. flyte/remote/_client/controlplane.py +13 -13
  99. flyte/remote/_console.py +1 -1
  100. flyte/remote/_data.py +10 -6
  101. flyte/remote/_logs.py +89 -29
  102. flyte/remote/_project.py +8 -9
  103. flyte/remote/_run.py +228 -131
  104. flyte/remote/_secret.py +12 -12
  105. flyte/remote/_task.py +179 -15
  106. flyte/report/_report.py +4 -4
  107. flyte/storage/__init__.py +5 -0
  108. flyte/storage/_config.py +233 -0
  109. flyte/storage/_storage.py +23 -3
  110. flyte/syncify/__init__.py +56 -0
  111. flyte/syncify/_api.py +371 -0
  112. flyte/types/__init__.py +23 -0
  113. flyte/types/_interface.py +22 -7
  114. flyte/{io/pickle/transformer.py → types/_pickle.py} +2 -1
  115. flyte/types/_type_engine.py +95 -18
  116. flyte-0.2.0a0.dist-info/METADATA +249 -0
  117. flyte-0.2.0a0.dist-info/RECORD +218 -0
  118. {flyte-0.0.1b3.dist-info → flyte-0.2.0a0.dist-info}/entry_points.txt +1 -1
  119. flyte/_api_commons.py +0 -3
  120. flyte/_cli/__init__.py +0 -0
  121. flyte/_cli/_create.py +0 -42
  122. flyte/_cli/main.py +0 -72
  123. flyte/_internal/controllers/pbhash.py +0 -39
  124. flyte/io/_dataframe.py +0 -0
  125. flyte/io/pickle/__init__.py +0 -0
  126. flyte-0.0.1b3.dist-info/METADATA +0 -179
  127. flyte-0.0.1b3.dist-info/RECORD +0 -390
  128. union/__init__.py +0 -54
  129. union/_api_commons.py +0 -3
  130. union/_bin/__init__.py +0 -0
  131. union/_bin/runtime.py +0 -113
  132. union/_build.py +0 -25
  133. union/_cache/__init__.py +0 -12
  134. union/_cache/cache.py +0 -141
  135. union/_cache/defaults.py +0 -9
  136. union/_cache/policy_function_body.py +0 -42
  137. union/_cli/__init__.py +0 -0
  138. union/_cli/_common.py +0 -263
  139. union/_cli/_create.py +0 -40
  140. union/_cli/_delete.py +0 -23
  141. union/_cli/_deploy.py +0 -120
  142. union/_cli/_get.py +0 -162
  143. union/_cli/_run.py +0 -150
  144. union/_cli/main.py +0 -72
  145. union/_code_bundle/__init__.py +0 -8
  146. union/_code_bundle/_ignore.py +0 -113
  147. union/_code_bundle/_packaging.py +0 -187
  148. union/_code_bundle/_utils.py +0 -342
  149. union/_code_bundle/bundle.py +0 -176
  150. union/_context.py +0 -146
  151. union/_datastructures.py +0 -295
  152. union/_deploy.py +0 -185
  153. union/_doc.py +0 -29
  154. union/_docstring.py +0 -26
  155. union/_environment.py +0 -43
  156. union/_group.py +0 -31
  157. union/_hash.py +0 -23
  158. union/_image.py +0 -760
  159. union/_initialize.py +0 -585
  160. union/_interface.py +0 -84
  161. union/_internal/__init__.py +0 -3
  162. union/_internal/controllers/__init__.py +0 -77
  163. union/_internal/controllers/_local_controller.py +0 -77
  164. union/_internal/controllers/pbhash.py +0 -39
  165. union/_internal/controllers/remote/__init__.py +0 -40
  166. union/_internal/controllers/remote/_action.py +0 -131
  167. union/_internal/controllers/remote/_client.py +0 -43
  168. union/_internal/controllers/remote/_controller.py +0 -169
  169. union/_internal/controllers/remote/_core.py +0 -341
  170. union/_internal/controllers/remote/_informer.py +0 -260
  171. union/_internal/controllers/remote/_service_protocol.py +0 -44
  172. union/_internal/imagebuild/__init__.py +0 -11
  173. union/_internal/imagebuild/docker_builder.py +0 -416
  174. union/_internal/imagebuild/image_builder.py +0 -243
  175. union/_internal/imagebuild/remote_builder.py +0 -0
  176. union/_internal/resolvers/__init__.py +0 -0
  177. union/_internal/resolvers/_task_module.py +0 -31
  178. union/_internal/resolvers/common.py +0 -24
  179. union/_internal/resolvers/default.py +0 -27
  180. union/_internal/runtime/__init__.py +0 -0
  181. union/_internal/runtime/convert.py +0 -163
  182. union/_internal/runtime/entrypoints.py +0 -121
  183. union/_internal/runtime/io.py +0 -136
  184. union/_internal/runtime/resources_serde.py +0 -134
  185. union/_internal/runtime/task_serde.py +0 -202
  186. union/_internal/runtime/taskrunner.py +0 -179
  187. union/_internal/runtime/types_serde.py +0 -53
  188. union/_logging.py +0 -124
  189. union/_protos/__init__.py +0 -0
  190. union/_protos/common/authorization_pb2.py +0 -66
  191. union/_protos/common/authorization_pb2.pyi +0 -106
  192. union/_protos/common/identifier_pb2.py +0 -71
  193. union/_protos/common/identifier_pb2.pyi +0 -82
  194. union/_protos/common/identity_pb2.py +0 -48
  195. union/_protos/common/identity_pb2.pyi +0 -72
  196. union/_protos/common/identity_pb2_grpc.py +0 -4
  197. union/_protos/common/list_pb2.py +0 -36
  198. union/_protos/common/list_pb2.pyi +0 -69
  199. union/_protos/common/list_pb2_grpc.py +0 -4
  200. union/_protos/common/policy_pb2.py +0 -37
  201. union/_protos/common/policy_pb2.pyi +0 -27
  202. union/_protos/common/policy_pb2_grpc.py +0 -4
  203. union/_protos/common/role_pb2.py +0 -37
  204. union/_protos/common/role_pb2.pyi +0 -51
  205. union/_protos/common/role_pb2_grpc.py +0 -4
  206. union/_protos/common/runtime_version_pb2.py +0 -28
  207. union/_protos/common/runtime_version_pb2.pyi +0 -24
  208. union/_protos/common/runtime_version_pb2_grpc.py +0 -4
  209. union/_protos/logs/dataplane/payload_pb2.py +0 -96
  210. union/_protos/logs/dataplane/payload_pb2.pyi +0 -168
  211. union/_protos/logs/dataplane/payload_pb2_grpc.py +0 -4
  212. union/_protos/secret/definition_pb2.py +0 -49
  213. union/_protos/secret/definition_pb2.pyi +0 -93
  214. union/_protos/secret/definition_pb2_grpc.py +0 -4
  215. union/_protos/secret/payload_pb2.py +0 -62
  216. union/_protos/secret/payload_pb2.pyi +0 -94
  217. union/_protos/secret/payload_pb2_grpc.py +0 -4
  218. union/_protos/secret/secret_pb2.py +0 -38
  219. union/_protos/secret/secret_pb2.pyi +0 -6
  220. union/_protos/secret/secret_pb2_grpc.py +0 -198
  221. union/_protos/validate/validate/validate_pb2.py +0 -76
  222. union/_protos/workflow/node_execution_service_pb2.py +0 -26
  223. union/_protos/workflow/node_execution_service_pb2.pyi +0 -4
  224. union/_protos/workflow/node_execution_service_pb2_grpc.py +0 -32
  225. union/_protos/workflow/queue_service_pb2.py +0 -75
  226. union/_protos/workflow/queue_service_pb2.pyi +0 -103
  227. union/_protos/workflow/queue_service_pb2_grpc.py +0 -172
  228. union/_protos/workflow/run_definition_pb2.py +0 -100
  229. union/_protos/workflow/run_definition_pb2.pyi +0 -256
  230. union/_protos/workflow/run_definition_pb2_grpc.py +0 -4
  231. union/_protos/workflow/run_logs_service_pb2.py +0 -41
  232. union/_protos/workflow/run_logs_service_pb2.pyi +0 -28
  233. union/_protos/workflow/run_logs_service_pb2_grpc.py +0 -69
  234. union/_protos/workflow/run_service_pb2.py +0 -133
  235. union/_protos/workflow/run_service_pb2.pyi +0 -173
  236. union/_protos/workflow/run_service_pb2_grpc.py +0 -412
  237. union/_protos/workflow/state_service_pb2.py +0 -58
  238. union/_protos/workflow/state_service_pb2.pyi +0 -69
  239. union/_protos/workflow/state_service_pb2_grpc.py +0 -138
  240. union/_protos/workflow/task_definition_pb2.py +0 -72
  241. union/_protos/workflow/task_definition_pb2.pyi +0 -65
  242. union/_protos/workflow/task_definition_pb2_grpc.py +0 -4
  243. union/_protos/workflow/task_service_pb2.py +0 -44
  244. union/_protos/workflow/task_service_pb2.pyi +0 -31
  245. union/_protos/workflow/task_service_pb2_grpc.py +0 -104
  246. union/_resources.py +0 -226
  247. union/_retry.py +0 -32
  248. union/_reusable_environment.py +0 -25
  249. union/_run.py +0 -374
  250. union/_secret.py +0 -61
  251. union/_task.py +0 -354
  252. union/_task_environment.py +0 -186
  253. union/_timeout.py +0 -47
  254. union/_tools.py +0 -27
  255. union/_utils/__init__.py +0 -11
  256. union/_utils/asyn.py +0 -119
  257. union/_utils/file_handling.py +0 -71
  258. union/_utils/helpers.py +0 -46
  259. union/_utils/lazy_module.py +0 -54
  260. union/_utils/uv_script_parser.py +0 -49
  261. union/_version.py +0 -21
  262. union/connectors/__init__.py +0 -0
  263. union/errors.py +0 -128
  264. union/extras/__init__.py +0 -5
  265. union/extras/_container.py +0 -263
  266. union/io/__init__.py +0 -11
  267. union/io/_dataframe.py +0 -0
  268. union/io/_dir.py +0 -425
  269. union/io/_file.py +0 -418
  270. union/io/pickle/__init__.py +0 -0
  271. union/io/pickle/transformer.py +0 -117
  272. union/io/structured_dataset/__init__.py +0 -122
  273. union/io/structured_dataset/basic_dfs.py +0 -219
  274. union/io/structured_dataset/structured_dataset.py +0 -1057
  275. union/py.typed +0 -0
  276. union/remote/__init__.py +0 -23
  277. union/remote/_client/__init__.py +0 -0
  278. union/remote/_client/_protocols.py +0 -129
  279. union/remote/_client/auth/__init__.py +0 -12
  280. union/remote/_client/auth/_authenticators/__init__.py +0 -0
  281. union/remote/_client/auth/_authenticators/base.py +0 -391
  282. union/remote/_client/auth/_authenticators/client_credentials.py +0 -73
  283. union/remote/_client/auth/_authenticators/device_code.py +0 -120
  284. union/remote/_client/auth/_authenticators/external_command.py +0 -77
  285. union/remote/_client/auth/_authenticators/factory.py +0 -200
  286. union/remote/_client/auth/_authenticators/pkce.py +0 -515
  287. union/remote/_client/auth/_channel.py +0 -184
  288. union/remote/_client/auth/_client_config.py +0 -83
  289. union/remote/_client/auth/_default_html.py +0 -32
  290. union/remote/_client/auth/_grpc_utils/__init__.py +0 -0
  291. union/remote/_client/auth/_grpc_utils/auth_interceptor.py +0 -204
  292. union/remote/_client/auth/_grpc_utils/default_metadata_interceptor.py +0 -144
  293. union/remote/_client/auth/_keyring.py +0 -154
  294. union/remote/_client/auth/_token_client.py +0 -258
  295. union/remote/_client/auth/errors.py +0 -16
  296. union/remote/_client/controlplane.py +0 -86
  297. union/remote/_data.py +0 -149
  298. union/remote/_logs.py +0 -74
  299. union/remote/_project.py +0 -86
  300. union/remote/_run.py +0 -820
  301. union/remote/_secret.py +0 -132
  302. union/remote/_task.py +0 -193
  303. union/report/__init__.py +0 -3
  304. union/report/_report.py +0 -178
  305. union/report/_template.html +0 -124
  306. union/storage/__init__.py +0 -24
  307. union/storage/_remote_fs.py +0 -34
  308. union/storage/_storage.py +0 -247
  309. union/storage/_utils.py +0 -5
  310. union/types/__init__.py +0 -11
  311. union/types/_renderer.py +0 -162
  312. union/types/_string_literals.py +0 -120
  313. union/types/_type_engine.py +0 -2131
  314. union/types/_utils.py +0 -80
  315. /union/_protos/common/authorization_pb2_grpc.py → /flyte/_protos/workflow/common_pb2_grpc.py +0 -0
  316. /union/_protos/common/identifier_pb2_grpc.py → /flyte/_protos/workflow/environment_pb2_grpc.py +0 -0
  317. /flyte/io/{structured_dataset → _structured_dataset}/__init__.py +0 -0
  318. {flyte-0.0.1b3.dist-info → flyte-0.2.0a0.dist-info}/WHEEL +0 -0
  319. {flyte-0.0.1b3.dist-info → flyte-0.2.0a0.dist-info}/top_level.txt +0 -0
union/_secret.py DELETED
@@ -1,61 +0,0 @@
1
- import pathlib
2
- import re
3
- from dataclasses import dataclass
4
- from typing import List, Optional, Union
5
-
6
-
7
- @dataclass
8
- class Secret:
9
- """
10
- Secrets are used to inject sensitive information into tasks. Secrets can be mounted as environment variables or
11
- files. The secret key is the name of the secret in the secret store. The group is optional and maybe used with some
12
- secret stores to organize secrets. The secret_mount is used to specify how the secret should be mounted. If the
13
- secret_mount is set to "env" the secret will be mounted as an environment variable. If the secret_mount is set to
14
- "file" the secret will be mounted as a file. The as_env_var is an optional parameter that can be used to specify the
15
- name of the environment variable that the secret should be mounted as.
16
-
17
- Example:
18
- ```python
19
- @task(secrets="MY_SECRET")
20
- async def my_task():
21
- os.environ["MY_SECRET"] # This will be set to the value of the secret
22
-
23
- @task(secrets=Secret("MY_SECRET", mount="/path/to/secret"))
24
- async def my_task2():
25
- async with open("/path/to/secret") as f:
26
- secret_value = f.read()
27
- ```
28
-
29
- TODO: Add support for secret versioning (some stores) and secret groups (some stores) and mounting as files.
30
-
31
- :param key: The name of the secret in the secret store.
32
- :param group: The group of the secret in the secret store.
33
- :param mount: Use this to specify the path where the secret should be mounted.
34
- :param as_env_var: The name of the environment variable that the secret should be mounted as.
35
- """
36
-
37
- key: str
38
- group: Optional[str] = None
39
- mount: pathlib.Path | None = None
40
- as_env_var: Optional[str] = None
41
-
42
- def __post_init__(self):
43
- if self.as_env_var is not None:
44
- pattern = r"^[A-Z_][A-Z0-9_]*$"
45
- if not re.match(pattern, self.as_env_var):
46
- raise ValueError(f"Invalid environment variable name: {self.as_env_var}, must match {pattern}")
47
-
48
-
49
- SecretRequest = Union[str, Secret, List[str | Secret]]
50
-
51
-
52
- def secrets_from_request(secrets: SecretRequest) -> List[Secret]:
53
- """
54
- Converts a secret request into a list of secrets.
55
- """
56
- if isinstance(secrets, str):
57
- return [Secret(key=secrets)]
58
- elif isinstance(secrets, Secret):
59
- return [secrets]
60
- else:
61
- return [Secret(key=s) if isinstance(s, str) else s for s in secrets]
union/_task.py DELETED
@@ -1,354 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import inspect
4
- import weakref
5
- from dataclasses import dataclass, field
6
- from functools import cached_property
7
- from typing import TYPE_CHECKING, Any, Callable, Dict, Generic, List, Literal, Optional, ParamSpec, TypeVar, Union
8
-
9
- from flyteidl.core.tasks_pb2 import DataLoadingConfig
10
-
11
- from ._cache import Cache, CacheRequest
12
- from ._context import internal_ctx
13
- from ._datastructures import NativeInterface, SerializationContext
14
- from ._doc import Documentation
15
- from ._image import Image
16
- from ._resources import Resources
17
- from ._retry import RetryStrategy
18
- from ._reusable_environment import ReusePolicy
19
- from ._secret import SecretRequest
20
- from ._timeout import TimeoutType
21
- from .errors import RuntimeUserError
22
-
23
- if TYPE_CHECKING:
24
- from kubernetes.client import V1PodTemplate
25
-
26
- from ._task_environment import TaskEnvironment
27
-
28
- P = ParamSpec("P") # capture the function's parameters
29
- R = TypeVar("R") # return type
30
-
31
-
32
- @dataclass(kw_only=True)
33
- class TaskTemplate(Generic[P, R]):
34
- """
35
- Task template is a template for a task that can be executed. It defines various parameters for the task, which
36
- can be defined statically at the time of task definition or dynamically at the time of task invocation using
37
- the override method.
38
-
39
- Example usage:
40
- ```python
41
- @task(name="my_task", image="my_image", resources=Resources(cpu="1", memory="1Gi"))
42
- def my_task():
43
- pass
44
- ```
45
-
46
- :param name: Optional The name of the task (defaults to the function name)
47
- :param task_type: Router type for the task, this is used to determine how the task will be executed.
48
- This is usually set to match with th execution plugin.
49
- :param image: Optional The image to use for the task, if set to "auto" will use the default image for the python
50
- version with union installed
51
- :param resources: Optional The resources to use for the task
52
- :param cache: Optional The cache policy for the task, defaults to auto, which will cache the results of the task.
53
- :param interruptable: Optional The interruptable policy for the task, defaults to False, which means the task
54
- will not be scheduled on interruptable nodes. If set to True, the task will be scheduled on interruptable nodes,
55
- and the code should handle interruptions and resumptions.
56
- :param retries: Optional The number of retries for the task, defaults to 0, which means no retries.
57
- :param reusable: Optional The reusability policy for the task, defaults to None, which means the task environment
58
- will not be reused across task invocations.
59
- :param docs: Optional The documentation for the task, if not provided the function docstring will be used.
60
- :param env: Optional The environment variables to set for the task.
61
- :param secrets: Optional The secrets that will be injected into the task at runtime.
62
- :param timeout: Optional The timeout for the task.
63
- """
64
-
65
- name: str
66
- task_type: str = "python"
67
- task_type_version: int = 0
68
- image: Union[str, Image, Literal["auto"]] = "auto"
69
- resources: Optional[Resources] = None
70
- cache: CacheRequest = "auto"
71
- interruptable: bool = False
72
- retries: Union[int, RetryStrategy] = 0
73
- reusable: Union[ReusePolicy, Literal["auto"], None] = (None,)
74
- docs: Optional[Documentation] = None
75
- env: Optional[Dict[str, str]] = None
76
- secrets: Optional[SecretRequest] = None
77
- timeout: Optional[TimeoutType] = None
78
- primary_container_name: str = "primary"
79
- pod_template: Optional[Union[str, V1PodTemplate]] = None
80
- interface: Optional[NativeInterface] = None
81
-
82
- parent_env: Optional[weakref.ReferenceType[TaskEnvironment]] = None
83
- local: bool = field(default=False, init=False)
84
- ref: bool = field(default=False, init=False, repr=False, compare=False)
85
-
86
- def __post_init__(self):
87
- # If pod_template is set to a pod, verify
88
- if self.pod_template is not None and not isinstance(self.pod_template, str):
89
- try:
90
- from kubernetes.client import V1PodTemplate # noqa: F401
91
- except ImportError as e:
92
- raise ImportError(
93
- "kubernetes is not installed, please install kubernetes package to use pod_template"
94
- ) from e
95
-
96
- # Auto set the image based on the image request
97
- if self.image == "auto":
98
- self.image = Image.auto()
99
- elif isinstance(self.image, str):
100
- self.image = Image.from_prebuilt(str(self.image))
101
-
102
- # Auto set cache based on the cache request
103
- if isinstance(self.cache, str):
104
- match self.cache:
105
- case "auto":
106
- self.cache = Cache(behavior="auto")
107
- case "override":
108
- self.cache = Cache(behavior="override")
109
- case "disable":
110
- self.cache = Cache(behavior="disable")
111
-
112
- # if retries is set to int, convert to RetryStrategy
113
- if isinstance(self.retries, int):
114
- self.retries = RetryStrategy(count=self.retries)
115
-
116
- def __getstate__(self):
117
- """
118
- This method is called when the object is pickled. We need to remove the parent_env reference
119
- to avoid circular references.
120
- """
121
- state = self.__dict__.copy()
122
- state.pop("parent_env", None)
123
- return state
124
-
125
- def __setstate__(self, state):
126
- """
127
- This method is called when the object is unpickled. We need to set the parent_env reference
128
- to the environment that created the task.
129
- """
130
- self.__dict__.update(state)
131
- self.parent_env = None
132
-
133
- def clone(self) -> TaskTemplate:
134
- import copy
135
-
136
- return copy.deepcopy(self)
137
-
138
- async def pre(self, *args, **kwargs) -> Dict[str, Any]:
139
- """
140
- This is the preexecute function that will be
141
- called before the task is executed
142
- """
143
- return {}
144
-
145
- async def execute(self, *args, **kwargs) -> Any:
146
- """
147
- This is the pure python function that will be executed when the task is called.
148
- """
149
- raise NotImplementedError
150
-
151
- async def post(self, return_vals: Any) -> Any:
152
- """
153
- This is the postexecute function that will be
154
- called after the task is executed
155
- """
156
- return return_vals
157
-
158
- # ---- Extension points ----
159
- def config(self, sctx: SerializationContext) -> Dict[str, str]:
160
- """
161
- Returns additional configuration for the task. This is a set of key-value pairs that can be used to
162
- configure the task execution environment at runtime. This is usually used by plugins.
163
- """
164
- return {}
165
-
166
- def custom_config(self, sctx: SerializationContext) -> Dict[str, str]:
167
- """
168
- Returns additional configuration for the task. This is a set of key-value pairs that can be used to
169
- configure the task execution environment at runtime. This is usually used by plugins.
170
- """
171
- return {}
172
-
173
- def data_loading_config(self, sctx: SerializationContext) -> DataLoadingConfig:
174
- """
175
- This configuration allows executing raw containers in Flyte using the Flyte CoPilot system
176
- Flyte CoPilot, eliminates the needs of sdk inside the container. Any inputs required by the users container
177
- are side-loaded in the input_path
178
- Any outputs generated by the user container - within output_path are automatically uploaded
179
- """
180
-
181
- def container_args(self, sctx: SerializationContext) -> List[str]:
182
- """
183
- Returns the container args for the task. This is a set of key-value pairs that can be used to
184
- configure the task execution environment at runtime. This is usually used by plugins.
185
- """
186
- return []
187
-
188
- def sql(self, sctx: SerializationContext) -> Optional[str]:
189
- """
190
- Returns the SQL for the task. This is a set of key-value pairs that can be used to
191
- configure the task execution environment at runtime. This is usually used by plugins.
192
- """
193
- return None
194
-
195
- # ---- Extension points ----
196
-
197
- @property
198
- def native_interface(self) -> NativeInterface:
199
- return self.interface
200
-
201
- async def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
202
- """
203
- This is the entrypoint for an async function task at runtime. It will be called during an execution.
204
- Please do not override this method, if you simply want to modify the execution behavior, override the
205
- execute method.
206
-
207
- # TODO lets provide one hook to implement, _pre, _execute and _post. We do not want actual execute to
208
- """
209
- try:
210
- ctx = internal_ctx()
211
- if ctx.data.task_context:
212
- # If we are in a task context, that implies we are executing a Run.
213
- # In this scenario, we should submit the task to the controller.
214
- # We will also check if we are not initialized, It is not expected to be not initialized
215
- from ._internal.controllers import get_controller
216
-
217
- controller = await get_controller()
218
- if controller:
219
- return await controller.submit(self, *args, **kwargs)
220
- if inspect.iscoroutinefunction(self.execute):
221
- return await self.execute(*args, **kwargs)
222
- return self.execute(*args, **kwargs)
223
- except RuntimeUserError:
224
- raise
225
- except Exception as e:
226
- raise RuntimeUserError(type(e).__name__, str(e)) from e
227
-
228
- def override(
229
- self,
230
- *,
231
- local: Optional[bool] = None,
232
- ref: Optional[bool] = None,
233
- resources: Optional[Resources] = None,
234
- cache: CacheRequest = "auto",
235
- retries: Union[int, RetryStrategy] = 0,
236
- timeout: Optional[TimeoutType] = None,
237
- reusable: Union[ReusePolicy, Literal["auto"], None] = None,
238
- env: Optional[Dict[str, str]] = None,
239
- secrets: Optional[SecretRequest] = None,
240
- **kwargs: Any,
241
- ) -> TaskTemplate:
242
- """
243
- Override various parameters of the task template. This allows for dynamic configuration of the task
244
- when it is called, such as changing the image, resources, cache policy, etc.
245
- """
246
- c = self.clone()
247
- c.resources = resources or self.resources
248
- c.cache = cache or self.cache
249
- c.retries = retries or self.retries
250
- c.timeout = timeout or self.timeout
251
- c.reusable = reusable or self.reusable
252
- c.env = env or self.env
253
- c.secrets = secrets or self.secrets
254
- c.local = local or self.local
255
- c.ref = ref or self.ref
256
- for k, v in kwargs.items():
257
- if k == "name":
258
- raise ValueError("Name cannot be overridden")
259
- if k == "image":
260
- raise ValueError("Image cannot be overridden")
261
- if k == "docs":
262
- raise ValueError("Docs cannot be overridden")
263
- if k == "interface":
264
- raise ValueError("Interface cannot be overridden")
265
- if hasattr(c, k):
266
- setattr(c, k, v)
267
- return c
268
-
269
-
270
- @dataclass(kw_only=True)
271
- class AsyncFunctionTaskTemplate(TaskTemplate[P, R]):
272
- """
273
- A task template that wraps an asynchronous functions. This is automatically created when an asynchronous function
274
- is decorated with the task decorator.
275
- """
276
-
277
- func: Callable[P, R]
278
-
279
- @cached_property
280
- def native_interface(self) -> NativeInterface:
281
- return NativeInterface.from_callable(self.func)
282
-
283
- async def execute(self, *args: P.args, **kwargs: P.kwargs) -> R:
284
- """
285
- This is the execute method that will be called when the task is invoked. It will call the actual function.
286
- # TODO We may need to keep this as the bare func execute, and need a pre and post execute some other func.
287
- """
288
- ctx = internal_ctx()
289
- ctx_data = await self.pre(*args, **kwargs)
290
- if ctx.data.task_context is not None:
291
- tctx = ctx.data.task_context.replace(data=ctx_data)
292
- with ctx.replace_task_context(tctx):
293
- v = await self.func(*args, **kwargs)
294
- await self.post(v)
295
- else:
296
- v = await self.func(*args, **kwargs)
297
- await self.post(v)
298
- return v
299
-
300
- def container_args(self, serialize_context: SerializationContext) -> List[str]:
301
- args = [
302
- "urun",
303
- "--org", # todo remove this
304
- "testorg", # todo remove this
305
- "--inputs",
306
- serialize_context.input_path,
307
- "--outputs-path",
308
- serialize_context.output_path,
309
- "--version",
310
- serialize_context.version, # pr: should this be serialize_context.version or code_bundle.version?
311
- "--raw-data-path",
312
- "{{.rawOutputDataPrefix}}",
313
- "--checkpoint-path",
314
- "{{.checkpointOutputPrefix}}",
315
- "--prev-checkpoint",
316
- "{{.prevCheckpointPrefix}}",
317
- "--run-name",
318
- "{{.runName}}",
319
- "--name",
320
- "{{.actionName}}",
321
- ]
322
- # Add on all the known images
323
- if serialize_context.image_cache and serialize_context.image_cache.serialized_form:
324
- args = [*args, "--image-cache", serialize_context.image_cache.serialized_form]
325
- else:
326
- if serialize_context.image_cache:
327
- args = [*args, "--image-cache", serialize_context.image_cache.to_transport]
328
-
329
- if serialize_context.code_bundle:
330
- if serialize_context.code_bundle.tgz:
331
- args = [*args, *["--tgz", f"{serialize_context.code_bundle.tgz}"]]
332
- elif serialize_context.code_bundle.pkl:
333
- args = [*args, *["--pkl", f"{serialize_context.code_bundle.pkl}"]]
334
- args = [*args, *["--dest", f"{serialize_context.code_bundle.destination or '.'}"]]
335
-
336
- if not serialize_context.code_bundle or not serialize_context.code_bundle.pkl:
337
- # If we do not have a code bundle, or if we have one, but it is not a pkl, we need to add the resolver
338
-
339
- from union._internal.resolvers.default import DefaultTaskResolver
340
-
341
- _task_resolver = DefaultTaskResolver()
342
- args = [
343
- *args,
344
- *[
345
- "--resolver",
346
- # pr: how do we determine which task resolver to use?
347
- _task_resolver.import_path,
348
- *_task_resolver.loader_args(task=self),
349
- ],
350
- ]
351
-
352
- assert all(isinstance(item, str) for item in args), f"All args should be strings, non string item = {args}"
353
-
354
- return args
@@ -1,186 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- import weakref
5
- from dataclasses import dataclass, field, replace
6
- from datetime import timedelta
7
- from functools import wraps
8
- from typing import TYPE_CHECKING, Callable, Dict, List, Literal, Optional, ParamSpec, TypeVar, Union
9
-
10
- import rich.repr
11
-
12
- from ._cache import CacheRequest
13
- from ._doc import Documentation
14
- from ._environment import Environment
15
- from ._image import Image
16
- from ._resources import Resources
17
- from ._retry import RetryStrategy
18
- from ._reusable_environment import ReusePolicy
19
- from ._secret import SecretRequest
20
- from ._task import AsyncFunctionTaskTemplate, TaskTemplate
21
-
22
- if TYPE_CHECKING:
23
- from kubernetes.client import V1PodTemplate
24
-
25
- P = ParamSpec("P") # capture the function's parameters
26
- R = TypeVar("R") # return type
27
-
28
-
29
- @rich.repr.auto
30
- @dataclass(init=True, repr=True)
31
- class TaskEnvironment(Environment):
32
- """
33
- Environment class to define a new environment for a set of tasks.
34
-
35
- Example usage:
36
- ```python
37
- env = union.TaskEnvironment(name="my_env", image="my_image", resources=Resources(cpu="1", memory="1Gi"))
38
-
39
- @env.task
40
- async def my_task():
41
- pass
42
- ```
43
-
44
- :param name: Name of the environment
45
- :param image: Docker image to use for the environment. If set to "auto", will use the default image.
46
- :param resources: Resources to allocate for the environment.
47
- :param env: Environment variables to set for the environment.
48
- :param secrets: Secrets to inject into the environment.
49
- :param env_dep_hints: Environment dependencies to hint, so when you deploy the environment, the dependencies are
50
- also deployed. This is useful when you have a set of environments that depend on each other.
51
- :param cache: Cache policy for the environment.
52
- :param reusable: Reuse policy for the environment, if set, a python process may be reused for multiple tasks.
53
- """
54
-
55
- cache: Union[CacheRequest] = "auto"
56
- reusable: Union[ReusePolicy, Literal["auto"], None] = None
57
- # TODO Shall we make this union of string or env? This way we can lookup the env by module/file:name
58
- # TODO also we could add list of files that are used by this environment
59
-
60
- _tasks: Dict[str, TaskTemplate] = field(default_factory=dict, init=False)
61
-
62
- def clone_with(
63
- self,
64
- name: str,
65
- image: Optional[Union[str, Image, Literal["auto"]]] = None,
66
- resources: Optional[Resources] = None,
67
- cache: Union[CacheRequest, None] = None,
68
- env: Optional[Dict[str, str]] = None,
69
- reusable: Union[ReusePolicy, None] = None,
70
- secrets: Optional[SecretRequest] = None,
71
- env_dep_hints: Optional[List[TaskEnvironment]] = None,
72
- ) -> TaskEnvironment:
73
- """
74
- Clone the environment with new settings.
75
- """
76
- if image is None:
77
- image = self.image
78
- else:
79
- image = "auto"
80
- return replace(
81
- self,
82
- cache=cache,
83
- reusable=reusable,
84
- name=name,
85
- image=image,
86
- resources=resources,
87
- env=env,
88
- secrets=secrets,
89
- env_dep_hints=env_dep_hints,
90
- )
91
-
92
- def _task(
93
- self,
94
- _func=None,
95
- *,
96
- name: Optional[str] = None,
97
- cache: Union[CacheRequest] | None = None,
98
- retries: Union[int, RetryStrategy] = 0,
99
- timeout: Union[timedelta, int] = 0,
100
- docs: Optional[Documentation] = None,
101
- secrets: Optional[SecretRequest] = None,
102
- pod_template: Optional[Union[str, "V1PodTemplate"]] = None,
103
- ) -> Union[AsyncFunctionTaskTemplate, Callable[P, R]]:
104
- """
105
- :param name: Optional The name of the task (defaults to the function name)
106
- :param cache: Optional The cache policy for the task, defaults to auto, which will cache the results of the
107
- task.
108
- :param retries: Optional The number of retries for the task, defaults to 0, which means no retries.
109
- :param docs: Optional The documentation for the task, if not provided the function docstring will be used.
110
- :param secrets: Optional The secrets that will be injected into the task at runtime.
111
- :param timeout: Optional The timeout for the task.
112
- """
113
- if self.reusable is not None:
114
- if pod_template is not None:
115
- raise ValueError("Cannot set pod_template when environment is reusable.")
116
-
117
- def decorator(func: Callable[P, R]) -> AsyncFunctionTaskTemplate:
118
- task_name = name or func.__name__
119
-
120
- @wraps(func)
121
- async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
122
- return await func(*args, **kwargs)
123
-
124
- if not asyncio.iscoroutinefunction(func):
125
- raise TypeError(
126
- f"Function {func.__name__} is not a coroutine function. Use @env.task decorator for async tasks."
127
- f"You can simply mark your function as async def {func.__name__} to make it a coroutine function, "
128
- f"it is ok to write sync code in async functions, but not the other way around."
129
- )
130
- tmpl = AsyncFunctionTaskTemplate(
131
- func=wrapper,
132
- name=task_name,
133
- image=self.image,
134
- resources=self.resources,
135
- cache=cache or self.cache,
136
- retries=retries,
137
- timeout=timeout,
138
- reusable=self.reusable,
139
- docs=docs,
140
- env=self.env,
141
- secrets=secrets or self.secrets,
142
- pod_template=pod_template or self.pod_template,
143
- parent_env=weakref.ref(self),
144
- )
145
- self._tasks[task_name] = tmpl
146
- return tmpl
147
-
148
- if _func is None:
149
- return decorator
150
- return decorator(_func)
151
-
152
- @property
153
- def task(self) -> Union[AsyncFunctionTaskTemplate, Callable[P, R]]:
154
- """
155
- Decorator to create a new task with the environment settings.
156
- The task will be executed in its own container with the specified image, resources, and environment variables,
157
- unless reusePolicy is set, in which case the same container will be reused for all tasks with the same
158
- environment settings.
159
-
160
- :param name: Optional The name of the task (defaults to the function name)
161
- :param cache: Optional The cache policy for the task, defaults to auto, which will cache the results of the
162
- task.
163
- :param retries: Optional The number of retries for the task, defaults to 0, which means no retries.
164
- :param docs: Optional The documentation for the task, if not provided the function docstring will be used.
165
- :param secrets: Optional The secrets that will be injected into the task at runtime.
166
- :param timeout: Optional The timeout for the task.
167
-
168
- :return: New Task instance or Task decorator
169
- """
170
- return self._task
171
-
172
- @property
173
- def tasks(self) -> Dict[str, TaskTemplate]:
174
- """
175
- Get all tasks defined in the environment.
176
- """
177
- return self._tasks
178
-
179
- def add_task(self, task: TaskTemplate) -> TaskTemplate:
180
- """
181
- Add a task to the environment.
182
- """
183
- if task.name in self._tasks:
184
- raise ValueError(f"Task {task.name} already exists in the environment. Task names should be unique.")
185
- self._tasks[task.name] = task
186
- return task
union/_timeout.py DELETED
@@ -1,47 +0,0 @@
1
- from dataclasses import dataclass
2
- from datetime import timedelta
3
-
4
-
5
- @dataclass
6
- class Timeout:
7
- """
8
- Timeout class to define a timeout for a task.
9
- The task timeout can be set to a maximum runtime and a maximum queued time.
10
- Maximum runtime is the maximum time the task can run for (in one attempt).
11
- Maximum queued time is the maximum time the task can stay in the queue before it starts executing.
12
-
13
- Example usage:
14
- ```python
15
- timeout = Timeout(max_runtime=timedelta(minutes=5), max_queued_time=timedelta(minutes=10))
16
- @env.task(timeout=timeout)
17
- async def my_task():
18
- pass
19
- ```
20
- :param max_runtime: timedelta or int - Maximum runtime for the task. If specified int, it will be converted to
21
- timedelta as seconds.
22
- :param max_queued_time: optional, timedelta or int - Maximum queued time for the task. If specified int,
23
- it will be converted to timedelta as seconds. Defaults to None.
24
-
25
- """
26
-
27
- max_runtime: timedelta | int
28
- max_queued_time: timedelta | int | None = None
29
-
30
-
31
- TimeoutType = Timeout | int | timedelta
32
-
33
-
34
- def timeout_from_request(timeout: TimeoutType) -> Timeout:
35
- """
36
- Converts a timeout request into a Timeout object.
37
- """
38
- if isinstance(timeout, Timeout):
39
- return timeout
40
- else:
41
- if isinstance(timeout, int):
42
- timeout = timedelta(seconds=timeout)
43
- elif isinstance(timeout, timedelta):
44
- pass
45
- else:
46
- raise ValueError("Timeout must be an instance of Timeout, int, or timedelta.")
47
- return Timeout(max_runtime=timeout)
union/_tools.py DELETED
@@ -1,27 +0,0 @@
1
- import os
2
-
3
-
4
- def ipython_check() -> bool:
5
- """
6
- Check if interface is launching from iPython (not colab)
7
- :return is_ipython (bool): True or False
8
- """
9
- is_ipython = False
10
- try: # Check if running interactively using ipython.
11
- from IPython import get_ipython
12
-
13
- if get_ipython() is not None:
14
- is_ipython = True
15
- except (ImportError, NameError):
16
- pass
17
- return is_ipython
18
-
19
-
20
- def is_in_cluster() -> bool:
21
- """
22
- Check if the task is running in a cluster
23
- :return is_in_cluster (bool): True or False
24
- """
25
- if os.getenv("_UN_CLS"):
26
- return True
27
- return False
union/_utils/__init__.py DELETED
@@ -1,11 +0,0 @@
1
- """
2
- Internal utility functions.
3
-
4
- Except for logging, modules in this package should not depend on any other part of the repo.
5
- """
6
-
7
- from .file_handling import filehash_update, update_hasher_for_source
8
- from .lazy_module import lazy_module
9
- from .uv_script_parser import parse_uv_script_file
10
-
11
- __all__ = ["filehash_update", "lazy_module", "parse_uv_script_file", "update_hasher_for_source"]