fal 1.25.0__tar.gz → 1.26.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 (185) hide show
  1. {fal-1.25.0/fal.egg-info → fal-1.26.0}/PKG-INFO +1 -1
  2. {fal-1.25.0 → fal-1.26.0/fal.egg-info}/PKG-INFO +1 -1
  3. {fal-1.25.0 → fal-1.26.0}/src/fal/_fal_version.py +2 -2
  4. {fal-1.25.0 → fal-1.26.0}/src/fal/api.py +7 -5
  5. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/apps.py +5 -1
  6. {fal-1.25.0 → fal-1.26.0}/src/fal/sdk.py +8 -3
  7. {fal-1.25.0 → fal-1.26.0}/tests/test_apps.py +13 -16
  8. {fal-1.25.0 → fal-1.26.0}/.gitignore +0 -0
  9. {fal-1.25.0 → fal-1.26.0}/Makefile +0 -0
  10. {fal-1.25.0 → fal-1.26.0}/README.md +0 -0
  11. {fal-1.25.0 → fal-1.26.0}/docs/conf.py +0 -0
  12. {fal-1.25.0 → fal-1.26.0}/docs/index.rst +0 -0
  13. {fal-1.25.0 → fal-1.26.0}/fal.egg-info/SOURCES.txt +0 -0
  14. {fal-1.25.0 → fal-1.26.0}/fal.egg-info/dependency_links.txt +0 -0
  15. {fal-1.25.0 → fal-1.26.0}/fal.egg-info/entry_points.txt +0 -0
  16. {fal-1.25.0 → fal-1.26.0}/fal.egg-info/requires.txt +0 -0
  17. {fal-1.25.0 → fal-1.26.0}/fal.egg-info/top_level.txt +0 -0
  18. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/README.md +0 -0
  19. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  20. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  21. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  22. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  23. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  24. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  25. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
  26. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
  27. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
  28. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
  29. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
  30. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
  31. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  32. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  33. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  34. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
  35. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
  36. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  37. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
  38. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
  39. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
  40. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
  41. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
  42. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  43. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  44. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  45. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  46. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  47. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
  48. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
  49. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
  50. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
  51. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
  52. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
  53. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
  54. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
  55. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  56. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  57. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  58. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  59. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
  60. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  61. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
  62. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
  63. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
  64. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  65. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
  66. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
  67. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  68. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  69. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
  70. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  71. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  72. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  73. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
  74. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  75. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  76. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  77. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  78. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  79. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  80. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  81. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  82. {fal-1.25.0 → fal-1.26.0}/openapi-fal-rest/pyproject.toml +0 -0
  83. {fal-1.25.0 → fal-1.26.0}/openapi_rest.config.yaml +0 -0
  84. {fal-1.25.0 → fal-1.26.0}/pyproject.toml +0 -0
  85. {fal-1.25.0 → fal-1.26.0}/setup.cfg +0 -0
  86. {fal-1.25.0 → fal-1.26.0}/src/fal/__init__.py +0 -0
  87. {fal-1.25.0 → fal-1.26.0}/src/fal/__main__.py +0 -0
  88. {fal-1.25.0 → fal-1.26.0}/src/fal/_serialization.py +0 -0
  89. {fal-1.25.0 → fal-1.26.0}/src/fal/_version.py +0 -0
  90. {fal-1.25.0 → fal-1.26.0}/src/fal/app.py +0 -0
  91. {fal-1.25.0 → fal-1.26.0}/src/fal/apps.py +0 -0
  92. {fal-1.25.0 → fal-1.26.0}/src/fal/auth/__init__.py +0 -0
  93. {fal-1.25.0 → fal-1.26.0}/src/fal/auth/auth0.py +0 -0
  94. {fal-1.25.0 → fal-1.26.0}/src/fal/auth/local.py +0 -0
  95. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/__init__.py +0 -0
  96. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/_utils.py +0 -0
  97. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/api.py +0 -0
  98. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/auth.py +0 -0
  99. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/cli_nested_json.py +0 -0
  100. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/create.py +0 -0
  101. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/debug.py +0 -0
  102. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/deploy.py +0 -0
  103. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/doctor.py +0 -0
  104. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/files.py +0 -0
  105. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/keys.py +0 -0
  106. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/main.py +0 -0
  107. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/parser.py +0 -0
  108. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/profile.py +0 -0
  109. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/run.py +0 -0
  110. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/runners.py +0 -0
  111. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/secrets.py +0 -0
  112. {fal-1.25.0 → fal-1.26.0}/src/fal/cli/teams.py +0 -0
  113. {fal-1.25.0 → fal-1.26.0}/src/fal/config.py +0 -0
  114. {fal-1.25.0 → fal-1.26.0}/src/fal/console/__init__.py +0 -0
  115. {fal-1.25.0 → fal-1.26.0}/src/fal/console/icons.py +0 -0
  116. {fal-1.25.0 → fal-1.26.0}/src/fal/console/ux.py +0 -0
  117. {fal-1.25.0 → fal-1.26.0}/src/fal/container.py +0 -0
  118. {fal-1.25.0 → fal-1.26.0}/src/fal/exceptions/__init__.py +0 -0
  119. {fal-1.25.0 → fal-1.26.0}/src/fal/exceptions/_base.py +0 -0
  120. {fal-1.25.0 → fal-1.26.0}/src/fal/exceptions/_cuda.py +0 -0
  121. {fal-1.25.0 → fal-1.26.0}/src/fal/exceptions/auth.py +0 -0
  122. {fal-1.25.0 → fal-1.26.0}/src/fal/files.py +0 -0
  123. {fal-1.25.0 → fal-1.26.0}/src/fal/flags.py +0 -0
  124. {fal-1.25.0 → fal-1.26.0}/src/fal/logging/__init__.py +0 -0
  125. {fal-1.25.0 → fal-1.26.0}/src/fal/logging/isolate.py +0 -0
  126. {fal-1.25.0 → fal-1.26.0}/src/fal/logging/style.py +0 -0
  127. {fal-1.25.0 → fal-1.26.0}/src/fal/logging/trace.py +0 -0
  128. {fal-1.25.0 → fal-1.26.0}/src/fal/logging/user.py +0 -0
  129. {fal-1.25.0 → fal-1.26.0}/src/fal/project.py +0 -0
  130. {fal-1.25.0 → fal-1.26.0}/src/fal/py.typed +0 -0
  131. {fal-1.25.0 → fal-1.26.0}/src/fal/rest_client.py +0 -0
  132. {fal-1.25.0 → fal-1.26.0}/src/fal/sync.py +0 -0
  133. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/__init__.py +0 -0
  134. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/audio/__init__.py +0 -0
  135. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/audio/audio.py +0 -0
  136. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/exceptions.py +0 -0
  137. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/file/__init__.py +0 -0
  138. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/file/file.py +0 -0
  139. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/file/providers/fal.py +0 -0
  140. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
  141. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/file/providers/r2.py +0 -0
  142. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/file/providers/s3.py +0 -0
  143. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/file/types.py +0 -0
  144. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/__init__.py +0 -0
  145. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/image.py +0 -0
  146. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
  147. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
  148. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
  149. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
  150. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
  151. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/image/safety_checker.py +0 -0
  152. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/kv.py +0 -0
  153. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/optimize.py +0 -0
  154. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/types.py +0 -0
  155. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/utils/__init__.py +0 -0
  156. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/utils/download_utils.py +0 -0
  157. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/utils/endpoint.py +0 -0
  158. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/utils/retry.py +0 -0
  159. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/video/__init__.py +0 -0
  160. {fal-1.25.0 → fal-1.26.0}/src/fal/toolkit/video/video.py +0 -0
  161. {fal-1.25.0 → fal-1.26.0}/src/fal/utils.py +0 -0
  162. {fal-1.25.0 → fal-1.26.0}/src/fal/workflows.py +0 -0
  163. {fal-1.25.0 → fal-1.26.0}/tests/__init__.py +0 -0
  164. {fal-1.25.0 → fal-1.26.0}/tests/assets/cat.png +0 -0
  165. {fal-1.25.0 → fal-1.26.0}/tests/cli/__init__.py +0 -0
  166. {fal-1.25.0 → fal-1.26.0}/tests/cli/test_apps.py +0 -0
  167. {fal-1.25.0 → fal-1.26.0}/tests/cli/test_auth.py +0 -0
  168. {fal-1.25.0 → fal-1.26.0}/tests/cli/test_deploy.py +0 -0
  169. {fal-1.25.0 → fal-1.26.0}/tests/cli/test_keys.py +0 -0
  170. {fal-1.25.0 → fal-1.26.0}/tests/cli/test_run.py +0 -0
  171. {fal-1.25.0 → fal-1.26.0}/tests/cli/test_secrets.py +0 -0
  172. {fal-1.25.0 → fal-1.26.0}/tests/conftest.py +0 -0
  173. {fal-1.25.0 → fal-1.26.0}/tests/integration_test.py +0 -0
  174. {fal-1.25.0 → fal-1.26.0}/tests/mainify_package/__init__.py +0 -0
  175. {fal-1.25.0 → fal-1.26.0}/tests/mainify_package/impl.py +0 -0
  176. {fal-1.25.0 → fal-1.26.0}/tests/mainify_package/utils.py +0 -0
  177. {fal-1.25.0 → fal-1.26.0}/tests/mainify_target.py +0 -0
  178. {fal-1.25.0 → fal-1.26.0}/tests/test_kv.py +0 -0
  179. {fal-1.25.0 → fal-1.26.0}/tests/test_stability.py +0 -0
  180. {fal-1.25.0 → fal-1.26.0}/tests/toolkit/file/providers/test_fal_retry.py +0 -0
  181. {fal-1.25.0 → fal-1.26.0}/tests/toolkit/file_test.py +0 -0
  182. {fal-1.25.0 → fal-1.26.0}/tests/toolkit/image_test.py +0 -0
  183. {fal-1.25.0 → fal-1.26.0}/tests/toolkit/test_types.py +0 -0
  184. {fal-1.25.0 → fal-1.26.0}/tests/toolkit/utils/retry.py +0 -0
  185. {fal-1.25.0 → fal-1.26.0}/tools/demo_script.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.25.0
3
+ Version: 1.26.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.25.0
3
+ Version: 1.26.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.25.0'
21
- __version_tuple__ = version_tuple = (1, 25, 0)
20
+ __version__ = version = '1.26.0'
21
+ __version_tuple__ = version_tuple = (1, 26, 0)
@@ -319,24 +319,26 @@ def _handle_grpc_error():
319
319
  try:
320
320
  return fn(*args, **kwargs)
321
321
  except grpc.RpcError as e:
322
+ msg = e.details() or str(e)
322
323
  if e.code() == grpc.StatusCode.UNAVAILABLE:
323
324
  raise FalServerlessError(
324
325
  "Could not reach fal host. "
325
326
  "This is most likely a transient problem. "
326
- "Please, try again."
327
+ "If it persists, please reach out to support@fal.ai with the following details: " # noqa: E501
328
+ f"{msg}"
327
329
  )
328
- elif e.details().endswith("died with <Signals.SIGKILL: 9>.`."):
330
+ elif msg.endswith("died with <Signals.SIGKILL: 9>.`."):
329
331
  raise FalServerlessError(
330
332
  "Isolated function crashed. "
331
333
  "This is likely due to resource overflow. "
332
334
  "You can try again by setting a bigger `machine_type`"
333
335
  )
334
336
  elif e.code() == grpc.StatusCode.INVALID_ARGUMENT and (
335
- "The function function could not be deserialized" in e.details()
337
+ "The function function could not be deserialized" in msg
336
338
  ):
337
- raise FalMissingDependencyError(e.details()) from None
339
+ raise FalMissingDependencyError(msg) from None
338
340
  else:
339
- raise FalServerlessError(e.details())
341
+ raise FalServerlessError(msg)
340
342
 
341
343
  return handler
342
344
 
@@ -310,7 +310,11 @@ def _add_runners_parser(subparsers, parents):
310
310
  def _delete(args):
311
311
  client = get_client(args.host, args.team)
312
312
  with client.connect() as connection:
313
- connection.delete_alias(args.app_name)
313
+ res = connection.delete_alias(args.app_name)
314
+ if res is None:
315
+ args.console.print(f"Application {args.app_name!r} not found.")
316
+ else:
317
+ args.console.print(f"Application {args.app_name!r} deleted ({res})")
314
318
 
315
319
 
316
320
  def _add_delete_parser(subparsers, parents):
@@ -746,10 +746,15 @@ class FalServerlessConnection:
746
746
  )
747
747
  self.stub.SetAlias(request)
748
748
 
749
- def delete_alias(self, alias: str) -> str:
749
+ def delete_alias(self, alias: str) -> str | None:
750
750
  request = isolate_proto.DeleteAliasRequest(alias=alias)
751
- res: isolate_proto.DeleteAliasResult = self.stub.DeleteAlias(request)
752
- return res.revision
751
+ try:
752
+ res: isolate_proto.DeleteAliasResult = self.stub.DeleteAlias(request)
753
+ return res.revision
754
+ except grpc.RpcError as e:
755
+ if e.code() == grpc.StatusCode.NOT_FOUND:
756
+ return None
757
+ raise
753
758
 
754
759
  def list_aliases(self) -> list[AliasInfo]:
755
760
  request = isolate_proto.ListAliasesRequest()
@@ -6,7 +6,7 @@ import time
6
6
  import uuid
7
7
  from contextlib import contextmanager, suppress
8
8
  from datetime import datetime, timedelta, timezone
9
- from typing import Generator, List, Tuple
9
+ from typing import Generator, List, Tuple, Union
10
10
 
11
11
  import httpx
12
12
  import pytest
@@ -20,7 +20,7 @@ from pydantic import __version__ as pydantic_version
20
20
  import fal
21
21
  import fal.api as api
22
22
  from fal import apps
23
- from fal.app import AppClient, AppClientError
23
+ from fal.app import AppClient, AppClientError, wrap_app
24
24
  from fal.cli.deploy import User, _get_user
25
25
  from fal.container import ContainerImage
26
26
  from fal.exceptions import (
@@ -332,7 +332,7 @@ class BrokenApp(fal.App, keep_alive=300, max_concurrency=1):
332
332
 
333
333
 
334
334
  @pytest.fixture(scope="module")
335
- def host() -> Generator[api.FalServerlessHost, None, None]:
335
+ def host() -> Generator[api.Host, None, None]:
336
336
  yield addition_app.host
337
337
 
338
338
 
@@ -343,7 +343,11 @@ def user() -> Generator[User, None, None]:
343
343
 
344
344
 
345
345
  @contextmanager
346
- def register_app(host: api.FalServerlessHost, app: fal.App, suffix: str = ""):
346
+ def register_app(
347
+ host: api.FalServerlessHost,
348
+ app: Union[api.ServedIsolatedFunction, api.IsolatedFunction],
349
+ suffix: str = "",
350
+ ):
347
351
  app_alias = str(uuid.uuid4()) + "-test-alias" + ("-" + suffix if suffix else "")
348
352
  app_revision = host.register(
349
353
  func=app.func,
@@ -398,7 +402,7 @@ def test_fastapi_app(host: api.FalServerlessHost, user: User):
398
402
 
399
403
  @pytest.fixture(scope="module")
400
404
  def test_stateful_app(host: api.FalServerlessHost, user: User):
401
- stateful_app = fal.wrap_app(StatefulAdditionApp)
405
+ stateful_app = wrap_app(StatefulAdditionApp)
402
406
  with register_app(host, stateful_app, "stateful") as (app_alias, _):
403
407
  yield f"{user.username}/{app_alias}"
404
408
 
@@ -411,7 +415,7 @@ def test_pydantic_validation_error():
411
415
 
412
416
  @pytest.fixture(scope="module")
413
417
  def test_cancellable_app(host: api.FalServerlessHost, user: User):
414
- cancellable_app = fal.wrap_app(CancellableApp)
418
+ cancellable_app = wrap_app(CancellableApp)
415
419
  with register_app(host, cancellable_app, "cancellable") as (app_alias, _):
416
420
  yield f"{user.username}/{app_alias}"
417
421
 
@@ -424,21 +428,21 @@ def test_exception_app():
424
428
 
425
429
  @pytest.fixture(scope="module")
426
430
  def test_sleep_app(host: api.FalServerlessHost, user: User):
427
- sleep_app = fal.wrap_app(SleepApp)
431
+ sleep_app = wrap_app(SleepApp)
428
432
  with register_app(host, sleep_app, "sleep") as (app_alias, _):
429
433
  yield f"{user.username}/{app_alias}"
430
434
 
431
435
 
432
436
  @pytest.fixture(scope="module")
433
437
  def test_realtime_app(host: api.FalServerlessHost, user: User):
434
- realtime_app = fal.wrap_app(RealtimeApp)
438
+ realtime_app = wrap_app(RealtimeApp)
435
439
  with register_app(host, realtime_app, "realtime") as (app_alias, _):
436
440
  yield f"{user.username}/{app_alias}"
437
441
 
438
442
 
439
443
  def test_broken_app_failure(host: api.FalServerlessHost, user: User):
440
444
  with pytest.raises(FalServerlessException) as e:
441
- fal.wrap_app(BrokenApp)
445
+ wrap_app(BrokenApp)
442
446
 
443
447
  assert "Failed to generate OpenAPI" in str(e)
444
448
 
@@ -577,13 +581,6 @@ def test_app_disconnect_behavior(test_app: str, test_cancellable_app: str):
577
581
  e.value.response.status_code == 504
578
582
  ), "Expected Gateway Timeout even though the app handled it"
579
583
 
580
- with pytest.raises(HTTPStatusError) as e:
581
- apps.run(
582
- test_cancellable_app,
583
- arguments={"lhs": 1, "rhs": 2, "wait_time": 1},
584
- )
585
- assert e.value.response.status_code == 500
586
-
587
584
 
588
585
  @pytest.mark.xfail(
589
586
  reason="Temporary disabled while investigating backend issue. Ping @efiop"
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
File without changes
File without changes
File without changes
File without changes