fal 1.27.0__tar.gz → 1.28.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.
- {fal-1.27.0/fal.egg-info → fal-1.28.0}/PKG-INFO +1 -1
- {fal-1.27.0 → fal-1.28.0/fal.egg-info}/PKG-INFO +1 -1
- {fal-1.27.0 → fal-1.28.0}/src/fal/_fal_version.py +2 -2
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/_utils.py +10 -3
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/deploy.py +16 -11
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/profile.py +9 -4
- {fal-1.27.0 → fal-1.28.0}/src/fal/config.py +3 -1
- {fal-1.27.0 → fal-1.28.0}/src/fal/exceptions/auth.py +1 -1
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/utils/download_utils.py +26 -2
- {fal-1.27.0 → fal-1.28.0}/tests/cli/test_deploy.py +12 -13
- {fal-1.27.0 → fal-1.28.0}/.gitignore +0 -0
- {fal-1.27.0 → fal-1.28.0}/Makefile +0 -0
- {fal-1.27.0 → fal-1.28.0}/README.md +0 -0
- {fal-1.27.0 → fal-1.28.0}/docs/conf.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/docs/index.rst +0 -0
- {fal-1.27.0 → fal-1.28.0}/fal.egg-info/SOURCES.txt +0 -0
- {fal-1.27.0 → fal-1.28.0}/fal.egg-info/dependency_links.txt +0 -0
- {fal-1.27.0 → fal-1.28.0}/fal.egg-info/entry_points.txt +0 -0
- {fal-1.27.0 → fal-1.28.0}/fal.egg-info/requires.txt +0 -0
- {fal-1.27.0 → fal-1.28.0}/fal.egg-info/top_level.txt +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/README.md +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/pyproject.toml +0 -0
- {fal-1.27.0 → fal-1.28.0}/openapi_rest.config.yaml +0 -0
- {fal-1.27.0 → fal-1.28.0}/pyproject.toml +0 -0
- {fal-1.27.0 → fal-1.28.0}/setup.cfg +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/__main__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/_serialization.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/_version.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/api.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/app.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/apps.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/auth/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/auth/auth0.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/auth/local.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/api.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/apps.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/auth.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/cli_nested_json.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/create.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/debug.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/doctor.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/files.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/keys.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/main.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/parser.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/run.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/runners.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/secrets.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/cli/teams.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/console/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/console/icons.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/console/ux.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/container.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/exceptions/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/exceptions/_base.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/exceptions/_cuda.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/files.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/flags.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/logging/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/logging/isolate.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/logging/style.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/logging/trace.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/logging/user.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/project.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/py.typed +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/rest_client.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/sdk.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/sync.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/audio/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/audio/audio.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/exceptions.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/file/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/file/file.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/file/providers/fal.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/file/providers/r2.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/file/providers/s3.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/file/types.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/image.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/image/safety_checker.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/kv.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/optimize.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/types.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/utils/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/utils/endpoint.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/utils/retry.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/video/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/toolkit/video/video.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/utils.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/src/fal/workflows.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/assets/cat.png +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/cli/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/cli/test_apps.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/cli/test_auth.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/cli/test_keys.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/cli/test_run.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/cli/test_secrets.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/conftest.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/integration_test.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/mainify_package/__init__.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/mainify_package/impl.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/mainify_package/utils.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/mainify_target.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/test_apps.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/test_files.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/test_kv.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/test_stability.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/toolkit/file/providers/test_fal_retry.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/toolkit/file_test.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/toolkit/image_test.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/toolkit/test_types.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tests/toolkit/utils/retry.py +0 -0
- {fal-1.27.0 → fal-1.28.0}/tools/demo_script.py +0 -0
|
@@ -12,7 +12,7 @@ def get_client(host: str, team: str | None = None):
|
|
|
12
12
|
|
|
13
13
|
def is_app_name(app_ref: tuple[str, str | None]) -> bool:
|
|
14
14
|
is_single_file = app_ref[1] is None
|
|
15
|
-
is_python_file = app_ref[0].endswith(".py")
|
|
15
|
+
is_python_file = app_ref[0] is None or app_ref[0].endswith(".py")
|
|
16
16
|
|
|
17
17
|
return is_single_file and not is_python_file
|
|
18
18
|
|
|
@@ -42,9 +42,16 @@ def get_app_data_from_toml(app_name):
|
|
|
42
42
|
|
|
43
43
|
app_auth = app_data.pop("auth", "private")
|
|
44
44
|
app_deployment_strategy = app_data.pop("deployment_strategy", "recreate")
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
if "no_scale" in app_data:
|
|
47
|
+
# Deprecated
|
|
48
|
+
app_no_scale = app_data.pop("no_scale")
|
|
49
|
+
print("[WARNING] no_scale is deprecated, use app_scale_settings instead")
|
|
50
|
+
app_reset_scale = not app_no_scale
|
|
51
|
+
else:
|
|
52
|
+
app_reset_scale = app_data.pop("app_scale_settings", False)
|
|
46
53
|
|
|
47
54
|
if len(app_data) > 0:
|
|
48
55
|
raise ValueError(f"Found unexpected keys in pyproject.toml: {app_data}")
|
|
49
56
|
|
|
50
|
-
return app_ref, app_auth, app_deployment_strategy,
|
|
57
|
+
return app_ref, app_auth, app_deployment_strategy, app_reset_scale
|
|
@@ -66,9 +66,9 @@ def _deploy_from_reference(
|
|
|
66
66
|
app_ref: Tuple[Optional[Union[Path, str]], ...],
|
|
67
67
|
app_name: str,
|
|
68
68
|
args,
|
|
69
|
-
auth: Optional[Literal["public", "shared", "private"]]
|
|
70
|
-
deployment_strategy: Optional[Literal["recreate", "rolling"]]
|
|
71
|
-
scale: bool
|
|
69
|
+
auth: Optional[Literal["public", "shared", "private"]],
|
|
70
|
+
deployment_strategy: Optional[Literal["recreate", "rolling"]],
|
|
71
|
+
scale: bool,
|
|
72
72
|
):
|
|
73
73
|
from fal.api import FalServerlessError, FalServerlessHost
|
|
74
74
|
from fal.utils import load_function_from
|
|
@@ -146,7 +146,7 @@ def _deploy(args):
|
|
|
146
146
|
raise ValueError("Cannot use --app-name or --auth with app name reference.")
|
|
147
147
|
|
|
148
148
|
app_name = args.app_ref[0]
|
|
149
|
-
app_ref, app_auth, app_deployment_strategy,
|
|
149
|
+
app_ref, app_auth, app_deployment_strategy, app_scale_settings = (
|
|
150
150
|
get_app_data_from_toml(app_name)
|
|
151
151
|
)
|
|
152
152
|
file_path, func_name = RefAction.split_ref(app_ref)
|
|
@@ -157,7 +157,7 @@ def _deploy(args):
|
|
|
157
157
|
app_name = args.app_name
|
|
158
158
|
app_auth = args.auth
|
|
159
159
|
app_deployment_strategy = args.strategy
|
|
160
|
-
|
|
160
|
+
app_scale_settings = args.app_scale_settings
|
|
161
161
|
|
|
162
162
|
_deploy_from_reference(
|
|
163
163
|
(file_path, func_name),
|
|
@@ -165,7 +165,7 @@ def _deploy(args):
|
|
|
165
165
|
args,
|
|
166
166
|
app_auth,
|
|
167
167
|
app_deployment_strategy,
|
|
168
|
-
scale=
|
|
168
|
+
scale=app_scale_settings,
|
|
169
169
|
)
|
|
170
170
|
|
|
171
171
|
|
|
@@ -233,12 +233,17 @@ def add_parser(main_subparsers, parents):
|
|
|
233
233
|
)
|
|
234
234
|
parser.add_argument(
|
|
235
235
|
"--no-scale",
|
|
236
|
+
action="store_false",
|
|
237
|
+
dest="app_scale_settings",
|
|
238
|
+
default=False,
|
|
239
|
+
help="Use the previous deployment of the application for scale settings. "
|
|
240
|
+
"This is the default behavior.",
|
|
241
|
+
)
|
|
242
|
+
parser.add_argument(
|
|
243
|
+
"--reset-scale",
|
|
236
244
|
action="store_true",
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
"from previous deployment of application with this name, if exists. "
|
|
240
|
-
"Otherwise will use the values from the application code."
|
|
241
|
-
),
|
|
245
|
+
dest="app_scale_settings",
|
|
246
|
+
help="Use the application code for scale settings.",
|
|
242
247
|
)
|
|
243
248
|
|
|
244
249
|
parser.set_defaults(func=_deploy)
|
|
@@ -68,12 +68,17 @@ def _unset(args, config: Config | None = None):
|
|
|
68
68
|
def _key_set(args):
|
|
69
69
|
config = Config(validate_profile=True)
|
|
70
70
|
|
|
71
|
+
args.console.print("Go to https://fal.ai/dashboard/keys to create a key.")
|
|
72
|
+
args.console.print(
|
|
73
|
+
"Enter the key in the format [cyan][bold]id:secret[/][/]. You can copy and paste it from the browser." # noqa: E501
|
|
74
|
+
)
|
|
75
|
+
|
|
71
76
|
while True:
|
|
72
77
|
key = input("Enter the key: ")
|
|
73
78
|
if ":" in key:
|
|
74
79
|
break
|
|
75
80
|
args.console.print(
|
|
76
|
-
"[
|
|
81
|
+
"[yellow]Invalid key. The key must be in the format:[/] [cyan][bold]id:secret[/][/]." # noqa: E501
|
|
77
82
|
)
|
|
78
83
|
|
|
79
84
|
with config.edit():
|
|
@@ -99,10 +104,10 @@ def _create(args):
|
|
|
99
104
|
with config.edit() as config:
|
|
100
105
|
config._config[args.PROFILE] = {}
|
|
101
106
|
|
|
102
|
-
args.console.print(f"Profile [cyan]{args.PROFILE}[/] created.")
|
|
103
107
|
args.console.print(
|
|
104
|
-
f"
|
|
108
|
+
f"Profile [cyan]{args.PROFILE}[/] created. Setting it as default profile..."
|
|
105
109
|
)
|
|
110
|
+
_set(args)
|
|
106
111
|
|
|
107
112
|
|
|
108
113
|
def _delete(args):
|
|
@@ -184,7 +189,7 @@ def add_parser(main_subparsers, parents):
|
|
|
184
189
|
)
|
|
185
190
|
host_set_parser.set_defaults(func=_host_set)
|
|
186
191
|
|
|
187
|
-
create_help = "Create a new profile.
|
|
192
|
+
create_help = "Create a new profile."
|
|
188
193
|
create_parser = subparsers.add_parser(
|
|
189
194
|
"create",
|
|
190
195
|
description=create_help,
|
|
@@ -6,7 +6,9 @@ from typing import Dict, Iterator, List, Optional
|
|
|
6
6
|
|
|
7
7
|
SETTINGS_SECTION = "__internal__"
|
|
8
8
|
|
|
9
|
-
NO_PROFILE_ERROR = ValueError(
|
|
9
|
+
NO_PROFILE_ERROR = ValueError(
|
|
10
|
+
"No profile set. Use command [bold]fal profile set[/] to set a profile."
|
|
11
|
+
)
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class Config:
|
|
@@ -7,5 +7,5 @@ class UnauthenticatedException(FalServerlessException):
|
|
|
7
7
|
def __init__(self) -> None:
|
|
8
8
|
super().__init__(
|
|
9
9
|
"You must be authenticated. "
|
|
10
|
-
"
|
|
10
|
+
"Use [bold]fal auth login[/] or [bold]fal profile key[/] to set your fal key." # noqa: E501
|
|
11
11
|
)
|
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
import shutil
|
|
7
7
|
import subprocess
|
|
8
8
|
import sys
|
|
9
|
+
import time
|
|
9
10
|
from contextlib import suppress
|
|
10
11
|
from pathlib import Path, PurePath
|
|
11
12
|
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
|
@@ -345,6 +346,14 @@ def _stream_url_data_to_file(
|
|
|
345
346
|
raise DownloadError("Received less data than expected from the server.")
|
|
346
347
|
|
|
347
348
|
|
|
349
|
+
def _mark_used_dir(dir: Path):
|
|
350
|
+
used_file = dir / ".fal_used"
|
|
351
|
+
day_ago = time.time() - 86400
|
|
352
|
+
if not used_file.exists() or used_file.stat().st_mtime < day_ago:
|
|
353
|
+
# Touch a last-used file to indicate that the weights have been used
|
|
354
|
+
used_file.touch()
|
|
355
|
+
|
|
356
|
+
|
|
348
357
|
def download_model_weights(
|
|
349
358
|
url: str, force: bool = False, request_headers: dict[str, str] | None = None
|
|
350
359
|
) -> Path:
|
|
@@ -375,19 +384,34 @@ def download_model_weights(
|
|
|
375
384
|
|
|
376
385
|
if weights_dir.exists() and not force:
|
|
377
386
|
try:
|
|
378
|
-
|
|
387
|
+
# TODO: sometimes the directory can hold multiple files
|
|
388
|
+
# Example:
|
|
389
|
+
# .fal/model_weights/00155dc2d9579360d577d1a87d31b52c21135c14a5f44fcbab36fbb8352f3e0d # noqa: E501
|
|
390
|
+
# We need to either not allow multiple files in the directory or
|
|
391
|
+
# find the one that is the most recently used.
|
|
392
|
+
weights_path = next(
|
|
393
|
+
# Ignore .fal dotfiles since they are metadata files
|
|
394
|
+
f
|
|
395
|
+
for f in weights_dir.glob("*")
|
|
396
|
+
if not f.name.startswith(".fal")
|
|
397
|
+
)
|
|
398
|
+
_mark_used_dir(weights_dir)
|
|
379
399
|
return weights_path
|
|
380
400
|
# The model weights directory is empty, so we need to download the weights
|
|
381
401
|
except StopIteration:
|
|
382
402
|
pass
|
|
383
403
|
|
|
384
|
-
|
|
404
|
+
path = download_file(
|
|
385
405
|
url,
|
|
386
406
|
target_dir=weights_dir,
|
|
387
407
|
force=force,
|
|
388
408
|
request_headers=request_headers,
|
|
389
409
|
)
|
|
390
410
|
|
|
411
|
+
_mark_used_dir(weights_dir)
|
|
412
|
+
|
|
413
|
+
return path
|
|
414
|
+
|
|
391
415
|
|
|
392
416
|
def clone_repository(
|
|
393
417
|
https_url: str,
|
|
@@ -39,7 +39,7 @@ def mock_args(
|
|
|
39
39
|
app_name: Optional[str] = None,
|
|
40
40
|
auth: Optional[str] = None,
|
|
41
41
|
strategy: Optional[str] = None,
|
|
42
|
-
|
|
42
|
+
reset_scale: bool = False,
|
|
43
43
|
):
|
|
44
44
|
args = MagicMock()
|
|
45
45
|
|
|
@@ -47,8 +47,7 @@ def mock_args(
|
|
|
47
47
|
args.app_name = app_name
|
|
48
48
|
args.auth = auth
|
|
49
49
|
args.strategy = strategy
|
|
50
|
-
|
|
51
|
-
args.no_scale = no_scale
|
|
50
|
+
args.app_scale_settings = reset_scale
|
|
52
51
|
|
|
53
52
|
return args
|
|
54
53
|
|
|
@@ -75,7 +74,7 @@ def test_deploy_with_toml_success(
|
|
|
75
74
|
args,
|
|
76
75
|
"shared",
|
|
77
76
|
"rolling",
|
|
78
|
-
scale=
|
|
77
|
+
scale=False,
|
|
79
78
|
)
|
|
80
79
|
|
|
81
80
|
|
|
@@ -101,7 +100,7 @@ def test_deploy_with_toml_no_auth(
|
|
|
101
100
|
args,
|
|
102
101
|
"private",
|
|
103
102
|
"recreate",
|
|
104
|
-
scale=
|
|
103
|
+
scale=False,
|
|
105
104
|
)
|
|
106
105
|
|
|
107
106
|
|
|
@@ -212,7 +211,7 @@ def test_deploy_with_toml_deployment_strategy(
|
|
|
212
211
|
args,
|
|
213
212
|
"shared",
|
|
214
213
|
"rolling",
|
|
215
|
-
scale=
|
|
214
|
+
scale=False,
|
|
216
215
|
)
|
|
217
216
|
|
|
218
217
|
|
|
@@ -236,7 +235,7 @@ def test_deploy_with_toml_default_deployment_strategy(
|
|
|
236
235
|
args,
|
|
237
236
|
"private",
|
|
238
237
|
"recreate",
|
|
239
|
-
scale=
|
|
238
|
+
scale=False,
|
|
240
239
|
)
|
|
241
240
|
|
|
242
241
|
|
|
@@ -258,7 +257,7 @@ def test_deploy_with_cli_auth(
|
|
|
258
257
|
args,
|
|
259
258
|
"shared",
|
|
260
259
|
None,
|
|
261
|
-
scale=
|
|
260
|
+
scale=False,
|
|
262
261
|
)
|
|
263
262
|
|
|
264
263
|
|
|
@@ -280,19 +279,19 @@ def test_deploy_with_cli_deployment_strategy(
|
|
|
280
279
|
args,
|
|
281
280
|
None,
|
|
282
281
|
"rolling",
|
|
283
|
-
scale=
|
|
282
|
+
scale=False,
|
|
284
283
|
)
|
|
285
284
|
|
|
286
285
|
|
|
287
286
|
@patch("fal.cli._utils.find_pyproject_toml", return_value="pyproject.toml")
|
|
288
287
|
@patch("fal.cli._utils.parse_pyproject_toml")
|
|
289
288
|
@patch("fal.cli.deploy._deploy_from_reference")
|
|
290
|
-
def
|
|
289
|
+
def test_deploy_with_cli_reset_scale(
|
|
291
290
|
mock_deploy_ref, mock_parse_toml, mock_find_toml, mock_parse_pyproject_toml
|
|
292
291
|
):
|
|
293
292
|
mock_parse_toml.return_value = mock_parse_pyproject_toml
|
|
294
293
|
|
|
295
|
-
args = mock_args(app_ref=("src/my_app/inference.py", "MyApp"),
|
|
294
|
+
args = mock_args(app_ref=("src/my_app/inference.py", "MyApp"), reset_scale=True)
|
|
296
295
|
|
|
297
296
|
_deploy(args)
|
|
298
297
|
|
|
@@ -302,7 +301,7 @@ def test_deploy_with_cli_no_scale(
|
|
|
302
301
|
args,
|
|
303
302
|
None,
|
|
304
303
|
None,
|
|
305
|
-
scale=
|
|
304
|
+
scale=True,
|
|
306
305
|
)
|
|
307
306
|
|
|
308
307
|
|
|
@@ -324,5 +323,5 @@ def test_deploy_with_cli_scale(
|
|
|
324
323
|
args,
|
|
325
324
|
None,
|
|
326
325
|
None,
|
|
327
|
-
scale=
|
|
326
|
+
scale=False,
|
|
328
327
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py
RENAMED
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py
RENAMED
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py
RENAMED
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py
RENAMED
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py
RENAMED
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py
RENAMED
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-1.27.0 → fal-1.28.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|