latch 2.71.0__tar.gz → 2.71.2__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 (197) hide show
  1. {latch-2.71.0 → latch-2.71.2}/.gitignore +2 -1
  2. {latch-2.71.0 → latch-2.71.2}/PKG-INFO +2 -2
  3. {latch-2.71.0 → latch-2.71.2}/pyproject.toml +2 -2
  4. {latch-2.71.0 → latch-2.71.2}/src/latch/utils.py +16 -6
  5. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/main.py +27 -2
  6. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/workspace.py +16 -3
  7. {latch-2.71.0 → latch-2.71.2}/LICENSE +0 -0
  8. {latch-2.71.0 → latch-2.71.2}/README.md +0 -0
  9. {latch-2.71.0 → latch-2.71.2}/src/latch/__init__.py +0 -0
  10. {latch-2.71.0 → latch-2.71.2}/src/latch/account.py +0 -0
  11. {latch-2.71.0 → latch-2.71.2}/src/latch/executions.py +0 -0
  12. {latch-2.71.0 → latch-2.71.2}/src/latch/functions/__init__.py +0 -0
  13. {latch-2.71.0 → latch-2.71.2}/src/latch/functions/messages.py +0 -0
  14. {latch-2.71.0 → latch-2.71.2}/src/latch/functions/operators.py +0 -0
  15. {latch-2.71.0 → latch-2.71.2}/src/latch/functions/secrets.py +0 -0
  16. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/admin/common.py +0 -0
  17. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/admin/launch_plan.py +0 -0
  18. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/admin/schedule.py +0 -0
  19. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/admin/workflow.py +0 -0
  20. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/condition.py +0 -0
  21. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/execution.py +0 -0
  22. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/identifier.py +0 -0
  23. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/interface.py +0 -0
  24. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/literals.py +0 -0
  25. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/security.py +0 -0
  26. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/tasks.py +0 -0
  27. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/types.py +0 -0
  28. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/core/workflow.py +0 -0
  29. {latch-2.71.0 → latch-2.71.2}/src/latch/idl/utils.py +0 -0
  30. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/__init__.py +0 -0
  31. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/__init__.py +0 -0
  32. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/download.py +0 -0
  33. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/manager.py +0 -0
  34. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/node.py +0 -0
  35. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/progress.py +0 -0
  36. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/remote_copy.py +0 -0
  37. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/throttle.py +0 -0
  38. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/upload.py +0 -0
  39. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/_transfer/utils.py +0 -0
  40. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/path.py +0 -0
  41. {latch-2.71.0 → latch-2.71.2}/src/latch/ldata/type.py +0 -0
  42. {latch-2.71.0 → latch-2.71.2}/src/latch/py.typed +0 -0
  43. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/__init__.py +0 -0
  44. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/project.py +0 -0
  45. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/record.py +0 -0
  46. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/table.py +0 -0
  47. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/types.py +0 -0
  48. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/upstream_types/__init__.py +0 -0
  49. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/upstream_types/types.py +0 -0
  50. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/upstream_types/values.py +0 -0
  51. {latch-2.71.0 → latch-2.71.2}/src/latch/registry/utils.py +0 -0
  52. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/__init__.py +0 -0
  53. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/conditional.py +0 -0
  54. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/dynamic.py +0 -0
  55. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/launch_plan.py +0 -0
  56. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/map_tasks.py +0 -0
  57. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/reference_workflow.py +0 -0
  58. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/tasks.py +0 -0
  59. {latch-2.71.0 → latch-2.71.2}/src/latch/resources/workflow.py +0 -0
  60. {latch-2.71.0 → latch-2.71.2}/src/latch/types/__init__.py +0 -0
  61. {latch-2.71.0 → latch-2.71.2}/src/latch/types/directory.py +0 -0
  62. {latch-2.71.0 → latch-2.71.2}/src/latch/types/file.py +0 -0
  63. {latch-2.71.0 → latch-2.71.2}/src/latch/types/glob.py +0 -0
  64. {latch-2.71.0 → latch-2.71.2}/src/latch/types/json.py +0 -0
  65. {latch-2.71.0 → latch-2.71.2}/src/latch/types/metadata.py +0 -0
  66. {latch-2.71.0 → latch-2.71.2}/src/latch/types/plots.py +0 -0
  67. {latch-2.71.0 → latch-2.71.2}/src/latch/types/samplesheet_item.py +0 -0
  68. {latch-2.71.0 → latch-2.71.2}/src/latch/types/utils.py +0 -0
  69. {latch-2.71.0 → latch-2.71.2}/src/latch/verified/__init__.py +0 -0
  70. {latch-2.71.0 → latch-2.71.2}/src/latch/verified/deseq2.py +0 -0
  71. {latch-2.71.0 → latch-2.71.2}/src/latch/verified/mafft.py +0 -0
  72. {latch-2.71.0 → latch-2.71.2}/src/latch/verified/pathway.py +0 -0
  73. {latch-2.71.0 → latch-2.71.2}/src/latch/verified/rnaseq.py +0 -0
  74. {latch-2.71.0 → latch-2.71.2}/src/latch/verified/trim_galore.py +0 -0
  75. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/__init__.py +0 -0
  76. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/auth/__init__.py +0 -0
  77. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/auth/csrf.py +0 -0
  78. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/auth/oauth2.py +0 -0
  79. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/auth/pkce.py +0 -0
  80. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/auth/utils.py +0 -0
  81. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/centromere/__init__.py +0 -0
  82. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/centromere/ast_parsing.py +0 -0
  83. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/centromere/ctx.py +0 -0
  84. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/centromere/utils.py +0 -0
  85. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/click_utils.py +0 -0
  86. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/constants.py +0 -0
  87. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/docker_utils/__init__.py +0 -0
  88. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/exceptions/__init__.py +0 -0
  89. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/exceptions/cache.py +0 -0
  90. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/exceptions/errors.py +0 -0
  91. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/exceptions/handler.py +0 -0
  92. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/exceptions/traceback.py +0 -0
  93. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/menus.py +0 -0
  94. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/nextflow/__init__.py +0 -0
  95. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/nextflow/config.py +0 -0
  96. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/nextflow/forch_register.py +0 -0
  97. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/nextflow/parse_schema.py +0 -0
  98. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/nextflow/utils.py +0 -0
  99. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/nextflow/workflow.py +0 -0
  100. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/py.typed +0 -0
  101. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/__init__.py +0 -0
  102. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/cp/__init__.py +0 -0
  103. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/cp/autocomplete.py +0 -0
  104. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/cp/glob.py +0 -0
  105. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/cp/main.py +0 -0
  106. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/cp/utils.py +0 -0
  107. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/docker/__init__.py +0 -0
  108. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/docker/utils.py +0 -0
  109. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/get.py +0 -0
  110. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/get_executions.py +0 -0
  111. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/get_params.py +0 -0
  112. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/__init__.py +0 -0
  113. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/assemble_and_sort/.env +0 -0
  114. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/assemble_and_sort/LICENSE +0 -0
  115. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/assemble_and_sort/README.md +0 -0
  116. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/assemble_and_sort/__init__.py +0 -0
  117. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/assemble_and_sort/assemble.py +0 -0
  118. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/assemble_and_sort/sort.py +0 -0
  119. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/assemble_and_sort/system-requirements.txt +0 -0
  120. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/common/.dockerignore +0 -0
  121. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_conda/__init__.py +0 -0
  122. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_conda/conda_task.py +0 -0
  123. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_conda/environment.yaml +0 -0
  124. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_docker/__init__.py +0 -0
  125. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_docker/task.py +0 -0
  126. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_nfcore/Dockerfile +0 -0
  127. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_nfcore/__init__.py +0 -0
  128. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_nfcore/task.py +0 -0
  129. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_r/__init__.py +0 -0
  130. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_r/environment.R +0 -0
  131. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_r/r_task.py +0 -0
  132. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/.latch/latch_entrypoint +0 -0
  133. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/Dockerfile +0 -0
  134. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/Snakefile +0 -0
  135. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/config.yaml +0 -0
  136. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/environment.yaml +0 -0
  137. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/latch_metadata.py +0 -0
  138. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/scripts/plot-quals.py +0 -0
  139. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/example_snakemake/version +0 -0
  140. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/init.py +0 -0
  141. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/template/LICENSE +0 -0
  142. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/template/README.md +0 -0
  143. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/template/__init__.py +0 -0
  144. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/init/template/task.py +0 -0
  145. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/k8s/__init__.py +0 -0
  146. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/k8s/attach.py +0 -0
  147. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/k8s/develop.py +0 -0
  148. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/k8s/execute.py +0 -0
  149. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/k8s/utils.py +0 -0
  150. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/k8s/ws_utils.py +0 -0
  151. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/launch/__init__.py +0 -0
  152. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/launch/interface.py +0 -0
  153. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/launch/launch.py +0 -0
  154. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/launch/launch_v2.py +0 -0
  155. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/launch/type_converter.py +0 -0
  156. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/local_dev_old.py +0 -0
  157. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/login.py +0 -0
  158. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/ls.py +0 -0
  159. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/mkdir.py +0 -0
  160. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/move.py +0 -0
  161. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/preview.py +0 -0
  162. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/private_images.py +0 -0
  163. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/register/__init__.py +0 -0
  164. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/register/constants.py +0 -0
  165. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/register/register.py +0 -0
  166. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/register/staging.py +0 -0
  167. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/register/utils.py +0 -0
  168. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/rm.py +0 -0
  169. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/stop_pod.py +0 -0
  170. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/sync.py +0 -0
  171. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/test_data/__init__.py +0 -0
  172. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/test_data/ls.py +0 -0
  173. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/test_data/remove.py +0 -0
  174. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/test_data/upload.py +0 -0
  175. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/services/test_data/utils.py +0 -0
  176. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/__init__.py +0 -0
  177. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/config/__init__.py +0 -0
  178. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/config/parser.py +0 -0
  179. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/config/utils.py +0 -0
  180. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/serialize.py +0 -0
  181. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/serialize_utils.py +0 -0
  182. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/single_task_snakemake.py +0 -0
  183. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/utils.py +0 -0
  184. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/snakemake/workflow.py +0 -0
  185. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/tinyrequests.py +0 -0
  186. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/tui/__init__.py +0 -0
  187. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/utils/__init__.py +0 -0
  188. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/utils/path.py +0 -0
  189. {latch-2.71.0 → latch-2.71.2}/src/latch_cli/workflow_config.py +0 -0
  190. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_config/__init__.py +0 -0
  191. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_config/latch.py +0 -0
  192. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_config/py.typed +0 -0
  193. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_config/user.py +0 -0
  194. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_gql/__init__.py +0 -0
  195. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_gql/execute.py +0 -0
  196. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_gql/py.typed +0 -0
  197. {latch-2.71.0 → latch-2.71.2}/src/latch_sdk_gql/utils.py +0 -0
@@ -19,4 +19,5 @@ docs/build
19
19
  scratch.py
20
20
  /scratch
21
21
  .latch_report.tar.gz
22
- /credentials
22
+ /credentials/*
23
+ !/credentials/.gitignore
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: latch
3
- Version: 2.71.0
3
+ Version: 2.71.2
4
4
  Summary: The Latch SDK
5
5
  Project-URL: Homepage, https://latch.bio
6
6
  Project-URL: Documentation, https://latch.wiki
@@ -53,7 +53,7 @@ Requires-Dist: gql==3.5.0
53
53
  Requires-Dist: graphql-core==3.2.3
54
54
  Requires-Dist: kubernetes>=24.2.0
55
55
  Requires-Dist: latch-persistence>=0.1.5
56
- Requires-Dist: lytekit==0.15.34
56
+ Requires-Dist: lytekit==0.15.35
57
57
  Requires-Dist: lytekitplugins-pods==0.7.4
58
58
  Requires-Dist: orjson>=3.10.12
59
59
  Requires-Dist: paramiko>=3.4.0
@@ -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.71.0"
15
+ version = "2.71.2"
16
16
  description = "The Latch SDK"
17
17
  authors = [{ name = "Kenny Workman", email = "kenny@latch.bio" }]
18
18
  maintainers = [{ name = "Ayush Kamat", email = "ayush@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.34",
34
+ "lytekit==0.15.35",
35
35
  "lytekitplugins-pods==0.7.4",
36
36
  "typing-extensions>=4.12.0",
37
37
  "apscheduler>=3.10.0",
@@ -47,6 +47,9 @@ class WSInfo(TypedDict):
47
47
  default: bool
48
48
 
49
49
 
50
+ class NoWorkspaceSelectedError(ValueError): ...
51
+
52
+
50
53
  def get_workspaces() -> Dict[str, WSInfo]:
51
54
  """Retrieve workspaces that user can access.
52
55
 
@@ -150,7 +153,7 @@ def current_workspace() -> str:
150
153
  """
151
154
 
152
155
  ws = os.environ.get("LATCH_WORKSPACE")
153
- if ws is not None:
156
+ if ws not in {None, ""}:
154
157
  return ws
155
158
 
156
159
  ws = user_config.workspace_id
@@ -170,13 +173,20 @@ def current_workspace() -> str:
170
173
  """),
171
174
  )["accountInfoCurrent"]
172
175
 
173
- ws = res["id"]
176
+ if res is not None:
177
+ is_local = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") is None
178
+ if is_local and res["user"] is not None:
179
+ default_account = res["user"]["defaultAccount"]
180
+ if default_account is not None:
181
+ return default_account
174
182
 
175
- is_local = os.environ.get("FLYTE_INTERNAL_EXECUTION_ID") is None
176
- if is_local and res["user"] is not None:
177
- ws = res["user"]["defaultAccount"]
183
+ ws = res["id"]
184
+ if ws is not None:
185
+ return ws
178
186
 
179
- return ws
187
+ raise NoWorkspaceSelectedError(
188
+ "No workspaces found. Please create a workspace at https://console.latch.bio before proceeding."
189
+ )
180
190
 
181
191
 
182
192
  class NotFoundError(ValueError): ...
@@ -15,7 +15,7 @@ from typing_extensions import ParamSpec
15
15
 
16
16
  import latch_cli.click_utils
17
17
  from latch.ldata._transfer.progress import Progress as _Progress # noqa: PLC2701
18
- from latch.utils import current_workspace
18
+ from latch.utils import NoWorkspaceSelectedError, current_workspace
19
19
  from latch_cli.click_utils import EnumChoice
20
20
  from latch_cli.exceptions.handler import CrashHandler
21
21
  from latch_cli.services.cp.autocomplete import complete as cp_complete
@@ -66,6 +66,21 @@ def requires_login(f: Callable[P, T]) -> Callable[P, T]:
66
66
  return decorated
67
67
 
68
68
 
69
+ def requires_workspace(f: Callable[P, T]) -> Callable[P, T]:
70
+ def decorated(*args: P.args, **kwargs: P.kwargs):
71
+ try:
72
+ current_workspace()
73
+ except NoWorkspaceSelectedError as e:
74
+ click.secho(str(e), fg="red")
75
+ raise click.exceptions.Exit(1) from e
76
+
77
+ return f(*args, **kwargs)
78
+
79
+ decorated.__doc__ = f.__doc__
80
+
81
+ return decorated
82
+
83
+
69
84
  @click.group("latch", context_settings={"max_content_width": 160})
70
85
  @click.version_option(package_name="latch")
71
86
  def main():
@@ -485,6 +500,7 @@ def generate_metadata(
485
500
  help="Size of machine to provision for develop session",
486
501
  )
487
502
  @requires_login
503
+ @requires_workspace
488
504
  def local_development(
489
505
  pkg_root: Path,
490
506
  yes: bool,
@@ -533,6 +549,7 @@ def local_development(
533
549
  help="Optional container index to inspect (only used for Map Tasks)",
534
550
  )
535
551
  @requires_login
552
+ @requires_workspace
536
553
  def execute(
537
554
  execution_id: Optional[str], egn_id: Optional[str], container_index: Optional[int]
538
555
  ):
@@ -583,7 +600,7 @@ def upload_image(
583
600
  @image.command("ls")
584
601
  @requires_login
585
602
  def image_ls():
586
- """Uploads an existing Docker image to Latch ECR"""
603
+ """Lists existing Docker images in Latch ECR"""
587
604
 
588
605
  from .services.private_images import ls
589
606
 
@@ -714,6 +731,7 @@ def image_ls():
714
731
  ),
715
732
  )
716
733
  @requires_login
734
+ @requires_workspace
717
735
  def register(
718
736
  pkg_root: str,
719
737
  disable_auto_version: bool,
@@ -810,6 +828,7 @@ def register(
810
828
  help="The version of the workflow to launch. Defaults to latest.",
811
829
  )
812
830
  @requires_login
831
+ @requires_workspace
813
832
  def launch(params_file: Path, version: Union[str, None] = None):
814
833
  """[DEPRECATED] Launch a workflow using a python parameter map.
815
834
 
@@ -851,6 +870,7 @@ def launch(params_file: Path, version: Union[str, None] = None):
851
870
  "--version", default=None, help="The version of the workflow. Defaults to latest."
852
871
  )
853
872
  @requires_login
873
+ @requires_workspace
854
874
  def get_params(wf_name: Union[str, None], version: Union[str, None] = None):
855
875
  """[DEPRECATED] Generate a python parameter map for a workflow.
856
876
 
@@ -890,6 +910,7 @@ def get_params(wf_name: Union[str, None], version: Union[str, None] = None):
890
910
  help="The name of the workflow to list. Will display all versions",
891
911
  )
892
912
  @requires_login
913
+ @requires_workspace
893
914
  def get_wf(name: Union[str, None] = None):
894
915
  """List workflows."""
895
916
  crash_handler.message = "Unable to get workflows"
@@ -919,6 +940,7 @@ def get_wf(name: Union[str, None] = None):
919
940
  @main.command("preview")
920
941
  @click.argument("pkg_root", nargs=1, type=click.Path(exists=True, path_type=Path))
921
942
  @requires_login
943
+ @requires_workspace
922
944
  def preview(pkg_root: Path):
923
945
  """Creates a preview of your workflow interface."""
924
946
  crash_handler.message = f"Unable to preview inputs for {pkg_root}"
@@ -931,6 +953,7 @@ def preview(pkg_root: Path):
931
953
 
932
954
  @main.command("get-executions")
933
955
  @requires_login
956
+ @requires_workspace
934
957
  def get_executions():
935
958
  """Spawns an interactive terminal UI that shows all executions in a given workspace"""
936
959
 
@@ -1263,6 +1286,7 @@ def generate_entrypoint(
1263
1286
  "--execution-id", "-e", type=str, help="Optional execution ID to inspect."
1264
1287
  )
1265
1288
  @requires_login
1289
+ @requires_workspace
1266
1290
  def attach(execution_id: Optional[str]):
1267
1291
  """Drops the user into an interactive shell to inspect the workdir of a nextflow execution."""
1268
1292
 
@@ -1302,6 +1326,7 @@ def attach(execution_id: Optional[str]):
1302
1326
  help="Path to the entrypoint nextflow file. Must be relative to the package root.",
1303
1327
  )
1304
1328
  @requires_login
1329
+ @requires_workspace
1305
1330
  def nf_register(
1306
1331
  pkg_root: Path,
1307
1332
  yes: bool,
@@ -3,7 +3,12 @@ from typing import List, TypedDict
3
3
  import click
4
4
  from latch_sdk_config.user import user_config
5
5
 
6
- from latch.utils import current_workspace, get_workspaces, WSInfo
6
+ from latch.utils import (
7
+ NoWorkspaceSelectedError,
8
+ WSInfo,
9
+ current_workspace,
10
+ get_workspaces,
11
+ )
7
12
  from latch_cli.menus import SelectOption, select_tui
8
13
 
9
14
 
@@ -15,7 +20,11 @@ def workspace():
15
20
  """
16
21
  data = get_workspaces()
17
22
 
18
- old_id = current_workspace()
23
+ old_id: str | None
24
+ try:
25
+ old_id = current_workspace()
26
+ except NoWorkspaceSelectedError:
27
+ old_id = None
19
28
 
20
29
  selected_marker = "\x1b[3m\x1b[2m (currently selected) \x1b[22m\x1b[23m"
21
30
 
@@ -25,7 +34,11 @@ def workspace():
25
34
  ):
26
35
  options.append(
27
36
  {
28
- "display_name": info["name"] if old_id != info["workspace_id"] else info["name"] + selected_marker,
37
+ "display_name": (
38
+ info["name"]
39
+ if old_id != info["workspace_id"]
40
+ else info["name"] + selected_marker
41
+ ),
29
42
  "value": info,
30
43
  }
31
44
  )
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