latch 2.76.3__tar.gz → 2.76.5__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 (203) hide show
  1. {latch-2.76.3 → latch-2.76.5}/PKG-INFO +5 -4
  2. {latch-2.76.3 → latch-2.76.5}/pyproject.toml +6 -5
  3. {latch-2.76.3 → latch-2.76.5}/src/latch/utils.py +21 -9
  4. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/centromere/ctx.py +22 -2
  5. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/centromere/utils.py +49 -4
  6. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/constants.py +3 -2
  7. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/main.py +232 -57
  8. latch-2.76.5/src/latch_cli/services/gql/pod_ssh.graphql +10 -0
  9. latch-2.76.5/src/latch_cli/services/gql/pods_list.graphql +48 -0
  10. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/local_dev_old.py +11 -18
  11. latch-2.76.5/src/latch_cli/services/login.py +160 -0
  12. latch-2.76.5/src/latch_cli/services/pods.py +435 -0
  13. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/register/register.py +14 -2
  14. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/register/utils.py +19 -2
  15. latch-2.76.5/src/latch_cli/services/stop_pod.py +3 -0
  16. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/workspace.py +28 -6
  17. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/serialize.py +14 -25
  18. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/utils/__init__.py +13 -0
  19. {latch-2.76.3 → latch-2.76.5}/src/latch_sdk_config/latch.py +0 -11
  20. {latch-2.76.3 → latch-2.76.5}/src/latch_sdk_gql/execute.py +6 -2
  21. latch-2.76.3/src/latch_cli/services/login.py +0 -95
  22. latch-2.76.3/src/latch_cli/services/stop_pod.py +0 -32
  23. {latch-2.76.3 → latch-2.76.5}/.gitignore +0 -0
  24. {latch-2.76.3 → latch-2.76.5}/LICENSE +0 -0
  25. {latch-2.76.3 → latch-2.76.5}/README.md +0 -0
  26. {latch-2.76.3 → latch-2.76.5}/src/latch/__init__.py +0 -0
  27. {latch-2.76.3 → latch-2.76.5}/src/latch/account.py +0 -0
  28. {latch-2.76.3 → latch-2.76.5}/src/latch/executions.py +0 -0
  29. {latch-2.76.3 → latch-2.76.5}/src/latch/functions/__init__.py +0 -0
  30. {latch-2.76.3 → latch-2.76.5}/src/latch/functions/messages.py +0 -0
  31. {latch-2.76.3 → latch-2.76.5}/src/latch/functions/operators.py +0 -0
  32. {latch-2.76.3 → latch-2.76.5}/src/latch/functions/secrets.py +0 -0
  33. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/admin/common.py +0 -0
  34. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/admin/launch_plan.py +0 -0
  35. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/admin/schedule.py +0 -0
  36. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/admin/workflow.py +0 -0
  37. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/condition.py +0 -0
  38. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/execution.py +0 -0
  39. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/identifier.py +0 -0
  40. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/interface.py +0 -0
  41. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/literals.py +0 -0
  42. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/security.py +0 -0
  43. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/tasks.py +0 -0
  44. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/types.py +0 -0
  45. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/core/workflow.py +0 -0
  46. {latch-2.76.3 → latch-2.76.5}/src/latch/idl/utils.py +0 -0
  47. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/__init__.py +0 -0
  48. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/__init__.py +0 -0
  49. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/download.py +0 -0
  50. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/manager.py +0 -0
  51. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/node.py +0 -0
  52. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/progress.py +0 -0
  53. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/remote_copy.py +0 -0
  54. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/throttle.py +0 -0
  55. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/upload.py +0 -0
  56. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/_transfer/utils.py +0 -0
  57. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/path.py +0 -0
  58. {latch-2.76.3 → latch-2.76.5}/src/latch/ldata/type.py +0 -0
  59. {latch-2.76.3 → latch-2.76.5}/src/latch/py.typed +0 -0
  60. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/__init__.py +0 -0
  61. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/project.py +0 -0
  62. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/record.py +0 -0
  63. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/table.py +0 -0
  64. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/types.py +0 -0
  65. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/upstream_types/__init__.py +0 -0
  66. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/upstream_types/types.py +0 -0
  67. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/upstream_types/values.py +0 -0
  68. {latch-2.76.3 → latch-2.76.5}/src/latch/registry/utils.py +0 -0
  69. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/__init__.py +0 -0
  70. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/conditional.py +0 -0
  71. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/dynamic.py +0 -0
  72. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/launch_plan.py +0 -0
  73. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/map_tasks.py +0 -0
  74. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/reference_workflow.py +0 -0
  75. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/tasks.py +0 -0
  76. {latch-2.76.3 → latch-2.76.5}/src/latch/resources/workflow.py +0 -0
  77. {latch-2.76.3 → latch-2.76.5}/src/latch/types/__init__.py +0 -0
  78. {latch-2.76.3 → latch-2.76.5}/src/latch/types/directory.py +0 -0
  79. {latch-2.76.3 → latch-2.76.5}/src/latch/types/file.py +0 -0
  80. {latch-2.76.3 → latch-2.76.5}/src/latch/types/glob.py +0 -0
  81. {latch-2.76.3 → latch-2.76.5}/src/latch/types/json.py +0 -0
  82. {latch-2.76.3 → latch-2.76.5}/src/latch/types/metadata.py +0 -0
  83. {latch-2.76.3 → latch-2.76.5}/src/latch/types/plots.py +0 -0
  84. {latch-2.76.3 → latch-2.76.5}/src/latch/types/samplesheet_item.py +0 -0
  85. {latch-2.76.3 → latch-2.76.5}/src/latch/types/utils.py +0 -0
  86. {latch-2.76.3 → latch-2.76.5}/src/latch/verified/__init__.py +0 -0
  87. {latch-2.76.3 → latch-2.76.5}/src/latch/verified/deseq2.py +0 -0
  88. {latch-2.76.3 → latch-2.76.5}/src/latch/verified/mafft.py +0 -0
  89. {latch-2.76.3 → latch-2.76.5}/src/latch/verified/pathway.py +0 -0
  90. {latch-2.76.3 → latch-2.76.5}/src/latch/verified/rnaseq.py +0 -0
  91. {latch-2.76.3 → latch-2.76.5}/src/latch/verified/trim_galore.py +0 -0
  92. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/__init__.py +0 -0
  93. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/auth/__init__.py +0 -0
  94. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/auth/csrf.py +0 -0
  95. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/auth/oauth2.py +0 -0
  96. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/auth/pkce.py +0 -0
  97. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/auth/utils.py +0 -0
  98. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/centromere/__init__.py +0 -0
  99. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/centromere/ast_parsing.py +0 -0
  100. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/click_utils.py +0 -0
  101. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/docker_utils/__init__.py +0 -0
  102. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/exceptions/__init__.py +0 -0
  103. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/exceptions/cache.py +0 -0
  104. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/exceptions/errors.py +0 -0
  105. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/exceptions/handler.py +0 -0
  106. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/exceptions/traceback.py +0 -0
  107. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/menus.py +0 -0
  108. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/nextflow/__init__.py +0 -0
  109. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/nextflow/config.py +0 -0
  110. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/nextflow/forch_register.py +0 -0
  111. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/nextflow/parse_schema.py +0 -0
  112. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/nextflow/utils.py +0 -0
  113. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/nextflow/workflow.py +0 -0
  114. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/py.typed +0 -0
  115. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/__init__.py +0 -0
  116. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/cp/__init__.py +0 -0
  117. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/cp/autocomplete.py +0 -0
  118. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/cp/glob.py +0 -0
  119. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/cp/main.py +0 -0
  120. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/cp/utils.py +0 -0
  121. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/docker/__init__.py +0 -0
  122. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/docker/utils.py +0 -0
  123. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/get.py +0 -0
  124. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/get_executions.py +0 -0
  125. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/get_params.py +0 -0
  126. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/__init__.py +0 -0
  127. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/assemble_and_sort/.env +0 -0
  128. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
  129. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/assemble_and_sort/README.md +0 -0
  130. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/assemble_and_sort/__init__.py +0 -0
  131. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
  132. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
  133. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
  134. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/common/.dockerignore +0 -0
  135. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_conda/__init__.py +0 -0
  136. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_conda/conda_task.py +0 -0
  137. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_conda/environment.yaml +0 -0
  138. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_docker/__init__.py +0 -0
  139. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_docker/task.py +0 -0
  140. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
  141. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_nfcore/__init__.py +0 -0
  142. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_nfcore/task.py +0 -0
  143. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_r/__init__.py +0 -0
  144. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_r/environment.R +0 -0
  145. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_r/r_task.py +0 -0
  146. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
  147. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
  148. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/Snakefile +0 -0
  149. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/config.yaml +0 -0
  150. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
  151. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
  152. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
  153. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/example_snakemake/version +0 -0
  154. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/init.py +0 -0
  155. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/template/LICENSE +0 -0
  156. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/template/README.md +0 -0
  157. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/template/__init__.py +0 -0
  158. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/init/template/task.py +0 -0
  159. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/k8s/__init__.py +0 -0
  160. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/k8s/attach.py +0 -0
  161. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/k8s/develop.py +0 -0
  162. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/k8s/execute.py +0 -0
  163. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/k8s/utils.py +0 -0
  164. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/k8s/ws_utils.py +0 -0
  165. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/launch/__init__.py +0 -0
  166. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/launch/interface.py +0 -0
  167. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/launch/launch.py +0 -0
  168. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/launch/launch_v2.py +0 -0
  169. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/launch/type_converter.py +0 -0
  170. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/launch.py +0 -0
  171. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/ls.py +0 -0
  172. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/mkdir.py +0 -0
  173. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/move.py +0 -0
  174. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/preview.py +0 -0
  175. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/private_images.py +0 -0
  176. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/register/__init__.py +0 -0
  177. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/register/constants.py +0 -0
  178. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/register/staging.py +0 -0
  179. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/rm.py +0 -0
  180. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/sync.py +0 -0
  181. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/test_data/__init__.py +0 -0
  182. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/test_data/ls.py +0 -0
  183. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/test_data/remove.py +0 -0
  184. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/test_data/upload.py +0 -0
  185. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/services/test_data/utils.py +0 -0
  186. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/__init__.py +0 -0
  187. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/config/__init__.py +0 -0
  188. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/config/parser.py +0 -0
  189. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/config/utils.py +0 -0
  190. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/serialize_utils.py +0 -0
  191. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/single_task_snakemake.py +0 -0
  192. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/utils.py +0 -0
  193. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/snakemake/workflow.py +0 -0
  194. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/tinyrequests.py +0 -0
  195. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/tui/__init__.py +0 -0
  196. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/utils/path.py +0 -0
  197. {latch-2.76.3 → latch-2.76.5}/src/latch_cli/workflow_config.py +0 -0
  198. {latch-2.76.3 → latch-2.76.5}/src/latch_sdk_config/__init__.py +0 -0
  199. {latch-2.76.3 → latch-2.76.5}/src/latch_sdk_config/py.typed +0 -0
  200. {latch-2.76.3 → latch-2.76.5}/src/latch_sdk_config/user.py +0 -0
  201. {latch-2.76.3 → latch-2.76.5}/src/latch_sdk_gql/__init__.py +0 -0
  202. {latch-2.76.3 → latch-2.76.5}/src/latch_sdk_gql/py.typed +0 -0
  203. {latch-2.76.3 → latch-2.76.5}/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.3
3
+ Version: 2.76.5
4
4
  Summary: The Latch SDK
5
5
  Project-URL: Homepage, https://latch.bio
6
6
  Project-URL: Documentation, https://latch.wiki
@@ -41,7 +41,6 @@ Classifier: Topic :: Scientific/Engineering
41
41
  Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
42
42
  Classifier: Topic :: Software Development :: Build Tools
43
43
  Requires-Python: >=3.9
44
- Requires-Dist: aioconsole==0.6.1
45
44
  Requires-Dist: apscheduler>=3.10.0
46
45
  Requires-Dist: asyncssh==2.13.2
47
46
  Requires-Dist: boto3>=1.26.0
@@ -53,20 +52,22 @@ Requires-Dist: gql==3.5.0
53
52
  Requires-Dist: graphql-core==3.2.3
54
53
  Requires-Dist: kubernetes>=24.2.0
55
54
  Requires-Dist: latch-persistence>=0.1.5
56
- Requires-Dist: lytekit==0.15.35
55
+ Requires-Dist: lytekit==0.16
57
56
  Requires-Dist: lytekitplugins-pods==0.7.4
58
57
  Requires-Dist: orjson>=3.10.12
59
58
  Requires-Dist: paramiko>=3.4.0
59
+ Requires-Dist: pydantic<3,>=2
60
60
  Requires-Dist: pyjwt>=0.2.0
61
61
  Requires-Dist: python-dateutil>=2.8
62
62
  Requires-Dist: pyxattr>=0.8.1
63
63
  Requires-Dist: requests-toolbelt==1.0.0
64
64
  Requires-Dist: requests>=2.28.1
65
+ Requires-Dist: rich>=14.0.0
65
66
  Requires-Dist: scp>=0.14.0
66
67
  Requires-Dist: tqdm>=4.63.0
67
68
  Requires-Dist: typing-extensions>=4.12.0
68
69
  Requires-Dist: watchfiles==1.1.1
69
- Requires-Dist: websockets>=15.0.1
70
+ Requires-Dist: websockets<16,>=11
70
71
  Provides-Extra: pandas
71
72
  Requires-Dist: pandas>=2.0.0; extra == 'pandas'
72
73
  Provides-Extra: snakemake
@@ -3,7 +3,7 @@ requires = ["hatchling"]
3
3
  build-backend = "hatchling.build"
4
4
 
5
5
  [tool.hatch.build.targets.sdist]
6
- include = ["src/**/*.py", "src/**/py.typed", "src/latch_cli/services/init/*"]
6
+ include = ["src/**/*.py", "src/**/*.graphql", "src/**/py.typed", "src/latch_cli/services/init/*"]
7
7
 
8
8
  [tool.hatch.build.targets.wheel.force-include]
9
9
  "src/latch_cli" = "latch_cli"
@@ -12,7 +12,7 @@ include = ["src/**/*.py", "src/**/py.typed", "src/latch_cli/services/init/*"]
12
12
 
13
13
  [project]
14
14
  name = "latch"
15
- version = "2.76.3"
15
+ version = "2.76.5"
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.15.35",
34
+ "lytekit==0.16",
35
35
  "lytekitplugins-pods==0.7.4",
36
36
  "typing-extensions>=4.12.0",
37
37
  "apscheduler>=3.10.0",
@@ -39,11 +39,12 @@ dependencies = [
39
39
  "graphql-core==3.2.3",
40
40
  "requests-toolbelt==1.0.0",
41
41
  "python-dateutil>=2.8",
42
+ "pydantic>=2,<3",
43
+ "rich>=14.0.0",
42
44
  "GitPython==3.1.40",
43
45
  # for old latch develop, to be removed
44
- "aioconsole==0.6.1",
45
46
  "asyncssh==2.13.2",
46
- "websockets>=15.0.1",
47
+ "websockets>=11,<16",
47
48
  "watchfiles==1.1.1",
48
49
  "pyxattr>=0.8.1",
49
50
  "orjson>=3.10.12",
@@ -4,27 +4,39 @@ from typing import Dict, TypedDict
4
4
 
5
5
  import gql
6
6
  import jwt
7
+
7
8
  from latch_sdk_config.user import user_config
8
9
  from latch_sdk_gql.execute import execute
9
10
 
10
11
 
11
12
  def account_id_from_token(token: str) -> str:
12
- """Exchanges a valid JWT for a Latch account ID.
13
+ """Resolve the Latch account ID associated with ``token``.
13
14
 
14
15
  Latch account IDs are needed for any user-specific request, eg. register
15
16
  workflows or copy files to Latch.
16
17
 
17
18
  Args:
18
- token: JWT
19
+ token: A Latch SDK token.
19
20
 
20
21
  Returns:
21
- A Latch account ID (UUID).
22
+ A Latch account ID.
22
23
  """
23
- decoded_jwt = jwt.decode(token, options={"verify_signature": False})
24
- try:
25
- return decoded_jwt.get("id")
26
- except KeyError as e:
27
- raise ValueError("Your Latch access token is malformed") from e
24
+
25
+ res = execute(
26
+ gql.gql("""
27
+ query AccountIdFromToken {
28
+ accountInfoCurrent {
29
+ id
30
+ }
31
+ }
32
+ """)
33
+ )
34
+ aic = res.get("accountInfoCurrent")
35
+ if aic is None or aic.get("id") is None:
36
+ raise ValueError(
37
+ "Your Latch access token is invalid or could not be resolved to an account."
38
+ )
39
+ return aic["id"]
28
40
 
29
41
 
30
42
  def retrieve_or_login() -> str:
@@ -170,7 +182,7 @@ def current_workspace() -> str:
170
182
  }
171
183
  }
172
184
  }
173
- """),
185
+ """)
174
186
  )["accountInfoCurrent"]
175
187
 
176
188
  if res is not None:
@@ -1,3 +1,4 @@
1
+ from logging import getLogger
1
2
  import re
2
3
  import sys
3
4
  import traceback
@@ -30,6 +31,8 @@ from latch_cli.utils import (
30
31
  )
31
32
  from latch_sdk_config.latch import config
32
33
 
34
+ log = getLogger(__name__)
35
+
33
36
 
34
37
  @dataclass
35
38
  class _Container:
@@ -91,12 +94,14 @@ class _CentromereCtx:
91
94
  use_new_centromere: bool = False,
92
95
  overwrite: bool = False,
93
96
  dockerfile_path: Optional[Path] = None,
97
+ account_id: Optional[str] = None,
94
98
  ):
95
99
  self.use_new_centromere = use_new_centromere
96
100
  self.remote = remote
97
101
  self.disable_auto_version = disable_auto_version
98
102
  self.wf_module = wf_module if wf_module is not None else "wf"
99
103
 
104
+ log.debug("Initializing CentromereCtx")
100
105
  if self.wf_module.startswith("."):
101
106
  click.secho(
102
107
  dedent(f"""\
@@ -107,10 +112,15 @@ class _CentromereCtx:
107
112
  raise click.exceptions.Exit(1)
108
113
 
109
114
  try:
115
+ log.debug("retrieve_or_login")
110
116
  self.token = retrieve_or_login()
111
- self.account_id = current_workspace()
117
+ log.debug("current_workspace")
118
+ self.account_id = (
119
+ account_id if account_id is not None else current_workspace()
120
+ )
112
121
 
113
122
  self.dkr_repo = config.dkr_repo
123
+ log.debug("resolving pkg_root")
114
124
  self.pkg_root = pkg_root.resolve()
115
125
 
116
126
  if snakefile is not None and nf_script is not None:
@@ -131,6 +141,7 @@ class _CentromereCtx:
131
141
  else:
132
142
  self.workflow_type = WorkflowType.latchbiosdk
133
143
 
144
+ log.debug("Determining version")
134
145
  version_file = self.pkg_root / "version"
135
146
  try:
136
147
  self.version = version_file.read_text()
@@ -143,6 +154,7 @@ class _CentromereCtx:
143
154
 
144
155
  self.version = self.version.strip()
145
156
 
157
+ log.debug("Loading the git repo")
146
158
  try:
147
159
  from git import GitError, Repo
148
160
 
@@ -162,6 +174,7 @@ class _CentromereCtx:
162
174
  fg="yellow",
163
175
  )
164
176
 
177
+ log.debug("Auto-versioning")
165
178
  if not self.disable_auto_version:
166
179
  hash = ""
167
180
 
@@ -198,6 +211,7 @@ class _CentromereCtx:
198
211
  ),
199
212
  )
200
213
 
214
+ log.debug("Loading Flyte objects")
201
215
  try:
202
216
  if not module_path.exists():
203
217
  click.secho(error_msg, fg="red")
@@ -426,6 +440,7 @@ class _CentromereCtx:
426
440
  self.ssh_key_path, add_to_agent=False
427
441
  )
428
442
 
443
+ log.debug("use_new_centromere=%s", use_new_centromere)
429
444
  if use_new_centromere:
430
445
  self.internal_ip, self.username = (
431
446
  self.provision_register_deployment()
@@ -448,6 +463,7 @@ class _CentromereCtx:
448
463
  def _patched_connect(self): ...
449
464
 
450
465
  def _patched_create_paramiko_client(self, base_url):
466
+ log.debug("_patched_create_paramiko_client")
451
467
  self.ssh_client = ssh_client
452
468
 
453
469
  SSHHTTPAdapter._create_paramiko_client = _patched_create_paramiko_client
@@ -514,6 +530,7 @@ class _CentromereCtx:
514
530
  return f"{self.image}:{self.version}"
515
531
 
516
532
  def task_image_name(self, task_name: str) -> str:
533
+ log.debug("task_image_name: %s", task_name)
517
534
  task_name = identifier_suffix_from_str(task_name).lower()
518
535
  task_name = docker_image_name_illegal_pat.sub("_", task_name)
519
536
 
@@ -555,6 +572,7 @@ class _CentromereCtx:
555
572
 
556
573
  def provision_register_deployment(self) -> Tuple[str, str]:
557
574
  """Retrieve centromere IP + username."""
575
+ log.debug("provision_register_deployment")
558
576
  click.echo("Provisioning register instance. This may take a few minutes.")
559
577
 
560
578
  assert self.ssh_key_path is not None
@@ -610,9 +628,11 @@ class _CentromereCtx:
610
628
  def nucleus_check_version(self, version: str, workflow_name: str) -> bool:
611
629
  """Check if version has already been registered for given workflow"""
612
630
 
631
+ log.debug("nucleus_check_version")
632
+
613
633
  headers = {"Authorization": f"Bearer {self.token}"}
614
634
 
615
- ws_id = current_workspace()
635
+ ws_id = self.account_id
616
636
  if ws_id is None or ws_id == "":
617
637
  ws_id = account_id_from_token(retrieve_or_login())
618
638
 
@@ -6,6 +6,7 @@ import string
6
6
  import sys
7
7
  import tempfile
8
8
  from dataclasses import dataclass
9
+ from logging import getLogger
9
10
  from pathlib import Path
10
11
  from types import ModuleType
11
12
  from typing import Callable, Iterator, List, Optional, TypeVar
@@ -17,6 +18,8 @@ from typing_extensions import ParamSpec
17
18
 
18
19
  from latch_cli.constants import latch_constants
19
20
 
21
+ log = getLogger(__name__)
22
+
20
23
 
21
24
  @dataclass
22
25
  class RemoteConnInfo:
@@ -109,6 +112,7 @@ def _construct_dkr_client(ssh_host: Optional[str] = None):
109
112
  If `ssh_host` is passed, we attempt to make a connection with a remote
110
113
  machine.
111
114
  """
115
+ log.debug("Creating docker client: %s", ssh_host)
112
116
 
113
117
  def _from_env():
114
118
  host = environment.get("DOCKER_HOST")
@@ -124,6 +128,8 @@ def _construct_dkr_client(ssh_host: Optional[str] = None):
124
128
 
125
129
  enable_tls = tls_verify or cert_path is not None
126
130
 
131
+ log.debug("Determined Docker host from environment: %s", host)
132
+
127
133
  dkr_client = None
128
134
  try:
129
135
  if not enable_tls:
@@ -164,8 +170,19 @@ def _construct_dkr_client(ssh_host: Optional[str] = None):
164
170
  if host is not None and host != "":
165
171
  return _from_env()
166
172
  else:
173
+ try:
174
+ base_url = f"unix:/{Path.home()}/.docker/run/docker.sock"
175
+ log.debug(
176
+ "Using default Docker host: unix://$HOME/run/docker.sock (%s)", base_url
177
+ )
178
+ return docker.APIClient(base_url=base_url)
179
+ except docker.errors.DockerException:
180
+ tracebac
181
+ pass
182
+
167
183
  try:
168
184
  # TODO: platform specific socket defaults
185
+ log.debug("Using default Docker host: unix://var/run/docker.sock")
169
186
  return docker.APIClient(base_url="unix://var/run/docker.sock")
170
187
  except docker.errors.DockerException as de:
171
188
  raise OSError(
@@ -177,40 +194,66 @@ def _construct_dkr_client(ssh_host: Optional[str] = None):
177
194
  def _construct_ssh_client(
178
195
  remote_conn_info: RemoteConnInfo, *, use_gateway: bool = True
179
196
  ) -> paramiko.SSHClient:
197
+ log.debug(
198
+ "_construct_ssh_client conn_info=%s use_gateway=%s",
199
+ remote_conn_info,
200
+ use_gateway,
201
+ )
202
+
180
203
  if use_gateway:
181
204
  gateway = paramiko.SSHClient()
205
+
206
+ log.debug("Loading system host keys")
182
207
  gateway.load_system_host_keys()
208
+
209
+ log.debug("Setting missing host key policy")
183
210
  gateway.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy)
184
211
 
185
- gateway_pkey = paramiko.PKey.from_path(
186
- path=str(remote_conn_info.jump_key_path.resolve())
187
- )
212
+ path = str(remote_conn_info.jump_key_path.resolve())
213
+ log.debug("Loading public key from %s", path)
214
+ gateway_pkey = paramiko.PKey.from_path(path=path)
188
215
 
216
+ log.debug(
217
+ "Connecting to gateway: %s@%s",
218
+ latch_constants.jump_user,
219
+ latch_constants.jump_host,
220
+ )
189
221
  gateway.connect(
190
222
  latch_constants.jump_host,
191
223
  username=latch_constants.jump_user,
192
224
  pkey=gateway_pkey,
193
225
  )
194
226
 
227
+ log.debug("Getting gateway transport")
195
228
  gateway_transport = gateway.get_transport()
196
229
  if gateway_transport is None:
197
230
  raise ConnectionError("unable to create connection to jump host")
198
231
 
232
+ log.debug("Opening gateway channel")
199
233
  sock = gateway_transport.open_channel(
200
234
  kind="direct-tcpip", dest_addr=(remote_conn_info.ip, 22), src_addr=("", 0)
201
235
  )
202
236
  else:
203
237
  sock = None
204
238
 
205
- pkey = paramiko.PKey.from_path(path=str(remote_conn_info.ssh_key_path.resolve()))
239
+ path = str(remote_conn_info.ssh_key_path.resolve())
240
+ log.debug("Loading public key")
241
+ pkey = paramiko.PKey.from_path(path=path)
206
242
 
207
243
  ssh = paramiko.SSHClient()
244
+
245
+ log.debug("Loading system host keys")
208
246
  ssh.load_system_host_keys()
247
+
248
+ log.debug("Setting missing host key policy")
209
249
  ssh.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy)
250
+
251
+ log.debug("Connecting to remote")
210
252
  ssh.connect(
211
253
  remote_conn_info.ip, username=remote_conn_info.username, sock=sock, pkey=pkey
212
254
  )
213
255
 
256
+ log.debug("Getting transport")
214
257
  transport = ssh.get_transport()
215
258
  if transport is None:
216
259
  raise ConnectionError(
@@ -219,6 +262,7 @@ def _construct_ssh_client(
219
262
 
220
263
  # (kenny) Equivalent of OpenSSH configuration `ServerAliveInterval`
221
264
  # No analogue for `ServerAliveCountMax` in paramiko I could find.
265
+ log.debug("Setting Keep-Alive")
222
266
  transport.set_keepalive(latch_constants.centromere_keepalive_interval)
223
267
 
224
268
  return ssh
@@ -242,6 +286,7 @@ class MaybeRemoteDir:
242
286
  self.reconnect_info = reconnect_info
243
287
 
244
288
  def __enter__(self):
289
+ log.debug("MaybeRemoteDir.__enter__")
245
290
  return self.create()
246
291
 
247
292
  def __exit__(self, exc_type, exc_value, tb):
@@ -57,10 +57,11 @@ latch_constants = LatchConstants()
57
57
 
58
58
  @dataclass(frozen=True)
59
59
  class OAuth2Constants:
60
- client_id: str = "jzFBOhIbfp4EPRYZ8wmx4YyvL27LFDeB"
60
+ client_id: str = "UQs8mV2SvKLrPkcI5dt3nmsnrdZvPUs0"
61
61
  """Identifies the authentication server in 0Auth2.0 flow"""
62
62
 
63
- authz_server_host: str = "https://latchai.us.auth0.com"
63
+ authz_server_host: str = "https://auth.latch.bio"
64
+
64
65
  """Host of the authentication server used in 0Auth2.0 flow."""
65
66
 
66
67
  redirect_url: str = "http://127.0.0.1:5050/callback"