latch 2.76.5__tar.gz → 2.76.6__tar.gz

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 (201) hide show
  1. {latch-2.76.5 → latch-2.76.6}/PKG-INFO +2 -2
  2. {latch-2.76.5 → latch-2.76.6}/pyproject.toml +2 -2
  3. latch-2.76.5/src/latch_cli/services/launch.py +0 -262
  4. {latch-2.76.5 → latch-2.76.6}/.gitignore +0 -0
  5. {latch-2.76.5 → latch-2.76.6}/LICENSE +0 -0
  6. {latch-2.76.5 → latch-2.76.6}/README.md +0 -0
  7. {latch-2.76.5 → latch-2.76.6}/src/latch/__init__.py +0 -0
  8. {latch-2.76.5 → latch-2.76.6}/src/latch/account.py +0 -0
  9. {latch-2.76.5 → latch-2.76.6}/src/latch/executions.py +0 -0
  10. {latch-2.76.5 → latch-2.76.6}/src/latch/functions/__init__.py +0 -0
  11. {latch-2.76.5 → latch-2.76.6}/src/latch/functions/messages.py +0 -0
  12. {latch-2.76.5 → latch-2.76.6}/src/latch/functions/operators.py +0 -0
  13. {latch-2.76.5 → latch-2.76.6}/src/latch/functions/secrets.py +0 -0
  14. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/admin/common.py +0 -0
  15. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/admin/launch_plan.py +0 -0
  16. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/admin/schedule.py +0 -0
  17. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/admin/workflow.py +0 -0
  18. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/condition.py +0 -0
  19. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/execution.py +0 -0
  20. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/identifier.py +0 -0
  21. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/interface.py +0 -0
  22. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/literals.py +0 -0
  23. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/security.py +0 -0
  24. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/tasks.py +0 -0
  25. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/types.py +0 -0
  26. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/core/workflow.py +0 -0
  27. {latch-2.76.5 → latch-2.76.6}/src/latch/idl/utils.py +0 -0
  28. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/__init__.py +0 -0
  29. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/__init__.py +0 -0
  30. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/download.py +0 -0
  31. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/manager.py +0 -0
  32. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/node.py +0 -0
  33. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/progress.py +0 -0
  34. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/remote_copy.py +0 -0
  35. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/throttle.py +0 -0
  36. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/upload.py +0 -0
  37. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/_transfer/utils.py +0 -0
  38. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/path.py +0 -0
  39. {latch-2.76.5 → latch-2.76.6}/src/latch/ldata/type.py +0 -0
  40. {latch-2.76.5 → latch-2.76.6}/src/latch/py.typed +0 -0
  41. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/__init__.py +0 -0
  42. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/project.py +0 -0
  43. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/record.py +0 -0
  44. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/table.py +0 -0
  45. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/types.py +0 -0
  46. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/upstream_types/__init__.py +0 -0
  47. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/upstream_types/types.py +0 -0
  48. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/upstream_types/values.py +0 -0
  49. {latch-2.76.5 → latch-2.76.6}/src/latch/registry/utils.py +0 -0
  50. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/__init__.py +0 -0
  51. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/conditional.py +0 -0
  52. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/dynamic.py +0 -0
  53. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/launch_plan.py +0 -0
  54. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/map_tasks.py +0 -0
  55. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/reference_workflow.py +0 -0
  56. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/tasks.py +0 -0
  57. {latch-2.76.5 → latch-2.76.6}/src/latch/resources/workflow.py +0 -0
  58. {latch-2.76.5 → latch-2.76.6}/src/latch/types/__init__.py +0 -0
  59. {latch-2.76.5 → latch-2.76.6}/src/latch/types/directory.py +0 -0
  60. {latch-2.76.5 → latch-2.76.6}/src/latch/types/file.py +0 -0
  61. {latch-2.76.5 → latch-2.76.6}/src/latch/types/glob.py +0 -0
  62. {latch-2.76.5 → latch-2.76.6}/src/latch/types/json.py +0 -0
  63. {latch-2.76.5 → latch-2.76.6}/src/latch/types/metadata.py +0 -0
  64. {latch-2.76.5 → latch-2.76.6}/src/latch/types/plots.py +0 -0
  65. {latch-2.76.5 → latch-2.76.6}/src/latch/types/samplesheet_item.py +0 -0
  66. {latch-2.76.5 → latch-2.76.6}/src/latch/types/utils.py +0 -0
  67. {latch-2.76.5 → latch-2.76.6}/src/latch/utils.py +0 -0
  68. {latch-2.76.5 → latch-2.76.6}/src/latch/verified/__init__.py +0 -0
  69. {latch-2.76.5 → latch-2.76.6}/src/latch/verified/deseq2.py +0 -0
  70. {latch-2.76.5 → latch-2.76.6}/src/latch/verified/mafft.py +0 -0
  71. {latch-2.76.5 → latch-2.76.6}/src/latch/verified/pathway.py +0 -0
  72. {latch-2.76.5 → latch-2.76.6}/src/latch/verified/rnaseq.py +0 -0
  73. {latch-2.76.5 → latch-2.76.6}/src/latch/verified/trim_galore.py +0 -0
  74. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/__init__.py +0 -0
  75. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/auth/__init__.py +0 -0
  76. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/auth/csrf.py +0 -0
  77. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/auth/oauth2.py +0 -0
  78. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/auth/pkce.py +0 -0
  79. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/auth/utils.py +0 -0
  80. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/centromere/__init__.py +0 -0
  81. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/centromere/ast_parsing.py +0 -0
  82. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/centromere/ctx.py +0 -0
  83. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/centromere/utils.py +0 -0
  84. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/click_utils.py +0 -0
  85. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/constants.py +0 -0
  86. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/docker_utils/__init__.py +0 -0
  87. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/exceptions/__init__.py +0 -0
  88. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/exceptions/cache.py +0 -0
  89. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/exceptions/errors.py +0 -0
  90. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/exceptions/handler.py +0 -0
  91. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/exceptions/traceback.py +0 -0
  92. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/main.py +0 -0
  93. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/menus.py +0 -0
  94. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/nextflow/__init__.py +0 -0
  95. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/nextflow/config.py +0 -0
  96. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/nextflow/forch_register.py +0 -0
  97. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/nextflow/parse_schema.py +0 -0
  98. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/nextflow/utils.py +0 -0
  99. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/nextflow/workflow.py +0 -0
  100. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/py.typed +0 -0
  101. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/__init__.py +0 -0
  102. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/cp/__init__.py +0 -0
  103. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/cp/autocomplete.py +0 -0
  104. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/cp/glob.py +0 -0
  105. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/cp/main.py +0 -0
  106. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/cp/utils.py +0 -0
  107. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/docker/__init__.py +0 -0
  108. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/docker/utils.py +0 -0
  109. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/get.py +0 -0
  110. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/get_executions.py +0 -0
  111. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/get_params.py +0 -0
  112. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/gql/pod_ssh.graphql +0 -0
  113. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/gql/pods_list.graphql +0 -0
  114. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/__init__.py +0 -0
  115. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/assemble_and_sort/.env +0 -0
  116. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
  117. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/assemble_and_sort/README.md +0 -0
  118. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/assemble_and_sort/__init__.py +0 -0
  119. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
  120. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
  121. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
  122. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/common/.dockerignore +0 -0
  123. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_conda/__init__.py +0 -0
  124. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_conda/conda_task.py +0 -0
  125. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_conda/environment.yaml +0 -0
  126. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_docker/__init__.py +0 -0
  127. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_docker/task.py +0 -0
  128. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
  129. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_nfcore/__init__.py +0 -0
  130. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_nfcore/task.py +0 -0
  131. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_r/__init__.py +0 -0
  132. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_r/environment.R +0 -0
  133. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_r/r_task.py +0 -0
  134. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
  135. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
  136. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/Snakefile +0 -0
  137. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/config.yaml +0 -0
  138. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
  139. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
  140. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
  141. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/example_snakemake/version +0 -0
  142. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/init.py +0 -0
  143. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/template/LICENSE +0 -0
  144. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/template/README.md +0 -0
  145. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/template/__init__.py +0 -0
  146. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/init/template/task.py +0 -0
  147. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/k8s/__init__.py +0 -0
  148. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/k8s/attach.py +0 -0
  149. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/k8s/develop.py +0 -0
  150. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/k8s/execute.py +0 -0
  151. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/k8s/utils.py +0 -0
  152. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/k8s/ws_utils.py +0 -0
  153. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/launch/__init__.py +0 -0
  154. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/launch/interface.py +0 -0
  155. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/launch/launch.py +0 -0
  156. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/launch/launch_v2.py +0 -0
  157. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/launch/type_converter.py +0 -0
  158. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/local_dev_old.py +0 -0
  159. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/login.py +0 -0
  160. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/ls.py +0 -0
  161. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/mkdir.py +0 -0
  162. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/move.py +0 -0
  163. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/pods.py +0 -0
  164. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/preview.py +0 -0
  165. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/private_images.py +0 -0
  166. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/register/__init__.py +0 -0
  167. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/register/constants.py +0 -0
  168. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/register/register.py +0 -0
  169. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/register/staging.py +0 -0
  170. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/register/utils.py +0 -0
  171. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/rm.py +0 -0
  172. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/stop_pod.py +0 -0
  173. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/sync.py +0 -0
  174. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/test_data/__init__.py +0 -0
  175. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/test_data/ls.py +0 -0
  176. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/test_data/remove.py +0 -0
  177. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/test_data/upload.py +0 -0
  178. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/test_data/utils.py +0 -0
  179. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/services/workspace.py +0 -0
  180. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/__init__.py +0 -0
  181. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/config/__init__.py +0 -0
  182. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/config/parser.py +0 -0
  183. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/config/utils.py +0 -0
  184. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/serialize.py +0 -0
  185. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/serialize_utils.py +0 -0
  186. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/single_task_snakemake.py +0 -0
  187. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/utils.py +0 -0
  188. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/snakemake/workflow.py +0 -0
  189. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/tinyrequests.py +0 -0
  190. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/tui/__init__.py +0 -0
  191. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/utils/__init__.py +0 -0
  192. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/utils/path.py +0 -0
  193. {latch-2.76.5 → latch-2.76.6}/src/latch_cli/workflow_config.py +0 -0
  194. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_config/__init__.py +0 -0
  195. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_config/latch.py +0 -0
  196. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_config/py.typed +0 -0
  197. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_config/user.py +0 -0
  198. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_gql/__init__.py +0 -0
  199. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_gql/execute.py +0 -0
  200. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_gql/py.typed +0 -0
  201. {latch-2.76.5 → latch-2.76.6}/src/latch_sdk_gql/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: latch
3
- Version: 2.76.5
3
+ Version: 2.76.6
4
4
  Summary: The Latch SDK
5
5
  Project-URL: Homepage, https://latch.bio
6
6
  Project-URL: Documentation, https://latch.wiki
@@ -52,7 +52,7 @@ Requires-Dist: gql==3.5.0
52
52
  Requires-Dist: graphql-core==3.2.3
53
53
  Requires-Dist: kubernetes>=24.2.0
54
54
  Requires-Dist: latch-persistence>=0.1.5
55
- Requires-Dist: lytekit==0.16
55
+ Requires-Dist: lytekit<0.17,>=0.16
56
56
  Requires-Dist: lytekitplugins-pods==0.7.4
57
57
  Requires-Dist: orjson>=3.10.12
58
58
  Requires-Dist: paramiko>=3.4.0
@@ -12,7 +12,7 @@ include = ["src/**/*.py", "src/**/*.graphql", "src/**/py.typed", "src/latch_cli/
12
12
 
13
13
  [project]
14
14
  name = "latch"
15
- version = "2.76.5"
15
+ version = "2.76.6"
16
16
  description = "The Latch SDK"
17
17
  authors = [{ name = "Kenny Workman", email = "kenny@latch.bio" }]
18
18
  maintainers = [{ name = "Kenny Workman", email = "kenny@latch.bio" }]
@@ -31,7 +31,7 @@ dependencies = [
31
31
  "scp>=0.14.0",
32
32
  "boto3>=1.26.0",
33
33
  "tqdm>=4.63.0",
34
- "lytekit==0.16",
34
+ "lytekit>=0.16,<0.17",
35
35
  "lytekitplugins-pods==0.7.4",
36
36
  "typing-extensions>=4.12.0",
37
37
  "apscheduler>=3.10.0",
@@ -1,262 +0,0 @@
1
- """Service to launch a workflow."""
2
-
3
- import importlib.util
4
- import typing
5
- from pathlib import Path
6
- from typing import Optional, Tuple, Union
7
-
8
- import google.protobuf.json_format as gpjson
9
- import requests
10
- from flyteidl.core.types_pb2 import LiteralType
11
- from flytekit.core.context_manager import FlyteContextManager
12
- from flytekit.core.type_engine import TypeEngine
13
- from requests.adapters import HTTPAdapter
14
- from urllib3.util.retry import Retry
15
-
16
- from latch.utils import current_workspace, retrieve_or_login
17
- from latch_sdk_config.latch import config
18
-
19
-
20
- def launch(params_file: Path, version: Optional[str] = None) -> str:
21
- """Launches a (versioned) workflow with parameters specified in python.
22
-
23
- Using a parameter map written in python (this can be generated for you with
24
- `get_params`), this function will launch the workflow specified in the file
25
- using the parameters therein. This function also accepts an optional
26
- `version` parameter to further specify the workflow to be run. If it is not
27
- provided, this function will default to running the latest version of the
28
- specified workflow.
29
-
30
- Args:
31
- params_file: A path pointing to a python parameter file containing a
32
- function call that represents the workflow execution with valid
33
- parameter values.
34
- version: An optional workflow version to launch, defaulting to the
35
- latest if not provided.
36
-
37
- Returns:
38
- The name of the workflow.
39
-
40
- Example:
41
- >>> launch(Path("wf.__init__.assemble_and_sort.params.py"))
42
- # Launches an execution of `wf.__init__.assemble_and_sort` with the
43
- # parameters specified in the referenced file.
44
- """
45
-
46
- token = retrieve_or_login()
47
-
48
- with open(params_file) as pf:
49
- param_code = pf.read()
50
- spec = importlib.util.spec_from_loader("wf_params", loader=None)
51
- param_module = importlib.util.module_from_spec(spec)
52
- exec(param_code, param_module.__dict__)
53
-
54
- module_vars = vars(param_module)
55
- try:
56
- wf_params = module_vars["params"]
57
- except KeyError as e:
58
- raise ValueError(
59
- f"Execution file {params_file.name} needs to have"
60
- " a parameter value dictionary named 'params'"
61
- ) from e
62
-
63
- wf_name = wf_params.get("_name")
64
- if wf_name is None:
65
- raise ValueError(
66
- "The dictionary of parameters in the launch file lacks the"
67
- " _name key used to identify the workflow. Make sure a _name"
68
- " key with the workflow name exists in the dictionary."
69
- )
70
-
71
- wf_id, wf_interface, _ = _get_workflow_interface(token, wf_name, version)
72
-
73
- wf_vars = wf_interface["variables"]
74
- wf_literals = {}
75
- for key, value in wf_vars.items():
76
- ctx = FlyteContextManager.current_context()
77
- literal_type_json = value["type"]
78
- literal_type = gpjson.ParseDict(literal_type_json, LiteralType())
79
-
80
- if key in wf_params:
81
- python_value = wf_params[key]
82
- # Recover parameterized generics for TypeTransformer.
83
- python_type = _guess_python_type(python_value)
84
-
85
- python_type_literal = TypeEngine.to_literal(
86
- ctx, python_value, python_type, literal_type
87
- )
88
-
89
- wf_literals[key] = gpjson.MessageToDict(python_type_literal.to_flyte_idl())
90
-
91
- _launch_workflow(token, wf_id, wf_literals)
92
- return wf_name
93
-
94
-
95
- def _guess_python_type(v: any) -> typing.T:
96
- """Python literal guesser.
97
-
98
- We will attempt to construct the correct python type representation from the
99
- value and JSON type representation and rely on the TypeTransformer to produce
100
- the correct flyte literal for execution (FlyteIDL representation of the value).
101
- This is essentially how flytekit does it.
102
-
103
- Using the type() function alone is not sufficient because flyte interprets
104
- the python list literal as a generic collection type and needs a
105
- parameterization.
106
-
107
- For example:
108
-
109
- ..
110
- >> type(["AUG", "AAA"]) = list
111
- <class 'list'>
112
-
113
- Becomes List[str] s.t.
114
-
115
- ..
116
- >> TypeEngine.to_literal(ctx, ["AUG", "AAA"], List[str], type_literal)
117
-
118
- Returns our desired flyte literal.
119
- """
120
-
121
- if type(v) is list:
122
- if len(v) == 0:
123
- return typing.List[None]
124
- if type(v[0]) is list:
125
- return typing.List[_guess_python_type(v[0])]
126
- return typing.List[type(v[0])]
127
-
128
- # TODO: maps, Records, future complex types
129
-
130
- return type(v)
131
-
132
-
133
- def _get_workflow_interface(
134
- token: str, wf_name: str, version: Union[None, str]
135
- ) -> Tuple[int, dict]:
136
- """Retrieves the set of idl parameter values for a given workflow by name.
137
-
138
- Returns workflow id + interface as JSON string.
139
- """
140
-
141
- headers = {"Authorization": f"Bearer {token}"}
142
- _interface_request = {
143
- "workflow_name": wf_name,
144
- "version": version,
145
- "ws_account_id": current_workspace(),
146
- }
147
-
148
- url = config.api.workflow.interface
149
-
150
- # TODO(ayush) - figure out why timeout within this endpoint only.
151
- session = requests.Session()
152
- retries = 5
153
- retry = Retry(total=retries, read=retries, connect=retries, method_whitelist=False)
154
- adapter = HTTPAdapter(max_retries=retry)
155
- session.mount("http://", adapter)
156
- session.mount("https://", adapter)
157
-
158
- response = session.post(url, headers=headers, json=_interface_request)
159
-
160
- wf_interface_resp = response.json()
161
-
162
- wf_id, wf_interface, wf_default_params = (
163
- wf_interface_resp.get("id"),
164
- wf_interface_resp.get("interface"),
165
- wf_interface_resp.get("default_params"),
166
- )
167
- if wf_interface is None:
168
- raise ValueError(
169
- "Could not find interface. Nucleus returned a malformed JSON response -"
170
- f" {wf_interface_resp}"
171
- )
172
- if wf_id is None:
173
- raise ValueError(
174
- "Could not find wf ID. Nucleus returned a malformed JSON response -"
175
- f" {wf_interface_resp}"
176
- )
177
- if wf_default_params is None:
178
- raise ValueError(
179
- "Could not find wf default parameters. Nucleus returned a malformed JSON"
180
- f" response - {wf_interface_resp}"
181
- )
182
-
183
- return int(wf_id), wf_interface, wf_default_params
184
-
185
-
186
- def _launch_workflow(token: str, wf_id: str, params: dict) -> bool:
187
- """Launch the workflow of given id with parameter map.
188
-
189
- Return True if success, raises appropriate exceptions on failure.
190
- """
191
- # Server sometimes stalls on requests with python user-agent
192
- headers = {
193
- "Authorization": f"Bearer {token}",
194
- "User-Agent": (
195
- "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like"
196
- " Gecko) Chrome/72.0.3626.119 Safari/537.36"
197
- ),
198
- }
199
-
200
- _interface_request = {
201
- "workflow_id": str(wf_id),
202
- "params": params,
203
- "ws_account_id": current_workspace(),
204
- }
205
- url = config.api.execution.create
206
-
207
- response = requests.post(url, headers=headers, json=_interface_request)
208
- response_data = response.json()
209
-
210
- def extract_error_message(data: dict) -> str:
211
- if "error" in data:
212
- error = data["error"]
213
- source = error.get("source", "unknown")
214
-
215
- error_data = error.get("data", {})
216
- message = (
217
- error_data.get("stderr") or error_data.get("message") or str(error_data)
218
- )
219
-
220
- if isinstance(message, str):
221
- error_lines = [line for line in message.split("\n") if "Error:" in line]
222
- if error_lines:
223
- message = error_lines[-1].replace("Error:", "").strip()
224
-
225
- return f"({source}): {message}"
226
- return str(data)
227
-
228
- if response.status_code != 200:
229
- print("\nRaw server response:")
230
- print(response_data)
231
-
232
- if response.status_code == 403:
233
- raise PermissionError(
234
- "You need access to the latch sdk beta ~ join the waitlist @"
235
- " https://latch.bio/sdk"
236
- )
237
- if response.status_code == 401:
238
- raise ValueError(
239
- "your token has expired - please run latch login to refresh your token and"
240
- " try again."
241
- )
242
- if response.status_code == 429:
243
- error_msg = extract_error_message(response_data)
244
- print(f"\nFormatted error message: {error_msg}")
245
- raise RuntimeError(f"Rate limit reached - {error_msg}")
246
- if response.status_code == 400:
247
- error_msg = extract_error_message(response_data)
248
- print(f"\nFormatted error message: {error_msg}")
249
- raise ValueError(f"Workflow launch failed - {error_msg}")
250
- if response.status_code != 200:
251
- error_msg = extract_error_message(response_data)
252
- print(f"\nFormatted error message: {error_msg}")
253
- raise RuntimeError(f"Server error (HTTP {response.status_code}) - {error_msg}")
254
- if (
255
- "error" in response_data
256
- or response_data.get("status") != "Successfully launched workflow"
257
- ):
258
- error_msg = extract_error_message(response_data)
259
- print(f"\nFormatted error message: {error_msg}")
260
- raise RuntimeError(f"Workflow launch failed - {error_msg}")
261
-
262
- return True
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes