fal 1.17.0__tar.gz → 1.18.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 (178) hide show
  1. {fal-1.17.0/fal.egg-info → fal-1.18.0}/PKG-INFO +2 -2
  2. {fal-1.17.0 → fal-1.18.0/fal.egg-info}/PKG-INFO +2 -2
  3. {fal-1.17.0 → fal-1.18.0}/fal.egg-info/requires.txt +1 -1
  4. {fal-1.17.0 → fal-1.18.0}/pyproject.toml +1 -1
  5. {fal-1.17.0 → fal-1.18.0}/src/fal/_fal_version.py +2 -2
  6. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/apps.py +2 -0
  7. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/files.py +14 -0
  8. {fal-1.17.0 → fal-1.18.0}/src/fal/files.py +28 -8
  9. {fal-1.17.0 → fal-1.18.0}/src/fal/sdk.py +2 -0
  10. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/utils/download_utils.py +6 -2
  11. {fal-1.17.0 → fal-1.18.0}/.gitignore +0 -0
  12. {fal-1.17.0 → fal-1.18.0}/Makefile +0 -0
  13. {fal-1.17.0 → fal-1.18.0}/README.md +0 -0
  14. {fal-1.17.0 → fal-1.18.0}/docs/conf.py +0 -0
  15. {fal-1.17.0 → fal-1.18.0}/docs/index.rst +0 -0
  16. {fal-1.17.0 → fal-1.18.0}/fal.egg-info/SOURCES.txt +0 -0
  17. {fal-1.17.0 → fal-1.18.0}/fal.egg-info/dependency_links.txt +0 -0
  18. {fal-1.17.0 → fal-1.18.0}/fal.egg-info/entry_points.txt +0 -0
  19. {fal-1.17.0 → fal-1.18.0}/fal.egg-info/top_level.txt +0 -0
  20. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/README.md +0 -0
  21. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  22. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  23. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  24. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  25. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  26. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  27. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
  28. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
  29. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
  30. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
  31. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
  32. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
  33. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  34. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  35. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  36. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
  37. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
  38. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  39. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
  40. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
  41. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
  42. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
  43. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
  44. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  45. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  46. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  47. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  48. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  49. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
  50. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
  51. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
  52. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
  53. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
  54. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
  55. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
  56. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
  57. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  58. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  59. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  60. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  61. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
  62. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  63. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
  64. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
  65. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
  66. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  67. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
  68. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
  69. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  70. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  71. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
  72. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  73. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  74. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  75. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
  76. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  77. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  78. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  79. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  80. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  81. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  82. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  83. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  84. {fal-1.17.0 → fal-1.18.0}/openapi-fal-rest/pyproject.toml +0 -0
  85. {fal-1.17.0 → fal-1.18.0}/openapi_rest.config.yaml +0 -0
  86. {fal-1.17.0 → fal-1.18.0}/setup.cfg +0 -0
  87. {fal-1.17.0 → fal-1.18.0}/src/fal/__init__.py +0 -0
  88. {fal-1.17.0 → fal-1.18.0}/src/fal/__main__.py +0 -0
  89. {fal-1.17.0 → fal-1.18.0}/src/fal/_serialization.py +0 -0
  90. {fal-1.17.0 → fal-1.18.0}/src/fal/_version.py +0 -0
  91. {fal-1.17.0 → fal-1.18.0}/src/fal/api.py +0 -0
  92. {fal-1.17.0 → fal-1.18.0}/src/fal/app.py +0 -0
  93. {fal-1.17.0 → fal-1.18.0}/src/fal/apps.py +0 -0
  94. {fal-1.17.0 → fal-1.18.0}/src/fal/auth/__init__.py +0 -0
  95. {fal-1.17.0 → fal-1.18.0}/src/fal/auth/auth0.py +0 -0
  96. {fal-1.17.0 → fal-1.18.0}/src/fal/auth/local.py +0 -0
  97. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/__init__.py +0 -0
  98. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/_utils.py +0 -0
  99. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/api.py +0 -0
  100. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/auth.py +0 -0
  101. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/cli_nested_json.py +0 -0
  102. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/create.py +0 -0
  103. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/debug.py +0 -0
  104. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/deploy.py +0 -0
  105. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/doctor.py +0 -0
  106. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/keys.py +0 -0
  107. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/main.py +0 -0
  108. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/parser.py +0 -0
  109. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/profile.py +0 -0
  110. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/run.py +0 -0
  111. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/runners.py +0 -0
  112. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/secrets.py +0 -0
  113. {fal-1.17.0 → fal-1.18.0}/src/fal/cli/teams.py +0 -0
  114. {fal-1.17.0 → fal-1.18.0}/src/fal/config.py +0 -0
  115. {fal-1.17.0 → fal-1.18.0}/src/fal/console/__init__.py +0 -0
  116. {fal-1.17.0 → fal-1.18.0}/src/fal/console/icons.py +0 -0
  117. {fal-1.17.0 → fal-1.18.0}/src/fal/console/ux.py +0 -0
  118. {fal-1.17.0 → fal-1.18.0}/src/fal/container.py +0 -0
  119. {fal-1.17.0 → fal-1.18.0}/src/fal/exceptions/__init__.py +0 -0
  120. {fal-1.17.0 → fal-1.18.0}/src/fal/exceptions/_base.py +0 -0
  121. {fal-1.17.0 → fal-1.18.0}/src/fal/exceptions/_cuda.py +0 -0
  122. {fal-1.17.0 → fal-1.18.0}/src/fal/exceptions/auth.py +0 -0
  123. {fal-1.17.0 → fal-1.18.0}/src/fal/flags.py +0 -0
  124. {fal-1.17.0 → fal-1.18.0}/src/fal/logging/__init__.py +0 -0
  125. {fal-1.17.0 → fal-1.18.0}/src/fal/logging/isolate.py +0 -0
  126. {fal-1.17.0 → fal-1.18.0}/src/fal/logging/style.py +0 -0
  127. {fal-1.17.0 → fal-1.18.0}/src/fal/logging/trace.py +0 -0
  128. {fal-1.17.0 → fal-1.18.0}/src/fal/logging/user.py +0 -0
  129. {fal-1.17.0 → fal-1.18.0}/src/fal/project.py +0 -0
  130. {fal-1.17.0 → fal-1.18.0}/src/fal/py.typed +0 -0
  131. {fal-1.17.0 → fal-1.18.0}/src/fal/rest_client.py +0 -0
  132. {fal-1.17.0 → fal-1.18.0}/src/fal/sync.py +0 -0
  133. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/__init__.py +0 -0
  134. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/exceptions.py +0 -0
  135. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/file/__init__.py +0 -0
  136. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/file/file.py +0 -0
  137. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/file/providers/fal.py +0 -0
  138. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
  139. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/file/providers/r2.py +0 -0
  140. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/file/providers/s3.py +0 -0
  141. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/file/types.py +0 -0
  142. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/__init__.py +0 -0
  143. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/image.py +0 -0
  144. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
  145. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
  146. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
  147. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
  148. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
  149. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/image/safety_checker.py +0 -0
  150. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/optimize.py +0 -0
  151. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/types.py +0 -0
  152. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/utils/__init__.py +0 -0
  153. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/utils/endpoint.py +0 -0
  154. {fal-1.17.0 → fal-1.18.0}/src/fal/toolkit/utils/retry.py +0 -0
  155. {fal-1.17.0 → fal-1.18.0}/src/fal/utils.py +0 -0
  156. {fal-1.17.0 → fal-1.18.0}/src/fal/workflows.py +0 -0
  157. {fal-1.17.0 → fal-1.18.0}/tests/__init__.py +0 -0
  158. {fal-1.17.0 → fal-1.18.0}/tests/assets/cat.png +0 -0
  159. {fal-1.17.0 → fal-1.18.0}/tests/cli/__init__.py +0 -0
  160. {fal-1.17.0 → fal-1.18.0}/tests/cli/test_apps.py +0 -0
  161. {fal-1.17.0 → fal-1.18.0}/tests/cli/test_auth.py +0 -0
  162. {fal-1.17.0 → fal-1.18.0}/tests/cli/test_deploy.py +0 -0
  163. {fal-1.17.0 → fal-1.18.0}/tests/cli/test_keys.py +0 -0
  164. {fal-1.17.0 → fal-1.18.0}/tests/cli/test_run.py +0 -0
  165. {fal-1.17.0 → fal-1.18.0}/tests/cli/test_secrets.py +0 -0
  166. {fal-1.17.0 → fal-1.18.0}/tests/conftest.py +0 -0
  167. {fal-1.17.0 → fal-1.18.0}/tests/integration_test.py +0 -0
  168. {fal-1.17.0 → fal-1.18.0}/tests/mainify_package/__init__.py +0 -0
  169. {fal-1.17.0 → fal-1.18.0}/tests/mainify_package/impl.py +0 -0
  170. {fal-1.17.0 → fal-1.18.0}/tests/mainify_package/utils.py +0 -0
  171. {fal-1.17.0 → fal-1.18.0}/tests/mainify_target.py +0 -0
  172. {fal-1.17.0 → fal-1.18.0}/tests/test_apps.py +0 -0
  173. {fal-1.17.0 → fal-1.18.0}/tests/test_stability.py +0 -0
  174. {fal-1.17.0 → fal-1.18.0}/tests/toolkit/file_test.py +0 -0
  175. {fal-1.17.0 → fal-1.18.0}/tests/toolkit/image_test.py +0 -0
  176. {fal-1.17.0 → fal-1.18.0}/tests/toolkit/test_types.py +0 -0
  177. {fal-1.17.0 → fal-1.18.0}/tests/toolkit/utils/retry.py +0 -0
  178. {fal-1.17.0 → fal-1.18.0}/tools/demo_script.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.17.0
3
+ Version: 1.18.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.17.0,>=0.16.2
9
- Requires-Dist: isolate-proto<0.9.0,>=0.8.1
9
+ Requires-Dist: isolate-proto<0.10.0,>=0.9.0
10
10
  Requires-Dist: grpcio==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.17.0
3
+ Version: 1.18.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.17.0,>=0.16.2
9
- Requires-Dist: isolate-proto<0.9.0,>=0.8.1
9
+ Requires-Dist: isolate-proto<0.10.0,>=0.9.0
10
10
  Requires-Dist: grpcio==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.17.0,>=0.16.2
2
- isolate-proto<0.9.0,>=0.8.1
2
+ isolate-proto<0.10.0,>=0.9.0
3
3
  grpcio==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.16.2,<0.17.0",
26
- "isolate-proto>=0.8.1,<0.9.0",
26
+ "isolate-proto>=0.9.0,<0.10.0",
27
27
  "grpcio==1.64.0",
28
28
  "dill==0.3.7",
29
29
  "cloudpickle==3.0.0",
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.17.0'
21
- __version_tuple__ = version_tuple = (1, 17, 0)
20
+ __version__ = version = '1.18.0'
21
+ __version_tuple__ = version_tuple = (1, 18, 0)
@@ -102,6 +102,7 @@ def _app_rev_table(revs: list[ApplicationInfo]):
102
102
  table.add_column("Machine Type")
103
103
  table.add_column("Runners")
104
104
  table.add_column("Regions")
105
+ table.add_column("Created")
105
106
 
106
107
  for rev in revs:
107
108
  table.add_row(
@@ -115,6 +116,7 @@ def _app_rev_table(revs: list[ApplicationInfo]):
115
116
  " ".join(rev.machine_types),
116
117
  str(rev.active_runners),
117
118
  " ".join(rev.valid_regions),
119
+ str(rev.created_at),
118
120
  )
119
121
 
120
122
  return table
@@ -28,6 +28,13 @@ def _upload(args):
28
28
  fs.put(args.local_path, args.remote_path, recursive=True)
29
29
 
30
30
 
31
+ def _upload_url(args):
32
+ from fal.files import FalFileSystem
33
+
34
+ fs = FalFileSystem()
35
+ fs.put_file_from_url(args.url, args.remote_path)
36
+
37
+
31
38
  def add_parser(main_subparsers, parents):
32
39
  files_help = "Manage fal files."
33
40
  parser = main_subparsers.add_parser(
@@ -68,3 +75,10 @@ def add_parser(main_subparsers, parents):
68
75
  upload_parser.add_argument("local_path", type=str, help="Local path to upload")
69
76
  upload_parser.add_argument("remote_path", type=str, help="Remote path to upload to")
70
77
  upload_parser.set_defaults(func=_upload)
78
+
79
+ upload_url_parser = subparsers.add_parser("upload-url", parents=parents)
80
+ upload_url_parser.add_argument("url", type=str, help="URL to upload")
81
+ upload_url_parser.add_argument(
82
+ "remote_path", type=str, help="Remote path to upload to"
83
+ )
84
+ upload_url_parser.set_defaults(func=_upload_url)
@@ -28,9 +28,20 @@ class FalFileSystem(AbstractFileSystem):
28
28
  },
29
29
  )
30
30
 
31
+ def _request(self, method, path, **kwargs):
32
+ from fal.exceptions import FalServerlessException
33
+
34
+ response = self._client.request(method, path, **kwargs)
35
+ if response.status_code != 200:
36
+ try:
37
+ detail = response.json()["detail"]
38
+ except Exception:
39
+ detail = response.text
40
+ raise FalServerlessException(detail)
41
+ return response
42
+
31
43
  def _ls(self, path):
32
- response = self._client.get(f"/files/list/{path}")
33
- response.raise_for_status()
44
+ response = self._request("GET", f"/files/list/{path}")
34
45
  files = response.json()
35
46
  return sorted(
36
47
  (
@@ -81,8 +92,7 @@ class FalFileSystem(AbstractFileSystem):
81
92
  return
82
93
 
83
94
  with open(lpath, "wb") as fobj:
84
- response = self._client.get(f"/files/file/{rpath}")
85
- response.raise_for_status()
95
+ response = self._request("GET", f"/files/file/{rpath}")
86
96
  fobj.write(response.content)
87
97
 
88
98
  def put_file(self, lpath, rpath, mode="overwrite", **kwargs):
@@ -90,14 +100,24 @@ class FalFileSystem(AbstractFileSystem):
90
100
  return
91
101
 
92
102
  with open(lpath, "rb") as fobj:
93
- response = self._client.post(
103
+ self._request(
104
+ "POST",
94
105
  f"/files/file/local/{rpath}",
95
106
  files={"file_upload": (posixpath.basename(lpath), fobj, "text/plain")},
96
107
  )
97
- response.raise_for_status()
108
+ self.dircache.clear()
109
+
110
+ def put_file_from_url(self, url, rpath, mode="overwrite", **kwargs):
111
+ self._request(
112
+ "POST",
113
+ f"/files/file/url/{rpath}",
114
+ json={"url": url},
115
+ )
98
116
  self.dircache.clear()
99
117
 
100
118
  def rm(self, path, **kwargs):
101
- response = self._client.delete(f"/files/file/{path}")
102
- response.raise_for_status()
119
+ self._request(
120
+ "DELETE",
121
+ f"/files/file/{path}",
122
+ )
103
123
  self.dircache.clear()
@@ -238,6 +238,7 @@ class ApplicationInfo:
238
238
  request_timeout: int
239
239
  startup_timeout: int
240
240
  valid_regions: list[str]
241
+ created_at: datetime
241
242
 
242
243
 
243
244
  @dataclass
@@ -368,6 +369,7 @@ def _from_grpc_application_info(
368
369
  request_timeout=message.request_timeout,
369
370
  startup_timeout=message.startup_timeout,
370
371
  valid_regions=list(message.valid_regions),
372
+ created_at=isolate_proto.datetime_from_timestamp(message.created_at),
371
373
  )
372
374
 
373
375
 
@@ -6,6 +6,7 @@ import os
6
6
  import shutil
7
7
  import subprocess
8
8
  import sys
9
+ from contextlib import suppress
9
10
  from pathlib import Path, PurePath
10
11
  from tempfile import NamedTemporaryFile, TemporaryDirectory
11
12
  from urllib.parse import urlparse
@@ -451,8 +452,11 @@ def clone_repository(
451
452
  with TemporaryDirectory(
452
453
  dir=target_dir, suffix=f"{local_repo_path.name}.tmp.old"
453
454
  ) as tmp_dir:
454
- os.rename(local_repo_path, tmp_dir)
455
- shutil.rmtree(tmp_dir)
455
+ with suppress(FileNotFoundError):
456
+ # repository might be already deleted by another worker
457
+ os.rename(local_repo_path, tmp_dir)
458
+ # sometimes seeing FileNotFoundError even here on juicefs
459
+ shutil.rmtree(tmp_dir)
456
460
 
457
461
  # NOTE: using the target_dir to be able to avoid potential copies across temp fs
458
462
  # and target fs, and also to be able to atomically rename repo_name dir into place
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