fal 1.0.8__py3-none-any.whl → 1.1.1__py3-none-any.whl
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/_fal_version.py +2 -2
- fal/api.py +27 -26
- fal/cli/deploy.py +18 -8
- fal/toolkit/file/file.py +2 -0
- fal/toolkit/file/providers/fal.py +15 -3
- fal/toolkit/file/types.py +1 -1
- fal/workflows.py +1 -1
- {fal-1.0.8.dist-info → fal-1.1.1.dist-info}/METADATA +1 -1
- {fal-1.0.8.dist-info → fal-1.1.1.dist-info}/RECORD +47 -26
- {fal-1.0.8.dist-info → fal-1.1.1.dist-info}/WHEEL +1 -1
- openapi_fal_rest/api/comfy/__init__.py +0 -0
- openapi_fal_rest/api/comfy/create_workflow.py +172 -0
- openapi_fal_rest/api/comfy/delete_workflow.py +175 -0
- openapi_fal_rest/api/comfy/get_workflow.py +181 -0
- openapi_fal_rest/api/comfy/list_user_workflows.py +189 -0
- openapi_fal_rest/api/comfy/update_workflow.py +198 -0
- openapi_fal_rest/api/users/__init__.py +0 -0
- openapi_fal_rest/api/users/get_current_user.py +143 -0
- openapi_fal_rest/api/workflows/{create_or_update_workflow_workflows_post.py → create_workflow.py} +4 -4
- openapi_fal_rest/api/workflows/{get_workflows_workflows_get.py → list_user_workflows.py} +4 -4
- openapi_fal_rest/api/workflows/update_workflow.py +198 -0
- openapi_fal_rest/models/__init__.py +32 -10
- openapi_fal_rest/models/comfy_workflow_detail.py +109 -0
- openapi_fal_rest/models/comfy_workflow_item.py +88 -0
- openapi_fal_rest/models/comfy_workflow_schema.py +119 -0
- openapi_fal_rest/models/{execute_workflow_workflows_user_id_workflow_name_post_json_body_type_0.py → comfy_workflow_schema_extra_data.py} +5 -5
- openapi_fal_rest/models/{execute_workflow_workflows_user_id_workflow_name_post_response_200_type_0.py → comfy_workflow_schema_fal_inputs.py} +5 -5
- openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py +44 -0
- openapi_fal_rest/models/{workflow_detail_contents_type_0.py → comfy_workflow_schema_prompt.py} +5 -5
- openapi_fal_rest/models/current_user.py +138 -0
- openapi_fal_rest/models/customer_details.py +8 -8
- openapi_fal_rest/models/lock_reason.py +3 -0
- openapi_fal_rest/models/page_comfy_workflow_item.py +107 -0
- openapi_fal_rest/models/team_role.py +10 -0
- openapi_fal_rest/models/typed_comfy_workflow.py +85 -0
- openapi_fal_rest/models/typed_comfy_workflow_update.py +95 -0
- openapi_fal_rest/models/typed_workflow_update.py +95 -0
- openapi_fal_rest/models/user_member.py +87 -0
- openapi_fal_rest/models/workflow_contents.py +20 -1
- openapi_fal_rest/models/workflow_contents_metadata.py +44 -0
- openapi_fal_rest/models/workflow_detail.py +18 -59
- openapi_fal_rest/models/workflow_detail_contents.py +44 -0
- openapi_fal_rest/models/workflow_item.py +19 -1
- openapi_fal_rest/api/workflows/execute_workflow_workflows_user_id_workflow_name_post.py +0 -268
- {fal-1.0.8.dist-info → fal-1.1.1.dist-info}/entry_points.txt +0 -0
- {fal-1.0.8.dist-info → fal-1.1.1.dist-info}/top_level.txt +0 -0
- /openapi_fal_rest/api/workflows/{delete_workflow_workflows_user_id_workflow_name_delete.py → delete_workflow.py} +0 -0
- /openapi_fal_rest/api/workflows/{get_workflow_workflows_user_id_workflow_name_get.py → get_workflow.py} +0 -0
fal/_fal_version.py
CHANGED
fal/api.py
CHANGED
|
@@ -75,6 +75,7 @@ SERVE_REQUIREMENTS = [
|
|
|
75
75
|
|
|
76
76
|
THREAD_POOL = ThreadPoolExecutor()
|
|
77
77
|
|
|
78
|
+
|
|
78
79
|
@dataclass
|
|
79
80
|
class FalServerlessError(FalServerlessException):
|
|
80
81
|
message: str
|
|
@@ -86,8 +87,7 @@ class InternalFalServerlessError(FalServerlessException):
|
|
|
86
87
|
|
|
87
88
|
|
|
88
89
|
@dataclass
|
|
89
|
-
class FalMissingDependencyError(FalServerlessError):
|
|
90
|
-
...
|
|
90
|
+
class FalMissingDependencyError(FalServerlessError): ...
|
|
91
91
|
|
|
92
92
|
|
|
93
93
|
@dataclass
|
|
@@ -548,7 +548,6 @@ class FalServerlessHost(Host):
|
|
|
548
548
|
|
|
549
549
|
return cast(ReturnT, return_value)
|
|
550
550
|
|
|
551
|
-
|
|
552
551
|
def run(
|
|
553
552
|
self,
|
|
554
553
|
func: Callable[..., ReturnT],
|
|
@@ -644,8 +643,7 @@ def function(
|
|
|
644
643
|
max_concurrency: int | None = None,
|
|
645
644
|
) -> Callable[
|
|
646
645
|
[Callable[Concatenate[ArgsT], ReturnT]], IsolatedFunction[ArgsT, ReturnT]
|
|
647
|
-
]:
|
|
648
|
-
...
|
|
646
|
+
]: ...
|
|
649
647
|
|
|
650
648
|
|
|
651
649
|
@overload
|
|
@@ -661,8 +659,7 @@ def function(
|
|
|
661
659
|
max_concurrency: int | None = None,
|
|
662
660
|
) -> Callable[
|
|
663
661
|
[Callable[Concatenate[ArgsT], ReturnT]], ServedIsolatedFunction[ArgsT, ReturnT]
|
|
664
|
-
]:
|
|
665
|
-
...
|
|
662
|
+
]: ...
|
|
666
663
|
|
|
667
664
|
|
|
668
665
|
### FalServerlessHost
|
|
@@ -688,8 +685,7 @@ def function(
|
|
|
688
685
|
_scheduler: str | None = None,
|
|
689
686
|
) -> Callable[
|
|
690
687
|
[Callable[Concatenate[ArgsT], ReturnT]], IsolatedFunction[ArgsT, ReturnT]
|
|
691
|
-
]:
|
|
692
|
-
...
|
|
688
|
+
]: ...
|
|
693
689
|
|
|
694
690
|
|
|
695
691
|
@overload
|
|
@@ -714,8 +710,7 @@ def function(
|
|
|
714
710
|
_scheduler: str | None = None,
|
|
715
711
|
) -> Callable[
|
|
716
712
|
[Callable[Concatenate[ArgsT], ReturnT]], ServedIsolatedFunction[ArgsT, ReturnT]
|
|
717
|
-
]:
|
|
718
|
-
...
|
|
713
|
+
]: ...
|
|
719
714
|
|
|
720
715
|
|
|
721
716
|
## conda
|
|
@@ -738,8 +733,7 @@ def function(
|
|
|
738
733
|
max_concurrency: int | None = None,
|
|
739
734
|
) -> Callable[
|
|
740
735
|
[Callable[Concatenate[ArgsT], ReturnT]], IsolatedFunction[ArgsT, ReturnT]
|
|
741
|
-
]:
|
|
742
|
-
...
|
|
736
|
+
]: ...
|
|
743
737
|
|
|
744
738
|
|
|
745
739
|
@overload
|
|
@@ -760,8 +754,7 @@ def function(
|
|
|
760
754
|
max_concurrency: int | None = None,
|
|
761
755
|
) -> Callable[
|
|
762
756
|
[Callable[Concatenate[ArgsT], ReturnT]], ServedIsolatedFunction[ArgsT, ReturnT]
|
|
763
|
-
]:
|
|
764
|
-
...
|
|
757
|
+
]: ...
|
|
765
758
|
|
|
766
759
|
|
|
767
760
|
### FalServerlessHost
|
|
@@ -792,8 +785,7 @@ def function(
|
|
|
792
785
|
_scheduler: str | None = None,
|
|
793
786
|
) -> Callable[
|
|
794
787
|
[Callable[Concatenate[ArgsT], ReturnT]], IsolatedFunction[ArgsT, ReturnT]
|
|
795
|
-
]:
|
|
796
|
-
...
|
|
788
|
+
]: ...
|
|
797
789
|
|
|
798
790
|
|
|
799
791
|
@overload
|
|
@@ -967,6 +959,9 @@ class BaseServable:
|
|
|
967
959
|
yield
|
|
968
960
|
|
|
969
961
|
def _build_app(self) -> FastAPI:
|
|
962
|
+
import json
|
|
963
|
+
import traceback
|
|
964
|
+
|
|
970
965
|
from fastapi import HTTPException, Request
|
|
971
966
|
from fastapi.middleware.cors import CORSMiddleware
|
|
972
967
|
from fastapi.responses import JSONResponse
|
|
@@ -1007,6 +1002,15 @@ class BaseServable:
|
|
|
1007
1002
|
# If it's not a generic 404, just return the original message.
|
|
1008
1003
|
return JSONResponse({"detail": exc.detail}, 404)
|
|
1009
1004
|
|
|
1005
|
+
@_app.exception_handler(Exception)
|
|
1006
|
+
async def traceback_logging_exception_handler(request: Request, exc: Exception):
|
|
1007
|
+
print(
|
|
1008
|
+
json.dumps(
|
|
1009
|
+
{"traceback": "".join(traceback.format_exception(exc)[::-1])} # type: ignore
|
|
1010
|
+
)
|
|
1011
|
+
)
|
|
1012
|
+
return JSONResponse({"detail": "Internal Server Error"}, 500)
|
|
1013
|
+
|
|
1010
1014
|
routes = self.collect_routes()
|
|
1011
1015
|
if not routes:
|
|
1012
1016
|
raise ValueError("An application must have at least one route!")
|
|
@@ -1056,7 +1060,8 @@ class BaseServable:
|
|
|
1056
1060
|
}
|
|
1057
1061
|
|
|
1058
1062
|
_, pending = await asyncio.wait(
|
|
1059
|
-
tasks.keys(),
|
|
1063
|
+
tasks.keys(),
|
|
1064
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
1060
1065
|
)
|
|
1061
1066
|
if not pending:
|
|
1062
1067
|
return
|
|
@@ -1175,14 +1180,12 @@ class IsolatedFunction(Generic[ArgsT, ReturnT]):
|
|
|
1175
1180
|
@overload
|
|
1176
1181
|
def on(
|
|
1177
1182
|
self, host: Host | None = None, *, serve: Literal[False] = False, **config: Any
|
|
1178
|
-
) -> IsolatedFunction[ArgsT, ReturnT]:
|
|
1179
|
-
...
|
|
1183
|
+
) -> IsolatedFunction[ArgsT, ReturnT]: ...
|
|
1180
1184
|
|
|
1181
1185
|
@overload
|
|
1182
1186
|
def on(
|
|
1183
1187
|
self, host: Host | None = None, *, serve: Literal[True], **config: Any
|
|
1184
|
-
) -> ServedIsolatedFunction[ArgsT, ReturnT]:
|
|
1185
|
-
...
|
|
1188
|
+
) -> ServedIsolatedFunction[ArgsT, ReturnT]: ...
|
|
1186
1189
|
|
|
1187
1190
|
def on(self, host: Host | None = None, **config: Any): # type: ignore
|
|
1188
1191
|
host = host or self.host
|
|
@@ -1236,14 +1239,12 @@ class ServedIsolatedFunction(
|
|
|
1236
1239
|
@overload # type: ignore[override,no-overload-impl]
|
|
1237
1240
|
def on( # type: ignore[no-overload-impl]
|
|
1238
1241
|
self, host: Host | None = None, *, serve: Literal[True] = True, **config: Any
|
|
1239
|
-
) -> ServedIsolatedFunction[ArgsT, ReturnT]:
|
|
1240
|
-
...
|
|
1242
|
+
) -> ServedIsolatedFunction[ArgsT, ReturnT]: ...
|
|
1241
1243
|
|
|
1242
1244
|
@overload
|
|
1243
1245
|
def on(
|
|
1244
1246
|
self, host: Host | None = None, *, serve: Literal[False], **config: Any
|
|
1245
|
-
) -> IsolatedFunction[ArgsT, ReturnT]:
|
|
1246
|
-
...
|
|
1247
|
+
) -> IsolatedFunction[ArgsT, ReturnT]: ...
|
|
1247
1248
|
|
|
1248
1249
|
|
|
1249
1250
|
class Server(uvicorn.Server):
|
fal/cli/deploy.py
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from collections import namedtuple
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
from .parser import FalClientParser, RefAction
|
|
4
6
|
|
|
7
|
+
User = namedtuple("User", ["user_id", "username"])
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
def _remove_http_and_port_from_url(url):
|
|
7
11
|
# Remove http://
|
|
@@ -20,17 +24,17 @@ def _remove_http_and_port_from_url(url):
|
|
|
20
24
|
return url
|
|
21
25
|
|
|
22
26
|
|
|
23
|
-
def
|
|
27
|
+
def _get_user() -> User:
|
|
24
28
|
import json
|
|
25
29
|
from http import HTTPStatus
|
|
26
30
|
|
|
27
|
-
import openapi_fal_rest.api.
|
|
31
|
+
import openapi_fal_rest.api.users.get_current_user as get_current_user
|
|
28
32
|
|
|
29
33
|
from fal.api import FalServerlessError
|
|
30
34
|
from fal.rest_client import REST_CLIENT
|
|
31
35
|
|
|
32
36
|
try:
|
|
33
|
-
user_details_response =
|
|
37
|
+
user_details_response = get_current_user.sync_detailed(
|
|
34
38
|
client=REST_CLIENT,
|
|
35
39
|
)
|
|
36
40
|
except Exception as e:
|
|
@@ -51,7 +55,7 @@ def _get_user_id() -> str:
|
|
|
51
55
|
if not user_id:
|
|
52
56
|
user_id = full_user_id
|
|
53
57
|
|
|
54
|
-
return user_id
|
|
58
|
+
return User(user_id=user_id, username=user_details_response.parsed.nickname)
|
|
55
59
|
except Exception as e:
|
|
56
60
|
raise FalServerlessError(f"Could not parse the user data: {e}")
|
|
57
61
|
|
|
@@ -77,7 +81,7 @@ def _deploy(args):
|
|
|
77
81
|
[file_path] = options
|
|
78
82
|
file_path = str(file_path)
|
|
79
83
|
|
|
80
|
-
|
|
84
|
+
user = _get_user()
|
|
81
85
|
host = FalServerlessHost(args.host)
|
|
82
86
|
isolated_function, app_name = load_function_from(
|
|
83
87
|
host,
|
|
@@ -103,12 +107,18 @@ def _deploy(args):
|
|
|
103
107
|
"Registered a new revision for function "
|
|
104
108
|
f"'{app_name}' (revision='{app_id}')."
|
|
105
109
|
)
|
|
106
|
-
args.console.print(f"
|
|
110
|
+
args.console.print(f"Playground: https://fal.ai/models/{user.username}/{app_name}")
|
|
111
|
+
args.console.print(f"Endpoint: https://{gateway_host}/{user.username}/{app_name}")
|
|
107
112
|
|
|
108
113
|
|
|
109
114
|
def add_parser(main_subparsers, parents):
|
|
110
115
|
from fal.sdk import ALIAS_AUTH_MODES
|
|
111
116
|
|
|
117
|
+
def valid_auth_option(option):
|
|
118
|
+
if option not in ALIAS_AUTH_MODES:
|
|
119
|
+
raise argparse.ArgumentTypeError(f"{option} is not a auth option")
|
|
120
|
+
return option
|
|
121
|
+
|
|
112
122
|
deploy_help = "Deploy a fal application."
|
|
113
123
|
epilog = (
|
|
114
124
|
"Examples:\n"
|
|
@@ -139,8 +149,8 @@ def add_parser(main_subparsers, parents):
|
|
|
139
149
|
)
|
|
140
150
|
parser.add_argument(
|
|
141
151
|
"--auth",
|
|
142
|
-
|
|
152
|
+
type=valid_auth_option,
|
|
143
153
|
default="private",
|
|
144
|
-
help="Application authentication mode.",
|
|
154
|
+
help="Application authentication mode (private, public).",
|
|
145
155
|
)
|
|
146
156
|
parser.set_defaults(func=_deploy)
|
fal/toolkit/file/file.py
CHANGED
|
@@ -22,6 +22,7 @@ from pydantic import BaseModel, Field
|
|
|
22
22
|
from fal.toolkit.file.providers.fal import (
|
|
23
23
|
FalCDNFileRepository,
|
|
24
24
|
FalFileRepository,
|
|
25
|
+
FalFileRepositoryV2,
|
|
25
26
|
InMemoryRepository,
|
|
26
27
|
)
|
|
27
28
|
from fal.toolkit.file.providers.gcp import GoogleStorageRepository
|
|
@@ -33,6 +34,7 @@ FileRepositoryFactory = Callable[[], FileRepository]
|
|
|
33
34
|
|
|
34
35
|
BUILT_IN_REPOSITORIES: dict[RepositoryId, FileRepositoryFactory] = {
|
|
35
36
|
"fal": lambda: FalFileRepository(),
|
|
37
|
+
"fal_v2": lambda: FalFileRepositoryV2(),
|
|
36
38
|
"in_memory": lambda: InMemoryRepository(),
|
|
37
39
|
"gcp_storage": lambda: GoogleStorageRepository(),
|
|
38
40
|
"r2": lambda: R2Repository(),
|
|
@@ -26,8 +26,8 @@ GLOBAL_LIFECYCLE_PREFERENCE = ObjectLifecyclePreference(
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
@dataclass
|
|
29
|
-
class
|
|
30
|
-
def
|
|
29
|
+
class FalFileRepositoryBase(FileRepository):
|
|
30
|
+
def _save(self, file: FileData, storage_type: str) -> str:
|
|
31
31
|
key_creds = key_credentials()
|
|
32
32
|
if not key_creds:
|
|
33
33
|
raise FileUploadException("FAL_KEY must be set")
|
|
@@ -41,7 +41,7 @@ class FalFileRepository(FileRepository):
|
|
|
41
41
|
|
|
42
42
|
grpc_host = os.environ.get("FAL_HOST", "api.alpha.fal.ai")
|
|
43
43
|
rest_host = grpc_host.replace("api", "rest", 1)
|
|
44
|
-
storage_url = f"https://{rest_host}/storage/upload/initiate"
|
|
44
|
+
storage_url = f"https://{rest_host}/storage/upload/initiate?storage_type={storage_type}"
|
|
45
45
|
|
|
46
46
|
try:
|
|
47
47
|
req = Request(
|
|
@@ -79,6 +79,18 @@ class FalFileRepository(FileRepository):
|
|
|
79
79
|
return
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
@dataclass
|
|
83
|
+
class FalFileRepository(FalFileRepositoryBase):
|
|
84
|
+
def save(self, file: FileData) -> str:
|
|
85
|
+
return self._save(file, "gcs")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class FalFileRepositoryV2(FalFileRepositoryBase):
|
|
90
|
+
def save(self, file: FileData) -> str:
|
|
91
|
+
return self._save(file, "fal-cdn")
|
|
92
|
+
|
|
93
|
+
|
|
82
94
|
@dataclass
|
|
83
95
|
class InMemoryRepository(FileRepository):
|
|
84
96
|
def save(
|
fal/toolkit/file/types.py
CHANGED
fal/workflows.py
CHANGED
|
@@ -10,7 +10,7 @@ from typing import Any, Iterator, Union, cast
|
|
|
10
10
|
import graphlib
|
|
11
11
|
import rich
|
|
12
12
|
from openapi_fal_rest.api.workflows import (
|
|
13
|
-
|
|
13
|
+
create_workflow as publish_workflow,
|
|
14
14
|
)
|
|
15
15
|
from openapi_fal_rest.models.http_validation_error import HTTPValidationError
|
|
16
16
|
from pydantic import BaseModel
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
fal/__init__.py,sha256=wXs1G0gSc7ZK60-bHe-B2m0l_sA6TrFk4BxY0tMoLe8,784
|
|
2
2
|
fal/__main__.py,sha256=MSmt_5Xg84uHqzTN38JwgseJK8rsJn_11A8WD99VtEo,61
|
|
3
|
-
fal/_fal_version.py,sha256=
|
|
3
|
+
fal/_fal_version.py,sha256=EPoWF0em1tKJgBz5dbBF-r29860VBk-SsdiXh6E1aO0,411
|
|
4
4
|
fal/_serialization.py,sha256=7urrZXw99qmsK-RkjCurk6Va4TMEfDIMajkzKbSW4j4,7655
|
|
5
5
|
fal/_version.py,sha256=EBGqrknaf1WygENX-H4fBefLvHryvJBBGtVJetaB0NY,266
|
|
6
|
-
fal/api.py,sha256=
|
|
6
|
+
fal/api.py,sha256=x60GlBWynDd1yhHsVWeqf07WVTzgbwNC6cqCjhlTiFQ,40556
|
|
7
7
|
fal/app.py,sha256=duOf_YKE8o30hmhNtF9zvkT8wlKYXW7hdQLJtPrXHik,15793
|
|
8
8
|
fal/apps.py,sha256=UhR6mq8jBiTAp-QvUnvbnMNcuJ5wHIKSqdlfyx8aBQ8,6829
|
|
9
9
|
fal/container.py,sha256=V7riyyq8AZGwEX9QaqRQDZyDN_bUKeRKV1OOZArXjL0,622
|
|
@@ -13,7 +13,7 @@ fal/rest_client.py,sha256=kGBGmuyHfX1lR910EoKCYPjsyU8MdXawT_cW2q8Sajc,568
|
|
|
13
13
|
fal/sdk.py,sha256=_1aK9VSzHPoDPbLm3nbhE4213zI66qAsgYs1Y1Wc3J8,20077
|
|
14
14
|
fal/sync.py,sha256=ZuIJA2-hTPNANG9B_NNJZUsO68EIdTH0dc9MzeVE2VU,4340
|
|
15
15
|
fal/utils.py,sha256=MFDs-eO3rBgc3jqIwBpfBtvvK5tbzAYWMzHV-tTVLic,1754
|
|
16
|
-
fal/workflows.py,sha256=
|
|
16
|
+
fal/workflows.py,sha256=jx3tGy2R7cN6lLvOzT6lhhlcjmiq64iZls2smVrmQj0,14657
|
|
17
17
|
fal/auth/__init__.py,sha256=r8iA2-5ih7-Fik3gEC4HEWNFbGoxpYnXpZu1icPIoS0,3561
|
|
18
18
|
fal/auth/auth0.py,sha256=rSG1mgH-QGyKfzd7XyAaj1AYsWt-ho8Y_LZ-FUVWzh4,5421
|
|
19
19
|
fal/auth/local.py,sha256=sndkM6vKpeVny6NHTacVlTbiIFqaksOmw0Viqs_RN1U,1790
|
|
@@ -21,7 +21,7 @@ fal/cli/__init__.py,sha256=padK4o0BFqq61kxAA1qQ0jYr2SuhA2mf90B3AaRkmJA,37
|
|
|
21
21
|
fal/cli/apps.py,sha256=Dqcx7ewUNY6dh0bYqRlOCHVDzmkdpFxe9CNThEz7HX4,8144
|
|
22
22
|
fal/cli/auth.py,sha256=--MhfHGwxmtHbRkGioyn1prKn_U-pBzbz0G_QeZou-U,1352
|
|
23
23
|
fal/cli/debug.py,sha256=1doDNwoaPDfLQginGNBxpC20dZYs5UxIojflDvV1Q04,1342
|
|
24
|
-
fal/cli/deploy.py,sha256=
|
|
24
|
+
fal/cli/deploy.py,sha256=yx7QDv4PTrqLCUODgK3glMRs58of9nlCM1_a_GYaZBk,4783
|
|
25
25
|
fal/cli/doctor.py,sha256=U4ne9LX5gQwNblsYQ27XdO8AYDgbYjTO39EtxhwexRM,983
|
|
26
26
|
fal/cli/keys.py,sha256=-9N6ZY6rW-_IE9tpupgaBPDGjGdKB3HKqU2g9daM3Xc,3109
|
|
27
27
|
fal/cli/main.py,sha256=MxETDhqIT37quMbmofSMxBcAFOhnEHjpQ_pYEtOhApM,1993
|
|
@@ -43,9 +43,9 @@ fal/toolkit/__init__.py,sha256=sV95wiUzKoiDqF9vDgq4q-BLa2sD6IpuKSqp5kdTQNE,658
|
|
|
43
43
|
fal/toolkit/exceptions.py,sha256=elHZ7dHCJG5zlHGSBbz-ilkZe9QUvQMomJFi8Pt91LA,198
|
|
44
44
|
fal/toolkit/optimize.py,sha256=p75sovF0SmRP6zxzpIaaOmqlxvXB_xEz3XPNf59EF7w,1339
|
|
45
45
|
fal/toolkit/file/__init__.py,sha256=FbNl6wD-P0aSSTUwzHt4HujBXrbC3ABmaigPQA4hRfg,70
|
|
46
|
-
fal/toolkit/file/file.py,sha256=
|
|
47
|
-
fal/toolkit/file/types.py,sha256=
|
|
48
|
-
fal/toolkit/file/providers/fal.py,sha256=
|
|
46
|
+
fal/toolkit/file/file.py,sha256=S-So4RNSfcKgESFKnCFmQxdCpEov-JqbO2vIW73ZyC8,6136
|
|
47
|
+
fal/toolkit/file/types.py,sha256=bJCeV5NPcpJYJoglailiRgFsuNAfcextYA8Et5-XUag,1060
|
|
48
|
+
fal/toolkit/file/providers/fal.py,sha256=C0j2bRf_xwKNjwv4awdVCggQ-2fBNGPRClTeHbG79v4,4091
|
|
49
49
|
fal/toolkit/file/providers/gcp.py,sha256=7Lg7BXoHKkFu0jkGv3_vKh2Ks6eRfDMbw31N3mvDUtk,1913
|
|
50
50
|
fal/toolkit/file/providers/r2.py,sha256=YW5aJBOX41MQxfx1rA_f-IiJhAPMZ5md0cxBcg3y08I,2537
|
|
51
51
|
fal/toolkit/image/__init__.py,sha256=qNLyXsBWysionUjbeWbohLqWlw3G_UpzunamkZd_JLQ,71
|
|
@@ -62,40 +62,61 @@ openapi_fal_rest/api/applications/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
|
62
62
|
openapi_fal_rest/api/applications/app_metadata.py,sha256=GqG6Q7jt8Jcyhb3ms_6i0M1B3cy205y3_A8W-AGEapY,5120
|
|
63
63
|
openapi_fal_rest/api/billing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
64
|
openapi_fal_rest/api/billing/get_user_details.py,sha256=2HQHRUQj8QwqSKgiV_USBdXCxGlfaVTBbLiPaDsMBUM,4013
|
|
65
|
+
openapi_fal_rest/api/comfy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
|
+
openapi_fal_rest/api/comfy/create_workflow.py,sha256=3TTnMB3s2IQSMvECzQx6c68mcEO4ZwU8s8MfrQyCU7o,4689
|
|
67
|
+
openapi_fal_rest/api/comfy/delete_workflow.py,sha256=eiK1usnC16mUtRyrWrys-7nrMepEir9FxQaVb7BkVIs,4406
|
|
68
|
+
openapi_fal_rest/api/comfy/get_workflow.py,sha256=nAkEi8XnJGb1q7FySoqDEzVR1aIh28hK-ZedijbpUwc,4645
|
|
69
|
+
openapi_fal_rest/api/comfy/list_user_workflows.py,sha256=ty6OBZkR8pz6KJJZ4BbI_Gt-WWDRIDhFldOMkWp2_3s,5328
|
|
70
|
+
openapi_fal_rest/api/comfy/update_workflow.py,sha256=ACUt2IU22AR7MXLcA9ffFstzSB43YQ2X-HQ25YVw1p4,5322
|
|
65
71
|
openapi_fal_rest/api/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
72
|
openapi_fal_rest/api/files/check_dir_hash.py,sha256=zPNlOwG4YVvnhgfrleQtYLhI1lG0t8YQ1CU3TyvXvfk,4747
|
|
67
73
|
openapi_fal_rest/api/files/upload_local_file.py,sha256=p2lM7hswGbs8KNLg1Pp6vwV7x-1PKtWX-aYmaHUHSDU,5649
|
|
74
|
+
openapi_fal_rest/api/users/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
|
+
openapi_fal_rest/api/users/get_current_user.py,sha256=PpOBI3q1mGjAjb-SMWbV6xKounZXWNlsO62ZxOa5Oys,3942
|
|
68
76
|
openapi_fal_rest/api/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
|
-
openapi_fal_rest/api/workflows/
|
|
70
|
-
openapi_fal_rest/api/workflows/
|
|
71
|
-
openapi_fal_rest/api/workflows/
|
|
72
|
-
openapi_fal_rest/api/workflows/
|
|
73
|
-
openapi_fal_rest/api/workflows/
|
|
74
|
-
openapi_fal_rest/models/__init__.py,sha256=
|
|
77
|
+
openapi_fal_rest/api/workflows/create_workflow.py,sha256=ICeiqkVJtzuBp9BruZzMqgrqbZBiLmY_uVQhOWILZ-o,4571
|
|
78
|
+
openapi_fal_rest/api/workflows/delete_workflow.py,sha256=svJcV5q2e8caxuLJKIld3M7-raQFqSIxPNq58e3AgaA,4590
|
|
79
|
+
openapi_fal_rest/api/workflows/get_workflow.py,sha256=-E-TELi9Q_-yqobdHAcTHVm-8HithJRUGk7wc1mLA18,4763
|
|
80
|
+
openapi_fal_rest/api/workflows/list_user_workflows.py,sha256=aO7Wa0ogMgoKBDxbG7NMBbPs74Pp7XyM71b9mOuYEbc,5262
|
|
81
|
+
openapi_fal_rest/api/workflows/update_workflow.py,sha256=Q3-FnFnCGNBjYGgip-6L4QMWVOcZuODmAM1HPfKiYyI,5384
|
|
82
|
+
openapi_fal_rest/models/__init__.py,sha256=JNBQjkcf5E_vaeYvEtdEHzxSSk6H1d0Fop8s4Mk8R1c,2872
|
|
75
83
|
openapi_fal_rest/models/app_metadata_response_app_metadata.py,sha256=1vx_5cp8V0jyE8iBRIe8TfngaeXMojfEpMCpT6i3qvs,1252
|
|
76
84
|
openapi_fal_rest/models/body_upload_local_file.py,sha256=rOTEbYBXfwZk8TsywZWSPPQQEfJgvsLIufT6A40RJZs,1980
|
|
77
|
-
openapi_fal_rest/models/
|
|
78
|
-
openapi_fal_rest/models/
|
|
79
|
-
openapi_fal_rest/models/
|
|
85
|
+
openapi_fal_rest/models/comfy_workflow_detail.py,sha256=GR3Ft0iGlk3MTzJ-DyWJP0et2fxcS2aPMrbjzFd49kQ,2885
|
|
86
|
+
openapi_fal_rest/models/comfy_workflow_item.py,sha256=ZqFfqxr-BBWy-GBuPmyzzaSER6CaJFRIR2FevzV0OZs,2249
|
|
87
|
+
openapi_fal_rest/models/comfy_workflow_schema.py,sha256=SW8XYfYCZ0GUq5bOaxSeDrBh0cS-uA1jBajYV1mdj08,4586
|
|
88
|
+
openapi_fal_rest/models/comfy_workflow_schema_extra_data.py,sha256=DImMZQEmwPl3VTyZUK_dGIjwbhiQYYTbTizU3QB3LN8,1242
|
|
89
|
+
openapi_fal_rest/models/comfy_workflow_schema_fal_inputs.py,sha256=ZbM4bR77-Bzknwz6NBHSk0F3-oYAX8lxJ5dn1qUABKw,1242
|
|
90
|
+
openapi_fal_rest/models/comfy_workflow_schema_fal_inputs_dev_info.py,sha256=2n_NQZD5HfNa7-FPhoxGbrgCj5BbmYSZAPioGg35PWM,1283
|
|
91
|
+
openapi_fal_rest/models/comfy_workflow_schema_prompt.py,sha256=akFEhmHHaLiC3dJJcePKpnWF7G_G00ugl13lHVkRsGw,1224
|
|
92
|
+
openapi_fal_rest/models/current_user.py,sha256=MjEnWZGBs2TjyjeDOJ9QFF06phLxYcX50psEi86w7qY,4044
|
|
93
|
+
openapi_fal_rest/models/customer_details.py,sha256=dxo1c6Eh5Sht5cFxtWIzh52PYEF5N7_hpxaqiC7KhrE,4073
|
|
80
94
|
openapi_fal_rest/models/hash_check.py,sha256=T9R7n4EdadCxbFUZvresZZFPYwDfyJMZVNxY6wIJEE8,1352
|
|
81
95
|
openapi_fal_rest/models/http_validation_error.py,sha256=2nhqlv8RX2qp6VR7hb8-SKtzJWXSZ0J95ThW9J4agJo,2131
|
|
82
|
-
openapi_fal_rest/models/lock_reason.py,sha256=
|
|
96
|
+
openapi_fal_rest/models/lock_reason.py,sha256=f3m_JdFhY4pmSyYH9tL4fJmpzIzGIikLlOoc32wdLgk,846
|
|
97
|
+
openapi_fal_rest/models/page_comfy_workflow_item.py,sha256=kw6mYOcLkMv5MdfKme7IXzuhYmSlmwIIzmBJ3zD1grs,2877
|
|
83
98
|
openapi_fal_rest/models/page_workflow_item.py,sha256=5DCUMQ2b8LAH8So6nQJW8mhlxZbedM4ixAJqbf-KZNE,2812
|
|
99
|
+
openapi_fal_rest/models/team_role.py,sha256=SY1MjPLsXeLE7nb6Zz9MzKucSLbO8fQVhugY7mjEvWg,185
|
|
100
|
+
openapi_fal_rest/models/typed_comfy_workflow.py,sha256=2UmQnZneQI0za4mwQSw4luzMseYyvdK5XtIBIQUtxj0,2170
|
|
101
|
+
openapi_fal_rest/models/typed_comfy_workflow_update.py,sha256=6ym6WKSvqxeiUnVhUX9JHWiWywe8ZDra7Hy6rJpV96c,2821
|
|
84
102
|
openapi_fal_rest/models/typed_workflow.py,sha256=haE4Sa16s4iea_VNYtVR7cP3A8Z2ja2KNywYJhc6GmQ,2119
|
|
103
|
+
openapi_fal_rest/models/typed_workflow_update.py,sha256=u0omx2jSdf4UaFoio2IIJZuDckYSR4SJYF47zJ3bhPY,2767
|
|
104
|
+
openapi_fal_rest/models/user_member.py,sha256=WrErlZpCsQtLZVOJrdSpcIOqnBfEycig-oZVIu8KGeA,2212
|
|
85
105
|
openapi_fal_rest/models/validation_error.py,sha256=I6tB-HbEOmE0ua27erDX5PX5YUynENv_dgPN3SrwTrQ,2091
|
|
86
|
-
openapi_fal_rest/models/workflow_contents.py,sha256=
|
|
106
|
+
openapi_fal_rest/models/workflow_contents.py,sha256=3n14xb_irIBWBrsbI0X3kKIPj8NNiWI4bwQb9m2sMmY,3542
|
|
107
|
+
openapi_fal_rest/models/workflow_contents_metadata.py,sha256=JNuIQ70mSHASUW4suVbr5Z-WZWzh_l7eQB6QWOT8xI0,1216
|
|
87
108
|
openapi_fal_rest/models/workflow_contents_nodes.py,sha256=mMeQO_DlQZQPSwyGKTNC9eBovFVCVQNFbrB60k7tTtU,1695
|
|
88
109
|
openapi_fal_rest/models/workflow_contents_output.py,sha256=2m4ITxXcQxTt8iiY5bos0QQW_uMYOGAR1xAcm1rzrcI,1206
|
|
89
|
-
openapi_fal_rest/models/workflow_detail.py,sha256=
|
|
90
|
-
openapi_fal_rest/models/
|
|
91
|
-
openapi_fal_rest/models/workflow_item.py,sha256=
|
|
110
|
+
openapi_fal_rest/models/workflow_detail.py,sha256=DrCvgCaZJT-P8Zj48Iza3fF5wEh-Wo7MbGqfP7k33QM,2877
|
|
111
|
+
openapi_fal_rest/models/workflow_detail_contents.py,sha256=Dy2bxIuh4Sls30oRggbMA4QBnF-toWh_lJLu9mC-hkA,1206
|
|
112
|
+
openapi_fal_rest/models/workflow_item.py,sha256=fUCx9lM0USogxwn-ymxXt1uKakNxjGsSEcM04GXbYps,2584
|
|
92
113
|
openapi_fal_rest/models/workflow_node.py,sha256=DZ3i-auxvm2cWFTBE52YSoLOEIVFvLPW9MyzyR91e78,1797
|
|
93
114
|
openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRiPyAthdBLlioLH8Zw,161
|
|
94
115
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
95
116
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
96
117
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
97
|
-
fal-1.
|
|
98
|
-
fal-1.
|
|
99
|
-
fal-1.
|
|
100
|
-
fal-1.
|
|
101
|
-
fal-1.
|
|
118
|
+
fal-1.1.1.dist-info/METADATA,sha256=oygGKONaPZI7r2VFFwKzOyGfV2ljvWwFchw2Tz5UG3E,3777
|
|
119
|
+
fal-1.1.1.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
|
120
|
+
fal-1.1.1.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
121
|
+
fal-1.1.1.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
122
|
+
fal-1.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from typing import Any, Dict, Optional, Union
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from ... import errors
|
|
7
|
+
from ...client import Client
|
|
8
|
+
from ...models.comfy_workflow_detail import ComfyWorkflowDetail
|
|
9
|
+
from ...models.http_validation_error import HTTPValidationError
|
|
10
|
+
from ...models.typed_comfy_workflow import TypedComfyWorkflow
|
|
11
|
+
from ...types import Response
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _get_kwargs(
|
|
15
|
+
*,
|
|
16
|
+
client: Client,
|
|
17
|
+
json_body: TypedComfyWorkflow,
|
|
18
|
+
) -> Dict[str, Any]:
|
|
19
|
+
url = "{}/comfy/".format(client.base_url)
|
|
20
|
+
|
|
21
|
+
headers: Dict[str, str] = client.get_headers()
|
|
22
|
+
cookies: Dict[str, Any] = client.get_cookies()
|
|
23
|
+
|
|
24
|
+
json_json_body = json_body.to_dict()
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
"method": "post",
|
|
28
|
+
"url": url,
|
|
29
|
+
"headers": headers,
|
|
30
|
+
"cookies": cookies,
|
|
31
|
+
"timeout": client.get_timeout(),
|
|
32
|
+
"follow_redirects": client.follow_redirects,
|
|
33
|
+
"json": json_json_body,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _parse_response(
|
|
38
|
+
*, client: Client, response: httpx.Response
|
|
39
|
+
) -> Optional[Union[ComfyWorkflowDetail, HTTPValidationError]]:
|
|
40
|
+
if response.status_code == HTTPStatus.CREATED:
|
|
41
|
+
response_201 = ComfyWorkflowDetail.from_dict(response.json())
|
|
42
|
+
|
|
43
|
+
return response_201
|
|
44
|
+
if response.status_code == HTTPStatus.UNPROCESSABLE_ENTITY:
|
|
45
|
+
response_422 = HTTPValidationError.from_dict(response.json())
|
|
46
|
+
|
|
47
|
+
return response_422
|
|
48
|
+
if client.raise_on_unexpected_status:
|
|
49
|
+
raise errors.UnexpectedStatus(response.status_code, response.content)
|
|
50
|
+
else:
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _build_response(
|
|
55
|
+
*, client: Client, response: httpx.Response
|
|
56
|
+
) -> Response[Union[ComfyWorkflowDetail, HTTPValidationError]]:
|
|
57
|
+
return Response(
|
|
58
|
+
status_code=HTTPStatus(response.status_code),
|
|
59
|
+
content=response.content,
|
|
60
|
+
headers=response.headers,
|
|
61
|
+
parsed=_parse_response(client=client, response=response),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def sync_detailed(
|
|
66
|
+
*,
|
|
67
|
+
client: Client,
|
|
68
|
+
json_body: TypedComfyWorkflow,
|
|
69
|
+
) -> Response[Union[ComfyWorkflowDetail, HTTPValidationError]]:
|
|
70
|
+
"""Create Workflow
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
json_body (TypedComfyWorkflow):
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
77
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Response[Union[ComfyWorkflowDetail, HTTPValidationError]]
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
kwargs = _get_kwargs(
|
|
84
|
+
client=client,
|
|
85
|
+
json_body=json_body,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
response = httpx.request(
|
|
89
|
+
verify=client.verify_ssl,
|
|
90
|
+
**kwargs,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
return _build_response(client=client, response=response)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def sync(
|
|
97
|
+
*,
|
|
98
|
+
client: Client,
|
|
99
|
+
json_body: TypedComfyWorkflow,
|
|
100
|
+
) -> Optional[Union[ComfyWorkflowDetail, HTTPValidationError]]:
|
|
101
|
+
"""Create Workflow
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
json_body (TypedComfyWorkflow):
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
108
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Union[ComfyWorkflowDetail, HTTPValidationError]
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
return sync_detailed(
|
|
115
|
+
client=client,
|
|
116
|
+
json_body=json_body,
|
|
117
|
+
).parsed
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
async def asyncio_detailed(
|
|
121
|
+
*,
|
|
122
|
+
client: Client,
|
|
123
|
+
json_body: TypedComfyWorkflow,
|
|
124
|
+
) -> Response[Union[ComfyWorkflowDetail, HTTPValidationError]]:
|
|
125
|
+
"""Create Workflow
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
json_body (TypedComfyWorkflow):
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
132
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Response[Union[ComfyWorkflowDetail, HTTPValidationError]]
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
kwargs = _get_kwargs(
|
|
139
|
+
client=client,
|
|
140
|
+
json_body=json_body,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
async with httpx.AsyncClient(verify=client.verify_ssl) as _client:
|
|
144
|
+
response = await _client.request(**kwargs)
|
|
145
|
+
|
|
146
|
+
return _build_response(client=client, response=response)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
async def asyncio(
|
|
150
|
+
*,
|
|
151
|
+
client: Client,
|
|
152
|
+
json_body: TypedComfyWorkflow,
|
|
153
|
+
) -> Optional[Union[ComfyWorkflowDetail, HTTPValidationError]]:
|
|
154
|
+
"""Create Workflow
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
json_body (TypedComfyWorkflow):
|
|
158
|
+
|
|
159
|
+
Raises:
|
|
160
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
161
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
Union[ComfyWorkflowDetail, HTTPValidationError]
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
await asyncio_detailed(
|
|
169
|
+
client=client,
|
|
170
|
+
json_body=json_body,
|
|
171
|
+
)
|
|
172
|
+
).parsed
|