fal 1.4.1__py3-none-any.whl → 1.5.0__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 +11 -0
- fal/app.py +7 -1
- fal/cli/_utils.py +2 -1
- fal/cli/deploy.py +13 -5
- fal/cli/run.py +1 -1
- fal/sdk.py +3 -0
- {fal-1.4.1.dist-info → fal-1.5.0.dist-info}/METADATA +2 -2
- {fal-1.4.1.dist-info → fal-1.5.0.dist-info}/RECORD +12 -12
- {fal-1.4.1.dist-info → fal-1.5.0.dist-info}/WHEEL +0 -0
- {fal-1.4.1.dist-info → fal-1.5.0.dist-info}/entry_points.txt +0 -0
- {fal-1.4.1.dist-info → fal-1.5.0.dist-info}/top_level.txt +0 -0
fal/_fal_version.py
CHANGED
fal/api.py
CHANGED
|
@@ -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,
|
fal/app.py
CHANGED
|
@@ -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."""
|
fal/cli/_utils.py
CHANGED
|
@@ -34,5 +34,6 @@ def get_app_data_from_toml(app_name):
|
|
|
34
34
|
app_ref = str(project_root / app_ref)
|
|
35
35
|
|
|
36
36
|
app_auth = app_data.get("auth", "private")
|
|
37
|
+
app_deployment_strategy = app_data.get("deployment_strategy", "recreate")
|
|
37
38
|
|
|
38
|
-
return app_ref, app_auth
|
|
39
|
+
return app_ref, app_auth, app_deployment_strategy
|
fal/cli/deploy.py
CHANGED
|
@@ -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):
|
fal/cli/run.py
CHANGED
|
@@ -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
|
fal/sdk.py
CHANGED
|
@@ -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
|
|
@@ -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,17 +1,17 @@
|
|
|
1
1
|
fal/__init__.py,sha256=wXs1G0gSc7ZK60-bHe-B2m0l_sA6TrFk4BxY0tMoLe8,784
|
|
2
2
|
fal/__main__.py,sha256=4JMK66Wj4uLZTKbF-sT3LAxOsr6buig77PmOkJCRRxw,83
|
|
3
|
-
fal/_fal_version.py,sha256=
|
|
3
|
+
fal/_fal_version.py,sha256=OYzqgMEgfFG0au4hzbEdgYI-c7Hxo3wdBtrpEjK1RoY,411
|
|
4
4
|
fal/_serialization.py,sha256=rD2YiSa8iuzCaZohZwN_MPEB-PpSKbWRDeaIDpTEjyY,7653
|
|
5
5
|
fal/_version.py,sha256=EBGqrknaf1WygENX-H4fBefLvHryvJBBGtVJetaB0NY,266
|
|
6
|
-
fal/api.py,sha256=
|
|
7
|
-
fal/app.py,sha256=
|
|
6
|
+
fal/api.py,sha256=echMD8k9HxAKk1ShtnBsaNf87_K2JdrTB-Bd9V1bPys,42998
|
|
7
|
+
fal/app.py,sha256=OdF2y30i5gp7ZXPWW32Oinzq6nKCeHesvtHeRq7XWUw,17938
|
|
8
8
|
fal/apps.py,sha256=lge7-HITzI20l1oXdlkAzqxdMVtXRfnACIylKRWgCNQ,7151
|
|
9
9
|
fal/container.py,sha256=V7riyyq8AZGwEX9QaqRQDZyDN_bUKeRKV1OOZArXjL0,622
|
|
10
10
|
fal/files.py,sha256=QgfYfMKmNobMPufrAP_ga1FKcIAlSbw18Iar1-0qepo,2650
|
|
11
11
|
fal/flags.py,sha256=oWN_eidSUOcE9wdPK_77si3A1fpgOC0UEERPsvNLIMc,842
|
|
12
12
|
fal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
fal/rest_client.py,sha256=kGBGmuyHfX1lR910EoKCYPjsyU8MdXawT_cW2q8Sajc,568
|
|
14
|
-
fal/sdk.py,sha256
|
|
14
|
+
fal/sdk.py,sha256=-I-vjO-PuvtnZedFLKys8FpQVsRwEzTPD6heRYPQCE4,22260
|
|
15
15
|
fal/sync.py,sha256=ZuIJA2-hTPNANG9B_NNJZUsO68EIdTH0dc9MzeVE2VU,4340
|
|
16
16
|
fal/utils.py,sha256=9q_QrQBlQN3nZYA1kEGRfhJWi4RjnO4H1uQswfaei9w,2146
|
|
17
17
|
fal/workflows.py,sha256=jx3tGy2R7cN6lLvOzT6lhhlcjmiq64iZls2smVrmQj0,14657
|
|
@@ -19,17 +19,17 @@ fal/auth/__init__.py,sha256=r8iA2-5ih7-Fik3gEC4HEWNFbGoxpYnXpZu1icPIoS0,3561
|
|
|
19
19
|
fal/auth/auth0.py,sha256=rSG1mgH-QGyKfzd7XyAaj1AYsWt-ho8Y_LZ-FUVWzh4,5421
|
|
20
20
|
fal/auth/local.py,sha256=sndkM6vKpeVny6NHTacVlTbiIFqaksOmw0Viqs_RN1U,1790
|
|
21
21
|
fal/cli/__init__.py,sha256=padK4o0BFqq61kxAA1qQ0jYr2SuhA2mf90B3AaRkmJA,37
|
|
22
|
-
fal/cli/_utils.py,sha256=
|
|
22
|
+
fal/cli/_utils.py,sha256=u__PSeNxSC_4Psi3ZwLjefgNQVkYRpVH--vmwK7ppro,1187
|
|
23
23
|
fal/cli/apps.py,sha256=-DDp-Gvxz5kHho5YjAhbri8vOny_9cftAI_wP2KR5nU,8175
|
|
24
24
|
fal/cli/auth.py,sha256=--MhfHGwxmtHbRkGioyn1prKn_U-pBzbz0G_QeZou-U,1352
|
|
25
25
|
fal/cli/create.py,sha256=a8WDq-nJLFTeoIXqpb5cr7GR7YR9ZZrQCawNm34KXXE,627
|
|
26
26
|
fal/cli/debug.py,sha256=u_urnyFzSlNnrq93zz_GXE9FX4VyVxDoamJJyrZpFI0,1312
|
|
27
|
-
fal/cli/deploy.py,sha256=
|
|
27
|
+
fal/cli/deploy.py,sha256=uAMBMXpv3kYNJ3zeIWBL6xf83NpxvvPKOjeE95dOG5o,7099
|
|
28
28
|
fal/cli/doctor.py,sha256=U4ne9LX5gQwNblsYQ27XdO8AYDgbYjTO39EtxhwexRM,983
|
|
29
29
|
fal/cli/keys.py,sha256=trDpA3LJu9S27qE_K8Hr6fKLK4vwVzbxUHq8TFrV4pw,3157
|
|
30
30
|
fal/cli/main.py,sha256=_Wh_DQc02qwh-ZN7v41lZm0lDR1WseViXVOcqUlyWLg,2009
|
|
31
31
|
fal/cli/parser.py,sha256=edCqFWYAQSOhrxeEK9BtFRlTEUAlG2JUDjS_vhZ_nHE,2868
|
|
32
|
-
fal/cli/run.py,sha256=
|
|
32
|
+
fal/cli/run.py,sha256=J1lSZ_wJIhrygSduMr0Wf2pQ8OUJlFbyH5KKUjxDF6w,1204
|
|
33
33
|
fal/cli/secrets.py,sha256=740msFm7d41HruudlcfqUXlFl53N-WmChsQP9B9M9Po,2572
|
|
34
34
|
fal/console/__init__.py,sha256=ernZ4bzvvliQh5SmrEqQ7lA5eVcbw6Ra2jalKtA7dxg,132
|
|
35
35
|
fal/console/icons.py,sha256=De9MfFaSkO2Lqfne13n3PrYfTXJVIzYZVqYn5BWsdrA,108
|
|
@@ -126,8 +126,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
126
126
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
127
127
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
128
128
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
129
|
-
fal-1.
|
|
130
|
-
fal-1.
|
|
131
|
-
fal-1.
|
|
132
|
-
fal-1.
|
|
133
|
-
fal-1.
|
|
129
|
+
fal-1.5.0.dist-info/METADATA,sha256=T1lxxWWwhCxUkj3PD7Bu7iZc75unccRLj__MMXyW184,3787
|
|
130
|
+
fal-1.5.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
131
|
+
fal-1.5.0.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
132
|
+
fal-1.5.0.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
133
|
+
fal-1.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|