fal 1.35.0__tar.gz → 1.36.0__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.

Potentially problematic release.


This version of fal might be problematic. Click here for more details.

Files changed (188) hide show
  1. {fal-1.35.0/fal.egg-info → fal-1.36.0}/PKG-INFO +2 -2
  2. {fal-1.35.0 → fal-1.36.0/fal.egg-info}/PKG-INFO +2 -2
  3. {fal-1.35.0 → fal-1.36.0}/fal.egg-info/requires.txt +1 -1
  4. {fal-1.35.0 → fal-1.36.0}/pyproject.toml +1 -1
  5. {fal-1.35.0 → fal-1.36.0}/src/fal/_fal_version.py +2 -2
  6. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/apps.py +8 -2
  7. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/auth.py +35 -18
  8. fal-1.36.0/src/fal/cli/doctor.py +54 -0
  9. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/keys.py +35 -16
  10. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/parser.py +7 -0
  11. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/profile.py +31 -12
  12. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/runners.py +11 -4
  13. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/secrets.py +27 -9
  14. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/teams.py +3 -1
  15. {fal-1.35.0 → fal-1.36.0}/src/fal/sdk.py +3 -0
  16. fal-1.35.0/src/fal/cli/doctor.py +0 -37
  17. {fal-1.35.0 → fal-1.36.0}/.gitignore +0 -0
  18. {fal-1.35.0 → fal-1.36.0}/Makefile +0 -0
  19. {fal-1.35.0 → fal-1.36.0}/README.md +0 -0
  20. {fal-1.35.0 → fal-1.36.0}/docs/conf.py +0 -0
  21. {fal-1.35.0 → fal-1.36.0}/docs/index.rst +0 -0
  22. {fal-1.35.0 → fal-1.36.0}/fal.egg-info/SOURCES.txt +0 -0
  23. {fal-1.35.0 → fal-1.36.0}/fal.egg-info/dependency_links.txt +0 -0
  24. {fal-1.35.0 → fal-1.36.0}/fal.egg-info/entry_points.txt +0 -0
  25. {fal-1.35.0 → fal-1.36.0}/fal.egg-info/top_level.txt +0 -0
  26. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/README.md +0 -0
  27. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  28. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  29. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  30. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  31. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  32. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  33. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
  34. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
  35. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
  36. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
  37. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
  38. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
  39. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  40. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  41. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  42. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
  43. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
  44. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  45. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
  46. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
  47. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
  48. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
  49. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
  50. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  51. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  52. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  53. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  54. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  55. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
  56. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
  57. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
  58. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
  59. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
  60. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
  61. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
  62. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
  63. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  64. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  65. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  66. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  67. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
  68. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  69. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
  70. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
  71. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
  72. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  73. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
  74. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
  75. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  76. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  77. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
  78. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  79. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  80. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  81. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
  82. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  83. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  84. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  85. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  86. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  87. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  88. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  89. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  90. {fal-1.35.0 → fal-1.36.0}/openapi-fal-rest/pyproject.toml +0 -0
  91. {fal-1.35.0 → fal-1.36.0}/openapi_rest.config.yaml +0 -0
  92. {fal-1.35.0 → fal-1.36.0}/setup.cfg +0 -0
  93. {fal-1.35.0 → fal-1.36.0}/src/fal/__init__.py +0 -0
  94. {fal-1.35.0 → fal-1.36.0}/src/fal/__main__.py +0 -0
  95. {fal-1.35.0 → fal-1.36.0}/src/fal/_serialization.py +0 -0
  96. {fal-1.35.0 → fal-1.36.0}/src/fal/_version.py +0 -0
  97. {fal-1.35.0 → fal-1.36.0}/src/fal/api.py +0 -0
  98. {fal-1.35.0 → fal-1.36.0}/src/fal/app.py +0 -0
  99. {fal-1.35.0 → fal-1.36.0}/src/fal/apps.py +0 -0
  100. {fal-1.35.0 → fal-1.36.0}/src/fal/auth/__init__.py +0 -0
  101. {fal-1.35.0 → fal-1.36.0}/src/fal/auth/auth0.py +0 -0
  102. {fal-1.35.0 → fal-1.36.0}/src/fal/auth/local.py +0 -0
  103. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/__init__.py +0 -0
  104. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/_utils.py +0 -0
  105. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/api.py +0 -0
  106. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/cli_nested_json.py +0 -0
  107. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/create.py +0 -0
  108. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/debug.py +0 -0
  109. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/deploy.py +0 -0
  110. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/files.py +0 -0
  111. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/main.py +0 -0
  112. {fal-1.35.0 → fal-1.36.0}/src/fal/cli/run.py +0 -0
  113. {fal-1.35.0 → fal-1.36.0}/src/fal/config.py +0 -0
  114. {fal-1.35.0 → fal-1.36.0}/src/fal/console/__init__.py +0 -0
  115. {fal-1.35.0 → fal-1.36.0}/src/fal/console/icons.py +0 -0
  116. {fal-1.35.0 → fal-1.36.0}/src/fal/console/ux.py +0 -0
  117. {fal-1.35.0 → fal-1.36.0}/src/fal/container.py +0 -0
  118. {fal-1.35.0 → fal-1.36.0}/src/fal/exceptions/__init__.py +0 -0
  119. {fal-1.35.0 → fal-1.36.0}/src/fal/exceptions/_base.py +0 -0
  120. {fal-1.35.0 → fal-1.36.0}/src/fal/exceptions/_cuda.py +0 -0
  121. {fal-1.35.0 → fal-1.36.0}/src/fal/exceptions/auth.py +0 -0
  122. {fal-1.35.0 → fal-1.36.0}/src/fal/files.py +0 -0
  123. {fal-1.35.0 → fal-1.36.0}/src/fal/flags.py +0 -0
  124. {fal-1.35.0 → fal-1.36.0}/src/fal/logging/__init__.py +0 -0
  125. {fal-1.35.0 → fal-1.36.0}/src/fal/logging/isolate.py +0 -0
  126. {fal-1.35.0 → fal-1.36.0}/src/fal/logging/style.py +0 -0
  127. {fal-1.35.0 → fal-1.36.0}/src/fal/logging/trace.py +0 -0
  128. {fal-1.35.0 → fal-1.36.0}/src/fal/logging/user.py +0 -0
  129. {fal-1.35.0 → fal-1.36.0}/src/fal/project.py +0 -0
  130. {fal-1.35.0 → fal-1.36.0}/src/fal/py.typed +0 -0
  131. {fal-1.35.0 → fal-1.36.0}/src/fal/rest_client.py +0 -0
  132. {fal-1.35.0 → fal-1.36.0}/src/fal/sync.py +0 -0
  133. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/__init__.py +0 -0
  134. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/audio/__init__.py +0 -0
  135. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/audio/audio.py +0 -0
  136. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/exceptions.py +0 -0
  137. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/file/__init__.py +0 -0
  138. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/file/file.py +0 -0
  139. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/file/providers/fal.py +0 -0
  140. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
  141. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/file/providers/r2.py +0 -0
  142. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/file/providers/s3.py +0 -0
  143. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/file/types.py +0 -0
  144. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/__init__.py +0 -0
  145. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/image.py +0 -0
  146. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
  147. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
  148. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
  149. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
  150. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
  151. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/image/safety_checker.py +0 -0
  152. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/kv.py +0 -0
  153. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/optimize.py +0 -0
  154. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/types.py +0 -0
  155. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/utils/__init__.py +0 -0
  156. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/utils/download_utils.py +0 -0
  157. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/utils/endpoint.py +0 -0
  158. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/utils/retry.py +0 -0
  159. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/utils/setup_utils.py +0 -0
  160. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/video/__init__.py +0 -0
  161. {fal-1.35.0 → fal-1.36.0}/src/fal/toolkit/video/video.py +0 -0
  162. {fal-1.35.0 → fal-1.36.0}/src/fal/utils.py +0 -0
  163. {fal-1.35.0 → fal-1.36.0}/src/fal/workflows.py +0 -0
  164. {fal-1.35.0 → fal-1.36.0}/tests/__init__.py +0 -0
  165. {fal-1.35.0 → fal-1.36.0}/tests/assets/cat.png +0 -0
  166. {fal-1.35.0 → fal-1.36.0}/tests/cli/__init__.py +0 -0
  167. {fal-1.35.0 → fal-1.36.0}/tests/cli/test_apps.py +0 -0
  168. {fal-1.35.0 → fal-1.36.0}/tests/cli/test_auth.py +0 -0
  169. {fal-1.35.0 → fal-1.36.0}/tests/cli/test_deploy.py +0 -0
  170. {fal-1.35.0 → fal-1.36.0}/tests/cli/test_keys.py +0 -0
  171. {fal-1.35.0 → fal-1.36.0}/tests/cli/test_run.py +0 -0
  172. {fal-1.35.0 → fal-1.36.0}/tests/cli/test_secrets.py +0 -0
  173. {fal-1.35.0 → fal-1.36.0}/tests/conftest.py +0 -0
  174. {fal-1.35.0 → fal-1.36.0}/tests/integration_test.py +0 -0
  175. {fal-1.35.0 → fal-1.36.0}/tests/mainify_package/__init__.py +0 -0
  176. {fal-1.35.0 → fal-1.36.0}/tests/mainify_package/impl.py +0 -0
  177. {fal-1.35.0 → fal-1.36.0}/tests/mainify_package/utils.py +0 -0
  178. {fal-1.35.0 → fal-1.36.0}/tests/mainify_target.py +0 -0
  179. {fal-1.35.0 → fal-1.36.0}/tests/test_apps.py +0 -0
  180. {fal-1.35.0 → fal-1.36.0}/tests/test_files.py +0 -0
  181. {fal-1.35.0 → fal-1.36.0}/tests/test_kv.py +0 -0
  182. {fal-1.35.0 → fal-1.36.0}/tests/test_stability.py +0 -0
  183. {fal-1.35.0 → fal-1.36.0}/tests/toolkit/file/providers/test_fal_retry.py +0 -0
  184. {fal-1.35.0 → fal-1.36.0}/tests/toolkit/file_test.py +0 -0
  185. {fal-1.35.0 → fal-1.36.0}/tests/toolkit/image_test.py +0 -0
  186. {fal-1.35.0 → fal-1.36.0}/tests/toolkit/test_types.py +0 -0
  187. {fal-1.35.0 → fal-1.36.0}/tests/toolkit/utils/retry.py +0 -0
  188. {fal-1.35.0 → fal-1.36.0}/tools/demo_script.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.35.0
3
+ Version: 1.36.0
4
4
  Summary: fal is an easy-to-use Serverless Python Framework
5
5
  Author: Features & Labels <support@fal.ai>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: isolate[build]<0.20.0,>=0.18.0
9
- Requires-Dist: isolate-proto<0.13.0,>=0.12.0
9
+ Requires-Dist: isolate-proto<0.15.0,>=0.14.1
10
10
  Requires-Dist: grpcio<2,>=1.64.0
11
11
  Requires-Dist: dill==0.3.7
12
12
  Requires-Dist: cloudpickle==3.0.0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.35.0
3
+ Version: 1.36.0
4
4
  Summary: fal is an easy-to-use Serverless Python Framework
5
5
  Author: Features & Labels <support@fal.ai>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: isolate[build]<0.20.0,>=0.18.0
9
- Requires-Dist: isolate-proto<0.13.0,>=0.12.0
9
+ Requires-Dist: isolate-proto<0.15.0,>=0.14.1
10
10
  Requires-Dist: grpcio<2,>=1.64.0
11
11
  Requires-Dist: dill==0.3.7
12
12
  Requires-Dist: cloudpickle==3.0.0
@@ -1,5 +1,5 @@
1
1
  isolate[build]<0.20.0,>=0.18.0
2
- isolate-proto<0.13.0,>=0.12.0
2
+ isolate-proto<0.15.0,>=0.14.1
3
3
  grpcio<2,>=1.64.0
4
4
  dill==0.3.7
5
5
  cloudpickle==3.0.0
@@ -23,7 +23,7 @@ readme = "README.md"
23
23
  requires-python = ">=3.8"
24
24
  dependencies = [
25
25
  "isolate[build]>=0.18.0,<0.20.0",
26
- "isolate-proto>=0.12.0,<0.13.0",
26
+ "isolate-proto>=0.14.1,<0.15.0",
27
27
  "grpcio>=1.64.0,<2",
28
28
  "dill==0.3.7",
29
29
  "cloudpickle==3.0.0",
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.35.0'
32
- __version_tuple__ = version_tuple = (1, 35, 0)
31
+ __version__ = version = '1.36.0'
32
+ __version_tuple__ = version_tuple = (1, 36, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -297,8 +297,14 @@ def _runners(args):
297
297
  pending_runners = [
298
298
  runner for runner in alias_runners if runner.state == RunnerState.PENDING
299
299
  ]
300
- args.console.print(f"Runners: {len(alias_runners) - len(pending_runners)}")
301
- args.console.print(f"Pending Runners: {len(pending_runners)}")
300
+ setup_runners = [
301
+ runner for runner in alias_runners if runner.state == RunnerState.SETUP
302
+ ]
303
+ args.console.print(
304
+ f"Runners: {len(alias_runners) - len(pending_runners) - len(setup_runners)}"
305
+ )
306
+ args.console.print(f"Runners Pending: {len(pending_runners)}")
307
+ args.console.print(f"Runners Setting Up: {len(setup_runners)}")
302
308
  # Drop the alias column, which is the first column
303
309
  runners_table.columns.pop(0)
304
310
  args.console.print(runners_table)
@@ -35,8 +35,7 @@ def _logout(args):
35
35
 
36
36
 
37
37
  def _list_accounts(args):
38
- from rich.style import Style
39
- from rich.table import Table
38
+ import json
40
39
 
41
40
  from fal.auth import UserAccess
42
41
  from fal.config import Config
@@ -45,23 +44,41 @@ def _list_accounts(args):
45
44
  config = Config()
46
45
  current_account_name = config.get_internal("team") or user_access.info["nickname"]
47
46
 
48
- table = Table(border_style=Style(frame=False), show_header=False)
49
- table.add_column("#")
50
- table.add_column("Nickname")
51
- table.add_column("Type")
52
-
53
- for idx, account in enumerate(user_access.accounts):
54
- selected = account["nickname"] == current_account_name
55
- color = "bold yellow" if selected else None
56
-
57
- table.add_row(
58
- f"* {idx + 1}" if selected else f" {idx + 1}",
59
- account["nickname"],
60
- "Personal" if account["is_personal"] else "Team",
61
- style=color,
62
- )
47
+ if args.output == "json":
48
+ json_accounts = []
49
+ for account in user_access.accounts:
50
+ selected = account["nickname"] == current_account_name
51
+ json_accounts.append(
52
+ {
53
+ "nickname": account["nickname"],
54
+ "type": "personal" if account["is_personal"] else "team",
55
+ "is_selected": selected,
56
+ }
57
+ )
58
+ args.console.print(json.dumps({"teams": json_accounts}))
59
+ elif args.output == "pretty":
60
+ from rich.style import Style
61
+ from rich.table import Table
62
+
63
+ table = Table(border_style=Style(frame=False), show_header=False)
64
+ table.add_column("#")
65
+ table.add_column("Nickname")
66
+ table.add_column("Type")
67
+
68
+ for idx, account in enumerate(user_access.accounts):
69
+ selected = account["nickname"] == current_account_name
70
+ color = "bold yellow" if selected else None
71
+
72
+ table.add_row(
73
+ f"* {idx + 1}" if selected else f" {idx + 1}",
74
+ account["nickname"],
75
+ "Personal" if account["is_personal"] else "Team",
76
+ style=color,
77
+ )
63
78
 
64
- args.console.print(table)
79
+ args.console.print(table)
80
+ else:
81
+ raise AssertionError(f"Invalid output format: {args.output}")
65
82
 
66
83
 
67
84
  def _unset_account(args):
@@ -0,0 +1,54 @@
1
+ import json
2
+ import os
3
+ import platform
4
+
5
+
6
+ def _doctor(args):
7
+ import isolate
8
+
9
+ import fal
10
+
11
+ if args.output == "json":
12
+ data = {
13
+ "fal": fal.__version__,
14
+ "isolate": isolate.__version__,
15
+ "python": platform.python_version(),
16
+ "platform": platform.platform(),
17
+ "FAL_HOST": fal.flags.GRPC_HOST,
18
+ "FAL_KEY": os.getenv("FAL_KEY", "").split(":")[0],
19
+ }
20
+ args.console.print(json.dumps(data))
21
+ elif args.output == "pretty":
22
+ from rich.table import Table
23
+
24
+ table = Table(show_header=False, show_lines=False, box=None)
25
+ table.add_column("name", no_wrap=True, style="bold")
26
+ table.add_column("value", no_wrap=True)
27
+
28
+ table.add_row("fal", fal.__version__)
29
+ table.add_row("isolate", isolate.__version__)
30
+
31
+ table.add_row("", "")
32
+ table.add_row("python", platform.python_version())
33
+ table.add_row("platform", platform.platform())
34
+
35
+ table.add_row("", "")
36
+ table.add_row("FAL_HOST", fal.flags.GRPC_HOST)
37
+ table.add_row("FAL_KEY", os.getenv("FAL_KEY", "").split(":")[0])
38
+
39
+ args.console.print(table)
40
+ else:
41
+ raise AssertionError(f"Invalid output format: {args.output}")
42
+
43
+
44
+ def add_parser(main_subparsers, parents):
45
+ from .parser import get_output_parser
46
+
47
+ doctor_help = "fal version and misc environment information."
48
+ parser = main_subparsers.add_parser(
49
+ "doctor",
50
+ description=doctor_help,
51
+ help=doctor_help,
52
+ parents=[*parents, get_output_parser()],
53
+ )
54
+ parser.set_defaults(func=_doctor)
@@ -40,35 +40,54 @@ def _add_create_parser(subparsers, parents):
40
40
 
41
41
 
42
42
  def _list(args):
43
- from rich.table import Table
44
-
45
- table = Table()
46
- table.add_column("Key ID")
47
- table.add_column("Created At")
48
- table.add_column("Scope")
49
- table.add_column("Description")
43
+ import json
50
44
 
51
45
  client = get_client(args.host, args.team)
52
46
  with client.connect() as connection:
53
47
  keys = connection.list_user_keys()
54
- for key in keys:
55
- table.add_row(
56
- key.key_id,
57
- str(key.created_at),
58
- str(key.scope.value),
59
- key.alias,
60
- )
61
48
 
62
- args.console.print(table)
49
+ if args.output == "json":
50
+ json_keys = [
51
+ {
52
+ "key_id": key.key_id,
53
+ "created_at": str(key.created_at),
54
+ "scope": str(key.scope.value),
55
+ "description": key.alias,
56
+ }
57
+ for key in keys
58
+ ]
59
+ args.console.print(json.dumps({"keys": json_keys}))
60
+ elif args.output == "pretty":
61
+ from rich.table import Table
62
+
63
+ table = Table()
64
+ table.add_column("Key ID")
65
+ table.add_column("Created At")
66
+ table.add_column("Scope")
67
+ table.add_column("Description")
68
+
69
+ for key in keys:
70
+ table.add_row(
71
+ key.key_id,
72
+ str(key.created_at),
73
+ str(key.scope.value),
74
+ key.alias,
75
+ )
76
+
77
+ args.console.print(table)
78
+ else:
79
+ raise AssertionError(f"Invalid output format: {args.output}")
63
80
 
64
81
 
65
82
  def _add_list_parser(subparsers, parents):
83
+ from .parser import get_output_parser
84
+
66
85
  list_help = "List keys."
67
86
  parser = subparsers.add_parser(
68
87
  "list",
69
88
  description=list_help,
70
89
  help=list_help,
71
- parents=parents,
90
+ parents=[*parents, get_output_parser()],
72
91
  )
73
92
  parser.set_defaults(func=_list)
74
93
 
@@ -115,4 +115,11 @@ def get_output_parser():
115
115
  choices=["pretty", "json"],
116
116
  help="Modify the command output",
117
117
  )
118
+ group.add_argument(
119
+ "--json",
120
+ action="store_const",
121
+ const="json",
122
+ dest="output",
123
+ help="Output in JSON format (same as --output json)",
124
+ )
118
125
  return parser
@@ -6,20 +6,37 @@ from fal.config import Config
6
6
 
7
7
 
8
8
  def _list(args):
9
- table = Table()
10
- table.add_column("Set")
11
- table.add_column("Profile")
12
- table.add_column("Settings")
9
+ import json
13
10
 
14
11
  config = Config()
15
- for profile in config.profiles():
16
- table.add_row(
17
- "*" if profile == config._profile else "",
18
- profile,
19
- ", ".join(key for key in config._config[profile]),
20
- )
21
12
 
22
- args.console.print(table)
13
+ if args.output == "json":
14
+ json_profiles = []
15
+ for profile in config.profiles():
16
+ json_profiles.append(
17
+ {
18
+ "profile": profile,
19
+ "is_set": profile == config._profile,
20
+ "settings": list(config._config[profile].keys()),
21
+ }
22
+ )
23
+ args.console.print(json.dumps({"profiles": json_profiles}))
24
+ elif args.output == "pretty":
25
+ table = Table()
26
+ table.add_column("Set")
27
+ table.add_column("Profile")
28
+ table.add_column("Settings")
29
+
30
+ for profile in config.profiles():
31
+ table.add_row(
32
+ "*" if profile == config._profile else "",
33
+ profile,
34
+ ", ".join(key for key in config._config[profile]),
35
+ )
36
+
37
+ args.console.print(table)
38
+ else:
39
+ raise AssertionError(f"Invalid output format: {args.output}")
23
40
 
24
41
 
25
42
  def _set(args):
@@ -136,12 +153,14 @@ def add_parser(main_subparsers, parents):
136
153
  required=True,
137
154
  )
138
155
 
156
+ from .parser import get_output_parser
157
+
139
158
  list_help = "List all profiles."
140
159
  list_parser = subparsers.add_parser(
141
160
  "list",
142
161
  description=list_help,
143
162
  help=list_help,
144
- parents=parents,
163
+ parents=[*parents, get_output_parser()],
145
164
  )
146
165
  list_parser.set_defaults(func=_list)
147
166
 
@@ -81,7 +81,7 @@ def _kill(args):
81
81
  connection.kill_runner(args.id)
82
82
 
83
83
 
84
- def _list_json(args, runners: list[RunnerInfo], pending_runners: list[RunnerInfo]):
84
+ def _list_json(args, runners: list[RunnerInfo]):
85
85
  json_runners = [
86
86
  {
87
87
  "alias": r.alias,
@@ -108,16 +108,23 @@ def _list(args):
108
108
  pending_runners = [
109
109
  runner for runner in runners if runner.state == RunnerState.PENDING
110
110
  ]
111
+ setup_runners = [
112
+ runner for runner in runners if runner.state == RunnerState.SETUP
113
+ ]
111
114
  if args.output == "pretty":
112
- args.console.print(f"Runners: {len(runners) - len(pending_runners)}")
113
- args.console.print(f"Pending Runners: {len(pending_runners)}")
115
+ args.console.print(
116
+ "Runners: "
117
+ + str(len(runners) - len(pending_runners) - len(setup_runners))
118
+ )
119
+ args.console.print(f"Runners Pending: {len(pending_runners)}")
120
+ args.console.print(f"Runners Setting Up: {len(setup_runners)}")
114
121
  args.console.print(runners_table(runners))
115
122
 
116
123
  requests_table = runners_requests_table(runners)
117
124
  args.console.print(f"Requests: {len(requests_table.rows)}")
118
125
  args.console.print(requests_table)
119
126
  elif args.output == "json":
120
- _list_json(args, runners, pending_runners)
127
+ _list_json(args, runners)
121
128
  else:
122
129
  raise AssertionError(f"Invalid output format: {args.output}")
123
130
 
@@ -31,27 +31,45 @@ def _add_set_parser(subparsers, parents):
31
31
 
32
32
 
33
33
  def _list(args):
34
- from rich.table import Table
35
-
36
- table = Table()
37
- table.add_column("Secret Name")
38
- table.add_column("Created At")
34
+ import json
39
35
 
40
36
  client = get_client(args.host, args.team)
41
37
  with client.connect() as connection:
42
- for secret in connection.list_secrets():
43
- table.add_row(secret.name, str(secret.created_at))
38
+ secrets = list(connection.list_secrets())
39
+
40
+ if args.output == "json":
41
+ json_secrets = [
42
+ {
43
+ "name": secret.name,
44
+ "created_at": str(secret.created_at),
45
+ }
46
+ for secret in secrets
47
+ ]
48
+ args.console.print(json.dumps({"secrets": json_secrets}))
49
+ elif args.output == "pretty":
50
+ from rich.table import Table
51
+
52
+ table = Table()
53
+ table.add_column("Secret Name")
54
+ table.add_column("Created At")
44
55
 
45
- args.console.print(table)
56
+ for secret in secrets:
57
+ table.add_row(secret.name, str(secret.created_at))
58
+
59
+ args.console.print(table)
60
+ else:
61
+ raise AssertionError(f"Invalid output format: {args.output}")
46
62
 
47
63
 
48
64
  def _add_list_parser(subparsers, parents):
65
+ from .parser import get_output_parser
66
+
49
67
  list_help = "List secrets."
50
68
  parser = subparsers.add_parser(
51
69
  "list",
52
70
  description=list_help,
53
71
  help=list_help,
54
- parents=parents,
72
+ parents=[*parents, get_output_parser()],
55
73
  )
56
74
  parser.set_defaults(func=_list)
57
75
 
@@ -18,12 +18,14 @@ def add_parser(main_subparsers, parents):
18
18
  required=True,
19
19
  )
20
20
 
21
+ from .parser import get_output_parser
22
+
21
23
  list_help = "List teams."
22
24
  list_parser = subparsers.add_parser(
23
25
  "list",
24
26
  description=list_help,
25
27
  help=list_help,
26
- parents=parents,
28
+ parents=[*parents, get_output_parser()],
27
29
  )
28
30
  list_parser.set_defaults(func=_list_accounts)
29
31
 
@@ -264,6 +264,7 @@ class AliasInfo:
264
264
  class RunnerState(Enum):
265
265
  RUNNING = "running"
266
266
  PENDING = "pending"
267
+ SETUP = "setup"
267
268
  UNKNOWN = "unknown"
268
269
 
269
270
  @staticmethod
@@ -272,6 +273,8 @@ class RunnerState(Enum):
272
273
  return RunnerState.RUNNING
273
274
  elif proto is isolate_proto.RunnerInfo.State.PENDING:
274
275
  return RunnerState.PENDING
276
+ elif proto is isolate_proto.RunnerInfo.State.SETUP:
277
+ return RunnerState.SETUP
275
278
  else:
276
279
  return RunnerState.UNKNOWN
277
280
 
@@ -1,37 +0,0 @@
1
- import os
2
- import platform
3
-
4
-
5
- def _doctor(args):
6
- import isolate
7
- from rich.table import Table
8
-
9
- import fal
10
-
11
- table = Table(show_header=False, show_lines=False, box=None)
12
- table.add_column("name", no_wrap=True, style="bold")
13
- table.add_column("value", no_wrap=True)
14
-
15
- table.add_row("fal", fal.__version__)
16
- table.add_row("isolate", isolate.__version__)
17
-
18
- table.add_row("", "")
19
- table.add_row("python", platform.python_version())
20
- table.add_row("platform", platform.platform())
21
-
22
- table.add_row("", "")
23
- table.add_row("FAL_HOST", fal.flags.GRPC_HOST)
24
- table.add_row("FAL_KEY", os.getenv("FAL_KEY", "").split(":")[0])
25
-
26
- args.console.print(table)
27
-
28
-
29
- def add_parser(main_subparsers, parents):
30
- doctor_help = "fal version and misc environment information."
31
- parser = main_subparsers.add_parser(
32
- "doctor",
33
- description=doctor_help,
34
- help=doctor_help,
35
- parents=parents,
36
- )
37
- parser.set_defaults(func=_doctor)
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