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/_interface.py CHANGED
@@ -1,10 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import inspect
4
- from typing import Dict, Generator, Tuple, Type, TypeVar, Union, cast, get_args, get_type_hints
4
+ import typing
5
+ from enum import Enum
6
+ from typing import Dict, Generator, Literal, Tuple, Type, TypeVar, Union, cast, get_args, get_origin, get_type_hints
5
7
 
6
8
  from flyte._logging import logger
7
9
 
10
+ LITERAL_ENUM = "LiteralEnum"
11
+
8
12
 
9
13
  def default_output_name(index: int = 0) -> str:
10
14
  return f"o{index}"
@@ -47,6 +51,8 @@ def extract_return_annotation(return_annotation: Union[Type, Tuple, None]) -> Di
47
51
  Note that Options 1 and 2 are identical, just syntactic sugar. In the NamedTuple case, we'll use the names in the
48
52
  definition. In all other cases, we'll automatically generate output names, indexed starting at 0.
49
53
  """
54
+ if isinstance(return_annotation, str):
55
+ raise TypeError("String return annotations are not supported.")
50
56
 
51
57
  # Handle Option 6
52
58
  # We can think about whether we should add a default output name with type None in the future.
@@ -62,16 +68,24 @@ def extract_return_annotation(return_annotation: Union[Type, Tuple, None]) -> Di
62
68
  # Options 1 and 2
63
69
  bases = return_annotation.__bases__ # type: ignore
64
70
  if len(bases) == 1 and bases[0] is tuple and hasattr(return_annotation, "_fields"):
65
- logger.debug(f"Task returns named tuple {return_annotation}")
71
+ # Task returns named tuple
66
72
  return dict(get_type_hints(cast(Type, return_annotation), include_extras=True))
67
73
 
68
74
  if hasattr(return_annotation, "__origin__") and return_annotation.__origin__ is tuple: # type: ignore
69
75
  # Handle option 3
70
- logger.debug(f"Task returns unnamed typing.Tuple {return_annotation}")
76
+ # Task returns unnamed typing.Tuple
71
77
  if len(return_annotation.__args__) == 1: # type: ignore
72
78
  raise TypeError("Tuples should be used to indicate multiple return values, found only one return variable.")
73
79
  ra = get_args(return_annotation)
74
- return dict(zip(list(output_name_generator(len(ra))), ra))
80
+ annotations = {}
81
+ for i, r in enumerate(ra):
82
+ if r is Ellipsis:
83
+ raise TypeError("Variable length tuples are not supported as return types.")
84
+ if get_origin(r) is Literal:
85
+ annotations[default_output_name(i)] = literal_to_enum(cast(Type, r))
86
+ else:
87
+ annotations[default_output_name(i)] = r
88
+ return annotations
75
89
 
76
90
  elif isinstance(return_annotation, tuple):
77
91
  if len(return_annotation) == 1:
@@ -80,5 +94,26 @@ def extract_return_annotation(return_annotation: Union[Type, Tuple, None]) -> Di
80
94
 
81
95
  else:
82
96
  # Handle all other single return types
83
- logger.debug(f"Task returns unnamed native tuple {return_annotation}")
97
+ # Task returns unnamed native tuple
98
+ if get_origin(return_annotation) is Literal:
99
+ return {default_output_name(): literal_to_enum(cast(Type, return_annotation))}
84
100
  return {default_output_name(): cast(Type, return_annotation)}
101
+
102
+
103
+ def literal_to_enum(literal_type: Type) -> Type[Enum | typing.Any]:
104
+ """Convert a Literal[...] into Union[str, Enum]."""
105
+
106
+ if get_origin(literal_type) is not Literal:
107
+ raise TypeError(f"{literal_type} is not a Literal")
108
+
109
+ values = get_args(literal_type)
110
+ if not all(isinstance(v, str) for v in values):
111
+ logger.warning(f"Literal type {literal_type} contains non-string values, using Any instead of Enum")
112
+ return typing.Any
113
+ # Deduplicate & keep order
114
+ enum_dict = {str(v).upper(): v for v in values}
115
+
116
+ # Dynamically create an Enum
117
+ literal_enum = Enum(LITERAL_ENUM, enum_dict) # type: ignore
118
+
119
+ return literal_enum # type: ignore
@@ -1,14 +1,19 @@
1
+ import concurrent.futures
1
2
  import threading
2
- from typing import Any, Literal, Optional, Protocol, Tuple, TypeVar
3
+ from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, Protocol, Tuple, TypeVar
3
4
 
4
- from flyte._datastructures import ActionID, NativeInterface
5
5
  from flyte._task import TaskTemplate
6
+ from flyte.models import ActionID, NativeInterface
7
+
8
+ if TYPE_CHECKING:
9
+ from flyte.remote._task import TaskDetails
6
10
 
7
11
  from ._trace import TraceInfo
8
12
 
9
13
  __all__ = ["Controller", "ControllerType", "TraceInfo", "create_controller", "get_controller"]
10
14
 
11
- from ..._protos.workflow import task_definition_pb2
15
+ if TYPE_CHECKING:
16
+ import concurrent.futures
12
17
 
13
18
  ControllerType = Literal["local", "remote"]
14
19
 
@@ -28,7 +33,16 @@ class Controller(Protocol):
28
33
  """
29
34
  ...
30
35
 
31
- async def submit_task_ref(self, _task: task_definition_pb2.TaskDetails, *args, **kwargs) -> Any:
36
+ def submit_sync(self, _task: TaskTemplate, *args, **kwargs) -> concurrent.futures.Future:
37
+ """
38
+ This should call the async submit method above, but return a concurrent Future object that can be
39
+ used in a blocking wait or wrapped in an async future. This is called when
40
+ a) a synchronous task is kicked off locally,
41
+ b) a running task (of either kind) kicks off a downstream synchronous task.
42
+ """
43
+ ...
44
+
45
+ async def submit_task_ref(self, _task: "TaskDetails", *args, **kwargs) -> Any:
32
46
  """
33
47
  Submit a task reference to the controller asynchronously and wait for the result. This is async and will block
34
48
  the current coroutine until the result is available.
@@ -47,12 +61,12 @@ class Controller(Protocol):
47
61
  async def watch_for_errors(self): ...
48
62
 
49
63
  async def get_action_outputs(
50
- self, _interface: NativeInterface, _func_name: str, *args, **kwargs
64
+ self, _interface: NativeInterface, _func: Callable, *args, **kwargs
51
65
  ) -> Tuple[TraceInfo, bool]:
52
66
  """
53
67
  This method returns the outputs of the action, if it is available.
54
68
  :param _interface: NativeInterface
55
- :param _func_name: Function name
69
+ :param _func: Function name
56
70
  :param args: Arguments
57
71
  :param kwargs: Keyword arguments
58
72
  :return: TraceInfo object and a boolean indicating if the action was found.
@@ -81,13 +95,13 @@ class _ControllerState:
81
95
  lock = threading.Lock()
82
96
 
83
97
 
84
- async def get_controller() -> Controller:
98
+ def get_controller() -> Controller:
85
99
  """
86
100
  Get the controller instance. Raise an error if it has not been created.
87
101
  """
88
102
  if _ControllerState.controller is not None:
89
103
  return _ControllerState.controller
90
- raise RuntimeError("Controller is not initialized. Please call get_or_create_controller() first.")
104
+ raise RuntimeError("Controller is not initialized. Please call create_controller() first.")
91
105
 
92
106
 
93
107
  def create_controller(
@@ -1,26 +1,83 @@
1
- from typing import Any, Tuple, TypeVar
1
+ import asyncio
2
+ import atexit
3
+ import concurrent.futures
4
+ import os
5
+ import pathlib
6
+ import threading
7
+ from typing import Any, Callable, Tuple, TypeVar
2
8
 
3
9
  import flyte.errors
10
+ from flyte._cache.cache import VersionParameters, cache_from_request
11
+ from flyte._cache.local_cache import LocalTaskCache
4
12
  from flyte._context import internal_ctx
5
- from flyte._datastructures import ActionID, NativeInterface, RawDataPath
6
13
  from flyte._internal.controllers import TraceInfo
7
14
  from flyte._internal.runtime import convert
8
15
  from flyte._internal.runtime.entrypoints import direct_dispatch
16
+ from flyte._internal.runtime.types_serde import transform_native_to_typed_interface
9
17
  from flyte._logging import log, logger
10
- from flyte._protos.workflow import task_definition_pb2
11
- from flyte._task import TaskTemplate
18
+ from flyte._task import AsyncFunctionTaskTemplate, TaskTemplate
19
+ from flyte._utils.helpers import _selector_policy
20
+ from flyte.models import ActionID, NativeInterface
21
+ from flyte.remote._task import TaskDetails
12
22
 
13
23
  R = TypeVar("R")
14
24
 
15
25
 
26
+ class _TaskRunner:
27
+ """A task runner that runs an asyncio event loop on a background thread."""
28
+
29
+ def __init__(self) -> None:
30
+ self.__loop: asyncio.AbstractEventLoop | None = None
31
+ self.__runner_thread: threading.Thread | None = None
32
+ self.__lock = threading.Lock()
33
+ atexit.register(self._close)
34
+
35
+ def _close(self) -> None:
36
+ if self.__loop:
37
+ self.__loop.stop()
38
+
39
+ def _execute(self) -> None:
40
+ loop = self.__loop
41
+ assert loop is not None
42
+ try:
43
+ loop.run_forever()
44
+ finally:
45
+ loop.close()
46
+
47
+ def get_exc_handler(self):
48
+ def exc_handler(loop, context):
49
+ logger.error(
50
+ f"Taskrunner for {self.__runner_thread.name if self.__runner_thread else 'no thread'} caught"
51
+ f" exception in {loop}: {context}"
52
+ )
53
+
54
+ return exc_handler
55
+
56
+ def get_run_future(self, coro: Any) -> concurrent.futures.Future:
57
+ """Synchronously run a coroutine on a background thread."""
58
+ name = f"{threading.current_thread().name} : loop-runner"
59
+ with self.__lock:
60
+ if self.__loop is None:
61
+ with _selector_policy():
62
+ self.__loop = asyncio.new_event_loop()
63
+
64
+ exc_handler = self.get_exc_handler()
65
+ self.__loop.set_exception_handler(exc_handler)
66
+ self.__runner_thread = threading.Thread(target=self._execute, daemon=True, name=name)
67
+ self.__runner_thread.start()
68
+ fut = asyncio.run_coroutine_threadsafe(coro, self.__loop)
69
+ return fut
70
+
71
+
16
72
  class LocalController:
17
73
  def __init__(self):
18
74
  logger.debug("LocalController init")
75
+ self._runner_map: dict[str, _TaskRunner] = {}
19
76
 
20
77
  @log
21
78
  async def submit(self, _task: TaskTemplate, *args, **kwargs) -> Any:
22
79
  """
23
- Submit a node to the controller
80
+ Main entrypoint for submitting a task to the local controller.
24
81
  """
25
82
  ctx = internal_ctx()
26
83
  tctx = ctx.data.task_context
@@ -28,43 +85,100 @@ class LocalController:
28
85
  raise flyte.errors.RuntimeSystemError("BadContext", "Task context not initialized")
29
86
 
30
87
  inputs = await convert.convert_from_native_to_inputs(_task.native_interface, *args, **kwargs)
31
- sub_action_id, sub_action_output_path = convert.generate_sub_action_id_and_output_path(tctx, _task.name, inputs)
32
- sub_action_raw_data_path = RawDataPath(path=sub_action_output_path)
33
-
34
- out, err = await direct_dispatch(
35
- _task,
36
- controller=self,
37
- action=sub_action_id,
38
- raw_data_path=sub_action_raw_data_path,
39
- inputs=inputs,
40
- version=tctx.version,
41
- checkpoints=tctx.checkpoints,
42
- code_bundle=tctx.code_bundle,
43
- output_path=sub_action_output_path,
44
- run_base_dir=tctx.run_base_dir,
88
+ inputs_hash = convert.generate_inputs_hash_from_proto(inputs.proto_inputs)
89
+ task_interface = transform_native_to_typed_interface(_task.interface)
90
+
91
+ sub_action_id, sub_action_output_path = convert.generate_sub_action_id_and_output_path(
92
+ tctx, _task.name, inputs_hash, 0
93
+ )
94
+ sub_action_raw_data_path = tctx.raw_data_path
95
+ # Make sure the output path exists
96
+ pathlib.Path(sub_action_output_path).mkdir(parents=True, exist_ok=True)
97
+ pathlib.Path(sub_action_raw_data_path.path).mkdir(parents=True, exist_ok=True)
98
+
99
+ task_cache = cache_from_request(_task.cache)
100
+ cache_enabled = task_cache.is_enabled()
101
+ if isinstance(_task, AsyncFunctionTaskTemplate):
102
+ version_parameters = VersionParameters(func=_task.func, image=_task.image)
103
+ else:
104
+ version_parameters = VersionParameters(func=None, image=_task.image)
105
+ cache_version = task_cache.get_version(version_parameters)
106
+ cache_key = convert.generate_cache_key_hash(
107
+ _task.name,
108
+ inputs_hash,
109
+ task_interface,
110
+ cache_version,
111
+ list(task_cache.get_ignored_inputs()),
112
+ inputs.proto_inputs,
45
113
  )
46
- if err:
47
- exc = convert.convert_error_to_native(err)
48
- if exc:
49
- raise exc
50
- else:
51
- raise flyte.errors.RuntimeSystemError("BadError", "Unknown error")
52
- if _task.native_interface.outputs and out is not None:
114
+
115
+ out = None
116
+ # We only get output from cache if the cache behavior is set to auto
117
+ if task_cache.behavior == "auto":
118
+ out = await LocalTaskCache.get(cache_key)
119
+ if out is not None:
120
+ logger.info(
121
+ f"Cache hit for task '{_task.name}' (version: {cache_version}), getting result from cache..."
122
+ )
123
+
124
+ if out is None:
125
+ out, err = await direct_dispatch(
126
+ _task,
127
+ controller=self,
128
+ action=sub_action_id,
129
+ raw_data_path=sub_action_raw_data_path,
130
+ inputs=inputs,
131
+ version=cache_version,
132
+ checkpoints=tctx.checkpoints,
133
+ code_bundle=tctx.code_bundle,
134
+ output_path=sub_action_output_path,
135
+ run_base_dir=tctx.run_base_dir,
136
+ )
137
+
138
+ if err:
139
+ exc = convert.convert_error_to_native(err)
140
+ if exc:
141
+ raise exc
142
+ else:
143
+ raise flyte.errors.RuntimeSystemError("BadError", "Unknown error")
144
+
145
+ # store into cache
146
+ if cache_enabled and out is not None:
147
+ await LocalTaskCache.set(cache_key, out)
148
+
149
+ if _task.native_interface.outputs:
150
+ if out is None:
151
+ raise flyte.errors.RuntimeSystemError("BadOutput", "Task output not captured.")
53
152
  result = await convert.convert_outputs_to_native(_task.native_interface, out)
54
153
  return result
55
- return out
154
+ return None
155
+
156
+ def submit_sync(self, _task: TaskTemplate, *args, **kwargs) -> concurrent.futures.Future:
157
+ name = threading.current_thread().name + f"PID:{os.getpid()}"
158
+ coro = self.submit(_task, *args, **kwargs)
159
+ if name not in self._runner_map:
160
+ if len(self._runner_map) > 100:
161
+ logger.warning(
162
+ "More than 100 event loop runners created!!! This could be a case of runaway recursion..."
163
+ )
164
+ self._runner_map[name] = _TaskRunner()
165
+
166
+ return self._runner_map[name].get_run_future(coro)
56
167
 
57
168
  async def finalize_parent_action(self, action: ActionID):
58
169
  pass
59
170
 
60
171
  async def stop(self):
61
- pass
172
+ await LocalTaskCache.close()
62
173
 
63
174
  async def watch_for_errors(self):
64
- pass
175
+ try:
176
+ await asyncio.Event().wait() # Wait indefinitely until cancelled
177
+ except asyncio.CancelledError:
178
+ return # Return with no errors when cancelled
65
179
 
66
180
  async def get_action_outputs(
67
- self, _interface: NativeInterface, _func_name: str, *args, **kwargs
181
+ self, _interface: NativeInterface, _func: Callable, *args, **kwargs
68
182
  ) -> Tuple[TraceInfo, bool]:
69
183
  """
70
184
  This method returns the outputs of the action, if it is available.
@@ -75,16 +189,23 @@ class LocalController:
75
189
  tctx = ctx.data.task_context
76
190
  if not tctx:
77
191
  raise flyte.errors.NotInTaskContextError("BadContext", "Task context not initialized")
192
+
78
193
  converted_inputs = convert.Inputs.empty()
79
194
  if _interface.inputs:
80
195
  converted_inputs = await convert.convert_from_native_to_inputs(_interface, *args, **kwargs)
81
196
  assert converted_inputs
197
+
198
+ inputs_hash = convert.generate_inputs_hash_from_proto(converted_inputs.proto_inputs)
82
199
  action_id, action_output_path = convert.generate_sub_action_id_and_output_path(
83
- tctx, _func_name, converted_inputs
200
+ tctx,
201
+ _func.__name__,
202
+ inputs_hash,
203
+ 0,
84
204
  )
85
205
  assert action_output_path
86
206
  return (
87
207
  TraceInfo(
208
+ name=_func.__name__,
88
209
  action=action_id,
89
210
  interface=_interface,
90
211
  inputs_path=action_output_path,
@@ -105,14 +226,17 @@ class LocalController:
105
226
 
106
227
  if info.interface.outputs and info.output:
107
228
  # If the result is not an AsyncGenerator, convert it directly
108
- converted_outputs = await convert.convert_from_native_to_outputs(info.output, info.interface)
229
+ converted_outputs = await convert.convert_from_native_to_outputs(info.output, info.interface, info.name)
109
230
  assert converted_outputs
110
231
  elif info.error:
111
232
  # If there is an error, convert it to a native error
112
233
  converted_error = convert.convert_from_native_to_error(info.error)
113
234
  assert converted_error
114
235
  assert info.action
115
- assert info.duration
236
+ assert info.start_time
237
+ assert info.end_time
116
238
 
117
- async def submit_task_ref(self, _task: task_definition_pb2.TaskDetails, *args, **kwargs) -> Any:
118
- raise flyte.errors.ReferenceTaskError("Reference tasks cannot be executed locally, only remotely.")
239
+ async def submit_task_ref(self, _task: TaskDetails, max_inline_io_bytes: int, *args, **kwargs) -> Any:
240
+ raise flyte.errors.RemoteTaskError(
241
+ f"Remote tasks cannot be executed locally, only remotely. Found remote task {_task.name}"
242
+ )
@@ -1,8 +1,9 @@
1
- from dataclasses import dataclass
2
- from datetime import timedelta
1
+ from dataclasses import dataclass, field
3
2
  from typing import Any, Optional
4
3
 
5
- from flyte._datastructures import ActionID, NativeInterface
4
+ from flyteidl2.core import interface_pb2
5
+
6
+ from flyte.models import ActionID, NativeInterface
6
7
 
7
8
 
8
9
  @dataclass
@@ -12,29 +13,36 @@ class TraceInfo:
12
13
  the action is completed.
13
14
  """
14
15
 
16
+ name: str
15
17
  action: ActionID
16
18
  interface: NativeInterface
17
19
  inputs_path: str
18
- duration: Optional[timedelta] = None
20
+ start_time: float = field(init=False, default=0.0)
21
+ end_time: float = field(init=False, default=0.0)
19
22
  output: Optional[Any] = None
20
23
  error: Optional[Exception] = None
24
+ typed_interface: Optional[interface_pb2.TypedInterface] = None
21
25
 
22
- def add_outputs(self, output: Any, duration: timedelta):
26
+ def add_outputs(self, output: Any, start_time: float, end_time: float):
23
27
  """
24
28
  Add outputs to the trace information.
25
29
  :param output: Output of the action
26
- :param duration: Duration of the action
30
+ :param start_time: Start time of the action
31
+ :param end_time: End time of the action
27
32
  :return:
28
33
  """
29
34
  self.output = output
30
- self.duration = duration
35
+ self.start_time = start_time
36
+ self.end_time = end_time
31
37
 
32
- def add_error(self, error: Exception, duration: timedelta):
38
+ def add_error(self, error: Exception, start_time: float, end_time: float):
33
39
  """
34
40
  Add error to the trace information.
35
41
  :param error: Error of the action
36
- :param duration: Duration of the action
42
+ :param start_time: Start time of the action
43
+ :param end_time: End time of the action
37
44
  :return:
38
45
  """
39
46
  self.error = error
40
- self.duration = duration
47
+ self.start_time = start_time
48
+ self.end_time = end_time
@@ -10,13 +10,13 @@ __all__ = ["RemoteController", "create_remote_controller"]
10
10
  def create_remote_controller(
11
11
  *,
12
12
  api_key: str | None = None,
13
- auth_type: AuthType = "Pkce",
14
- endpoint: str,
15
- client_config: ClientConfig | None = None,
16
- headless: bool = False,
13
+ endpoint: str | None = None,
17
14
  insecure: bool = False,
18
15
  insecure_skip_verify: bool = False,
19
16
  ca_cert_file_path: str | None = None,
17
+ client_config: ClientConfig | None = None,
18
+ auth_type: AuthType = "Pkce",
19
+ headless: bool = False,
20
20
  command: List[str] | None = None,
21
21
  proxy_command: List[str] | None = None,
22
22
  client_id: str | None = None,
@@ -27,14 +27,43 @@ def create_remote_controller(
27
27
  """
28
28
  Create a new instance of the remote controller.
29
29
  """
30
+ assert endpoint or api_key, "Either endpoint or api_key must be provided when initializing remote controller"
30
31
  from ._client import ControllerClient
31
32
  from ._controller import RemoteController
32
33
 
34
+ # https://grpc.io/docs/guides/keepalive/#keepalive-configuration-specification
35
+ channel_options = [
36
+ ("grpc.keepalive_permit_without_calls", 1),
37
+ ("grpc.keepalive_time_ms", 30000), # Send keepalive ping every 30 seconds
38
+ ("grpc.keepalive_timeout_ms", 10000), # Wait 10 seconds for keepalive response
39
+ ("grpc.http2.max_pings_without_data", 0), # Allow unlimited pings without data
40
+ ("grpc.http2.min_ping_interval_without_data_ms", 30000), # Min 30s between pings
41
+ ]
42
+
43
+ if endpoint:
44
+ client_coro = ControllerClient.for_endpoint(
45
+ endpoint,
46
+ insecure=insecure,
47
+ insecure_skip_verify=insecure_skip_verify,
48
+ ca_cert_file_path=ca_cert_file_path,
49
+ client_id=client_id,
50
+ client_credentials_secret=client_credentials_secret,
51
+ auth_type=auth_type,
52
+ grpc_options=channel_options,
53
+ )
54
+ elif api_key:
55
+ client_coro = ControllerClient.for_api_key(
56
+ api_key,
57
+ insecure=insecure,
58
+ insecure_skip_verify=insecure_skip_verify,
59
+ ca_cert_file_path=ca_cert_file_path,
60
+ client_id=client_id,
61
+ client_credentials_secret=client_credentials_secret,
62
+ auth_type=auth_type,
63
+ grpc_options=channel_options,
64
+ )
65
+
33
66
  controller = RemoteController(
34
- client_coro=ControllerClient.for_endpoint(
35
- endpoint=endpoint, insecure=insecure, insecure_skip_verify=insecure_skip_verify
36
- ),
37
- workers=10,
38
- max_system_retries=5,
67
+ client_coro=client_coro,
39
68
  )
40
69
  return controller