fal 1.4.0__tar.gz → 1.5.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.4.0 → fal-1.5.0}/PKG-INFO +2 -2
- {fal-1.4.0 → fal-1.5.0}/fal.egg-info/PKG-INFO +2 -2
- {fal-1.4.0 → fal-1.5.0}/fal.egg-info/requires.txt +1 -1
- {fal-1.4.0 → fal-1.5.0}/pyproject.toml +1 -1
- {fal-1.4.0 → fal-1.5.0}/src/fal/_fal_version.py +2 -2
- {fal-1.4.0 → fal-1.5.0}/src/fal/api.py +11 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/app.py +7 -1
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/_utils.py +7 -2
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/deploy.py +13 -5
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/run.py +1 -1
- {fal-1.4.0 → fal-1.5.0}/src/fal/sdk.py +3 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/file/providers/fal.py +14 -11
- {fal-1.4.0 → fal-1.5.0}/tests/cli/test_deploy.py +109 -4
- {fal-1.4.0 → fal-1.5.0}/tests/cli/test_run.py +5 -2
- {fal-1.4.0 → fal-1.5.0}/.gitignore +0 -0
- {fal-1.4.0 → fal-1.5.0}/README.md +0 -0
- {fal-1.4.0 → fal-1.5.0}/fal.egg-info/SOURCES.txt +0 -0
- {fal-1.4.0 → fal-1.5.0}/fal.egg-info/dependency_links.txt +0 -0
- {fal-1.4.0 → fal-1.5.0}/fal.egg-info/entry_points.txt +0 -0
- {fal-1.4.0 → fal-1.5.0}/fal.egg-info/top_level.txt +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/README.md +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/create_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/delete_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/get_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/list_user_workflows.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/comfy/update_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/users/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/users/get_current_user.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/list_user_workflows.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/update_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_detail.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_item.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_prompt.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/current_user.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/page_comfy_workflow_item.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/team_role.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/typed_comfy_workflow_update.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow_update.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/user_member.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/pyproject.toml +0 -0
- {fal-1.4.0 → fal-1.5.0}/openapi_rest.config.yaml +0 -0
- {fal-1.4.0 → fal-1.5.0}/setup.cfg +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/__main__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/_serialization.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/_version.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/apps.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/auth/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/auth/auth0.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/auth/local.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/apps.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/auth.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/create.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/debug.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/doctor.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/keys.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/main.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/parser.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/cli/secrets.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/console/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/console/icons.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/console/ux.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/container.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/exceptions/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/exceptions/_base.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/exceptions/_cuda.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/exceptions/auth.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/files.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/flags.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/logging/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/logging/isolate.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/logging/style.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/logging/trace.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/logging/user.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/py.typed +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/rest_client.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/sync.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/exceptions.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/file/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/file/file.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/file/providers/r2.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/file/types.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/image.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/nsfw_filter/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/nsfw_filter/env.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/nsfw_filter/inference.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/nsfw_filter/model.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/nsfw_filter/requirements.txt +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/image/safety_checker.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/optimize.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/utils/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/utils/download_utils.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/toolkit/utils/retry.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/utils.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/src/fal/workflows.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/cli/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/cli/test_apps.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/cli/test_auth.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/cli/test_keys.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/cli/test_secrets.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/conftest.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/integration_test.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/mainify_package/__init__.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/mainify_package/impl.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/mainify_package/utils.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/mainify_target.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/test_apps.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/test_stability.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/toolkit/file_test.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/toolkit/image_test.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tests/toolkit/utils/retry.py +0 -0
- {fal-1.4.0 → fal-1.5.0}/tools/demo_script.py +0 -0
{fal-1.4.0 → fal-1.5.0}/PKG-INFO
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fal
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.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]<1.14.0,>=0.13.0
|
|
9
|
-
Requires-Dist: isolate-proto==0.5.
|
|
9
|
+
Requires-Dist: isolate-proto==0.5.4
|
|
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.1
|
|
2
2
|
Name: fal
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.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]<1.14.0,>=0.13.0
|
|
9
|
-
Requires-Dist: isolate-proto==0.5.
|
|
9
|
+
Requires-Dist: isolate-proto==0.5.4
|
|
10
10
|
Requires-Dist: grpcio==1.64.0
|
|
11
11
|
Requires-Dist: dill==0.3.7
|
|
12
12
|
Requires-Dist: cloudpickle==3.0.0
|
|
@@ -397,6 +397,7 @@ class FalServerlessHost(Host):
|
|
|
397
397
|
"max_multiplexing",
|
|
398
398
|
"setup_function",
|
|
399
399
|
"metadata",
|
|
400
|
+
"request_timeout",
|
|
400
401
|
"_base_image",
|
|
401
402
|
"_scheduler",
|
|
402
403
|
"_scheduler_options",
|
|
@@ -444,6 +445,7 @@ class FalServerlessHost(Host):
|
|
|
444
445
|
scheduler = options.host.get("_scheduler", None)
|
|
445
446
|
scheduler_options = options.host.get("_scheduler_options", None)
|
|
446
447
|
exposed_port = options.get_exposed_port()
|
|
448
|
+
request_timeout = options.host.get("request_timeout")
|
|
447
449
|
|
|
448
450
|
machine_requirements = MachineRequirements(
|
|
449
451
|
machine_types=machine_type, # type: ignore
|
|
@@ -456,6 +458,7 @@ class FalServerlessHost(Host):
|
|
|
456
458
|
max_multiplexing=max_multiplexing,
|
|
457
459
|
max_concurrency=max_concurrency,
|
|
458
460
|
min_concurrency=min_concurrency,
|
|
461
|
+
request_timeout=request_timeout,
|
|
459
462
|
)
|
|
460
463
|
|
|
461
464
|
partial_func = _prepare_partial_func(func)
|
|
@@ -516,6 +519,7 @@ class FalServerlessHost(Host):
|
|
|
516
519
|
scheduler_options = options.host.get("_scheduler_options", None)
|
|
517
520
|
exposed_port = options.get_exposed_port()
|
|
518
521
|
setup_function = options.host.get("setup_function", None)
|
|
522
|
+
request_timeout = options.host.get("request_timeout")
|
|
519
523
|
|
|
520
524
|
machine_requirements = MachineRequirements(
|
|
521
525
|
machine_types=machine_type, # type: ignore
|
|
@@ -528,6 +532,7 @@ class FalServerlessHost(Host):
|
|
|
528
532
|
max_multiplexing=max_multiplexing,
|
|
529
533
|
max_concurrency=max_concurrency,
|
|
530
534
|
min_concurrency=min_concurrency,
|
|
535
|
+
request_timeout=request_timeout,
|
|
531
536
|
)
|
|
532
537
|
|
|
533
538
|
return_value = _UNSET
|
|
@@ -693,6 +698,7 @@ def function(
|
|
|
693
698
|
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
694
699
|
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
695
700
|
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
701
|
+
request_timeout: int | None = None,
|
|
696
702
|
setup_function: Callable[..., None] | None = None,
|
|
697
703
|
_base_image: str | None = None,
|
|
698
704
|
_scheduler: str | None = None,
|
|
@@ -719,6 +725,7 @@ def function(
|
|
|
719
725
|
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
720
726
|
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
721
727
|
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
728
|
+
request_timeout: int | None = None,
|
|
722
729
|
setup_function: Callable[..., None] | None = None,
|
|
723
730
|
_base_image: str | None = None,
|
|
724
731
|
_scheduler: str | None = None,
|
|
@@ -795,6 +802,7 @@ def function(
|
|
|
795
802
|
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
796
803
|
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
797
804
|
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
805
|
+
request_timeout: int | None = None,
|
|
798
806
|
setup_function: Callable[..., None] | None = None,
|
|
799
807
|
_base_image: str | None = None,
|
|
800
808
|
_scheduler: str | None = None,
|
|
@@ -826,6 +834,7 @@ def function(
|
|
|
826
834
|
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
827
835
|
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
828
836
|
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
837
|
+
request_timeout: int | None = None,
|
|
829
838
|
setup_function: Callable[..., None] | None = None,
|
|
830
839
|
_base_image: str | None = None,
|
|
831
840
|
_scheduler: str | None = None,
|
|
@@ -851,6 +860,7 @@ def function(
|
|
|
851
860
|
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
852
861
|
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
853
862
|
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
863
|
+
request_timeout: int | None = None,
|
|
854
864
|
setup_function: Callable[..., None] | None = None,
|
|
855
865
|
_base_image: str | None = None,
|
|
856
866
|
_scheduler: str | None = None,
|
|
@@ -876,6 +886,7 @@ def function(
|
|
|
876
886
|
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
877
887
|
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
878
888
|
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
889
|
+
request_timeout: int | None = None,
|
|
879
890
|
setup_function: Callable[..., None] | None = None,
|
|
880
891
|
_base_image: str | None = None,
|
|
881
892
|
_scheduler: str | None = None,
|
|
@@ -189,11 +189,17 @@ class App(fal.api.BaseServable):
|
|
|
189
189
|
}
|
|
190
190
|
app_name: ClassVar[str]
|
|
191
191
|
app_auth: ClassVar[Literal["private", "public", "shared"]] = "private"
|
|
192
|
+
version: ClassVar[str] = "unknown"
|
|
193
|
+
request_timeout: ClassVar[int | None] = None
|
|
192
194
|
|
|
193
195
|
def __init_subclass__(cls, **kwargs):
|
|
194
196
|
app_name = kwargs.pop("name", None) or _to_fal_app_name(cls.__name__)
|
|
195
197
|
parent_settings = getattr(cls, "host_kwargs", {})
|
|
196
198
|
cls.host_kwargs = {**parent_settings, **kwargs}
|
|
199
|
+
|
|
200
|
+
if cls.request_timeout is not None:
|
|
201
|
+
cls.host_kwargs["request_timeout"] = cls.request_timeout
|
|
202
|
+
|
|
197
203
|
cls.app_name = getattr(cls, "app_name", app_name)
|
|
198
204
|
|
|
199
205
|
if cls.__init__ is not App.__init__:
|
|
@@ -232,7 +238,7 @@ class App(fal.api.BaseServable):
|
|
|
232
238
|
await _call_any_fn(self.teardown)
|
|
233
239
|
|
|
234
240
|
def health(self):
|
|
235
|
-
return {}
|
|
241
|
+
return {"version": self.version}
|
|
236
242
|
|
|
237
243
|
def setup(self):
|
|
238
244
|
"""Setup the application before serving."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from fal.files import find_pyproject_toml, parse_pyproject_toml
|
|
3
|
+
from fal.files import find_project_root, find_pyproject_toml, parse_pyproject_toml
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def is_app_name(app_ref: tuple[str, str | None]) -> bool:
|
|
@@ -29,6 +29,11 @@ def get_app_data_from_toml(app_name):
|
|
|
29
29
|
except KeyError:
|
|
30
30
|
raise ValueError(f"App {app_name} does not have a ref key in pyproject.toml")
|
|
31
31
|
|
|
32
|
+
# Convert the app_ref to a path relative to the project root
|
|
33
|
+
project_root, _ = find_project_root(None)
|
|
34
|
+
app_ref = str(project_root / app_ref)
|
|
35
|
+
|
|
32
36
|
app_auth = app_data.get("auth", "private")
|
|
37
|
+
app_deployment_strategy = app_data.get("deployment_strategy", "recreate")
|
|
33
38
|
|
|
34
|
-
return app_ref, app_auth
|
|
39
|
+
return app_ref, app_auth, app_deployment_strategy
|
|
@@ -65,8 +65,9 @@ def _get_user() -> User:
|
|
|
65
65
|
def _deploy_from_reference(
|
|
66
66
|
app_ref: Tuple[Optional[Union[Path, str]], ...],
|
|
67
67
|
app_name: str,
|
|
68
|
-
auth: Literal["public", "shared", "private"],
|
|
69
68
|
args,
|
|
69
|
+
auth: Optional[Literal["public", "shared", "private"]] = None,
|
|
70
|
+
deployment_strategy: Optional[Literal["recreate", "rolling"]] = None,
|
|
70
71
|
):
|
|
71
72
|
from fal.api import FalServerlessError, FalServerlessHost
|
|
72
73
|
from fal.utils import load_function_from
|
|
@@ -96,7 +97,7 @@ def _deploy_from_reference(
|
|
|
96
97
|
isolated_function = loaded.function
|
|
97
98
|
app_name = app_name or loaded.app_name # type: ignore
|
|
98
99
|
app_auth = auth or loaded.app_auth or "private"
|
|
99
|
-
deployment_strategy =
|
|
100
|
+
deployment_strategy = deployment_strategy or "recreate"
|
|
100
101
|
|
|
101
102
|
app_id = host.register(
|
|
102
103
|
func=isolated_function.func,
|
|
@@ -137,7 +138,7 @@ def _deploy(args):
|
|
|
137
138
|
raise ValueError("Cannot use --app-name or --auth with app name reference.")
|
|
138
139
|
|
|
139
140
|
app_name = args.app_ref[0]
|
|
140
|
-
app_ref, app_auth = get_app_data_from_toml(app_name)
|
|
141
|
+
app_ref, app_auth, app_deployment_strategy = get_app_data_from_toml(app_name)
|
|
141
142
|
file_path, func_name = RefAction.split_ref(app_ref)
|
|
142
143
|
|
|
143
144
|
# path/to/myfile.py::MyApp
|
|
@@ -145,8 +146,15 @@ def _deploy(args):
|
|
|
145
146
|
file_path, func_name = args.app_ref
|
|
146
147
|
app_name = args.app_name
|
|
147
148
|
app_auth = args.auth
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
app_deployment_strategy = args.strategy
|
|
150
|
+
|
|
151
|
+
_deploy_from_reference(
|
|
152
|
+
(file_path, func_name),
|
|
153
|
+
app_name,
|
|
154
|
+
args,
|
|
155
|
+
app_auth,
|
|
156
|
+
app_deployment_strategy,
|
|
157
|
+
)
|
|
150
158
|
|
|
151
159
|
|
|
152
160
|
def add_parser(main_subparsers, parents):
|
|
@@ -10,7 +10,7 @@ def _run(args):
|
|
|
10
10
|
|
|
11
11
|
if is_app_name(args.func_ref):
|
|
12
12
|
app_name = args.func_ref[0]
|
|
13
|
-
app_ref, _ = get_app_data_from_toml(app_name)
|
|
13
|
+
app_ref, _, _ = get_app_data_from_toml(app_name)
|
|
14
14
|
file_path, func_name = RefAction.split_ref(app_ref)
|
|
15
15
|
else:
|
|
16
16
|
file_path, func_name = args.func_ref
|
|
@@ -399,6 +399,7 @@ class MachineRequirements:
|
|
|
399
399
|
max_concurrency: int | None = None
|
|
400
400
|
max_multiplexing: int | None = None
|
|
401
401
|
min_concurrency: int | None = None
|
|
402
|
+
request_timeout: int | None = None
|
|
402
403
|
|
|
403
404
|
def __post_init__(self):
|
|
404
405
|
if isinstance(self.machine_types, str):
|
|
@@ -514,6 +515,7 @@ class FalServerlessConnection:
|
|
|
514
515
|
max_concurrency=machine_requirements.max_concurrency,
|
|
515
516
|
min_concurrency=machine_requirements.min_concurrency,
|
|
516
517
|
max_multiplexing=machine_requirements.max_multiplexing,
|
|
518
|
+
request_timeout=machine_requirements.request_timeout,
|
|
517
519
|
)
|
|
518
520
|
else:
|
|
519
521
|
wrapped_requirements = None
|
|
@@ -607,6 +609,7 @@ class FalServerlessConnection:
|
|
|
607
609
|
max_concurrency=machine_requirements.max_concurrency,
|
|
608
610
|
max_multiplexing=machine_requirements.max_multiplexing,
|
|
609
611
|
min_concurrency=machine_requirements.min_concurrency,
|
|
612
|
+
request_timeout=machine_requirements.request_timeout,
|
|
610
613
|
)
|
|
611
614
|
else:
|
|
612
615
|
wrapped_requirements = None
|
|
@@ -10,6 +10,7 @@ from dataclasses import dataclass
|
|
|
10
10
|
from datetime import datetime, timezone
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
from urllib.error import HTTPError
|
|
13
|
+
from urllib.parse import urlparse, urlunparse
|
|
13
14
|
from urllib.request import Request, urlopen
|
|
14
15
|
|
|
15
16
|
from fal.auth import key_credentials
|
|
@@ -24,7 +25,7 @@ _FAL_CDN = "https://fal.media"
|
|
|
24
25
|
class FalV2Token:
|
|
25
26
|
token: str
|
|
26
27
|
token_type: str
|
|
27
|
-
|
|
28
|
+
base_upload_url: str
|
|
28
29
|
expires_at: datetime
|
|
29
30
|
|
|
30
31
|
def is_expired(self) -> bool:
|
|
@@ -36,7 +37,7 @@ class FalV2TokenManager:
|
|
|
36
37
|
self._token: FalV2Token = FalV2Token(
|
|
37
38
|
token="",
|
|
38
39
|
token_type="",
|
|
39
|
-
|
|
40
|
+
base_upload_url="",
|
|
40
41
|
expires_at=datetime.min.replace(tzinfo=timezone.utc),
|
|
41
42
|
)
|
|
42
43
|
self._lock: threading.Lock = threading.Lock()
|
|
@@ -72,10 +73,15 @@ class FalV2TokenManager:
|
|
|
72
73
|
with urlopen(req) as response:
|
|
73
74
|
result = json.load(response)
|
|
74
75
|
|
|
76
|
+
parsed_base_url = urlparse(result["base_url"])
|
|
77
|
+
base_upload_url = urlunparse(
|
|
78
|
+
parsed_base_url._replace(netloc="upload." + parsed_base_url.netloc)
|
|
79
|
+
)
|
|
80
|
+
|
|
75
81
|
self._token = FalV2Token(
|
|
76
82
|
token=result["token"],
|
|
77
83
|
token_type=result["token_type"],
|
|
78
|
-
|
|
84
|
+
base_upload_url=base_upload_url,
|
|
79
85
|
expires_at=datetime.fromisoformat(result["expires_at"]),
|
|
80
86
|
)
|
|
81
87
|
|
|
@@ -179,7 +185,7 @@ class MultipartUpload:
|
|
|
179
185
|
token = fal_v2_token_manager.get_token()
|
|
180
186
|
try:
|
|
181
187
|
req = Request(
|
|
182
|
-
f"{token.
|
|
188
|
+
f"{token.base_upload_url}/upload/initiate-multipart",
|
|
183
189
|
method="POST",
|
|
184
190
|
headers={
|
|
185
191
|
"Authorization": f"{token.token_type} {token.token}",
|
|
@@ -195,7 +201,7 @@ class MultipartUpload:
|
|
|
195
201
|
)
|
|
196
202
|
with urlopen(req) as response:
|
|
197
203
|
result = json.load(response)
|
|
198
|
-
self.
|
|
204
|
+
self._upload_url = result["upload_url"]
|
|
199
205
|
self._file_url = result["file_url"]
|
|
200
206
|
except HTTPError as exc:
|
|
201
207
|
raise FileUploadException(
|
|
@@ -235,10 +241,7 @@ class MultipartUpload:
|
|
|
235
241
|
) as executor:
|
|
236
242
|
futures = []
|
|
237
243
|
for part_number in range(1, parts + 1):
|
|
238
|
-
upload_url =
|
|
239
|
-
f"{self._file_url}?upload_id={self._upload_id}"
|
|
240
|
-
f"&part_number={part_number}"
|
|
241
|
-
)
|
|
244
|
+
upload_url = f"{self._upload_url}&part_number={part_number}"
|
|
242
245
|
futures.append(
|
|
243
246
|
executor.submit(self._upload_part, upload_url, part_number)
|
|
244
247
|
)
|
|
@@ -248,7 +251,7 @@ class MultipartUpload:
|
|
|
248
251
|
self._parts.append(entry)
|
|
249
252
|
|
|
250
253
|
def complete(self):
|
|
251
|
-
url =
|
|
254
|
+
url = self._upload_url
|
|
252
255
|
try:
|
|
253
256
|
req = Request(
|
|
254
257
|
url,
|
|
@@ -281,7 +284,7 @@ class FalFileRepositoryV2(FalFileRepositoryBase):
|
|
|
281
284
|
"Content-Type": file.content_type,
|
|
282
285
|
}
|
|
283
286
|
|
|
284
|
-
storage_url = f"{token.
|
|
287
|
+
storage_url = f"{token.base_upload_url}/upload"
|
|
285
288
|
|
|
286
289
|
try:
|
|
287
290
|
req = Request(
|
|
@@ -4,6 +4,7 @@ from unittest.mock import MagicMock, patch
|
|
|
4
4
|
import pytest
|
|
5
5
|
from fal.cli.deploy import _deploy
|
|
6
6
|
from fal.cli.main import parse_args
|
|
7
|
+
from fal.files import find_project_root
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def test_deploy():
|
|
@@ -19,8 +20,8 @@ def mock_parse_pyproject_toml():
|
|
|
19
20
|
"my-app": {
|
|
20
21
|
"ref": "src/my_app/inference.py::MyApp",
|
|
21
22
|
"auth": "shared",
|
|
23
|
+
"deployment_strategy": "rolling",
|
|
22
24
|
},
|
|
23
|
-
# auth is not provided for another-app
|
|
24
25
|
"another-app": {
|
|
25
26
|
"ref": "src/another_app/inference.py::AnotherApp",
|
|
26
27
|
},
|
|
@@ -29,13 +30,17 @@ def mock_parse_pyproject_toml():
|
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def mock_args(
|
|
32
|
-
app_ref: tuple[str],
|
|
33
|
+
app_ref: tuple[str],
|
|
34
|
+
app_name: Optional[str] = None,
|
|
35
|
+
auth: Optional[str] = None,
|
|
36
|
+
strategy: Optional[str] = None,
|
|
33
37
|
):
|
|
34
38
|
args = MagicMock()
|
|
35
39
|
|
|
36
40
|
args.app_ref = app_ref
|
|
37
41
|
args.app_name = app_name
|
|
38
42
|
args.auth = auth
|
|
43
|
+
args.strategy = strategy
|
|
39
44
|
|
|
40
45
|
return args
|
|
41
46
|
|
|
@@ -53,9 +58,15 @@ def test_deploy_with_toml_success(
|
|
|
53
58
|
|
|
54
59
|
_deploy(args)
|
|
55
60
|
|
|
61
|
+
project_root, _ = find_project_root(None)
|
|
62
|
+
|
|
56
63
|
# Ensure the correct app is deployed
|
|
57
64
|
mock_deploy_ref.assert_called_once_with(
|
|
58
|
-
("src/my_app/inference.py", "MyApp"),
|
|
65
|
+
(f"{project_root / 'src/my_app/inference.py'}", "MyApp"),
|
|
66
|
+
"my-app",
|
|
67
|
+
args,
|
|
68
|
+
"shared",
|
|
69
|
+
"rolling",
|
|
59
70
|
)
|
|
60
71
|
|
|
61
72
|
|
|
@@ -72,9 +83,15 @@ def test_deploy_with_toml_no_auth(
|
|
|
72
83
|
|
|
73
84
|
_deploy(args)
|
|
74
85
|
|
|
86
|
+
project_root, _ = find_project_root(None)
|
|
87
|
+
|
|
75
88
|
# Since auth is not provided for "another-app", it should default to "private"
|
|
76
89
|
mock_deploy_ref.assert_called_once_with(
|
|
77
|
-
("src/another_app/inference.py", "AnotherApp"),
|
|
90
|
+
(f"{project_root / 'src/another_app/inference.py'}", "AnotherApp"),
|
|
91
|
+
"another-app",
|
|
92
|
+
args,
|
|
93
|
+
"private",
|
|
94
|
+
"recreate",
|
|
78
95
|
)
|
|
79
96
|
|
|
80
97
|
|
|
@@ -146,3 +163,91 @@ def test_deploy_with_toml_only_app_name_is_provided(
|
|
|
146
163
|
ValueError, match="Cannot use --app-name or --auth with app name reference."
|
|
147
164
|
):
|
|
148
165
|
_deploy(args)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@patch("fal.cli._utils.find_pyproject_toml", return_value="pyproject.toml")
|
|
169
|
+
@patch("fal.cli._utils.parse_pyproject_toml")
|
|
170
|
+
@patch("fal.cli.deploy._deploy_from_reference")
|
|
171
|
+
def test_deploy_with_toml_deployment_strategy(
|
|
172
|
+
mock_deploy_ref, mock_parse_toml, mock_find_toml, mock_parse_pyproject_toml
|
|
173
|
+
):
|
|
174
|
+
mock_parse_toml.return_value = mock_parse_pyproject_toml
|
|
175
|
+
|
|
176
|
+
args = mock_args(app_ref=("my-app", None), strategy="rolling")
|
|
177
|
+
|
|
178
|
+
_deploy(args)
|
|
179
|
+
|
|
180
|
+
project_root, _ = find_project_root(None)
|
|
181
|
+
|
|
182
|
+
mock_deploy_ref.assert_called_once_with(
|
|
183
|
+
(f"{project_root / 'src/my_app/inference.py'}", "MyApp"),
|
|
184
|
+
"my-app",
|
|
185
|
+
args,
|
|
186
|
+
"shared",
|
|
187
|
+
"rolling",
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@patch("fal.cli._utils.find_pyproject_toml", return_value="pyproject.toml")
|
|
192
|
+
@patch("fal.cli._utils.parse_pyproject_toml")
|
|
193
|
+
@patch("fal.cli.deploy._deploy_from_reference")
|
|
194
|
+
def test_deploy_with_toml_default_deployment_strategy(
|
|
195
|
+
mock_deploy_ref, mock_parse_toml, mock_find_toml, mock_parse_pyproject_toml
|
|
196
|
+
):
|
|
197
|
+
mock_parse_toml.return_value = mock_parse_pyproject_toml
|
|
198
|
+
|
|
199
|
+
args = mock_args(app_ref=("another-app", None))
|
|
200
|
+
|
|
201
|
+
_deploy(args)
|
|
202
|
+
|
|
203
|
+
project_root, _ = find_project_root(None)
|
|
204
|
+
|
|
205
|
+
mock_deploy_ref.assert_called_once_with(
|
|
206
|
+
(f"{project_root / 'src/another_app/inference.py'}", "AnotherApp"),
|
|
207
|
+
"another-app",
|
|
208
|
+
args,
|
|
209
|
+
"private",
|
|
210
|
+
"recreate",
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@patch("fal.cli._utils.find_pyproject_toml", return_value="pyproject.toml")
|
|
215
|
+
@patch("fal.cli._utils.parse_pyproject_toml")
|
|
216
|
+
@patch("fal.cli.deploy._deploy_from_reference")
|
|
217
|
+
def test_deploy_with_cli_auth(
|
|
218
|
+
mock_deploy_ref, mock_parse_toml, mock_find_toml, mock_parse_pyproject_toml
|
|
219
|
+
):
|
|
220
|
+
mock_parse_toml.return_value = mock_parse_pyproject_toml
|
|
221
|
+
|
|
222
|
+
args = mock_args(app_ref=("src/my_app/inference.py", "MyApp"), auth="shared")
|
|
223
|
+
|
|
224
|
+
_deploy(args)
|
|
225
|
+
|
|
226
|
+
mock_deploy_ref.assert_called_once_with(
|
|
227
|
+
("src/my_app/inference.py", "MyApp"),
|
|
228
|
+
None,
|
|
229
|
+
args,
|
|
230
|
+
"shared",
|
|
231
|
+
None,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@patch("fal.cli._utils.find_pyproject_toml", return_value="pyproject.toml")
|
|
236
|
+
@patch("fal.cli._utils.parse_pyproject_toml")
|
|
237
|
+
@patch("fal.cli.deploy._deploy_from_reference")
|
|
238
|
+
def test_deploy_with_cli_deployment_strategy(
|
|
239
|
+
mock_deploy_ref, mock_parse_toml, mock_find_toml, mock_parse_pyproject_toml
|
|
240
|
+
):
|
|
241
|
+
mock_parse_toml.return_value = mock_parse_pyproject_toml
|
|
242
|
+
|
|
243
|
+
args = mock_args(app_ref=("src/my_app/inference.py", "MyApp"), strategy="rolling")
|
|
244
|
+
|
|
245
|
+
_deploy(args)
|
|
246
|
+
|
|
247
|
+
mock_deploy_ref.assert_called_once_with(
|
|
248
|
+
("src/my_app/inference.py", "MyApp"),
|
|
249
|
+
None,
|
|
250
|
+
args,
|
|
251
|
+
None,
|
|
252
|
+
"rolling",
|
|
253
|
+
)
|
|
@@ -3,6 +3,7 @@ from unittest.mock import MagicMock, patch
|
|
|
3
3
|
import pytest
|
|
4
4
|
from fal.cli.main import parse_args
|
|
5
5
|
from fal.cli.run import _run
|
|
6
|
+
from fal.files import find_project_root
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
def test_run():
|
|
@@ -60,9 +61,11 @@ def test_run_with_toml_success(
|
|
|
60
61
|
|
|
61
62
|
_run(args)
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
project_root, _ = find_project_root(None)
|
|
65
|
+
|
|
66
|
+
# Ensure the correct app is ran
|
|
64
67
|
mock_load_function_from.assert_called_once_with(
|
|
65
|
-
host, "src/my_app/inference.py", "MyApp"
|
|
68
|
+
host, f"{project_root / 'src/my_app/inference.py'}", "MyApp"
|
|
66
69
|
)
|
|
67
70
|
|
|
68
71
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/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
|
|
File without changes
|
|
File without changes
|
{fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_extra_data.py
RENAMED
|
File without changes
|
{fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py
RENAMED
|
File without changes
|
|
File without changes
|
{fal-1.4.0 → fal-1.5.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.4.0 → fal-1.5.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.4.0 → fal-1.5.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.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_metadata.py
RENAMED
|
File without changes
|
|
File without changes
|
{fal-1.4.0 → fal-1.5.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py
RENAMED
|
File without changes
|
|
File without changes
|
{fal-1.4.0 → fal-1.5.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|