fal 1.34.1__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.34.1/fal.egg-info → fal-1.36.0}/PKG-INFO +2 -2
  2. {fal-1.34.1 → fal-1.36.0/fal.egg-info}/PKG-INFO +2 -2
  3. {fal-1.34.1 → fal-1.36.0}/fal.egg-info/requires.txt +1 -1
  4. {fal-1.34.1 → fal-1.36.0}/pyproject.toml +1 -1
  5. {fal-1.34.1 → fal-1.36.0}/src/fal/_fal_version.py +2 -2
  6. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/apps.py +12 -11
  7. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/auth.py +35 -18
  8. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/deploy.py +8 -9
  9. fal-1.36.0/src/fal/cli/doctor.py +54 -0
  10. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/keys.py +35 -16
  11. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/parser.py +20 -0
  12. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/profile.py +31 -12
  13. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/runners.py +41 -8
  14. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/secrets.py +27 -9
  15. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/teams.py +3 -1
  16. {fal-1.34.1 → fal-1.36.0}/src/fal/sdk.py +3 -0
  17. fal-1.34.1/src/fal/cli/doctor.py +0 -37
  18. {fal-1.34.1 → fal-1.36.0}/.gitignore +0 -0
  19. {fal-1.34.1 → fal-1.36.0}/Makefile +0 -0
  20. {fal-1.34.1 → fal-1.36.0}/README.md +0 -0
  21. {fal-1.34.1 → fal-1.36.0}/docs/conf.py +0 -0
  22. {fal-1.34.1 → fal-1.36.0}/docs/index.rst +0 -0
  23. {fal-1.34.1 → fal-1.36.0}/fal.egg-info/SOURCES.txt +0 -0
  24. {fal-1.34.1 → fal-1.36.0}/fal.egg-info/dependency_links.txt +0 -0
  25. {fal-1.34.1 → fal-1.36.0}/fal.egg-info/entry_points.txt +0 -0
  26. {fal-1.34.1 → fal-1.36.0}/fal.egg-info/top_level.txt +0 -0
  27. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/README.md +0 -0
  28. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  29. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  30. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  31. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  32. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  33. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  34. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
  35. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
  36. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
  37. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
  38. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
  39. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
  40. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  41. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  42. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  43. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
  44. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
  45. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  46. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
  47. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
  48. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
  49. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
  50. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
  51. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  52. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  53. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  54. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  55. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  56. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
  57. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
  58. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
  59. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
  60. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
  61. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
  62. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
  63. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
  64. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  65. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  66. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  67. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  68. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
  69. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  70. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
  71. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
  72. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
  73. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  74. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
  75. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
  76. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  77. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  78. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
  79. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  80. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  81. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  82. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
  83. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  84. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  85. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  86. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  87. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  88. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  89. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  90. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  91. {fal-1.34.1 → fal-1.36.0}/openapi-fal-rest/pyproject.toml +0 -0
  92. {fal-1.34.1 → fal-1.36.0}/openapi_rest.config.yaml +0 -0
  93. {fal-1.34.1 → fal-1.36.0}/setup.cfg +0 -0
  94. {fal-1.34.1 → fal-1.36.0}/src/fal/__init__.py +0 -0
  95. {fal-1.34.1 → fal-1.36.0}/src/fal/__main__.py +0 -0
  96. {fal-1.34.1 → fal-1.36.0}/src/fal/_serialization.py +0 -0
  97. {fal-1.34.1 → fal-1.36.0}/src/fal/_version.py +0 -0
  98. {fal-1.34.1 → fal-1.36.0}/src/fal/api.py +0 -0
  99. {fal-1.34.1 → fal-1.36.0}/src/fal/app.py +0 -0
  100. {fal-1.34.1 → fal-1.36.0}/src/fal/apps.py +0 -0
  101. {fal-1.34.1 → fal-1.36.0}/src/fal/auth/__init__.py +0 -0
  102. {fal-1.34.1 → fal-1.36.0}/src/fal/auth/auth0.py +0 -0
  103. {fal-1.34.1 → fal-1.36.0}/src/fal/auth/local.py +0 -0
  104. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/__init__.py +0 -0
  105. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/_utils.py +0 -0
  106. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/api.py +0 -0
  107. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/cli_nested_json.py +0 -0
  108. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/create.py +0 -0
  109. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/debug.py +0 -0
  110. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/files.py +0 -0
  111. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/main.py +0 -0
  112. {fal-1.34.1 → fal-1.36.0}/src/fal/cli/run.py +0 -0
  113. {fal-1.34.1 → fal-1.36.0}/src/fal/config.py +0 -0
  114. {fal-1.34.1 → fal-1.36.0}/src/fal/console/__init__.py +0 -0
  115. {fal-1.34.1 → fal-1.36.0}/src/fal/console/icons.py +0 -0
  116. {fal-1.34.1 → fal-1.36.0}/src/fal/console/ux.py +0 -0
  117. {fal-1.34.1 → fal-1.36.0}/src/fal/container.py +0 -0
  118. {fal-1.34.1 → fal-1.36.0}/src/fal/exceptions/__init__.py +0 -0
  119. {fal-1.34.1 → fal-1.36.0}/src/fal/exceptions/_base.py +0 -0
  120. {fal-1.34.1 → fal-1.36.0}/src/fal/exceptions/_cuda.py +0 -0
  121. {fal-1.34.1 → fal-1.36.0}/src/fal/exceptions/auth.py +0 -0
  122. {fal-1.34.1 → fal-1.36.0}/src/fal/files.py +0 -0
  123. {fal-1.34.1 → fal-1.36.0}/src/fal/flags.py +0 -0
  124. {fal-1.34.1 → fal-1.36.0}/src/fal/logging/__init__.py +0 -0
  125. {fal-1.34.1 → fal-1.36.0}/src/fal/logging/isolate.py +0 -0
  126. {fal-1.34.1 → fal-1.36.0}/src/fal/logging/style.py +0 -0
  127. {fal-1.34.1 → fal-1.36.0}/src/fal/logging/trace.py +0 -0
  128. {fal-1.34.1 → fal-1.36.0}/src/fal/logging/user.py +0 -0
  129. {fal-1.34.1 → fal-1.36.0}/src/fal/project.py +0 -0
  130. {fal-1.34.1 → fal-1.36.0}/src/fal/py.typed +0 -0
  131. {fal-1.34.1 → fal-1.36.0}/src/fal/rest_client.py +0 -0
  132. {fal-1.34.1 → fal-1.36.0}/src/fal/sync.py +0 -0
  133. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/__init__.py +0 -0
  134. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/audio/__init__.py +0 -0
  135. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/audio/audio.py +0 -0
  136. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/exceptions.py +0 -0
  137. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/file/__init__.py +0 -0
  138. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/file/file.py +0 -0
  139. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/file/providers/fal.py +0 -0
  140. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
  141. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/file/providers/r2.py +0 -0
  142. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/file/providers/s3.py +0 -0
  143. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/file/types.py +0 -0
  144. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/__init__.py +0 -0
  145. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/image.py +0 -0
  146. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
  147. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
  148. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
  149. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
  150. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
  151. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/image/safety_checker.py +0 -0
  152. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/kv.py +0 -0
  153. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/optimize.py +0 -0
  154. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/types.py +0 -0
  155. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/utils/__init__.py +0 -0
  156. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/utils/download_utils.py +0 -0
  157. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/utils/endpoint.py +0 -0
  158. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/utils/retry.py +0 -0
  159. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/utils/setup_utils.py +0 -0
  160. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/video/__init__.py +0 -0
  161. {fal-1.34.1 → fal-1.36.0}/src/fal/toolkit/video/video.py +0 -0
  162. {fal-1.34.1 → fal-1.36.0}/src/fal/utils.py +0 -0
  163. {fal-1.34.1 → fal-1.36.0}/src/fal/workflows.py +0 -0
  164. {fal-1.34.1 → fal-1.36.0}/tests/__init__.py +0 -0
  165. {fal-1.34.1 → fal-1.36.0}/tests/assets/cat.png +0 -0
  166. {fal-1.34.1 → fal-1.36.0}/tests/cli/__init__.py +0 -0
  167. {fal-1.34.1 → fal-1.36.0}/tests/cli/test_apps.py +0 -0
  168. {fal-1.34.1 → fal-1.36.0}/tests/cli/test_auth.py +0 -0
  169. {fal-1.34.1 → fal-1.36.0}/tests/cli/test_deploy.py +0 -0
  170. {fal-1.34.1 → fal-1.36.0}/tests/cli/test_keys.py +0 -0
  171. {fal-1.34.1 → fal-1.36.0}/tests/cli/test_run.py +0 -0
  172. {fal-1.34.1 → fal-1.36.0}/tests/cli/test_secrets.py +0 -0
  173. {fal-1.34.1 → fal-1.36.0}/tests/conftest.py +0 -0
  174. {fal-1.34.1 → fal-1.36.0}/tests/integration_test.py +0 -0
  175. {fal-1.34.1 → fal-1.36.0}/tests/mainify_package/__init__.py +0 -0
  176. {fal-1.34.1 → fal-1.36.0}/tests/mainify_package/impl.py +0 -0
  177. {fal-1.34.1 → fal-1.36.0}/tests/mainify_package/utils.py +0 -0
  178. {fal-1.34.1 → fal-1.36.0}/tests/mainify_target.py +0 -0
  179. {fal-1.34.1 → fal-1.36.0}/tests/test_apps.py +0 -0
  180. {fal-1.34.1 → fal-1.36.0}/tests/test_files.py +0 -0
  181. {fal-1.34.1 → fal-1.36.0}/tests/test_kv.py +0 -0
  182. {fal-1.34.1 → fal-1.36.0}/tests/test_stability.py +0 -0
  183. {fal-1.34.1 → fal-1.36.0}/tests/toolkit/file/providers/test_fal_retry.py +0 -0
  184. {fal-1.34.1 → fal-1.36.0}/tests/toolkit/file_test.py +0 -0
  185. {fal-1.34.1 → fal-1.36.0}/tests/toolkit/image_test.py +0 -0
  186. {fal-1.34.1 → fal-1.36.0}/tests/toolkit/test_types.py +0 -0
  187. {fal-1.34.1 → fal-1.36.0}/tests/toolkit/utils/retry.py +0 -0
  188. {fal-1.34.1 → 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.34.1
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.34.1
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.34.1'
32
- __version_tuple__ = version_tuple = (1, 34, 1)
31
+ __version__ = version = '1.36.0'
32
+ __version_tuple__ = version_tuple = (1, 36, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -8,7 +8,7 @@ import fal.cli.runners as runners
8
8
  from fal.sdk import RunnerState
9
9
 
10
10
  from ._utils import get_client
11
- from .parser import FalClientParser
11
+ from .parser import FalClientParser, get_output_parser
12
12
 
13
13
  if TYPE_CHECKING:
14
14
  from fal.sdk import AliasInfo, ApplicationInfo
@@ -72,6 +72,8 @@ def _list(args):
72
72
  apps_as_dicts = [asdict(a) for a in apps]
73
73
  res = json.dumps({"apps": apps_as_dicts})
74
74
  args.console.print(res)
75
+ else:
76
+ raise AssertionError(f"Invalid output format: {args.output}")
75
77
 
76
78
 
77
79
  def _add_list_parser(subparsers, parents):
@@ -80,7 +82,7 @@ def _add_list_parser(subparsers, parents):
80
82
  "list",
81
83
  description=list_help,
82
84
  help=list_help,
83
- parents=parents,
85
+ parents=[*parents, get_output_parser()],
84
86
  )
85
87
  parser.add_argument(
86
88
  "--sort-by-runners",
@@ -92,13 +94,6 @@ def _add_list_parser(subparsers, parents):
92
94
  type=str,
93
95
  help="Filter applications by alias contents",
94
96
  )
95
- parser.add_argument(
96
- "--output",
97
- type=str,
98
- default="pretty",
99
- choices=["pretty", "json"],
100
- help="Modify the command output",
101
- )
102
97
  parser.set_defaults(func=_list)
103
98
 
104
99
 
@@ -302,8 +297,14 @@ def _runners(args):
302
297
  pending_runners = [
303
298
  runner for runner in alias_runners if runner.state == RunnerState.PENDING
304
299
  ]
305
- args.console.print(f"Runners: {len(alias_runners) - len(pending_runners)}")
306
- 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)}")
307
308
  # Drop the alias column, which is the first column
308
309
  runners_table.columns.pop(0)
309
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):
@@ -5,7 +5,7 @@ from pathlib import Path
5
5
  from typing import Literal, Optional, Tuple, Union
6
6
 
7
7
  from ._utils import get_app_data_from_toml, is_app_name
8
- from .parser import FalClientParser, RefAction
8
+ from .parser import FalClientParser, RefAction, get_output_parser
9
9
 
10
10
  User = namedtuple("User", ["user_id", "username"])
11
11
 
@@ -152,6 +152,8 @@ def _deploy_from_reference(
152
152
  args.console.print(
153
153
  f"\thttps://queue.{endpoint_host}/{user.username}/{app_name}{endpoint}"
154
154
  )
155
+ else:
156
+ raise AssertionError(f"Invalid output format: {args.output}")
155
157
 
156
158
 
157
159
  def _deploy(args):
@@ -211,7 +213,11 @@ def add_parser(main_subparsers, parents):
211
213
 
212
214
  parser = main_subparsers.add_parser(
213
215
  "deploy",
214
- parents=[*parents, FalClientParser(add_help=False)],
216
+ parents=[
217
+ *parents,
218
+ get_output_parser(),
219
+ FalClientParser(add_help=False),
220
+ ],
215
221
  description=deploy_help,
216
222
  help=deploy_help,
217
223
  epilog=epilog,
@@ -261,12 +267,5 @@ def add_parser(main_subparsers, parents):
261
267
  dest="app_scale_settings",
262
268
  help="Use the application code for scale settings.",
263
269
  )
264
- parser.add_argument(
265
- "--output",
266
- type=str,
267
- default="pretty",
268
- choices=["pretty", "json"],
269
- help="Modify the command output",
270
- )
271
270
 
272
271
  parser.set_defaults(func=_deploy)
@@ -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
 
@@ -103,3 +103,23 @@ class FalClientParser(FalParser):
103
103
  "--team",
104
104
  help="The team to use.",
105
105
  )
106
+
107
+
108
+ def get_output_parser():
109
+ parser = FalParser(add_help=False)
110
+ group = parser.add_argument_group(title="Output")
111
+ group.add_argument(
112
+ "--output",
113
+ type=str,
114
+ default="pretty",
115
+ choices=["pretty", "json"],
116
+ help="Modify the command output",
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
+ )
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
 
@@ -1,11 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import json
3
4
  from typing import List
4
5
 
5
6
  from fal.sdk import RunnerInfo, RunnerState
6
7
 
7
8
  from ._utils import get_client
8
- from .parser import FalClientParser
9
+ from .parser import FalClientParser, get_output_parser
9
10
 
10
11
 
11
12
  def runners_table(runners: List[RunnerInfo]):
@@ -80,6 +81,26 @@ def _kill(args):
80
81
  connection.kill_runner(args.id)
81
82
 
82
83
 
84
+ def _list_json(args, runners: list[RunnerInfo]):
85
+ json_runners = [
86
+ {
87
+ "alias": r.alias,
88
+ "runner_id": r.runner_id,
89
+ "in_flight_requests": r.in_flight_requests,
90
+ "expiration_countdown": r.expiration_countdown,
91
+ "uptime_seconds": int(r.uptime.total_seconds()),
92
+ "revision": r.revision,
93
+ "state": r.state.value,
94
+ }
95
+ for r in runners
96
+ ]
97
+
98
+ res = {
99
+ "runners": json_runners,
100
+ }
101
+ args.console.print(json.dumps(res))
102
+
103
+
83
104
  def _list(args):
84
105
  client = get_client(args.host, args.team)
85
106
  with client.connect() as connection:
@@ -87,13 +108,25 @@ def _list(args):
87
108
  pending_runners = [
88
109
  runner for runner in runners if runner.state == RunnerState.PENDING
89
110
  ]
90
- args.console.print(f"Runners: {len(runners) - len(pending_runners)}")
91
- args.console.print(f"Pending Runners: {len(pending_runners)}")
92
- args.console.print(runners_table(runners))
111
+ setup_runners = [
112
+ runner for runner in runners if runner.state == RunnerState.SETUP
113
+ ]
114
+ if args.output == "pretty":
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)}")
121
+ args.console.print(runners_table(runners))
93
122
 
94
- requests_table = runners_requests_table(runners)
95
- args.console.print(f"Requests: {len(requests_table.rows)}")
96
- args.console.print(requests_table)
123
+ requests_table = runners_requests_table(runners)
124
+ args.console.print(f"Requests: {len(requests_table.rows)}")
125
+ args.console.print(requests_table)
126
+ elif args.output == "json":
127
+ _list_json(args, runners)
128
+ else:
129
+ raise AssertionError(f"Invalid output format: {args.output}")
97
130
 
98
131
 
99
132
  def _add_kill_parser(subparsers, parents):
@@ -117,7 +150,7 @@ def _add_list_parser(subparsers, parents):
117
150
  "list",
118
151
  description=list_help,
119
152
  help=list_help,
120
- parents=parents,
153
+ parents=[*parents, get_output_parser()],
121
154
  )
122
155
  parser.set_defaults(func=_list)
123
156
 
@@ -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