flyte 0.0.1b0__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 (455) 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 -234
  26. flyte/_initialize.py +443 -294
  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 +322 -33
  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 +461 -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. {union/_cli → flyte/cli}/_params.py +152 -153
  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 +3 -0
  121. flyte/config/_config.py +248 -0
  122. flyte/config/_internal.py +73 -0
  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 +230 -129
  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 -287
  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 -152
  195. flyte/_cli/main.py +0 -72
  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.0.1b0.dist-info/METADATA +0 -179
  261. flyte-0.0.1b0.dist-info/RECORD +0 -390
  262. flyte-0.0.1b0.dist-info/entry_points.txt +0 -3
  263. union/__init__.py +0 -54
  264. union/_api_commons.py +0 -3
  265. union/_bin/__init__.py +0 -0
  266. union/_bin/runtime.py +0 -113
  267. union/_build.py +0 -25
  268. union/_cache/__init__.py +0 -12
  269. union/_cache/cache.py +0 -141
  270. union/_cache/defaults.py +0 -9
  271. union/_cache/policy_function_body.py +0 -42
  272. union/_cli/__init__.py +0 -0
  273. union/_cli/_common.py +0 -263
  274. union/_cli/_create.py +0 -40
  275. union/_cli/_delete.py +0 -23
  276. union/_cli/_deploy.py +0 -120
  277. union/_cli/_get.py +0 -162
  278. union/_cli/_run.py +0 -150
  279. union/_cli/main.py +0 -72
  280. union/_code_bundle/__init__.py +0 -8
  281. union/_code_bundle/_ignore.py +0 -113
  282. union/_code_bundle/_packaging.py +0 -187
  283. union/_code_bundle/_utils.py +0 -342
  284. union/_code_bundle/bundle.py +0 -176
  285. union/_context.py +0 -146
  286. union/_datastructures.py +0 -295
  287. union/_deploy.py +0 -185
  288. union/_doc.py +0 -29
  289. union/_docstring.py +0 -26
  290. union/_environment.py +0 -43
  291. union/_group.py +0 -31
  292. union/_hash.py +0 -23
  293. union/_image.py +0 -760
  294. union/_initialize.py +0 -585
  295. union/_interface.py +0 -84
  296. union/_internal/__init__.py +0 -3
  297. union/_internal/controllers/__init__.py +0 -77
  298. union/_internal/controllers/_local_controller.py +0 -77
  299. union/_internal/controllers/pbhash.py +0 -39
  300. union/_internal/controllers/remote/__init__.py +0 -40
  301. union/_internal/controllers/remote/_action.py +0 -131
  302. union/_internal/controllers/remote/_client.py +0 -43
  303. union/_internal/controllers/remote/_controller.py +0 -169
  304. union/_internal/controllers/remote/_core.py +0 -341
  305. union/_internal/controllers/remote/_informer.py +0 -260
  306. union/_internal/controllers/remote/_service_protocol.py +0 -44
  307. union/_internal/imagebuild/__init__.py +0 -11
  308. union/_internal/imagebuild/docker_builder.py +0 -416
  309. union/_internal/imagebuild/image_builder.py +0 -243
  310. union/_internal/imagebuild/remote_builder.py +0 -0
  311. union/_internal/resolvers/__init__.py +0 -0
  312. union/_internal/resolvers/_task_module.py +0 -31
  313. union/_internal/resolvers/common.py +0 -24
  314. union/_internal/resolvers/default.py +0 -27
  315. union/_internal/runtime/__init__.py +0 -0
  316. union/_internal/runtime/convert.py +0 -163
  317. union/_internal/runtime/entrypoints.py +0 -121
  318. union/_internal/runtime/io.py +0 -136
  319. union/_internal/runtime/resources_serde.py +0 -134
  320. union/_internal/runtime/task_serde.py +0 -202
  321. union/_internal/runtime/taskrunner.py +0 -179
  322. union/_internal/runtime/types_serde.py +0 -53
  323. union/_logging.py +0 -124
  324. union/_protos/__init__.py +0 -0
  325. union/_protos/common/authorization_pb2.py +0 -66
  326. union/_protos/common/authorization_pb2.pyi +0 -106
  327. union/_protos/common/authorization_pb2_grpc.py +0 -4
  328. union/_protos/common/identifier_pb2.py +0 -71
  329. union/_protos/common/identifier_pb2.pyi +0 -82
  330. union/_protos/common/identifier_pb2_grpc.py +0 -4
  331. union/_protos/common/identity_pb2.py +0 -48
  332. union/_protos/common/identity_pb2.pyi +0 -72
  333. union/_protos/common/identity_pb2_grpc.py +0 -4
  334. union/_protos/common/list_pb2.py +0 -36
  335. union/_protos/common/list_pb2.pyi +0 -69
  336. union/_protos/common/list_pb2_grpc.py +0 -4
  337. union/_protos/common/policy_pb2.py +0 -37
  338. union/_protos/common/policy_pb2.pyi +0 -27
  339. union/_protos/common/policy_pb2_grpc.py +0 -4
  340. union/_protos/common/role_pb2.py +0 -37
  341. union/_protos/common/role_pb2.pyi +0 -51
  342. union/_protos/common/role_pb2_grpc.py +0 -4
  343. union/_protos/common/runtime_version_pb2.py +0 -28
  344. union/_protos/common/runtime_version_pb2.pyi +0 -24
  345. union/_protos/common/runtime_version_pb2_grpc.py +0 -4
  346. union/_protos/logs/dataplane/payload_pb2.py +0 -96
  347. union/_protos/logs/dataplane/payload_pb2.pyi +0 -168
  348. union/_protos/logs/dataplane/payload_pb2_grpc.py +0 -4
  349. union/_protos/secret/definition_pb2.py +0 -49
  350. union/_protos/secret/definition_pb2.pyi +0 -93
  351. union/_protos/secret/definition_pb2_grpc.py +0 -4
  352. union/_protos/secret/payload_pb2.py +0 -62
  353. union/_protos/secret/payload_pb2.pyi +0 -94
  354. union/_protos/secret/payload_pb2_grpc.py +0 -4
  355. union/_protos/secret/secret_pb2.py +0 -38
  356. union/_protos/secret/secret_pb2.pyi +0 -6
  357. union/_protos/secret/secret_pb2_grpc.py +0 -198
  358. union/_protos/validate/validate/validate_pb2.py +0 -76
  359. union/_protos/workflow/node_execution_service_pb2.py +0 -26
  360. union/_protos/workflow/node_execution_service_pb2.pyi +0 -4
  361. union/_protos/workflow/node_execution_service_pb2_grpc.py +0 -32
  362. union/_protos/workflow/queue_service_pb2.py +0 -75
  363. union/_protos/workflow/queue_service_pb2.pyi +0 -103
  364. union/_protos/workflow/queue_service_pb2_grpc.py +0 -172
  365. union/_protos/workflow/run_definition_pb2.py +0 -100
  366. union/_protos/workflow/run_definition_pb2.pyi +0 -256
  367. union/_protos/workflow/run_definition_pb2_grpc.py +0 -4
  368. union/_protos/workflow/run_logs_service_pb2.py +0 -41
  369. union/_protos/workflow/run_logs_service_pb2.pyi +0 -28
  370. union/_protos/workflow/run_logs_service_pb2_grpc.py +0 -69
  371. union/_protos/workflow/run_service_pb2.py +0 -133
  372. union/_protos/workflow/run_service_pb2.pyi +0 -173
  373. union/_protos/workflow/run_service_pb2_grpc.py +0 -412
  374. union/_protos/workflow/state_service_pb2.py +0 -58
  375. union/_protos/workflow/state_service_pb2.pyi +0 -69
  376. union/_protos/workflow/state_service_pb2_grpc.py +0 -138
  377. union/_protos/workflow/task_definition_pb2.py +0 -72
  378. union/_protos/workflow/task_definition_pb2.pyi +0 -65
  379. union/_protos/workflow/task_definition_pb2_grpc.py +0 -4
  380. union/_protos/workflow/task_service_pb2.py +0 -44
  381. union/_protos/workflow/task_service_pb2.pyi +0 -31
  382. union/_protos/workflow/task_service_pb2_grpc.py +0 -104
  383. union/_resources.py +0 -226
  384. union/_retry.py +0 -32
  385. union/_reusable_environment.py +0 -25
  386. union/_run.py +0 -374
  387. union/_secret.py +0 -61
  388. union/_task.py +0 -354
  389. union/_task_environment.py +0 -186
  390. union/_timeout.py +0 -47
  391. union/_tools.py +0 -27
  392. union/_utils/__init__.py +0 -11
  393. union/_utils/asyn.py +0 -119
  394. union/_utils/file_handling.py +0 -71
  395. union/_utils/helpers.py +0 -46
  396. union/_utils/lazy_module.py +0 -54
  397. union/_utils/uv_script_parser.py +0 -49
  398. union/_version.py +0 -21
  399. union/connectors/__init__.py +0 -0
  400. union/errors.py +0 -128
  401. union/extras/__init__.py +0 -5
  402. union/extras/_container.py +0 -263
  403. union/io/__init__.py +0 -11
  404. union/io/_dataframe.py +0 -0
  405. union/io/_dir.py +0 -425
  406. union/io/_file.py +0 -418
  407. union/io/pickle/__init__.py +0 -0
  408. union/io/pickle/transformer.py +0 -117
  409. union/io/structured_dataset/__init__.py +0 -122
  410. union/io/structured_dataset/basic_dfs.py +0 -219
  411. union/io/structured_dataset/structured_dataset.py +0 -1057
  412. union/py.typed +0 -0
  413. union/remote/__init__.py +0 -23
  414. union/remote/_client/__init__.py +0 -0
  415. union/remote/_client/_protocols.py +0 -129
  416. union/remote/_client/auth/__init__.py +0 -12
  417. union/remote/_client/auth/_authenticators/__init__.py +0 -0
  418. union/remote/_client/auth/_authenticators/base.py +0 -391
  419. union/remote/_client/auth/_authenticators/client_credentials.py +0 -73
  420. union/remote/_client/auth/_authenticators/device_code.py +0 -120
  421. union/remote/_client/auth/_authenticators/external_command.py +0 -77
  422. union/remote/_client/auth/_authenticators/factory.py +0 -200
  423. union/remote/_client/auth/_authenticators/pkce.py +0 -515
  424. union/remote/_client/auth/_channel.py +0 -184
  425. union/remote/_client/auth/_client_config.py +0 -83
  426. union/remote/_client/auth/_default_html.py +0 -32
  427. union/remote/_client/auth/_grpc_utils/__init__.py +0 -0
  428. union/remote/_client/auth/_grpc_utils/auth_interceptor.py +0 -204
  429. union/remote/_client/auth/_grpc_utils/default_metadata_interceptor.py +0 -144
  430. union/remote/_client/auth/_keyring.py +0 -154
  431. union/remote/_client/auth/_token_client.py +0 -258
  432. union/remote/_client/auth/errors.py +0 -16
  433. union/remote/_client/controlplane.py +0 -86
  434. union/remote/_data.py +0 -149
  435. union/remote/_logs.py +0 -74
  436. union/remote/_project.py +0 -86
  437. union/remote/_run.py +0 -820
  438. union/remote/_secret.py +0 -132
  439. union/remote/_task.py +0 -193
  440. union/report/__init__.py +0 -3
  441. union/report/_report.py +0 -178
  442. union/report/_template.html +0 -124
  443. union/storage/__init__.py +0 -24
  444. union/storage/_remote_fs.py +0 -34
  445. union/storage/_storage.py +0 -247
  446. union/storage/_utils.py +0 -5
  447. union/types/__init__.py +0 -11
  448. union/types/_renderer.py +0 -162
  449. union/types/_string_literals.py +0 -120
  450. union/types/_type_engine.py +0 -2131
  451. union/types/_utils.py +0 -80
  452. /flyte/{_cli → _debug}/__init__.py +0 -0
  453. /flyte/{_protos → _keyring}/__init__.py +0 -0
  454. {flyte-0.0.1b0.dist-info → flyte-2.0.0b46.dist-info}/WHEEL +0 -0
  455. {flyte-0.0.1b0.dist-info → flyte-2.0.0b46.dist-info}/top_level.txt +0 -0
flyte/_run.py CHANGED
@@ -1,45 +1,79 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import asyncio
3
4
  import pathlib
5
+ import sys
4
6
  import uuid
5
- from typing import TYPE_CHECKING, Any, Literal, Optional, Tuple, Union, cast
6
-
7
- import flyte
8
- import flyte.report
9
- from flyte import S3
10
-
11
- from ._api_commons import syncer
12
- from ._context import contextual_run, internal_ctx
13
- from ._datastructures import ActionID, Checkpoints, RawDataPath, SerializationContext, TaskContext
14
- from ._environment import Environment
15
- from ._initialize import (
16
- ABFS,
17
- GCS,
7
+ from dataclasses import dataclass
8
+ from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Tuple, Union, cast
9
+
10
+ import flyte.errors
11
+ from flyte._context import contextual_run, internal_ctx
12
+ from flyte._environment import Environment
13
+ from flyte._initialize import (
18
14
  _get_init_config,
19
15
  get_client,
20
- get_common_config,
16
+ get_init_config,
21
17
  get_storage,
22
18
  requires_initialization,
23
19
  requires_storage,
24
20
  )
25
- from ._internal import create_controller
26
- from ._internal.runtime.io import _CHECKPOINT_FILE_NAME
27
- from ._internal.runtime.taskrunner import run_task
28
- from ._logging import logger
29
- from ._protos.common import identifier_pb2
30
- from ._task import P, R, TaskTemplate
31
- from ._tools import ipython_check
32
- from .errors import InitializationError
21
+ from flyte._logging import LogFormat, logger
22
+ from flyte._task import F, P, R, TaskTemplate
23
+ from flyte.models import (
24
+ ActionID,
25
+ Checkpoints,
26
+ CodeBundle,
27
+ RawDataPath,
28
+ SerializationContext,
29
+ TaskContext,
30
+ )
31
+ from flyte.syncify import syncify
32
+
33
+ from ._constants import FLYTE_SYS_PATH
33
34
 
34
35
  if TYPE_CHECKING:
35
36
  from flyte.remote import Run
37
+ from flyte.remote._task import LazyEntity
36
38
 
37
39
  from ._code_bundle import CopyFiles
40
+ from ._internal.imagebuild.image_builder import ImageCache
38
41
 
39
42
  Mode = Literal["local", "remote", "hybrid"]
43
+ CacheLookupScope = Literal["global", "project-domain"]
44
+
45
+
46
+ @dataclass(frozen=True)
47
+ class _CacheKey:
48
+ obj_id: int
49
+ dry_run: bool
50
+
51
+
52
+ @dataclass(frozen=True)
53
+ class _CacheValue:
54
+ code_bundle: CodeBundle | None
55
+ image_cache: Optional[ImageCache]
56
+
57
+
58
+ _RUN_CACHE: Dict[_CacheKey, _CacheValue] = {}
59
+
60
+
61
+ async def _get_code_bundle_for_run(name: str) -> CodeBundle | None:
62
+ """
63
+ Get the code bundle for the run with the given name.
64
+ This is used to get the code bundle for the run when running in hybrid mode.
65
+ """
66
+ from flyte._internal.runtime.task_serde import extract_code_bundle
67
+ from flyte.remote import Run
68
+
69
+ run = await Run.get.aio(name=name)
70
+ if run:
71
+ run_details = await run.details.aio()
72
+ spec = run_details.action_details.pb2.resolved_task_spec
73
+ return extract_code_bundle(spec)
74
+ return None
40
75
 
41
76
 
42
- @syncer.wrap
43
77
  class _Runner:
44
78
  def __init__(
45
79
  self,
@@ -54,13 +88,29 @@ class _Runner:
54
88
  raw_data_path: str | None = None,
55
89
  metadata_path: str | None = None,
56
90
  run_base_dir: str | None = None,
91
+ overwrite_cache: bool = False,
92
+ project: str | None = None,
93
+ domain: str | None = None,
94
+ env_vars: Dict[str, str] | None = None,
95
+ labels: Dict[str, str] | None = None,
96
+ annotations: Dict[str, str] | None = None,
97
+ interruptible: bool | None = None,
98
+ log_level: int | None = None,
99
+ log_format: LogFormat = "console",
100
+ reset_root_logger: bool = False,
101
+ disable_run_cache: bool = False,
102
+ queue: Optional[str] = None,
103
+ custom_context: Dict[str, str] | None = None,
104
+ cache_lookup_scope: CacheLookupScope = "global",
57
105
  ):
106
+ from flyte._tools import ipython_check
107
+
58
108
  init_config = _get_init_config()
59
109
  client = init_config.client if init_config else None
60
110
  if not force_mode and client is not None:
61
111
  force_mode = "remote"
62
112
  force_mode = force_mode or "local"
63
- logger.debug(f"Effective run mode: {force_mode}, client configured: {client is not None}")
113
+ logger.debug(f"Effective run mode: `{force_mode}`, client configured: `{client is not None}`")
64
114
  self._mode = force_mode
65
115
  self._name = name
66
116
  self._service_account = service_account
@@ -70,105 +120,249 @@ class _Runner:
70
120
  self._copy_bundle_to = copy_bundle_to
71
121
  self._interactive_mode = interactive_mode if interactive_mode else ipython_check()
72
122
  self._raw_data_path = raw_data_path
73
- self._metadata_path = metadata_path or "/tmp"
74
- self._run_base_dir = run_base_dir or "/tmp/base"
123
+ self._metadata_path = metadata_path
124
+ self._run_base_dir = run_base_dir
125
+ self._overwrite_cache = overwrite_cache
126
+ self._project = project
127
+ self._domain = domain
128
+ self._env_vars = env_vars
129
+ self._labels = labels
130
+ self._annotations = annotations
131
+ self._interruptible = interruptible
132
+ self._log_level = log_level
133
+ self._log_format = log_format
134
+ self._reset_root_logger = reset_root_logger
135
+ self._disable_run_cache = disable_run_cache
136
+ self._queue = queue
137
+ self._custom_context = custom_context or {}
138
+ self._cache_lookup_scope = cache_lookup_scope
75
139
 
76
140
  @requires_initialization
77
- async def _run_remote(self, obj: TaskTemplate[P, R], *args: P.args, **kwargs: P.kwargs) -> Run:
141
+ async def _run_remote(self, obj: TaskTemplate[P, R, F] | LazyEntity, *args: P.args, **kwargs: P.kwargs) -> Run:
142
+ import grpc
143
+ from flyteidl2.common import identifier_pb2
144
+ from flyteidl2.core import literals_pb2, security_pb2
145
+ from flyteidl2.task import run_pb2
146
+ from flyteidl2.workflow import run_definition_pb2, run_service_pb2
147
+ from google.protobuf import wrappers_pb2
148
+
78
149
  from flyte.remote import Run
150
+ from flyte.remote._task import LazyEntity, TaskDetails
79
151
 
80
152
  from ._code_bundle import build_code_bundle, build_pkl_bundle
81
- from ._deploy import build_images, plan_deploy
153
+ from ._deploy import build_images
82
154
  from ._internal.runtime.convert import convert_from_native_to_inputs
83
155
  from ._internal.runtime.task_serde import translate_task_to_wire
84
- from ._protos.workflow import run_definition_pb2, run_service_pb2
85
156
 
86
- cfg = get_common_config()
157
+ cfg = get_init_config()
158
+ project = self._project or cfg.project
159
+ domain = self._domain or cfg.domain
87
160
 
88
- if obj.parent_env is None:
89
- raise ValueError("Task is not attached to an environment. Please attach the task to an environment.")
90
-
91
- deploy_plan = plan_deploy(cast(Environment, obj.parent_env()))
92
- image_cache = await build_images(deploy_plan)
161
+ task: TaskTemplate[P, R, F] | TaskDetails
162
+ if isinstance(obj, (LazyEntity, TaskDetails)):
163
+ if isinstance(obj, LazyEntity):
164
+ task = await obj.fetch.aio()
165
+ else:
166
+ task = obj
167
+ task_spec = task.pb2.spec
168
+ inputs = await convert_from_native_to_inputs(
169
+ task.interface, *args, custom_context=self._custom_context, **kwargs
170
+ )
171
+ version = task.pb2.task_id.version
172
+ code_bundle = None
173
+ elif isinstance(obj, TaskTemplate):
174
+ task = cast(TaskTemplate[P, R, F], obj)
175
+ if obj.parent_env is None:
176
+ raise ValueError("Task is not attached to an environment. Please attach the task to an environment")
177
+
178
+ if (
179
+ not self._disable_run_cache
180
+ and _RUN_CACHE.get(_CacheKey(obj_id=id(obj), dry_run=self._dry_run)) is not None
181
+ ):
182
+ cached_value = _RUN_CACHE[_CacheKey(obj_id=id(obj), dry_run=self._dry_run)]
183
+ code_bundle = cached_value.code_bundle
184
+ image_cache = cached_value.image_cache
185
+ else:
186
+ if not self._dry_run:
187
+ image_cache = await build_images.aio(cast(Environment, obj.parent_env()))
188
+ else:
189
+ image_cache = None
190
+
191
+ if self._interactive_mode:
192
+ code_bundle = await build_pkl_bundle(
193
+ obj,
194
+ upload_to_controlplane=not self._dry_run,
195
+ copy_bundle_to=self._copy_bundle_to,
196
+ )
197
+ else:
198
+ if self._copy_files != "none":
199
+ code_bundle = await build_code_bundle(
200
+ from_dir=cfg.root_dir,
201
+ dryrun=self._dry_run,
202
+ copy_bundle_to=self._copy_bundle_to,
203
+ copy_style=self._copy_files,
204
+ )
205
+ else:
206
+ code_bundle = None
207
+ if not self._disable_run_cache:
208
+ _RUN_CACHE[_CacheKey(obj_id=id(obj), dry_run=self._dry_run)] = _CacheValue(
209
+ code_bundle=code_bundle, image_cache=image_cache
210
+ )
93
211
 
94
- if self._interactive_mode:
95
- code_bundle = await build_pkl_bundle(
96
- obj, upload_to_controlplane=not self._dry_run, copy_bundle_to=self._copy_bundle_to
212
+ version = self._version or (
213
+ code_bundle.computed_version if code_bundle and code_bundle.computed_version else None
214
+ )
215
+ if not version:
216
+ raise ValueError("Version is required when running a task")
217
+ s_ctx = SerializationContext(
218
+ code_bundle=code_bundle,
219
+ version=version,
220
+ image_cache=image_cache,
221
+ root_dir=cfg.root_dir,
222
+ )
223
+ task_spec = translate_task_to_wire(obj, s_ctx)
224
+ inputs = await convert_from_native_to_inputs(
225
+ obj.native_interface, *args, custom_context=self._custom_context, **kwargs
97
226
  )
98
227
  else:
99
- if self._copy_files != "none":
100
- code_bundle = await build_code_bundle(
101
- from_dir=cfg.root_dir, dryrun=self._dry_run, copy_bundle_to=self._copy_bundle_to
102
- )
103
- else:
104
- code_bundle = None
228
+ raise ValueError(f"Not supported Task Type: {type(task)}")
105
229
 
106
- version = self._version or (
107
- code_bundle.computed_version if code_bundle and code_bundle.computed_version else None
108
- )
109
- if not version:
110
- raise ValueError("Version is required when running a task")
111
- s_ctx = SerializationContext(
112
- code_bundle=code_bundle,
113
- version=version,
114
- image_cache=image_cache,
115
- root_dir=cfg.root_dir,
116
- )
117
- task_spec = translate_task_to_wire(obj, s_ctx)
118
- inputs = await convert_from_native_to_inputs(obj.native_interface, *args, **kwargs)
230
+ env = self._env_vars or {}
231
+ if env.get("LOG_LEVEL") is None:
232
+ if self._log_level:
233
+ env["LOG_LEVEL"] = str(self._log_level)
234
+ else:
235
+ env["LOG_LEVEL"] = str(logger.getEffectiveLevel())
236
+ env["LOG_FORMAT"] = self._log_format
237
+ if self._reset_root_logger:
238
+ env["FLYTE_RESET_ROOT_LOGGER"] = "1"
239
+
240
+ # These paths will be appended to sys.path at runtime.
241
+ if cfg.sync_local_sys_paths:
242
+ env[FLYTE_SYS_PATH] = ":".join(
243
+ f"./{pathlib.Path(p).relative_to(cfg.root_dir)}" for p in sys.path if p.startswith(str(cfg.root_dir))
244
+ )
119
245
 
120
246
  if not self._dry_run:
121
247
  if get_client() is None:
122
248
  # This can only happen, if the user forces flyte.run(mode="remote") without initializing the client
123
- raise InitializationError(
249
+ raise flyte.errors.InitializationError(
124
250
  "ClientNotInitializedError",
125
251
  "user",
126
252
  "flyte.run requires client to be initialized. "
127
- "Call flyte.init() with a valid endpoint or api-key before using this function.",
253
+ "Call flyte.init() with a valid endpoint/api-key before using this function"
254
+ "or Call flyte.init_from_config() with a valid path to the config file",
128
255
  )
129
256
  run_id = None
130
257
  project_id = None
131
258
  if self._name:
132
- run_id = run_definition_pb2.RunIdentifier(
133
- project=cfg.project,
134
- domain=cfg.domain,
259
+ run_id = identifier_pb2.RunIdentifier(
260
+ project=project,
261
+ domain=domain,
135
262
  org=cfg.org,
136
263
  name=self._name if self._name else None,
137
264
  )
138
265
  else:
139
266
  project_id = identifier_pb2.ProjectIdentifier(
140
- name=cfg.project,
141
- domain=cfg.domain,
267
+ name=project,
268
+ domain=domain,
142
269
  organization=cfg.org,
143
270
  )
144
271
  # Fill in task id inside the task template if it's not provided.
145
272
  # Maybe this should be done here, or the backend.
146
273
  if task_spec.task_template.id.project == "":
147
- task_spec.task_template.id.project = cfg.project if cfg.project else ""
274
+ task_spec.task_template.id.project = project if project else ""
148
275
  if task_spec.task_template.id.domain == "":
149
- task_spec.task_template.id.domain = cfg.domain if cfg.domain else ""
276
+ task_spec.task_template.id.domain = domain if domain else ""
150
277
  if task_spec.task_template.id.org == "":
151
278
  task_spec.task_template.id.org = cfg.org if cfg.org else ""
152
279
  if task_spec.task_template.id.version == "":
153
280
  task_spec.task_template.id.version = version
154
281
 
155
- resp = await get_client().run_service.CreateRun(
156
- run_service_pb2.CreateRunRequest(
157
- run_id=run_id,
158
- project_id=project_id,
159
- task_spec=task_spec,
160
- inputs=inputs.proto_inputs,
161
- ),
282
+ kv_pairs: List[literals_pb2.KeyValuePair] = []
283
+ for k, v in env.items():
284
+ if not isinstance(v, str):
285
+ raise ValueError(f"Environment variable {k} must be a string, got {type(v)}")
286
+ kv_pairs.append(literals_pb2.KeyValuePair(key=k, value=v))
287
+
288
+ env_kv = run_pb2.Envs(values=kv_pairs)
289
+ annotations = run_pb2.Annotations(values=self._annotations)
290
+ labels = run_pb2.Labels(values=self._labels)
291
+ raw_data_storage = (
292
+ run_pb2.RawDataStorage(raw_data_prefix=self._raw_data_path) if self._raw_data_path else None
293
+ )
294
+ security_context = (
295
+ security_pb2.SecurityContext(run_as=security_pb2.Identity(k8s_service_account=self._service_account))
296
+ if self._service_account
297
+ else None
162
298
  )
163
- return Run(pb2=resp.run)
299
+
300
+ def _to_cache_lookup_scope(scope: CacheLookupScope | None = None) -> run_pb2.CacheLookupScope:
301
+ if scope == "global":
302
+ return run_pb2.CacheLookupScope.CACHE_LOOKUP_SCOPE_GLOBAL
303
+ elif scope == "project-domain":
304
+ return run_pb2.CacheLookupScope.CACHE_LOOKUP_SCOPE_PROJECT_DOMAIN
305
+ elif scope is None:
306
+ return run_pb2.CacheLookupScope.CACHE_LOOKUP_SCOPE_UNSPECIFIED
307
+ else:
308
+ raise ValueError(f"Unknown cache lookup scope: {scope}")
309
+
310
+ try:
311
+ resp = await get_client().run_service.CreateRun(
312
+ run_service_pb2.CreateRunRequest(
313
+ run_id=run_id,
314
+ project_id=project_id,
315
+ task_spec=task_spec,
316
+ inputs=inputs.proto_inputs,
317
+ run_spec=run_pb2.RunSpec(
318
+ overwrite_cache=self._overwrite_cache,
319
+ interruptible=wrappers_pb2.BoolValue(value=self._interruptible)
320
+ if self._interruptible is not None
321
+ else None,
322
+ annotations=annotations,
323
+ labels=labels,
324
+ envs=env_kv,
325
+ cluster=self._queue or task.queue,
326
+ raw_data_storage=raw_data_storage,
327
+ security_context=security_context,
328
+ cache_config=run_pb2.CacheConfig(
329
+ overwrite_cache=self._overwrite_cache,
330
+ cache_lookup_scope=_to_cache_lookup_scope(self._cache_lookup_scope)
331
+ if self._cache_lookup_scope
332
+ else None,
333
+ ),
334
+ ),
335
+ ),
336
+ )
337
+ return Run(pb2=resp.run)
338
+ except grpc.aio.AioRpcError as e:
339
+ if e.code() == grpc.StatusCode.UNAVAILABLE:
340
+ raise flyte.errors.RuntimeSystemError(
341
+ "SystemUnavailableError",
342
+ "Flyte system is currently unavailable. check your configuration, or the service status.",
343
+ ) from e
344
+ elif e.code() == grpc.StatusCode.INVALID_ARGUMENT:
345
+ raise flyte.errors.RuntimeUserError("InvalidArgumentError", e.details())
346
+ elif e.code() == grpc.StatusCode.ALREADY_EXISTS:
347
+ # TODO maybe this should be a pass and return existing run?
348
+ raise flyte.errors.RuntimeUserError(
349
+ "RunAlreadyExistsError",
350
+ f"A run with the name '{self._name}' already exists. Please choose a different name.",
351
+ )
352
+ else:
353
+ raise flyte.errors.RuntimeSystemError(
354
+ "RunCreationError",
355
+ f"Failed to create run: {e.details()}",
356
+ ) from e
164
357
 
165
358
  class DryRun(Run):
166
359
  def __init__(self, _task_spec, _inputs, _code_bundle):
167
360
  super().__init__(
168
361
  pb2=run_definition_pb2.Run(
169
362
  action=run_definition_pb2.Action(
170
- id=run_definition_pb2.ActionIdentifier(
171
- name="a0", run=run_definition_pb2.RunIdentifier(name="dry-run")
363
+ id=identifier_pb2.ActionIdentifier(
364
+ name="a0",
365
+ run=identifier_pb2.RunIdentifier(name="dry-run"),
172
366
  )
173
367
  )
174
368
  )
@@ -181,35 +375,50 @@ class _Runner:
181
375
 
182
376
  @requires_storage
183
377
  @requires_initialization
184
- async def _run_hybrid(self, obj: TaskTemplate[P, R], *args: P.args, **kwargs: P.kwargs) -> R:
378
+ async def _run_hybrid(self, obj: TaskTemplate[P, R, F], *args: P.args, **kwargs: P.kwargs) -> R:
185
379
  """
186
380
  Run a task in hybrid mode. This means that the parent action will be run locally, but the child actions will be
187
381
  run in the cluster remotely. This is currently only used for testing,
188
382
  over the longer term we will productize this.
189
383
  """
384
+ import flyte.report
190
385
  from flyte._code_bundle import build_code_bundle, build_pkl_bundle
191
- from flyte._datastructures import RawDataPath
192
- from flyte._deploy import build_images, plan_deploy
386
+ from flyte._deploy import build_images
387
+ from flyte.models import RawDataPath
388
+ from flyte.storage import ABFS, GCS, S3
193
389
 
194
- cfg = get_common_config()
390
+ from ._internal import create_controller
391
+ from ._internal.runtime.taskrunner import run_task
392
+
393
+ cfg = get_init_config()
195
394
 
196
395
  if obj.parent_env is None:
197
396
  raise ValueError("Task is not attached to an environment. Please attach the task to an environment.")
198
397
 
199
- deploy_plan = plan_deploy(cast(Environment, obj.parent_env()))
200
- image_cache = await build_images(deploy_plan)
398
+ image_cache = await build_images.aio(cast(Environment, obj.parent_env()))
201
399
 
202
- if self._interactive_mode:
203
- code_bundle = await build_pkl_bundle(
204
- obj, upload_to_controlplane=not self._dry_run, copy_bundle_to=self._copy_bundle_to
205
- )
206
- else:
207
- if self._copy_files != "none":
208
- code_bundle = await build_code_bundle(
209
- from_dir=cfg.root_dir, dryrun=self._dry_run, copy_bundle_to=self._copy_bundle_to
400
+ code_bundle = None
401
+ if self._name is not None:
402
+ # Check if remote run service has this run name already and if exists, then extract the code bundle from it.
403
+ code_bundle = await _get_code_bundle_for_run(name=self._name)
404
+
405
+ if not code_bundle:
406
+ if self._interactive_mode:
407
+ code_bundle = await build_pkl_bundle(
408
+ obj,
409
+ upload_to_controlplane=not self._dry_run,
410
+ copy_bundle_to=self._copy_bundle_to,
210
411
  )
211
412
  else:
212
- code_bundle = None
413
+ if self._copy_files != "none":
414
+ code_bundle = await build_code_bundle(
415
+ from_dir=cfg.root_dir,
416
+ dryrun=self._dry_run,
417
+ copy_bundle_to=self._copy_bundle_to,
418
+ copy_style=self._copy_files,
419
+ )
420
+ else:
421
+ code_bundle = None
213
422
 
214
423
  version = self._version or (
215
424
  code_bundle.computed_version if code_bundle and code_bundle.computed_version else None
@@ -217,14 +426,14 @@ class _Runner:
217
426
  if not version:
218
427
  raise ValueError("Version is required when running a task")
219
428
 
220
- project = cfg.project or "testproject"
221
- domain = cfg.domain or "development"
222
- org = cfg.org or "testorg"
429
+ project = cfg.project
430
+ domain = cfg.domain
431
+ org = cfg.org
223
432
  action_name = "a0"
224
433
  run_name = self._name
225
434
  random_id = str(uuid.uuid4())[:6]
226
435
 
227
- controller = create_controller(ct="remote", endpoint="localhost:8090", insecure=True)
436
+ controller = create_controller("remote", endpoint="localhost:8090", insecure=True)
228
437
  action = ActionID(name=action_name, run_name=run_name, project=project, domain=domain, org=org)
229
438
 
230
439
  inputs = obj.native_interface.convert_to_kwargs(*args, **kwargs)
@@ -240,9 +449,10 @@ class _Runner:
240
449
  " flyte.with_runcontext(run_base_dir='s3://bucket/metadata/outputs')",
241
450
  )
242
451
  output_path = self._run_base_dir
452
+ run_base_dir = self._run_base_dir
243
453
  raw_data_path = f"{output_path}/rd/{random_id}"
244
454
  raw_data_path_obj = RawDataPath(path=raw_data_path)
245
- checkpoint_path = f"{raw_data_path}/{_CHECKPOINT_FILE_NAME}"
455
+ checkpoint_path = f"{raw_data_path}/checkpoint"
246
456
  prev_checkpoint = f"{raw_data_path}/prev_checkpoint"
247
457
  checkpoints = Checkpoints(checkpoint_path, prev_checkpoint)
248
458
 
@@ -253,11 +463,12 @@ class _Runner:
253
463
  checkpoints=checkpoints,
254
464
  code_bundle=code_bundle,
255
465
  output_path=output_path,
256
- version=version,
466
+ version=version if version else "na",
257
467
  raw_data_path=raw_data_path_obj,
258
468
  compiled_image_cache=image_cache,
259
- run_base_dir=self._run_base_dir,
469
+ run_base_dir=run_base_dir,
260
470
  report=flyte.report.Report(name=action.name),
471
+ custom_context=self._custom_context,
261
472
  )
262
473
  async with ctx.replace_task_context(tctx):
263
474
  return await run_task(tctx=tctx, controller=controller, task=obj, inputs=inputs)
@@ -267,45 +478,101 @@ class _Runner:
267
478
  raise err
268
479
  return outputs
269
480
 
270
- async def _run_local(self, obj: TaskTemplate[P, R], *args: P.args, **kwargs: P.kwargs) -> R:
481
+ async def _run_local(self, obj: TaskTemplate[P, R, F], *args: P.args, **kwargs: P.kwargs) -> Run:
482
+ from flyteidl2.common import identifier_pb2
483
+
271
484
  from flyte._internal.controllers import create_controller
272
- from flyte._internal.runtime.convert import (
273
- convert_error_to_native,
274
- convert_from_native_to_inputs,
275
- convert_outputs_to_native,
276
- )
277
- from flyte._internal.runtime.entrypoints import direct_dispatch
485
+ from flyte._internal.controllers._local_controller import LocalController
486
+ from flyte.remote import ActionOutputs, Run
487
+ from flyte.report import Report
278
488
 
279
- controller = create_controller(ct="local")
489
+ controller = cast(LocalController, create_controller("local"))
280
490
 
281
- inputs = await convert_from_native_to_inputs(obj.native_interface, *args, **kwargs)
282
491
  if self._name is None:
283
492
  action = ActionID.create_random()
284
493
  else:
285
494
  action = ActionID(name=self._name)
286
- out, err = await direct_dispatch(
287
- obj,
495
+
496
+ metadata_path = self._metadata_path
497
+ if metadata_path is None:
498
+ metadata_path = pathlib.Path("/") / "tmp" / "flyte" / "metadata" / action.name
499
+ else:
500
+ metadata_path = pathlib.Path(metadata_path) / action.name
501
+ output_path = metadata_path / "a0"
502
+ if self._raw_data_path is None:
503
+ path = pathlib.Path("/") / "tmp" / "flyte" / "raw_data" / action.name
504
+ raw_data_path = RawDataPath(path=str(path))
505
+ else:
506
+ raw_data_path = RawDataPath(path=self._raw_data_path)
507
+
508
+ ctx = internal_ctx()
509
+ tctx = TaskContext(
288
510
  action=action,
289
- raw_data_path=internal_ctx().raw_data,
290
- version="na",
291
- controller=controller,
292
- inputs=inputs,
293
- output_path=self._metadata_path,
294
- run_base_dir=self._metadata_path,
295
511
  checkpoints=Checkpoints(
296
- prev_checkpoint_path=internal_ctx().raw_data.path, checkpoint_path=internal_ctx().raw_data.path
512
+ prev_checkpoint_path=internal_ctx().raw_data.path,
513
+ checkpoint_path=internal_ctx().raw_data.path,
297
514
  ),
298
- ) # type: ignore
299
- if err:
300
- native_err = convert_error_to_native(err)
301
- if native_err:
302
- raise native_err
303
- if obj.native_interface.outputs and len(obj.native_interface.outputs) > 0:
304
- if out is not None:
305
- return cast(R, await convert_outputs_to_native(obj.native_interface, out))
306
- return cast(R, None)
307
-
308
- async def run(self, task: TaskTemplate[P, Union[R, Run]], *args: P.args, **kwargs: P.kwargs) -> Union[R, Run]:
515
+ code_bundle=None,
516
+ output_path=str(output_path),
517
+ run_base_dir=str(metadata_path),
518
+ version="na",
519
+ raw_data_path=raw_data_path,
520
+ compiled_image_cache=None,
521
+ report=Report(name=action.name),
522
+ mode="local",
523
+ custom_context=self._custom_context,
524
+ )
525
+
526
+ with ctx.replace_task_context(tctx):
527
+ # make the local version always runs on a different thread, returns a wrapped future.
528
+ if obj._call_as_synchronous:
529
+ fut = controller.submit_sync(obj, *args, **kwargs)
530
+ awaitable = asyncio.wrap_future(fut)
531
+ outputs = await awaitable
532
+ else:
533
+ outputs = await controller.submit(obj, *args, **kwargs)
534
+
535
+ class _LocalRun(Run):
536
+ def __init__(self, outputs: Tuple[Any, ...] | Any):
537
+ from flyteidl2.workflow import run_definition_pb2
538
+
539
+ self._outputs = outputs
540
+ super().__init__(
541
+ pb2=run_definition_pb2.Run(
542
+ action=run_definition_pb2.Action(
543
+ id=identifier_pb2.ActionIdentifier(
544
+ name="a0",
545
+ run=identifier_pb2.RunIdentifier(name="dry-run"),
546
+ )
547
+ )
548
+ )
549
+ )
550
+
551
+ @property
552
+ def url(self) -> str:
553
+ return str(metadata_path)
554
+
555
+ @syncify
556
+ async def wait( # type: ignore[override]
557
+ self,
558
+ quiet: bool = False,
559
+ wait_for: Literal["terminal", "running"] = "terminal",
560
+ ) -> None:
561
+ pass
562
+
563
+ @syncify
564
+ async def outputs(self) -> ActionOutputs: # type: ignore[override]
565
+ return cast(ActionOutputs, self._outputs)
566
+
567
+ return _LocalRun(outputs)
568
+
569
+ @syncify # type: ignore[arg-type]
570
+ async def run(
571
+ self,
572
+ task: TaskTemplate[P, Union[R, Run], F] | LazyEntity,
573
+ *args: P.args,
574
+ **kwargs: P.kwargs,
575
+ ) -> Union[R, Run]:
309
576
  """
310
577
  Run an async `@env.task` or `TaskTemplate` instance. The existing async context will be used.
311
578
 
@@ -327,13 +594,22 @@ class _Runner:
327
594
  :param kwargs: Keyword arguments to pass to the Task
328
595
  :return: Run instance or the result of the task
329
596
  """
597
+ from flyte.remote._task import LazyEntity, TaskDetails
598
+
599
+ if isinstance(task, (LazyEntity, TaskDetails)) and self._mode != "remote":
600
+ raise ValueError("Remote task can only be run in remote mode.")
601
+
602
+ if not isinstance(task, TaskTemplate) and not isinstance(task, (LazyEntity, TaskDetails)):
603
+ raise TypeError(f"On Flyte tasks can be run, not generic functions or methods '{type(task)}'.")
604
+
330
605
  if self._mode == "remote":
331
606
  return await self._run_remote(task, *args, **kwargs)
607
+ task = cast(TaskTemplate, task)
332
608
  if self._mode == "hybrid":
333
609
  return await self._run_hybrid(task, *args, **kwargs)
334
610
 
335
611
  # TODO We could use this for remote as well and users could simply pass flyte:// or s3:// or file://
336
- async with internal_ctx().new_raw_data_path(
612
+ with internal_ctx().new_raw_data_path(
337
613
  raw_data_path=RawDataPath.from_local_folder(local_folder=self._raw_data_path)
338
614
  ):
339
615
  return await self._run_local(task, *args, **kwargs)
@@ -351,6 +627,20 @@ def with_runcontext(
351
627
  interactive_mode: bool | None = None,
352
628
  raw_data_path: str | None = None,
353
629
  run_base_dir: str | None = None,
630
+ overwrite_cache: bool = False,
631
+ project: str | None = None,
632
+ domain: str | None = None,
633
+ env_vars: Dict[str, str] | None = None,
634
+ labels: Dict[str, str] | None = None,
635
+ annotations: Dict[str, str] | None = None,
636
+ interruptible: bool | None = None,
637
+ log_level: int | None = None,
638
+ log_format: LogFormat = "console",
639
+ reset_root_logger: bool = False,
640
+ disable_run_cache: bool = False,
641
+ queue: Optional[str] = None,
642
+ custom_context: Dict[str, str] | None = None,
643
+ cache_lookup_scope: CacheLookupScope = "global",
354
644
  ) -> _Runner:
355
645
  """
356
646
  Launch a new run with the given parameters as the context.
@@ -378,12 +668,37 @@ def with_runcontext(
378
668
  :param interactive_mode: Optional, can be forced to True or False.
379
669
  If not provided, it will be set based on the current environment. For example Jupyter notebooks are considered
380
670
  interactive mode, while scripts are not. This is used to determine how the code bundle is created.
381
- :param raw_data_path: Use this path to store the raw data for the run. Currently only supported for local runs,
382
- and can be used to store raw data in specific locations. TODO coming soon for remote runs as well.
671
+ :param raw_data_path: Use this path to store the raw data for the run for local and remote, and can be used to
672
+ store raw data in specific locations.
673
+ :param run_base_dir: Optional The base directory to use for the run. This is used to store the metadata for the run,
674
+ that is passed between tasks.
675
+ :param overwrite_cache: Optional If true, the cache will be overwritten for the run
676
+ :param project: Optional The project to use for the run
677
+ :param domain: Optional The domain to use for the run
678
+ :param env_vars: Optional Environment variables to set for the run
679
+ :param labels: Optional Labels to set for the run
680
+ :param annotations: Optional Annotations to set for the run
681
+ :param interruptible: Optional If true, the run can be scheduled on interruptible instances and false implies
682
+ that all tasks in the run should only be scheduled on non-interruptible instances. If not specified the
683
+ original setting on all tasks is retained.
684
+ :param log_level: Optional Log level to set for the run. If not provided, it will be set to the default log level
685
+ set using `flyte.init()`
686
+ :param log_format: Optional Log format to set for the run. If not provided, it will be set to the default log format
687
+ :param reset_root_logger: If true, the root logger will be preserved and not modified by Flyte.
688
+ :param disable_run_cache: Optional If true, the run cache will be disabled. This is useful for testing purposes.
689
+ :param queue: Optional The queue to use for the run. This is used to specify the cluster to use for the run.
690
+ :param custom_context: Optional global input context to pass to the task. This will be available via
691
+ get_custom_context() within the task and will automatically propagate to sub-tasks.
692
+ Acts as base/default values that can be overridden by context managers in the code.
693
+ :param cache_lookup_scope: Optional Scope to use for the run. This is used to specify the scope to use for cache
694
+ lookups. If not specified, it will be set to the default scope (global unless overridden at the system level).
695
+
383
696
  :return: runner
384
697
  """
385
698
  if mode == "hybrid" and not name and not run_base_dir:
386
699
  raise ValueError("Run name and run base dir are required for hybrid mode")
700
+ if copy_style == "none" and not version:
701
+ raise ValueError("Version is required when copy_style is 'none'")
387
702
  return _Runner(
388
703
  force_mode=mode,
389
704
  name=name,
@@ -395,11 +710,25 @@ def with_runcontext(
395
710
  interactive_mode=interactive_mode,
396
711
  raw_data_path=raw_data_path,
397
712
  run_base_dir=run_base_dir,
713
+ overwrite_cache=overwrite_cache,
714
+ env_vars=env_vars,
715
+ labels=labels,
716
+ annotations=annotations,
717
+ interruptible=interruptible,
718
+ project=project,
719
+ domain=domain,
720
+ log_level=log_level,
721
+ log_format=log_format,
722
+ reset_root_logger=reset_root_logger,
723
+ disable_run_cache=disable_run_cache,
724
+ queue=queue,
725
+ custom_context=custom_context,
726
+ cache_lookup_scope=cache_lookup_scope,
398
727
  )
399
728
 
400
729
 
401
- @syncer.wrap
402
- async def run(task: TaskTemplate[P, R], *args: P.args, **kwargs: P.kwargs) -> Union[R, Run]:
730
+ @syncify
731
+ async def run(task: TaskTemplate[P, R, F], *args: P.args, **kwargs: P.kwargs) -> Run:
403
732
  """
404
733
  Run a task with the given parameters
405
734
  :param task: task to run