fal 1.29.0__tar.gz → 1.30.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 (187) hide show
  1. {fal-1.29.0/fal.egg-info → fal-1.30.0}/PKG-INFO +3 -3
  2. {fal-1.29.0 → fal-1.30.0/fal.egg-info}/PKG-INFO +3 -3
  3. {fal-1.29.0 → fal-1.30.0}/fal.egg-info/SOURCES.txt +1 -0
  4. {fal-1.29.0 → fal-1.30.0}/fal.egg-info/requires.txt +2 -2
  5. {fal-1.29.0 → fal-1.30.0}/pyproject.toml +2 -2
  6. {fal-1.29.0 → fal-1.30.0}/src/fal/_fal_version.py +2 -2
  7. {fal-1.29.0 → fal-1.30.0}/src/fal/app.py +3 -1
  8. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/apps.py +6 -1
  9. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/deploy.py +6 -1
  10. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/runners.py +8 -2
  11. {fal-1.29.0 → fal-1.30.0}/src/fal/sdk.py +42 -2
  12. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/utils/__init__.py +1 -0
  13. fal-1.30.0/src/fal/toolkit/utils/setup_utils.py +34 -0
  14. {fal-1.29.0 → fal-1.30.0}/tests/test_apps.py +15 -4
  15. {fal-1.29.0 → fal-1.30.0}/.gitignore +0 -0
  16. {fal-1.29.0 → fal-1.30.0}/Makefile +0 -0
  17. {fal-1.29.0 → fal-1.30.0}/README.md +0 -0
  18. {fal-1.29.0 → fal-1.30.0}/docs/conf.py +0 -0
  19. {fal-1.29.0 → fal-1.30.0}/docs/index.rst +0 -0
  20. {fal-1.29.0 → fal-1.30.0}/fal.egg-info/dependency_links.txt +0 -0
  21. {fal-1.29.0 → fal-1.30.0}/fal.egg-info/entry_points.txt +0 -0
  22. {fal-1.29.0 → fal-1.30.0}/fal.egg-info/top_level.txt +0 -0
  23. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/README.md +0 -0
  24. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  25. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  26. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  27. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  28. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  29. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  30. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
  31. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
  32. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
  33. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
  34. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
  35. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
  36. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  37. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  38. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  39. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
  40. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
  41. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  42. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
  43. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
  44. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
  45. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
  46. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
  47. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  48. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  49. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  50. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  51. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  52. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
  53. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
  54. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
  55. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
  56. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
  57. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
  58. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
  59. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
  60. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  61. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  62. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  63. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  64. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
  65. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  66. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
  67. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
  68. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
  69. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  70. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
  71. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
  72. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  73. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  74. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
  75. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  76. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  77. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  78. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
  79. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  80. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  81. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  82. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  83. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  84. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  85. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  86. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  87. {fal-1.29.0 → fal-1.30.0}/openapi-fal-rest/pyproject.toml +0 -0
  88. {fal-1.29.0 → fal-1.30.0}/openapi_rest.config.yaml +0 -0
  89. {fal-1.29.0 → fal-1.30.0}/setup.cfg +0 -0
  90. {fal-1.29.0 → fal-1.30.0}/src/fal/__init__.py +0 -0
  91. {fal-1.29.0 → fal-1.30.0}/src/fal/__main__.py +0 -0
  92. {fal-1.29.0 → fal-1.30.0}/src/fal/_serialization.py +0 -0
  93. {fal-1.29.0 → fal-1.30.0}/src/fal/_version.py +0 -0
  94. {fal-1.29.0 → fal-1.30.0}/src/fal/api.py +0 -0
  95. {fal-1.29.0 → fal-1.30.0}/src/fal/apps.py +0 -0
  96. {fal-1.29.0 → fal-1.30.0}/src/fal/auth/__init__.py +0 -0
  97. {fal-1.29.0 → fal-1.30.0}/src/fal/auth/auth0.py +0 -0
  98. {fal-1.29.0 → fal-1.30.0}/src/fal/auth/local.py +0 -0
  99. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/__init__.py +0 -0
  100. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/_utils.py +0 -0
  101. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/api.py +0 -0
  102. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/auth.py +0 -0
  103. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/cli_nested_json.py +0 -0
  104. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/create.py +0 -0
  105. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/debug.py +0 -0
  106. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/doctor.py +0 -0
  107. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/files.py +0 -0
  108. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/keys.py +0 -0
  109. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/main.py +0 -0
  110. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/parser.py +0 -0
  111. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/profile.py +0 -0
  112. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/run.py +0 -0
  113. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/secrets.py +0 -0
  114. {fal-1.29.0 → fal-1.30.0}/src/fal/cli/teams.py +0 -0
  115. {fal-1.29.0 → fal-1.30.0}/src/fal/config.py +0 -0
  116. {fal-1.29.0 → fal-1.30.0}/src/fal/console/__init__.py +0 -0
  117. {fal-1.29.0 → fal-1.30.0}/src/fal/console/icons.py +0 -0
  118. {fal-1.29.0 → fal-1.30.0}/src/fal/console/ux.py +0 -0
  119. {fal-1.29.0 → fal-1.30.0}/src/fal/container.py +0 -0
  120. {fal-1.29.0 → fal-1.30.0}/src/fal/exceptions/__init__.py +0 -0
  121. {fal-1.29.0 → fal-1.30.0}/src/fal/exceptions/_base.py +0 -0
  122. {fal-1.29.0 → fal-1.30.0}/src/fal/exceptions/_cuda.py +0 -0
  123. {fal-1.29.0 → fal-1.30.0}/src/fal/exceptions/auth.py +0 -0
  124. {fal-1.29.0 → fal-1.30.0}/src/fal/files.py +0 -0
  125. {fal-1.29.0 → fal-1.30.0}/src/fal/flags.py +0 -0
  126. {fal-1.29.0 → fal-1.30.0}/src/fal/logging/__init__.py +0 -0
  127. {fal-1.29.0 → fal-1.30.0}/src/fal/logging/isolate.py +0 -0
  128. {fal-1.29.0 → fal-1.30.0}/src/fal/logging/style.py +0 -0
  129. {fal-1.29.0 → fal-1.30.0}/src/fal/logging/trace.py +0 -0
  130. {fal-1.29.0 → fal-1.30.0}/src/fal/logging/user.py +0 -0
  131. {fal-1.29.0 → fal-1.30.0}/src/fal/project.py +0 -0
  132. {fal-1.29.0 → fal-1.30.0}/src/fal/py.typed +0 -0
  133. {fal-1.29.0 → fal-1.30.0}/src/fal/rest_client.py +0 -0
  134. {fal-1.29.0 → fal-1.30.0}/src/fal/sync.py +0 -0
  135. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/__init__.py +0 -0
  136. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/audio/__init__.py +0 -0
  137. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/audio/audio.py +0 -0
  138. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/exceptions.py +0 -0
  139. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/file/__init__.py +0 -0
  140. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/file/file.py +0 -0
  141. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/file/providers/fal.py +0 -0
  142. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
  143. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/file/providers/r2.py +0 -0
  144. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/file/providers/s3.py +0 -0
  145. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/file/types.py +0 -0
  146. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/__init__.py +0 -0
  147. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/image.py +0 -0
  148. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
  149. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
  150. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
  151. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
  152. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
  153. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/image/safety_checker.py +0 -0
  154. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/kv.py +0 -0
  155. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/optimize.py +0 -0
  156. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/types.py +0 -0
  157. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/utils/download_utils.py +0 -0
  158. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/utils/endpoint.py +0 -0
  159. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/utils/retry.py +0 -0
  160. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/video/__init__.py +0 -0
  161. {fal-1.29.0 → fal-1.30.0}/src/fal/toolkit/video/video.py +0 -0
  162. {fal-1.29.0 → fal-1.30.0}/src/fal/utils.py +0 -0
  163. {fal-1.29.0 → fal-1.30.0}/src/fal/workflows.py +0 -0
  164. {fal-1.29.0 → fal-1.30.0}/tests/__init__.py +0 -0
  165. {fal-1.29.0 → fal-1.30.0}/tests/assets/cat.png +0 -0
  166. {fal-1.29.0 → fal-1.30.0}/tests/cli/__init__.py +0 -0
  167. {fal-1.29.0 → fal-1.30.0}/tests/cli/test_apps.py +0 -0
  168. {fal-1.29.0 → fal-1.30.0}/tests/cli/test_auth.py +0 -0
  169. {fal-1.29.0 → fal-1.30.0}/tests/cli/test_deploy.py +0 -0
  170. {fal-1.29.0 → fal-1.30.0}/tests/cli/test_keys.py +0 -0
  171. {fal-1.29.0 → fal-1.30.0}/tests/cli/test_run.py +0 -0
  172. {fal-1.29.0 → fal-1.30.0}/tests/cli/test_secrets.py +0 -0
  173. {fal-1.29.0 → fal-1.30.0}/tests/conftest.py +0 -0
  174. {fal-1.29.0 → fal-1.30.0}/tests/integration_test.py +0 -0
  175. {fal-1.29.0 → fal-1.30.0}/tests/mainify_package/__init__.py +0 -0
  176. {fal-1.29.0 → fal-1.30.0}/tests/mainify_package/impl.py +0 -0
  177. {fal-1.29.0 → fal-1.30.0}/tests/mainify_package/utils.py +0 -0
  178. {fal-1.29.0 → fal-1.30.0}/tests/mainify_target.py +0 -0
  179. {fal-1.29.0 → fal-1.30.0}/tests/test_files.py +0 -0
  180. {fal-1.29.0 → fal-1.30.0}/tests/test_kv.py +0 -0
  181. {fal-1.29.0 → fal-1.30.0}/tests/test_stability.py +0 -0
  182. {fal-1.29.0 → fal-1.30.0}/tests/toolkit/file/providers/test_fal_retry.py +0 -0
  183. {fal-1.29.0 → fal-1.30.0}/tests/toolkit/file_test.py +0 -0
  184. {fal-1.29.0 → fal-1.30.0}/tests/toolkit/image_test.py +0 -0
  185. {fal-1.29.0 → fal-1.30.0}/tests/toolkit/test_types.py +0 -0
  186. {fal-1.29.0 → fal-1.30.0}/tests/toolkit/utils/retry.py +0 -0
  187. {fal-1.29.0 → fal-1.30.0}/tools/demo_script.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.29.0
3
+ Version: 1.30.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.19.0,>=0.18.0
9
- Requires-Dist: isolate-proto<0.11.0,>=0.10.2
9
+ Requires-Dist: isolate-proto<0.13.0,>=0.12.0
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
@@ -31,7 +31,7 @@ Requires-Dist: python-dateutil<3,>=2.8.0
31
31
  Requires-Dist: types-python-dateutil<3,>=2.8.0
32
32
  Requires-Dist: importlib-metadata>=4.4; python_version < "3.10"
33
33
  Requires-Dist: msgpack<2,>=1.0.7
34
- Requires-Dist: websockets<13,>=12.0
34
+ Requires-Dist: websockets<16,>=12.0
35
35
  Requires-Dist: pillow<11,>=10.2.0
36
36
  Requires-Dist: pyjwt[crypto]<3,>=2.8.0
37
37
  Requires-Dist: uvicorn<1,>=0.29.0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.29.0
3
+ Version: 1.30.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.19.0,>=0.18.0
9
- Requires-Dist: isolate-proto<0.11.0,>=0.10.2
9
+ Requires-Dist: isolate-proto<0.13.0,>=0.12.0
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
@@ -31,7 +31,7 @@ Requires-Dist: python-dateutil<3,>=2.8.0
31
31
  Requires-Dist: types-python-dateutil<3,>=2.8.0
32
32
  Requires-Dist: importlib-metadata>=4.4; python_version < "3.10"
33
33
  Requires-Dist: msgpack<2,>=1.0.7
34
- Requires-Dist: websockets<13,>=12.0
34
+ Requires-Dist: websockets<16,>=12.0
35
35
  Requires-Dist: pillow<11,>=10.2.0
36
36
  Requires-Dist: pyjwt[crypto]<3,>=2.8.0
37
37
  Requires-Dist: uvicorn<1,>=0.29.0
@@ -155,6 +155,7 @@ src/fal/toolkit/utils/__init__.py
155
155
  src/fal/toolkit/utils/download_utils.py
156
156
  src/fal/toolkit/utils/endpoint.py
157
157
  src/fal/toolkit/utils/retry.py
158
+ src/fal/toolkit/utils/setup_utils.py
158
159
  src/fal/toolkit/video/__init__.py
159
160
  src/fal/toolkit/video/video.py
160
161
  tests/__init__.py
@@ -1,5 +1,5 @@
1
1
  isolate[build]<0.19.0,>=0.18.0
2
- isolate-proto<0.11.0,>=0.10.2
2
+ isolate-proto<0.13.0,>=0.12.0
3
3
  grpcio<2,>=1.64.0
4
4
  dill==0.3.7
5
5
  cloudpickle==3.0.0
@@ -23,7 +23,7 @@ attrs>=21.3.0
23
23
  python-dateutil<3,>=2.8.0
24
24
  types-python-dateutil<3,>=2.8.0
25
25
  msgpack<2,>=1.0.7
26
- websockets<13,>=12.0
26
+ websockets<16,>=12.0
27
27
  pillow<11,>=10.2.0
28
28
  pyjwt[crypto]<3,>=2.8.0
29
29
  uvicorn<1,>=0.29.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.19.0",
26
- "isolate-proto>=0.10.2,<0.11.0",
26
+ "isolate-proto>=0.12.0,<0.13.0",
27
27
  "grpcio>=1.64.0,<2",
28
28
  "dill==0.3.7",
29
29
  "cloudpickle==3.0.0",
@@ -51,7 +51,7 @@ dependencies = [
51
51
  # For 3.9 and earlier, importlib-metadata's newer versions are included in the standard library.
52
52
  'importlib-metadata>=4.4; python_version < "3.10"',
53
53
  "msgpack>=1.0.7,<2",
54
- "websockets>=12.0,<13",
54
+ "websockets>=12.0,<16",
55
55
  "pillow>=10.2.0,<11",
56
56
  "pyjwt[crypto]>=2.8.0,<3",
57
57
  "uvicorn>=0.29.0,<1",
@@ -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.29.0'
32
- __version_tuple__ = version_tuple = (1, 29, 0)
31
+ __version__ = version = '1.30.0'
32
+ __version_tuple__ = version_tuple = (1, 30, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -337,8 +337,10 @@ class App(BaseServable):
337
337
 
338
338
  def __init__(self, *, _allow_init: bool = False):
339
339
  if not _allow_init and not os.getenv("IS_ISOLATE_AGENT"):
340
+ cls_name = self.__class__.__name__
340
341
  raise NotImplementedError(
341
- "Running apps through SDK is not implemented yet."
342
+ "Running apps through SDK is not implemented yet. "
343
+ f"Please use `fal run path/to/app.py::{cls_name}` to run your app."
342
344
  )
343
345
 
344
346
  @classmethod
@@ -5,6 +5,7 @@ from dataclasses import asdict
5
5
  from typing import TYPE_CHECKING
6
6
 
7
7
  import fal.cli.runners as runners
8
+ from fal.sdk import RunnerState
8
9
 
9
10
  from ._utils import get_client
10
11
  from .parser import FalClientParser
@@ -298,7 +299,11 @@ def _runners(args):
298
299
  alias_runners = connection.list_alias_runners(alias=args.app_name)
299
300
 
300
301
  runners_table = runners.runners_table(alias_runners)
301
- args.console.print(f"Runners: {len(alias_runners)}")
302
+ pending_runners = [
303
+ runner for runner in alias_runners if runner.state == RunnerState.PENDING
304
+ ]
305
+ args.console.print(f"Runners: {len(alias_runners) - len(pending_runners)}")
306
+ args.console.print(f"Pending Runners: {len(pending_runners)}")
302
307
  # Drop the alias column, which is the first column
303
308
  runners_table.columns.pop(0)
304
309
  args.console.print(runners_table)
@@ -142,11 +142,16 @@ def _deploy_from_reference(
142
142
  args.console.print(
143
143
  f"\thttps://{playground_host}/models/{user.username}/{app_name}{endpoint}"
144
144
  )
145
- args.console.print("Endpoints:")
145
+ args.console.print("Synchronous Endpoints:")
146
146
  for endpoint in loaded.endpoints:
147
147
  args.console.print(
148
148
  f"\thttps://{endpoint_host}/{user.username}/{app_name}{endpoint}"
149
149
  )
150
+ args.console.print("Asynchronous Endpoints (Recommended):")
151
+ for endpoint in loaded.endpoints:
152
+ args.console.print(
153
+ f"\thttps://queue.{endpoint_host}/{user.username}/{app_name}{endpoint}"
154
+ )
150
155
 
151
156
 
152
157
  def _deploy(args):
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from typing import List
4
4
 
5
- from fal.sdk import RunnerInfo
5
+ from fal.sdk import RunnerInfo, RunnerState
6
6
 
7
7
  from ._utils import get_client
8
8
  from .parser import FalClientParser
@@ -19,6 +19,7 @@ def runners_table(runners: List[RunnerInfo]):
19
19
  table.add_column("Expires In")
20
20
  table.add_column("Uptime")
21
21
  table.add_column("Revision")
22
+ table.add_column("State")
22
23
 
23
24
  for runner in runners:
24
25
  external_metadata = runner.external_metadata
@@ -45,6 +46,7 @@ def runners_table(runners: List[RunnerInfo]):
45
46
  ),
46
47
  f"{runner.uptime} ({runner.uptime.total_seconds()}s)",
47
48
  runner.revision,
49
+ runner.state.value,
48
50
  )
49
51
 
50
52
  return table
@@ -82,7 +84,11 @@ def _list(args):
82
84
  client = get_client(args.host, args.team)
83
85
  with client.connect() as connection:
84
86
  runners = connection.list_runners()
85
- args.console.print(f"Runners: {len(runners)}")
87
+ pending_runners = [
88
+ runner for runner in runners if runner.state == RunnerState.PENDING
89
+ ]
90
+ args.console.print(f"Runners: {len(runners) - len(pending_runners)}")
91
+ args.console.print(f"Pending Runners: {len(pending_runners)}")
86
92
  args.console.print(runners_table(runners))
87
93
 
88
94
  requests_table = runners_requests_table(runners)
@@ -261,6 +261,21 @@ class AliasInfo:
261
261
  valid_regions: list[str]
262
262
 
263
263
 
264
+ class RunnerState(Enum):
265
+ RUNNING = "running"
266
+ PENDING = "pending"
267
+ UNKNOWN = "unknown"
268
+
269
+ @staticmethod
270
+ def from_proto(proto: isolate_proto.RunnerInfo.State) -> RunnerState:
271
+ if proto is isolate_proto.RunnerInfo.State.RUNNING:
272
+ return RunnerState.RUNNING
273
+ elif proto is isolate_proto.RunnerInfo.State.PENDING:
274
+ return RunnerState.PENDING
275
+ else:
276
+ return RunnerState.UNKNOWN
277
+
278
+
264
279
  @dataclass
265
280
  class RunnerInfo:
266
281
  runner_id: str
@@ -270,6 +285,15 @@ class RunnerInfo:
270
285
  external_metadata: dict[str, Any]
271
286
  revision: str
272
287
  alias: str
288
+ state: RunnerState
289
+
290
+
291
+ @dataclass
292
+ class ServiceURLs:
293
+ playground: str
294
+ run: str
295
+ queue: str
296
+ ws: str
273
297
 
274
298
 
275
299
  @dataclass
@@ -279,12 +303,14 @@ class HostedRunResult(Generic[ResultT]):
279
303
  logs: list[Log] = field(default_factory=list)
280
304
  result: ResultT | None = None
281
305
  stream: Any = None
306
+ service_urls: ServiceURLs | None = None
282
307
 
283
308
 
284
309
  @dataclass
285
310
  class RegisterApplicationResult:
286
311
  result: RegisterApplicationResultType | None
287
312
  logs: list[Log] = field(default_factory=list)
313
+ service_urls: ServiceURLs | None = None
288
314
 
289
315
 
290
316
  @dataclass
@@ -421,6 +447,7 @@ def _from_grpc_runner_info(message: isolate_proto.RunnerInfo) -> RunnerInfo:
421
447
  external_metadata=external_metadata,
422
448
  revision=message.revision,
423
449
  alias=message.alias,
450
+ state=RunnerState.from_proto(message.state),
424
451
  )
425
452
 
426
453
 
@@ -435,6 +462,9 @@ def _from_grpc_register_application_result(
435
462
  if not message.HasField("result")
436
463
  else RegisterApplicationResultType(message.result.application_id)
437
464
  ),
465
+ service_urls=from_grpc(message.service_urls)
466
+ if message.HasField("service_urls")
467
+ else None,
438
468
  )
439
469
 
440
470
 
@@ -445,6 +475,13 @@ def _from_grpc_hosted_run_status(
445
475
  return HostedRunStatus(HostedRunState(message.state))
446
476
 
447
477
 
478
+ @from_grpc.register(isolate_proto.ServiceURLs)
479
+ def _from_grpc_service_urls(
480
+ message: isolate_proto.ServiceURLs,
481
+ ) -> ServiceURLs:
482
+ return ServiceURLs(message.playground, message.run, message.queue, message.ws)
483
+
484
+
448
485
  @from_grpc.register(isolate_proto.HostedRunResult)
449
486
  def _from_grpc_hosted_run_result(
450
487
  message: isolate_proto.HostedRunResult,
@@ -459,6 +496,9 @@ def _from_grpc_hosted_run_result(
459
496
  from_grpc(message.status),
460
497
  logs=[from_grpc(log) for log in message.logs],
461
498
  result=return_value,
499
+ service_urls=from_grpc(message.service_urls)
500
+ if message.HasField("service_urls")
501
+ else None,
462
502
  )
463
503
 
464
504
 
@@ -769,7 +809,7 @@ class FalServerlessConnection:
769
809
  return [from_grpc(alias) for alias in response.aliases]
770
810
 
771
811
  def list_alias_runners(self, alias: str) -> list[RunnerInfo]:
772
- request = isolate_proto.ListAliasRunnersRequest(alias=alias)
812
+ request = isolate_proto.ListAliasRunnersRequest(alias=alias, list_pending=True)
773
813
  response = self.stub.ListAliasRunners(request)
774
814
  return [from_grpc(runner) for runner in response.runners]
775
815
 
@@ -797,6 +837,6 @@ class FalServerlessConnection:
797
837
  self.stub.KillRunner(request)
798
838
 
799
839
  def list_runners(self) -> list[RunnerInfo]:
800
- request = isolate_proto.ListRunnersRequest()
840
+ request = isolate_proto.ListRunnersRequest(list_pending=True)
801
841
  response = self.stub.ListRunners(request)
802
842
  return [from_grpc(runner) for runner in response.runners]
@@ -1,3 +1,4 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from fal.toolkit.utils.download_utils import * # noqa: F403
4
+ from fal.toolkit.utils.setup_utils import patch_onnx_runtime # noqa: F401
@@ -0,0 +1,34 @@
1
+ import os
2
+
3
+
4
+ def patch_onnx_runtime(
5
+ inter_op_num_threads: int = 16,
6
+ intra_op_num_threads: int = 16,
7
+ omp_num_threads: int = 16,
8
+ ):
9
+ """
10
+ Patch ONNX Runtime's defaults to set the number of threads for inter-op,
11
+ intra-op, and OpenMP.Trying to use an ONNX Runtime session within a fal app
12
+ without explicitly setting these parameters can lead to issues, for example,
13
+ it can cause several logs related to these parameters to be printed.
14
+ Please run this function before importing any ONNX Runtime modules
15
+ in your application.
16
+
17
+ Args:
18
+ inter_op_num_threads (int): Number of threads for inter-op parallelism.
19
+ intra_op_num_threads (int): Number of threads for intra-op parallelism.
20
+ omp_num_threads (int): Number of threads for OpenMP parallelism.
21
+
22
+ """
23
+ import onnxruntime as ort
24
+
25
+ os.environ["OMP_NUM_THREADS"] = str(omp_num_threads)
26
+
27
+ _default_session_options = ort.capi._pybind_state.get_default_session_options()
28
+
29
+ def get_default_session_options_new():
30
+ _default_session_options.inter_op_num_threads = inter_op_num_threads
31
+ _default_session_options.intra_op_num_threads = intra_op_num_threads
32
+ return _default_session_options
33
+
34
+ ort.capi._pybind_state.get_default_session_options = get_default_session_options_new
@@ -727,7 +727,12 @@ def test_app_deploy_scale(host: api.FalServerlessHost):
727
727
  )
728
728
 
729
729
  options = replace(
730
- addition_app.options, host={**addition_app.options.host, "max_multiplexing": 30}
730
+ addition_app.options,
731
+ host={
732
+ **addition_app.options.host,
733
+ "max_multiplexing": 3,
734
+ "max_concurrency": 2,
735
+ },
731
736
  )
732
737
  kwargs = dict(
733
738
  func=addition_app.func,
@@ -743,7 +748,10 @@ def test_app_deploy_scale(host: api.FalServerlessHost):
743
748
  found = next(filter(lambda alias: alias.alias == app_alias, res), None)
744
749
  assert found, f"Could not find app {app_alias} in {res}"
745
750
  assert found.revision == app_revision
746
- assert found.max_multiplexing == 1
751
+ # multiplexing is revision-specific
752
+ assert found.max_multiplexing == 3, "Expected max_multiplexing to have changed"
753
+ # max_concurrency is alias-specific
754
+ assert found.max_concurrency == 1, "Expected max_concurrency to stay the same"
747
755
 
748
756
  app_revision = addition_app.host.register(**kwargs, scale=True)
749
757
 
@@ -752,7 +760,9 @@ def test_app_deploy_scale(host: api.FalServerlessHost):
752
760
  found = next(filter(lambda alias: alias.alias == app_alias, res), None)
753
761
  assert found, f"Could not find app {app_alias} in {res}"
754
762
  assert found.revision == app_revision
755
- assert found.max_multiplexing == 30
763
+ # when scaling, all values are updated
764
+ assert found.max_multiplexing == 3
765
+ assert found.max_concurrency == 2
756
766
 
757
767
 
758
768
  # List aliases is taking long
@@ -1015,7 +1025,8 @@ def test_kill_runner(host: api.FalServerlessHost, test_sleep_app: str):
1015
1025
  client.kill_runner(runners[0].runner_id)
1016
1026
 
1017
1027
  runners = client.list_alias_runners(app_alias)
1018
- assert len(runners) == 0
1028
+ num_runners = len([runner for runner in runners if runner.state == "running"])
1029
+ assert num_runners == 0
1019
1030
 
1020
1031
 
1021
1032
  def test_container_app_client(test_container_app: str):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes