flyte 0.2.0b1__py3-none-any.whl → 2.0.0b46__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.
Files changed (266) hide show
  1. flyte/__init__.py +83 -30
  2. flyte/_bin/connect.py +61 -0
  3. flyte/_bin/debug.py +38 -0
  4. flyte/_bin/runtime.py +87 -19
  5. flyte/_bin/serve.py +351 -0
  6. flyte/_build.py +3 -2
  7. flyte/_cache/cache.py +6 -5
  8. flyte/_cache/local_cache.py +216 -0
  9. flyte/_code_bundle/_ignore.py +31 -5
  10. flyte/_code_bundle/_packaging.py +42 -11
  11. flyte/_code_bundle/_utils.py +57 -34
  12. flyte/_code_bundle/bundle.py +130 -27
  13. flyte/_constants.py +1 -0
  14. flyte/_context.py +21 -5
  15. flyte/_custom_context.py +73 -0
  16. flyte/_debug/constants.py +37 -0
  17. flyte/_debug/utils.py +17 -0
  18. flyte/_debug/vscode.py +315 -0
  19. flyte/_deploy.py +396 -75
  20. flyte/_deployer.py +109 -0
  21. flyte/_environment.py +94 -11
  22. flyte/_excepthook.py +37 -0
  23. flyte/_group.py +2 -1
  24. flyte/_hash.py +1 -16
  25. flyte/_image.py +544 -231
  26. flyte/_initialize.py +456 -316
  27. flyte/_interface.py +40 -5
  28. flyte/_internal/controllers/__init__.py +22 -8
  29. flyte/_internal/controllers/_local_controller.py +159 -35
  30. flyte/_internal/controllers/_trace.py +18 -10
  31. flyte/_internal/controllers/remote/__init__.py +38 -9
  32. flyte/_internal/controllers/remote/_action.py +82 -12
  33. flyte/_internal/controllers/remote/_client.py +6 -2
  34. flyte/_internal/controllers/remote/_controller.py +290 -64
  35. flyte/_internal/controllers/remote/_core.py +155 -95
  36. flyte/_internal/controllers/remote/_informer.py +40 -20
  37. flyte/_internal/controllers/remote/_service_protocol.py +2 -2
  38. flyte/_internal/imagebuild/__init__.py +2 -10
  39. flyte/_internal/imagebuild/docker_builder.py +391 -84
  40. flyte/_internal/imagebuild/image_builder.py +111 -55
  41. flyte/_internal/imagebuild/remote_builder.py +409 -0
  42. flyte/_internal/imagebuild/utils.py +79 -0
  43. flyte/_internal/resolvers/_app_env_module.py +92 -0
  44. flyte/_internal/resolvers/_task_module.py +5 -38
  45. flyte/_internal/resolvers/app_env.py +26 -0
  46. flyte/_internal/resolvers/common.py +8 -1
  47. flyte/_internal/resolvers/default.py +2 -2
  48. flyte/_internal/runtime/convert.py +319 -36
  49. flyte/_internal/runtime/entrypoints.py +106 -18
  50. flyte/_internal/runtime/io.py +71 -23
  51. flyte/_internal/runtime/resources_serde.py +21 -7
  52. flyte/_internal/runtime/reuse.py +125 -0
  53. flyte/_internal/runtime/rusty.py +196 -0
  54. flyte/_internal/runtime/task_serde.py +239 -66
  55. flyte/_internal/runtime/taskrunner.py +48 -8
  56. flyte/_internal/runtime/trigger_serde.py +162 -0
  57. flyte/_internal/runtime/types_serde.py +7 -16
  58. flyte/_keyring/file.py +115 -0
  59. flyte/_link.py +30 -0
  60. flyte/_logging.py +241 -42
  61. flyte/_map.py +312 -0
  62. flyte/_metrics.py +59 -0
  63. flyte/_module.py +74 -0
  64. flyte/_pod.py +30 -0
  65. flyte/_resources.py +296 -33
  66. flyte/_retry.py +1 -7
  67. flyte/_reusable_environment.py +72 -7
  68. flyte/_run.py +462 -132
  69. flyte/_secret.py +47 -11
  70. flyte/_serve.py +333 -0
  71. flyte/_task.py +245 -56
  72. flyte/_task_environment.py +219 -97
  73. flyte/_task_plugins.py +47 -0
  74. flyte/_tools.py +8 -8
  75. flyte/_trace.py +15 -24
  76. flyte/_trigger.py +1027 -0
  77. flyte/_utils/__init__.py +12 -1
  78. flyte/_utils/asyn.py +3 -1
  79. flyte/_utils/async_cache.py +139 -0
  80. flyte/_utils/coro_management.py +5 -4
  81. flyte/_utils/description_parser.py +19 -0
  82. flyte/_utils/docker_credentials.py +173 -0
  83. flyte/_utils/helpers.py +45 -19
  84. flyte/_utils/module_loader.py +123 -0
  85. flyte/_utils/org_discovery.py +57 -0
  86. flyte/_utils/uv_script_parser.py +8 -1
  87. flyte/_version.py +16 -3
  88. flyte/app/__init__.py +27 -0
  89. flyte/app/_app_environment.py +362 -0
  90. flyte/app/_connector_environment.py +40 -0
  91. flyte/app/_deploy.py +130 -0
  92. flyte/app/_parameter.py +343 -0
  93. flyte/app/_runtime/__init__.py +3 -0
  94. flyte/app/_runtime/app_serde.py +383 -0
  95. flyte/app/_types.py +113 -0
  96. flyte/app/extras/__init__.py +9 -0
  97. flyte/app/extras/_auth_middleware.py +217 -0
  98. flyte/app/extras/_fastapi.py +93 -0
  99. flyte/app/extras/_model_loader/__init__.py +3 -0
  100. flyte/app/extras/_model_loader/config.py +7 -0
  101. flyte/app/extras/_model_loader/loader.py +288 -0
  102. flyte/cli/__init__.py +12 -0
  103. flyte/cli/_abort.py +28 -0
  104. flyte/cli/_build.py +114 -0
  105. flyte/cli/_common.py +493 -0
  106. flyte/cli/_create.py +371 -0
  107. flyte/cli/_delete.py +45 -0
  108. flyte/cli/_deploy.py +401 -0
  109. flyte/cli/_gen.py +316 -0
  110. flyte/cli/_get.py +446 -0
  111. flyte/cli/_option.py +33 -0
  112. flyte/{_cli → cli}/_params.py +57 -17
  113. flyte/cli/_plugins.py +209 -0
  114. flyte/cli/_prefetch.py +292 -0
  115. flyte/cli/_run.py +690 -0
  116. flyte/cli/_serve.py +338 -0
  117. flyte/cli/_update.py +86 -0
  118. flyte/cli/_user.py +20 -0
  119. flyte/cli/main.py +246 -0
  120. flyte/config/__init__.py +2 -167
  121. flyte/config/_config.py +215 -163
  122. flyte/config/_internal.py +10 -1
  123. flyte/config/_reader.py +225 -0
  124. flyte/connectors/__init__.py +11 -0
  125. flyte/connectors/_connector.py +330 -0
  126. flyte/connectors/_server.py +194 -0
  127. flyte/connectors/utils.py +159 -0
  128. flyte/errors.py +134 -2
  129. flyte/extend.py +24 -0
  130. flyte/extras/_container.py +69 -56
  131. flyte/git/__init__.py +3 -0
  132. flyte/git/_config.py +279 -0
  133. flyte/io/__init__.py +8 -1
  134. flyte/io/{structured_dataset → _dataframe}/__init__.py +32 -30
  135. flyte/io/{structured_dataset → _dataframe}/basic_dfs.py +75 -68
  136. flyte/io/{structured_dataset/structured_dataset.py → _dataframe/dataframe.py} +207 -242
  137. flyte/io/_dir.py +575 -113
  138. flyte/io/_file.py +587 -141
  139. flyte/io/_hashing_io.py +342 -0
  140. flyte/io/extend.py +7 -0
  141. flyte/models.py +635 -0
  142. flyte/prefetch/__init__.py +22 -0
  143. flyte/prefetch/_hf_model.py +563 -0
  144. flyte/remote/__init__.py +14 -3
  145. flyte/remote/_action.py +879 -0
  146. flyte/remote/_app.py +346 -0
  147. flyte/remote/_auth_metadata.py +42 -0
  148. flyte/remote/_client/_protocols.py +62 -4
  149. flyte/remote/_client/auth/_auth_utils.py +19 -0
  150. flyte/remote/_client/auth/_authenticators/base.py +8 -2
  151. flyte/remote/_client/auth/_authenticators/device_code.py +4 -5
  152. flyte/remote/_client/auth/_authenticators/factory.py +4 -0
  153. flyte/remote/_client/auth/_authenticators/passthrough.py +79 -0
  154. flyte/remote/_client/auth/_authenticators/pkce.py +17 -18
  155. flyte/remote/_client/auth/_channel.py +47 -18
  156. flyte/remote/_client/auth/_client_config.py +5 -3
  157. flyte/remote/_client/auth/_keyring.py +15 -2
  158. flyte/remote/_client/auth/_token_client.py +3 -3
  159. flyte/remote/_client/controlplane.py +206 -18
  160. flyte/remote/_common.py +66 -0
  161. flyte/remote/_data.py +107 -22
  162. flyte/remote/_logs.py +116 -33
  163. flyte/remote/_project.py +21 -19
  164. flyte/remote/_run.py +164 -631
  165. flyte/remote/_secret.py +72 -29
  166. flyte/remote/_task.py +387 -46
  167. flyte/remote/_trigger.py +368 -0
  168. flyte/remote/_user.py +43 -0
  169. flyte/report/_report.py +10 -6
  170. flyte/storage/__init__.py +13 -1
  171. flyte/storage/_config.py +237 -0
  172. flyte/storage/_parallel_reader.py +289 -0
  173. flyte/storage/_storage.py +268 -59
  174. flyte/syncify/__init__.py +56 -0
  175. flyte/syncify/_api.py +414 -0
  176. flyte/types/__init__.py +39 -0
  177. flyte/types/_interface.py +22 -7
  178. flyte/{io/pickle/transformer.py → types/_pickle.py} +37 -9
  179. flyte/types/_string_literals.py +8 -9
  180. flyte/types/_type_engine.py +226 -126
  181. flyte/types/_utils.py +1 -1
  182. flyte-2.0.0b46.data/scripts/debug.py +38 -0
  183. flyte-2.0.0b46.data/scripts/runtime.py +194 -0
  184. flyte-2.0.0b46.dist-info/METADATA +352 -0
  185. flyte-2.0.0b46.dist-info/RECORD +221 -0
  186. flyte-2.0.0b46.dist-info/entry_points.txt +8 -0
  187. flyte-2.0.0b46.dist-info/licenses/LICENSE +201 -0
  188. flyte/_api_commons.py +0 -3
  189. flyte/_cli/_common.py +0 -299
  190. flyte/_cli/_create.py +0 -42
  191. flyte/_cli/_delete.py +0 -23
  192. flyte/_cli/_deploy.py +0 -140
  193. flyte/_cli/_get.py +0 -235
  194. flyte/_cli/_run.py +0 -174
  195. flyte/_cli/main.py +0 -98
  196. flyte/_datastructures.py +0 -342
  197. flyte/_internal/controllers/pbhash.py +0 -39
  198. flyte/_protos/common/authorization_pb2.py +0 -66
  199. flyte/_protos/common/authorization_pb2.pyi +0 -108
  200. flyte/_protos/common/authorization_pb2_grpc.py +0 -4
  201. flyte/_protos/common/identifier_pb2.py +0 -71
  202. flyte/_protos/common/identifier_pb2.pyi +0 -82
  203. flyte/_protos/common/identifier_pb2_grpc.py +0 -4
  204. flyte/_protos/common/identity_pb2.py +0 -48
  205. flyte/_protos/common/identity_pb2.pyi +0 -72
  206. flyte/_protos/common/identity_pb2_grpc.py +0 -4
  207. flyte/_protos/common/list_pb2.py +0 -36
  208. flyte/_protos/common/list_pb2.pyi +0 -69
  209. flyte/_protos/common/list_pb2_grpc.py +0 -4
  210. flyte/_protos/common/policy_pb2.py +0 -37
  211. flyte/_protos/common/policy_pb2.pyi +0 -27
  212. flyte/_protos/common/policy_pb2_grpc.py +0 -4
  213. flyte/_protos/common/role_pb2.py +0 -37
  214. flyte/_protos/common/role_pb2.pyi +0 -53
  215. flyte/_protos/common/role_pb2_grpc.py +0 -4
  216. flyte/_protos/common/runtime_version_pb2.py +0 -28
  217. flyte/_protos/common/runtime_version_pb2.pyi +0 -24
  218. flyte/_protos/common/runtime_version_pb2_grpc.py +0 -4
  219. flyte/_protos/logs/dataplane/payload_pb2.py +0 -96
  220. flyte/_protos/logs/dataplane/payload_pb2.pyi +0 -168
  221. flyte/_protos/logs/dataplane/payload_pb2_grpc.py +0 -4
  222. flyte/_protos/secret/definition_pb2.py +0 -49
  223. flyte/_protos/secret/definition_pb2.pyi +0 -93
  224. flyte/_protos/secret/definition_pb2_grpc.py +0 -4
  225. flyte/_protos/secret/payload_pb2.py +0 -62
  226. flyte/_protos/secret/payload_pb2.pyi +0 -94
  227. flyte/_protos/secret/payload_pb2_grpc.py +0 -4
  228. flyte/_protos/secret/secret_pb2.py +0 -38
  229. flyte/_protos/secret/secret_pb2.pyi +0 -6
  230. flyte/_protos/secret/secret_pb2_grpc.py +0 -198
  231. flyte/_protos/secret/secret_pb2_grpc_grpc.py +0 -198
  232. flyte/_protos/validate/validate/validate_pb2.py +0 -76
  233. flyte/_protos/workflow/node_execution_service_pb2.py +0 -26
  234. flyte/_protos/workflow/node_execution_service_pb2.pyi +0 -4
  235. flyte/_protos/workflow/node_execution_service_pb2_grpc.py +0 -32
  236. flyte/_protos/workflow/queue_service_pb2.py +0 -106
  237. flyte/_protos/workflow/queue_service_pb2.pyi +0 -141
  238. flyte/_protos/workflow/queue_service_pb2_grpc.py +0 -172
  239. flyte/_protos/workflow/run_definition_pb2.py +0 -128
  240. flyte/_protos/workflow/run_definition_pb2.pyi +0 -310
  241. flyte/_protos/workflow/run_definition_pb2_grpc.py +0 -4
  242. flyte/_protos/workflow/run_logs_service_pb2.py +0 -41
  243. flyte/_protos/workflow/run_logs_service_pb2.pyi +0 -28
  244. flyte/_protos/workflow/run_logs_service_pb2_grpc.py +0 -69
  245. flyte/_protos/workflow/run_service_pb2.py +0 -133
  246. flyte/_protos/workflow/run_service_pb2.pyi +0 -175
  247. flyte/_protos/workflow/run_service_pb2_grpc.py +0 -412
  248. flyte/_protos/workflow/state_service_pb2.py +0 -58
  249. flyte/_protos/workflow/state_service_pb2.pyi +0 -71
  250. flyte/_protos/workflow/state_service_pb2_grpc.py +0 -138
  251. flyte/_protos/workflow/task_definition_pb2.py +0 -72
  252. flyte/_protos/workflow/task_definition_pb2.pyi +0 -65
  253. flyte/_protos/workflow/task_definition_pb2_grpc.py +0 -4
  254. flyte/_protos/workflow/task_service_pb2.py +0 -44
  255. flyte/_protos/workflow/task_service_pb2.pyi +0 -31
  256. flyte/_protos/workflow/task_service_pb2_grpc.py +0 -104
  257. flyte/io/_dataframe.py +0 -0
  258. flyte/io/pickle/__init__.py +0 -0
  259. flyte/remote/_console.py +0 -18
  260. flyte-0.2.0b1.dist-info/METADATA +0 -179
  261. flyte-0.2.0b1.dist-info/RECORD +0 -204
  262. flyte-0.2.0b1.dist-info/entry_points.txt +0 -3
  263. /flyte/{_cli → _debug}/__init__.py +0 -0
  264. /flyte/{_protos → _keyring}/__init__.py +0 -0
  265. {flyte-0.2.0b1.dist-info → flyte-2.0.0b46.dist-info}/WHEEL +0 -0
  266. {flyte-0.2.0b1.dist-info → flyte-2.0.0b46.dist-info}/top_level.txt +0 -0
flyte/cli/_deploy.py ADDED
@@ -0,0 +1,401 @@
1
+ import pathlib
2
+ from dataclasses import dataclass, field, fields
3
+ from pathlib import Path
4
+ from types import ModuleType
5
+ from typing import Any, Dict, List, cast, get_args
6
+
7
+ import rich_click as click
8
+
9
+ import flyte
10
+ from flyte._code_bundle._utils import CopyFiles
11
+
12
+ from . import _common as common
13
+ from ._common import CLIConfig
14
+
15
+
16
+ @dataclass
17
+ class DeployArguments:
18
+ project: str = field(
19
+ default=cast(str, common.PROJECT_OPTION.default), metadata={"click.option": common.PROJECT_OPTION}
20
+ )
21
+ domain: str = field(
22
+ default=cast(str, common.DOMAIN_OPTION.default), metadata={"click.option": common.DOMAIN_OPTION}
23
+ )
24
+ version: str = field(
25
+ default="",
26
+ metadata={
27
+ "click.option": click.Option(
28
+ ["--version"],
29
+ type=str,
30
+ help="Version of the environment to deploy",
31
+ )
32
+ },
33
+ )
34
+ dry_run: bool = field(default=False, metadata={"click.option": common.DRY_RUN_OPTION})
35
+ copy_style: CopyFiles = field(
36
+ default="loaded_modules",
37
+ metadata={
38
+ "click.option": click.Option(
39
+ ["--copy-style"],
40
+ type=click.Choice(get_args(CopyFiles)),
41
+ default="loaded_modules",
42
+ help="Copy style to use when running the task",
43
+ )
44
+ },
45
+ )
46
+ root_dir: str | None = field(
47
+ default=None,
48
+ metadata={
49
+ "click.option": click.Option(
50
+ ["--root-dir"],
51
+ type=str,
52
+ help="Override the root source directory, helpful when working with monorepos.",
53
+ )
54
+ },
55
+ )
56
+ recursive: bool = field(
57
+ default=False,
58
+ metadata={
59
+ "click.option": click.Option(
60
+ ["--recursive", "-r"],
61
+ is_flag=True,
62
+ help="Recursively deploy all environments in the current directory",
63
+ )
64
+ },
65
+ )
66
+ all: bool = field(
67
+ default=False,
68
+ metadata={
69
+ "click.option": click.Option(
70
+ ["--all"],
71
+ is_flag=True,
72
+ help="Deploy all environments in the current directory, ignoring the file name",
73
+ )
74
+ },
75
+ )
76
+ ignore_load_errors: bool = field(
77
+ default=False,
78
+ metadata={
79
+ "click.option": click.Option(
80
+ ["--ignore-load-errors", "-i"],
81
+ is_flag=True,
82
+ help="Ignore errors when loading environments especially when using --recursive or --all.",
83
+ )
84
+ },
85
+ )
86
+ no_sync_local_sys_paths: bool = field(
87
+ default=True,
88
+ metadata={
89
+ "click.option": click.Option(
90
+ ["--no-sync-local-sys-paths"],
91
+ is_flag=True,
92
+ flag_value=True,
93
+ default=False,
94
+ help="Disable synchronization of local sys.path entries under the root directory "
95
+ "to the remote container.",
96
+ )
97
+ },
98
+ )
99
+ image: List[str] = field(
100
+ default_factory=list,
101
+ metadata={
102
+ "click.option": click.Option(
103
+ ["--image"],
104
+ type=str,
105
+ multiple=True,
106
+ help="Image to be used in the run. Format: imagename=imageuri. Can be specified multiple times.",
107
+ )
108
+ },
109
+ )
110
+
111
+ @classmethod
112
+ def from_dict(cls, d: Dict[str, Any]) -> "DeployArguments":
113
+ return cls(**d)
114
+
115
+ @classmethod
116
+ def options(cls) -> List[click.Option]:
117
+ """
118
+ Return the set of base parameters added to every flyte run workflow subcommand.
119
+ """
120
+ return [common.get_option_from_metadata(f.metadata) for f in fields(cls) if f.metadata]
121
+
122
+
123
+ class DeployEnvCommand(click.RichCommand):
124
+ def __init__(self, env_name: str, env: Any, deploy_args: DeployArguments, *args, **kwargs):
125
+ self.env_name = env_name
126
+ self.env = env
127
+ self.deploy_args = deploy_args
128
+ super().__init__(*args, **kwargs)
129
+
130
+ def invoke(self, ctx: click.Context):
131
+ console = common.get_console()
132
+ console.print(f"Deploying root - environment: {self.env_name}")
133
+ obj: CLIConfig = ctx.obj
134
+ obj.init(
135
+ project=self.deploy_args.project,
136
+ domain=self.deploy_args.domain,
137
+ root_dir=self.deploy_args.root_dir,
138
+ sync_local_sys_paths=not self.deploy_args.no_sync_local_sys_paths,
139
+ images=tuple(self.deploy_args.image) or None,
140
+ )
141
+ with console.status("Deploying...", spinner="dots"):
142
+ deployment = flyte.deploy(
143
+ self.env,
144
+ dryrun=self.deploy_args.dry_run,
145
+ copy_style=self.deploy_args.copy_style,
146
+ version=self.deploy_args.version,
147
+ )
148
+
149
+ console.print(common.format("Environments", deployment[0].env_repr(), obj.output_format))
150
+ console.print(common.format("Entities", deployment[0].table_repr(), obj.output_format))
151
+
152
+
153
+ class DeployEnvRecursiveCommand(click.Command):
154
+ """
155
+ Command to deploy all loaded environments in a directory or a file, optionally recursively.
156
+ This command will load all python files in the directory, and deploy all environments found in them.
157
+ If the path is a file, it will deploy all environments in that file.
158
+ """
159
+
160
+ def __init__(self, path: pathlib.Path, deploy_args: DeployArguments, *args, **kwargs):
161
+ self.path = path
162
+ self.deploy_args = deploy_args
163
+ super().__init__(*args, **kwargs)
164
+
165
+ def invoke(self, ctx: click.Context):
166
+ from flyte._environment import list_loaded_environments
167
+ from flyte._utils import load_python_modules
168
+
169
+ obj: CLIConfig = ctx.obj
170
+ # Now start connection and deploy all environments
171
+ common.initialize_config(
172
+ ctx=ctx,
173
+ project=self.deploy_args.project,
174
+ domain=self.deploy_args.domain,
175
+ sync_local_sys_paths=not self.deploy_args.no_sync_local_sys_paths,
176
+ images=tuple(self.deploy_args.image) or None,
177
+ root_dir=self.deploy_args.root_dir,
178
+ )
179
+ console = common.get_console()
180
+
181
+ root_dir = Path.cwd()
182
+ if self.deploy_args.root_dir:
183
+ root_dir = pathlib.Path(self.deploy_args.root_dir).resolve()
184
+ # Load all python modules
185
+ loaded_modules, failed_paths = load_python_modules(self.path, root_dir, self.deploy_args.recursive)
186
+ if failed_paths:
187
+ console.print(f"Loaded {len(loaded_modules)} modules with, but failed to load {len(failed_paths)} paths:")
188
+ console.print(
189
+ common.format("Modules", [[("Path", p), ("Err", e)] for p, e in failed_paths], obj.output_format)
190
+ )
191
+ else:
192
+ console.print(f"Loaded {len(loaded_modules)} modules")
193
+
194
+ # Get newly loaded environments
195
+ all_envs = list_loaded_environments()
196
+ if not all_envs:
197
+ console.print("No environments found to deploy")
198
+ return
199
+ console.print(common.format("Loaded Environments", [[("name", e.name)] for e in all_envs], obj.output_format))
200
+
201
+ if not self.deploy_args.ignore_load_errors and len(failed_paths) > 0:
202
+ raise click.ClickException(
203
+ f"Failed to load {len(failed_paths)} files. Use --ignore-load-errors to ignore these errors."
204
+ )
205
+
206
+ with console.status("Deploying...", spinner="dots"):
207
+ deployments = flyte.deploy(
208
+ *all_envs,
209
+ dryrun=self.deploy_args.dry_run,
210
+ copy_style=self.deploy_args.copy_style,
211
+ version=self.deploy_args.version,
212
+ )
213
+
214
+ console.print(
215
+ common.format("Environments", [env for d in deployments for env in d.env_repr()], obj.output_format)
216
+ )
217
+ console.print(common.format("Tasks", [task for d in deployments for task in d.table_repr()], obj.output_format))
218
+
219
+
220
+ class EnvPerFileGroup(common.ObjectsPerFileGroup):
221
+ """
222
+ Group that creates a command for each task in the current directory that is not `__init__.py`.
223
+ """
224
+
225
+ def __init__(self, filename: Path, deploy_args: DeployArguments, *args, **kwargs):
226
+ args = (filename, *args)
227
+ super().__init__(*args, **kwargs)
228
+ self.deploy_args = deploy_args
229
+
230
+ def _filter_objects(self, module: ModuleType) -> Dict[str, Any]:
231
+ return {k: v for k, v in module.__dict__.items() if isinstance(v, flyte.Environment)}
232
+
233
+ def list_commands(self, ctx):
234
+ common.initialize_config(
235
+ ctx,
236
+ self.deploy_args.project,
237
+ self.deploy_args.domain,
238
+ self.deploy_args.root_dir,
239
+ sync_local_sys_paths=not self.deploy_args.no_sync_local_sys_paths,
240
+ )
241
+ return super().list_commands(ctx)
242
+
243
+ def get_command(self, ctx, obj_name):
244
+ common.initialize_config(
245
+ ctx,
246
+ self.deploy_args.project,
247
+ self.deploy_args.domain,
248
+ self.deploy_args.root_dir,
249
+ sync_local_sys_paths=not self.deploy_args.no_sync_local_sys_paths,
250
+ )
251
+ return super().get_command(ctx, obj_name)
252
+
253
+ def _get_command_for_obj(self, ctx: click.Context, obj_name: str, obj: Any) -> click.Command:
254
+ obj = cast(flyte.Environment, obj)
255
+ return DeployEnvCommand(
256
+ name=obj_name,
257
+ env_name=obj_name,
258
+ env=obj,
259
+ help=f"{obj.name}" + (f": {obj.description}" if obj.description else ""),
260
+ deploy_args=self.deploy_args,
261
+ )
262
+
263
+
264
+ class EnvFiles(common.FileGroup):
265
+ """
266
+ Group that creates a command for each file in the current directory that is not `__init__.py`.
267
+ """
268
+
269
+ common_options_enabled = False
270
+
271
+ def __init__(
272
+ self,
273
+ *args,
274
+ directory: Path | None = None,
275
+ **kwargs,
276
+ ):
277
+ if "params" not in kwargs:
278
+ kwargs["params"] = []
279
+ kwargs["params"].extend(DeployArguments.options())
280
+ super().__init__(*args, directory=directory, **kwargs)
281
+
282
+ def get_command(self, ctx, filename):
283
+ deploy_args = DeployArguments.from_dict(ctx.params)
284
+ fp = Path(filename)
285
+ if not fp.exists():
286
+ raise click.BadParameter(f"File {filename} does not exist")
287
+ if deploy_args.recursive or deploy_args.all:
288
+ # If recursive or all, we want to deploy all environments in the current directory
289
+ return DeployEnvRecursiveCommand(
290
+ path=fp,
291
+ deploy_args=deploy_args,
292
+ name=filename,
293
+ help="Deploy all loaded environments from the file, or directory (optional recursively)",
294
+ )
295
+ if fp.is_dir():
296
+ # If the path is a directory, we want to deploy all environments in that directory
297
+ return EnvFiles(directory=fp)
298
+ return EnvPerFileGroup(
299
+ filename=fp,
300
+ deploy_args=deploy_args,
301
+ name=filename,
302
+ help="Deploy a single environment and all its dependencies, from the file.",
303
+ )
304
+
305
+
306
+ deploy = EnvFiles(
307
+ name="deploy",
308
+ help="""
309
+ Deploy one or more environments from a python file.
310
+
311
+ This command will create or update environments in the Flyte system, registering
312
+ all tasks and their dependencies.
313
+
314
+ Example usage:
315
+
316
+ ```bash
317
+ flyte deploy hello.py my_env
318
+ ```
319
+
320
+ Arguments to the deploy command are provided right after the `deploy` command and before the file name.
321
+
322
+ To deploy all environments in a file, use the `--all` flag:
323
+
324
+ ```bash
325
+ flyte deploy --all hello.py
326
+ ```
327
+
328
+ To recursively deploy all environments in a directory and its subdirectories, use the `--recursive` flag:
329
+
330
+ ```bash
331
+ flyte deploy --recursive ./src
332
+ ```
333
+
334
+ You can combine `--all` and `--recursive` to deploy everything:
335
+
336
+ ```bash
337
+ flyte deploy --all --recursive ./src
338
+ ```
339
+
340
+ You can provide image mappings with `--image` flag. This allows you to specify
341
+ the image URI for the task environment during CLI execution without changing
342
+ the code. Any images defined with `Image.from_ref_name("name")` will resolve to the
343
+ corresponding URIs you specify here.
344
+
345
+ ```bash
346
+ flyte deploy --image my_image=ghcr.io/myorg/my-image:v1.0 hello.py my_env
347
+ ```
348
+
349
+ If the image name is not provided, it is regarded as a default image and will
350
+ be used when no image is specified in TaskEnvironment:
351
+
352
+ ```bash
353
+ flyte deploy --image ghcr.io/myorg/default-image:latest hello.py my_env
354
+ ```
355
+
356
+ You can specify multiple image arguments:
357
+
358
+ ```bash
359
+ flyte deploy --image ghcr.io/org/default:latest --image gpu=ghcr.io/org/gpu:v2.0 hello.py my_env
360
+ ```
361
+
362
+ To deploy a specific version, use the `--version` flag:
363
+
364
+ ```bash
365
+ flyte deploy --version v1.0.0 hello.py my_env
366
+ ```
367
+
368
+ To preview what would be deployed without actually deploying, use the `--dry-run` flag:
369
+
370
+ ```bash
371
+ flyte deploy --dry-run hello.py my_env
372
+ ```
373
+
374
+ You can specify the `--config` flag to point to a specific Flyte cluster:
375
+
376
+ ```bash
377
+ flyte --config my-config.yaml deploy hello.py my_env
378
+ ```
379
+
380
+ You can override the default configured project and domain:
381
+
382
+ ```bash
383
+ flyte deploy --project my-project --domain development hello.py my_env
384
+ ```
385
+
386
+ If loading some files fails during recursive deployment, you can use the `--ignore-load-errors` flag
387
+ to continue deploying the environments that loaded successfully:
388
+
389
+ ```bash
390
+ flyte deploy --recursive --ignore-load-errors ./src
391
+ ```
392
+
393
+ Other arguments to the deploy command are listed below.
394
+
395
+ To see the environments available in a file, use `--help` after the file name:
396
+
397
+ ```bash
398
+ flyte deploy hello.py --help
399
+ ```
400
+ """,
401
+ )