fal 1.15.0__tar.gz → 1.16.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 (177) hide show
  1. {fal-1.15.0/fal.egg-info → fal-1.16.0}/PKG-INFO +1 -1
  2. {fal-1.15.0 → fal-1.16.0/fal.egg-info}/PKG-INFO +1 -1
  3. {fal-1.15.0 → fal-1.16.0}/src/fal/_fal_version.py +2 -2
  4. {fal-1.15.0 → fal-1.16.0}/src/fal/_serialization.py +5 -5
  5. {fal-1.15.0 → fal-1.16.0}/src/fal/api.py +16 -1
  6. {fal-1.15.0 → fal-1.16.0}/src/fal/app.py +2 -0
  7. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/files.py +2 -2
  8. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/profile.py +19 -0
  9. {fal-1.15.0 → fal-1.16.0}/src/fal/files.py +24 -8
  10. {fal-1.15.0 → fal-1.16.0}/src/fal/flags.py +6 -1
  11. {fal-1.15.0 → fal-1.16.0}/src/fal/utils.py +3 -0
  12. {fal-1.15.0 → fal-1.16.0}/.gitignore +0 -0
  13. {fal-1.15.0 → fal-1.16.0}/Makefile +0 -0
  14. {fal-1.15.0 → fal-1.16.0}/README.md +0 -0
  15. {fal-1.15.0 → fal-1.16.0}/docs/conf.py +0 -0
  16. {fal-1.15.0 → fal-1.16.0}/docs/index.rst +0 -0
  17. {fal-1.15.0 → fal-1.16.0}/fal.egg-info/SOURCES.txt +0 -0
  18. {fal-1.15.0 → fal-1.16.0}/fal.egg-info/dependency_links.txt +0 -0
  19. {fal-1.15.0 → fal-1.16.0}/fal.egg-info/entry_points.txt +0 -0
  20. {fal-1.15.0 → fal-1.16.0}/fal.egg-info/requires.txt +0 -0
  21. {fal-1.15.0 → fal-1.16.0}/fal.egg-info/top_level.txt +0 -0
  22. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/README.md +0 -0
  23. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  24. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  25. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  26. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  27. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  28. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  29. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
  30. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
  31. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
  32. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
  33. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
  34. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
  35. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  36. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  37. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  38. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
  39. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
  40. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  41. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
  42. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
  43. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
  44. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
  45. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
  46. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  47. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  48. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  49. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  50. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  51. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
  52. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
  53. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
  54. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
  55. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
  56. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
  57. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
  58. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
  59. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  60. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  61. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  62. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  63. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
  64. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  65. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
  66. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
  67. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
  68. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  69. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
  70. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
  71. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  72. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  73. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
  74. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  75. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  76. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  77. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
  78. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  79. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  80. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  81. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  82. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  83. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  84. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  85. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  86. {fal-1.15.0 → fal-1.16.0}/openapi-fal-rest/pyproject.toml +0 -0
  87. {fal-1.15.0 → fal-1.16.0}/openapi_rest.config.yaml +0 -0
  88. {fal-1.15.0 → fal-1.16.0}/pyproject.toml +0 -0
  89. {fal-1.15.0 → fal-1.16.0}/setup.cfg +0 -0
  90. {fal-1.15.0 → fal-1.16.0}/src/fal/__init__.py +0 -0
  91. {fal-1.15.0 → fal-1.16.0}/src/fal/__main__.py +0 -0
  92. {fal-1.15.0 → fal-1.16.0}/src/fal/_version.py +0 -0
  93. {fal-1.15.0 → fal-1.16.0}/src/fal/apps.py +0 -0
  94. {fal-1.15.0 → fal-1.16.0}/src/fal/auth/__init__.py +0 -0
  95. {fal-1.15.0 → fal-1.16.0}/src/fal/auth/auth0.py +0 -0
  96. {fal-1.15.0 → fal-1.16.0}/src/fal/auth/local.py +0 -0
  97. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/__init__.py +0 -0
  98. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/_utils.py +0 -0
  99. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/api.py +0 -0
  100. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/apps.py +0 -0
  101. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/auth.py +0 -0
  102. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/cli_nested_json.py +0 -0
  103. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/create.py +0 -0
  104. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/debug.py +0 -0
  105. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/deploy.py +0 -0
  106. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/doctor.py +0 -0
  107. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/keys.py +0 -0
  108. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/main.py +0 -0
  109. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/parser.py +0 -0
  110. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/run.py +0 -0
  111. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/runners.py +0 -0
  112. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/secrets.py +0 -0
  113. {fal-1.15.0 → fal-1.16.0}/src/fal/cli/teams.py +0 -0
  114. {fal-1.15.0 → fal-1.16.0}/src/fal/config.py +0 -0
  115. {fal-1.15.0 → fal-1.16.0}/src/fal/console/__init__.py +0 -0
  116. {fal-1.15.0 → fal-1.16.0}/src/fal/console/icons.py +0 -0
  117. {fal-1.15.0 → fal-1.16.0}/src/fal/console/ux.py +0 -0
  118. {fal-1.15.0 → fal-1.16.0}/src/fal/container.py +0 -0
  119. {fal-1.15.0 → fal-1.16.0}/src/fal/exceptions/__init__.py +0 -0
  120. {fal-1.15.0 → fal-1.16.0}/src/fal/exceptions/_base.py +0 -0
  121. {fal-1.15.0 → fal-1.16.0}/src/fal/exceptions/_cuda.py +0 -0
  122. {fal-1.15.0 → fal-1.16.0}/src/fal/exceptions/auth.py +0 -0
  123. {fal-1.15.0 → fal-1.16.0}/src/fal/logging/__init__.py +0 -0
  124. {fal-1.15.0 → fal-1.16.0}/src/fal/logging/isolate.py +0 -0
  125. {fal-1.15.0 → fal-1.16.0}/src/fal/logging/style.py +0 -0
  126. {fal-1.15.0 → fal-1.16.0}/src/fal/logging/trace.py +0 -0
  127. {fal-1.15.0 → fal-1.16.0}/src/fal/logging/user.py +0 -0
  128. {fal-1.15.0 → fal-1.16.0}/src/fal/project.py +0 -0
  129. {fal-1.15.0 → fal-1.16.0}/src/fal/py.typed +0 -0
  130. {fal-1.15.0 → fal-1.16.0}/src/fal/rest_client.py +0 -0
  131. {fal-1.15.0 → fal-1.16.0}/src/fal/sdk.py +0 -0
  132. {fal-1.15.0 → fal-1.16.0}/src/fal/sync.py +0 -0
  133. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/__init__.py +0 -0
  134. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/exceptions.py +0 -0
  135. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/file/__init__.py +0 -0
  136. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/file/file.py +0 -0
  137. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/file/providers/fal.py +0 -0
  138. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
  139. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/file/providers/r2.py +0 -0
  140. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/file/providers/s3.py +0 -0
  141. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/file/types.py +0 -0
  142. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/__init__.py +0 -0
  143. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/image.py +0 -0
  144. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
  145. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
  146. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
  147. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
  148. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
  149. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/image/safety_checker.py +0 -0
  150. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/optimize.py +0 -0
  151. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/types.py +0 -0
  152. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/utils/__init__.py +0 -0
  153. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/utils/download_utils.py +0 -0
  154. {fal-1.15.0 → fal-1.16.0}/src/fal/toolkit/utils/retry.py +0 -0
  155. {fal-1.15.0 → fal-1.16.0}/src/fal/workflows.py +0 -0
  156. {fal-1.15.0 → fal-1.16.0}/tests/__init__.py +0 -0
  157. {fal-1.15.0 → fal-1.16.0}/tests/assets/cat.png +0 -0
  158. {fal-1.15.0 → fal-1.16.0}/tests/cli/__init__.py +0 -0
  159. {fal-1.15.0 → fal-1.16.0}/tests/cli/test_apps.py +0 -0
  160. {fal-1.15.0 → fal-1.16.0}/tests/cli/test_auth.py +0 -0
  161. {fal-1.15.0 → fal-1.16.0}/tests/cli/test_deploy.py +0 -0
  162. {fal-1.15.0 → fal-1.16.0}/tests/cli/test_keys.py +0 -0
  163. {fal-1.15.0 → fal-1.16.0}/tests/cli/test_run.py +0 -0
  164. {fal-1.15.0 → fal-1.16.0}/tests/cli/test_secrets.py +0 -0
  165. {fal-1.15.0 → fal-1.16.0}/tests/conftest.py +0 -0
  166. {fal-1.15.0 → fal-1.16.0}/tests/integration_test.py +0 -0
  167. {fal-1.15.0 → fal-1.16.0}/tests/mainify_package/__init__.py +0 -0
  168. {fal-1.15.0 → fal-1.16.0}/tests/mainify_package/impl.py +0 -0
  169. {fal-1.15.0 → fal-1.16.0}/tests/mainify_package/utils.py +0 -0
  170. {fal-1.15.0 → fal-1.16.0}/tests/mainify_target.py +0 -0
  171. {fal-1.15.0 → fal-1.16.0}/tests/test_apps.py +0 -0
  172. {fal-1.15.0 → fal-1.16.0}/tests/test_stability.py +0 -0
  173. {fal-1.15.0 → fal-1.16.0}/tests/toolkit/file_test.py +0 -0
  174. {fal-1.15.0 → fal-1.16.0}/tests/toolkit/image_test.py +0 -0
  175. {fal-1.15.0 → fal-1.16.0}/tests/toolkit/test_types.py +0 -0
  176. {fal-1.15.0 → fal-1.16.0}/tests/toolkit/utils/retry.py +0 -0
  177. {fal-1.15.0 → fal-1.16.0}/tools/demo_script.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.15.0
3
+ Version: 1.16.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.15.0
3
+ Version: 1.16.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
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.15.0'
21
- __version_tuple__ = version_tuple = (1, 15, 0)
20
+ __version__ = version = '1.16.0'
21
+ __version_tuple__ = version_tuple = (1, 16, 0)
@@ -6,7 +6,7 @@ from typing import Any, Callable
6
6
  import cloudpickle
7
7
 
8
8
 
9
- def _register_pickle_by_value(name) -> None:
9
+ def include_module(name) -> None:
10
10
  # cloudpickle.register_pickle_by_value wants an imported module object,
11
11
  # but there is really no reason to go through that complication, as
12
12
  # it might be prone to errors.
@@ -22,7 +22,7 @@ def include_package_from_path(raw_path: str) -> None:
22
22
  parent = parent.parent
23
23
 
24
24
  if parent != path:
25
- _register_pickle_by_value(parent.name)
25
+ include_module(parent.name)
26
26
 
27
27
 
28
28
  def include_modules_from(obj: Any) -> None:
@@ -33,7 +33,7 @@ def include_modules_from(obj: Any) -> None:
33
33
  if "." in module_name:
34
34
  # Just include the whole package
35
35
  package_name, *_ = module_name.partition(".")
36
- _register_pickle_by_value(package_name)
36
+ include_module(package_name)
37
37
  return
38
38
 
39
39
  if module_name == "__main__":
@@ -44,7 +44,7 @@ def include_modules_from(obj: Any) -> None:
44
44
  include_package_from_path(__main__.__file__)
45
45
  return
46
46
 
47
- _register_pickle_by_value(module_name)
47
+ include_module(module_name)
48
48
 
49
49
 
50
50
  def _register(cls: Any, func: Callable) -> None:
@@ -230,4 +230,4 @@ def patch_pickle() -> None:
230
230
  _patch_console_thread_locals()
231
231
  _patch_exceptions()
232
232
 
233
- _register_pickle_by_value("fal")
233
+ include_module("fal")
@@ -39,7 +39,7 @@ from pydantic import __version__ as pydantic_version
39
39
  from typing_extensions import Concatenate, ParamSpec
40
40
 
41
41
  import fal.flags as flags
42
- from fal._serialization import include_modules_from, patch_pickle
42
+ from fal._serialization import include_module, include_modules_from, patch_pickle
43
43
  from fal.container import ContainerImage
44
44
  from fal.exceptions import (
45
45
  AppException,
@@ -694,6 +694,7 @@ def function(
694
694
  serve: Literal[False] = False,
695
695
  exposed_port: int | None = None,
696
696
  max_concurrency: int | None = None,
697
+ local_python_modules: list[str] | None = None,
697
698
  ) -> Callable[
698
699
  [Callable[Concatenate[ArgsT], ReturnT]], IsolatedFunction[ArgsT, ReturnT]
699
700
  ]: ...
@@ -710,6 +711,7 @@ def function(
710
711
  serve: Literal[True],
711
712
  exposed_port: int | None = None,
712
713
  max_concurrency: int | None = None,
714
+ local_python_modules: list[str] | None = None,
713
715
  ) -> Callable[
714
716
  [Callable[Concatenate[ArgsT], ReturnT]], ServedIsolatedFunction[ArgsT, ReturnT]
715
717
  ]: ...
@@ -727,6 +729,7 @@ def function(
727
729
  serve: Literal[False] = False,
728
730
  exposed_port: int | None = None,
729
731
  max_concurrency: int | None = None,
732
+ local_python_modules: list[str] | None = None,
730
733
  # FalServerlessHost options
731
734
  metadata: dict[str, Any] | None = None,
732
735
  machine_type: str | list[str] = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
@@ -756,6 +759,7 @@ def function(
756
759
  serve: Literal[True],
757
760
  exposed_port: int | None = None,
758
761
  max_concurrency: int | None = None,
762
+ local_python_modules: list[str] | None = None,
759
763
  # FalServerlessHost options
760
764
  metadata: dict[str, Any] | None = None,
761
765
  machine_type: str | list[str] = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
@@ -792,6 +796,7 @@ def function(
792
796
  serve: Literal[False] = False,
793
797
  exposed_port: int | None = None,
794
798
  max_concurrency: int | None = None,
799
+ local_python_modules: list[str] | None = None,
795
800
  ) -> Callable[
796
801
  [Callable[Concatenate[ArgsT], ReturnT]], IsolatedFunction[ArgsT, ReturnT]
797
802
  ]: ...
@@ -813,6 +818,7 @@ def function(
813
818
  serve: Literal[True],
814
819
  exposed_port: int | None = None,
815
820
  max_concurrency: int | None = None,
821
+ local_python_modules: list[str] | None = None,
816
822
  ) -> Callable[
817
823
  [Callable[Concatenate[ArgsT], ReturnT]], ServedIsolatedFunction[ArgsT, ReturnT]
818
824
  ]: ...
@@ -835,6 +841,7 @@ def function(
835
841
  serve: Literal[False] = False,
836
842
  exposed_port: int | None = None,
837
843
  max_concurrency: int | None = None,
844
+ local_python_modules: list[str] | None = None,
838
845
  # FalServerlessHost options
839
846
  metadata: dict[str, Any] | None = None,
840
847
  machine_type: str | list[str] = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
@@ -869,6 +876,7 @@ def function(
869
876
  serve: Literal[True],
870
877
  exposed_port: int | None = None,
871
878
  max_concurrency: int | None = None,
879
+ local_python_modules: list[str] | None = None,
872
880
  # FalServerlessHost options
873
881
  metadata: dict[str, Any] | None = None,
874
882
  machine_type: str | list[str] = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
@@ -897,6 +905,7 @@ def function(
897
905
  serve: Literal[False] = False,
898
906
  exposed_port: int | None = None,
899
907
  max_concurrency: int | None = None,
908
+ local_python_modules: list[str] | None = None,
900
909
  # FalServerlessHost options
901
910
  metadata: dict[str, Any] | None = None,
902
911
  machine_type: str | list[str] = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
@@ -925,6 +934,7 @@ def function(
925
934
  serve: Literal[True],
926
935
  exposed_port: int | None = None,
927
936
  max_concurrency: int | None = None,
937
+ local_python_modules: list[str] | None = None,
928
938
  # FalServerlessHost options
929
939
  metadata: dict[str, Any] | None = None,
930
940
  machine_type: str | list[str] = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
@@ -948,6 +958,7 @@ def function( # type: ignore
948
958
  kind: str = "virtualenv",
949
959
  *,
950
960
  host: Host | None = None,
961
+ local_python_modules: list[str] | None = None,
951
962
  **config: Any,
952
963
  ):
953
964
  if host is None:
@@ -956,6 +967,10 @@ def function( # type: ignore
956
967
 
957
968
  def wrapper(func: Callable[ArgsT, ReturnT]):
958
969
  include_modules_from(func)
970
+
971
+ for module_name in local_python_modules or []:
972
+ include_module(module_name)
973
+
959
974
  proxy = IsolatedFunction(
960
975
  host=host, # type: ignore
961
976
  raw_func=func, # type: ignore
@@ -122,6 +122,7 @@ def wrap_app(cls: type[App], **kwargs) -> IsolatedFunction:
122
122
  wrapper = fal_function(
123
123
  kind,
124
124
  requirements=cls.requirements,
125
+ local_python_modules=cls.local_python_modules,
125
126
  machine_type=cls.machine_type,
126
127
  num_gpus=cls.num_gpus,
127
128
  **cls.host_kwargs,
@@ -265,6 +266,7 @@ def _print_python_packages() -> None:
265
266
 
266
267
  class App(BaseServable):
267
268
  requirements: ClassVar[list[str]] = []
269
+ local_python_modules: ClassVar[list[str]] = []
268
270
  machine_type: ClassVar[str] = "S"
269
271
  num_gpus: ClassVar[int | None] = None
270
272
  host_kwargs: ClassVar[dict[str, Any]] = {
@@ -18,14 +18,14 @@ def _download(args):
18
18
  from fal.files import FalFileSystem
19
19
 
20
20
  fs = FalFileSystem()
21
- fs.get(args.remote_path, args.local_path)
21
+ fs.get(args.remote_path, args.local_path, recursive=True)
22
22
 
23
23
 
24
24
  def _upload(args):
25
25
  from fal.files import FalFileSystem
26
26
 
27
27
  fs = FalFileSystem()
28
- fs.put(args.local_path, args.remote_path)
28
+ fs.put(args.local_path, args.remote_path, recursive=True)
29
29
 
30
30
 
31
31
  def add_parser(main_subparsers, parents):
@@ -55,6 +55,12 @@ def _key_set(args):
55
55
  args.console.print(f"Key set for profile [cyan]{config.profile}[/].")
56
56
 
57
57
 
58
+ def _host_set(args):
59
+ with Config().edit() as config:
60
+ config.set("host", args.HOST)
61
+ args.console.print(f"Fal host set to [cyan]{args.HOST}[/].")
62
+
63
+
58
64
  def _delete(args):
59
65
  with Config().edit() as config:
60
66
  if config.profile == args.PROFILE:
@@ -121,6 +127,19 @@ def add_parser(main_subparsers, parents):
121
127
  )
122
128
  key_set_parser.set_defaults(func=_key_set)
123
129
 
130
+ host_set_help = "Set fal host."
131
+ host_set_parser = subparsers.add_parser(
132
+ "host",
133
+ description=host_set_help,
134
+ help=host_set_help,
135
+ parents=parents,
136
+ )
137
+ host_set_parser.add_argument(
138
+ "HOST",
139
+ help="Fal host.",
140
+ )
141
+ host_set_parser.set_defaults(func=_host_set)
142
+
124
143
  delete_help = "Delete profile."
125
144
  delete_parser = subparsers.add_parser(
126
145
  "delete",
@@ -1,3 +1,4 @@
1
+ import os
1
2
  import posixpath
2
3
  from functools import cached_property
3
4
  from typing import TYPE_CHECKING
@@ -28,14 +29,16 @@ class FalFileSystem(AbstractFileSystem):
28
29
  )
29
30
 
30
31
  def ls(self, path, detail=True, **kwargs):
31
- response = self._client.get(f"/files/list/{path.lstrip('/')}")
32
- response.raise_for_status()
33
- files = response.json()
34
- if detail:
35
- return sorted(
32
+ if path in self.dircache:
33
+ entries = self.dircache[path]
34
+ else:
35
+ response = self._client.get(f"/files/list/{path.lstrip('/')}")
36
+ response.raise_for_status()
37
+ files = response.json()
38
+ entries = sorted(
36
39
  (
37
40
  {
38
- "name": entry["path"],
41
+ "name": entry["path"].lstrip("/data/"),
39
42
  "size": entry["size"],
40
43
  "type": "file" if entry["is_file"] else "directory",
41
44
  "mtime": entry["updated_time"],
@@ -44,8 +47,12 @@ class FalFileSystem(AbstractFileSystem):
44
47
  ),
45
48
  key=lambda x: x["name"],
46
49
  )
47
- else:
48
- return sorted(entry["path"] for entry in files)
50
+ self.dircache[path] = entries
51
+
52
+ if detail:
53
+ return entries
54
+
55
+ return [entry["name"] for entry in entries]
49
56
 
50
57
  def info(self, path, **kwargs):
51
58
  parent = posixpath.dirname(path)
@@ -56,19 +63,28 @@ class FalFileSystem(AbstractFileSystem):
56
63
  raise FileNotFoundError(f"File not found: {path}")
57
64
 
58
65
  def get_file(self, rpath, lpath, **kwargs):
66
+ if self.isdir(rpath):
67
+ os.makedirs(lpath, exist_ok=True)
68
+ return
69
+
59
70
  with open(lpath, "wb") as fobj:
60
71
  response = self._client.get(f"/files/file/{rpath.lstrip('/')}")
61
72
  response.raise_for_status()
62
73
  fobj.write(response.content)
63
74
 
64
75
  def put_file(self, lpath, rpath, mode="overwrite", **kwargs):
76
+ if os.path.isdir(lpath):
77
+ return
78
+
65
79
  with open(lpath, "rb") as fobj:
66
80
  response = self._client.post(
67
81
  f"/files/file/local/{rpath.lstrip('/')}",
68
82
  files={"file_upload": (posixpath.basename(lpath), fobj, "text/plain")},
69
83
  )
70
84
  response.raise_for_status()
85
+ self.dircache.clear()
71
86
 
72
87
  def rm(self, path, **kwargs):
73
88
  response = self._client.delete(f"/files/file/{path.lstrip('/')}")
74
89
  response.raise_for_status()
90
+ self.dircache.clear()
@@ -2,6 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  import os
4
4
 
5
+ from fal.config import Config
6
+
5
7
 
6
8
  def bool_envvar(name: str):
7
9
  if name in os.environ:
@@ -14,7 +16,10 @@ DEBUG = bool_envvar("DEBUG")
14
16
  TEST_MODE = bool_envvar("ISOLATE_TEST_MODE")
15
17
  AUTH_DISABLED = bool_envvar("ISOLATE_AUTH_DISABLED")
16
18
 
17
- GRPC_HOST = os.getenv("FAL_HOST", "api.alpha.fal.ai")
19
+ config = Config()
20
+ config_host = config.get("host")
21
+
22
+ GRPC_HOST = config_host or os.getenv("FAL_HOST") or "api.alpha.fal.ai"
18
23
  if not TEST_MODE:
19
24
  assert GRPC_HOST.startswith("api"), "FAL_HOST must start with 'api'"
20
25
 
@@ -21,8 +21,11 @@ def load_function_from(
21
21
  file_path: str,
22
22
  function_name: str | None = None,
23
23
  ) -> LoadedFunction:
24
+ import os
24
25
  import runpy
26
+ import sys
25
27
 
28
+ sys.path.append(os.getcwd())
26
29
  module = runpy.run_path(file_path)
27
30
  if function_name is None:
28
31
  fal_objects = {
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