fal 1.0.4__py3-none-any.whl → 1.0.6__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/__init__.py +2 -0
- fal/_fal_version.py +2 -2
- fal/api.py +54 -4
- fal/app.py +5 -1
- fal/container.py +19 -0
- {fal-1.0.4.dist-info → fal-1.0.6.dist-info}/METADATA +4 -4
- {fal-1.0.4.dist-info → fal-1.0.6.dist-info}/RECORD +10 -9
- {fal-1.0.4.dist-info → fal-1.0.6.dist-info}/WHEEL +0 -0
- {fal-1.0.4.dist-info → fal-1.0.6.dist-info}/entry_points.txt +0 -0
- {fal-1.0.4.dist-info → fal-1.0.6.dist-info}/top_level.txt +0 -0
fal/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ from fal import apps # noqa: F401
|
|
|
4
4
|
from fal.api import FalServerlessHost, LocalHost, cached, function
|
|
5
5
|
from fal.api import function as isolated # noqa: F401
|
|
6
6
|
from fal.app import App, endpoint, realtime, wrap_app # noqa: F401
|
|
7
|
+
from fal.container import ContainerImage
|
|
7
8
|
from fal.sdk import FalServerlessKeyCredentials
|
|
8
9
|
from fal.sync import sync_dir
|
|
9
10
|
|
|
@@ -26,4 +27,5 @@ __all__ = [
|
|
|
26
27
|
"sync_dir",
|
|
27
28
|
"__version__",
|
|
28
29
|
"version_tuple",
|
|
30
|
+
"ContainerImage",
|
|
29
31
|
]
|
fal/_fal_version.py
CHANGED
fal/api.py
CHANGED
|
@@ -42,6 +42,7 @@ from typing_extensions import Concatenate, ParamSpec
|
|
|
42
42
|
|
|
43
43
|
import fal.flags as flags
|
|
44
44
|
from fal._serialization import include_modules_from, patch_pickle
|
|
45
|
+
from fal.container import ContainerImage
|
|
45
46
|
from fal.exceptions import FalServerlessException
|
|
46
47
|
from fal.logging.isolate import IsolateLogPrinter
|
|
47
48
|
from fal.sdk import (
|
|
@@ -523,9 +524,12 @@ class Options:
|
|
|
523
524
|
pip_requirements = self.environment.setdefault("requirements", [])
|
|
524
525
|
elif kind == "conda":
|
|
525
526
|
pip_requirements = self.environment.setdefault("pip", [])
|
|
527
|
+
elif kind == "container":
|
|
528
|
+
return None
|
|
526
529
|
else:
|
|
527
530
|
raise FalServerlessError(
|
|
528
|
-
"Only conda
|
|
531
|
+
"Only {conda, virtualenv, container} "
|
|
532
|
+
"are supported as environment options."
|
|
529
533
|
)
|
|
530
534
|
|
|
531
535
|
# Already has these.
|
|
@@ -743,8 +747,55 @@ def function(
|
|
|
743
747
|
_scheduler: str | None = None,
|
|
744
748
|
) -> Callable[
|
|
745
749
|
[Callable[Concatenate[ArgsT], ReturnT]], ServedIsolatedFunction[ArgsT, ReturnT]
|
|
746
|
-
]:
|
|
747
|
-
|
|
750
|
+
]: ...
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
@overload
|
|
754
|
+
def function(
|
|
755
|
+
kind: Literal["container"],
|
|
756
|
+
*,
|
|
757
|
+
image: ContainerImage | None = None,
|
|
758
|
+
# Common options
|
|
759
|
+
host: FalServerlessHost = _DEFAULT_HOST,
|
|
760
|
+
serve: Literal[False] = False,
|
|
761
|
+
exposed_port: int | None = None,
|
|
762
|
+
max_concurrency: int | None = None,
|
|
763
|
+
# FalServerlessHost options
|
|
764
|
+
metadata: dict[str, Any] | None = None,
|
|
765
|
+
machine_type: str = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
|
|
766
|
+
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
767
|
+
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
768
|
+
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
769
|
+
setup_function: Callable[..., None] | None = None,
|
|
770
|
+
_base_image: str | None = None,
|
|
771
|
+
_scheduler: str | None = None,
|
|
772
|
+
) -> Callable[
|
|
773
|
+
[Callable[Concatenate[ArgsT], ReturnT]], IsolatedFunction[ArgsT, ReturnT]
|
|
774
|
+
]: ...
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
@overload
|
|
778
|
+
def function(
|
|
779
|
+
kind: Literal["container"],
|
|
780
|
+
*,
|
|
781
|
+
image: ContainerImage | None = None,
|
|
782
|
+
# Common options
|
|
783
|
+
host: FalServerlessHost = _DEFAULT_HOST,
|
|
784
|
+
serve: Literal[True],
|
|
785
|
+
exposed_port: int | None = None,
|
|
786
|
+
max_concurrency: int | None = None,
|
|
787
|
+
# FalServerlessHost options
|
|
788
|
+
metadata: dict[str, Any] | None = None,
|
|
789
|
+
machine_type: str = FAL_SERVERLESS_DEFAULT_MACHINE_TYPE,
|
|
790
|
+
keep_alive: int = FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
|
|
791
|
+
max_multiplexing: int = FAL_SERVERLESS_DEFAULT_MAX_MULTIPLEXING,
|
|
792
|
+
min_concurrency: int = FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY,
|
|
793
|
+
setup_function: Callable[..., None] | None = None,
|
|
794
|
+
_base_image: str | None = None,
|
|
795
|
+
_scheduler: str | None = None,
|
|
796
|
+
) -> Callable[
|
|
797
|
+
[Callable[Concatenate[ArgsT], ReturnT]], ServedIsolatedFunction[ArgsT, ReturnT]
|
|
798
|
+
]: ...
|
|
748
799
|
|
|
749
800
|
|
|
750
801
|
# implementation
|
|
@@ -1121,4 +1172,3 @@ class Server(uvicorn.Server):
|
|
|
1121
1172
|
|
|
1122
1173
|
def install_signal_handlers(self) -> None:
|
|
1123
1174
|
pass
|
|
1124
|
-
|
fal/app.py
CHANGED
|
@@ -47,8 +47,12 @@ def wrap_app(cls: type[App], **kwargs) -> fal.api.IsolatedFunction:
|
|
|
47
47
|
routes = app.collect_routes()
|
|
48
48
|
realtime_app = any(route.is_websocket for route in routes)
|
|
49
49
|
|
|
50
|
+
kind = cls.host_kwargs.pop("kind", "virtualenv")
|
|
51
|
+
if kind == "container":
|
|
52
|
+
cls.host_kwargs.pop("resolver", None)
|
|
53
|
+
|
|
50
54
|
wrapper = fal.api.function(
|
|
51
|
-
|
|
55
|
+
kind,
|
|
52
56
|
requirements=cls.requirements,
|
|
53
57
|
machine_type=cls.machine_type,
|
|
54
58
|
**cls.host_kwargs,
|
fal/container.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class ContainerImage:
|
|
2
|
+
"""ContainerImage represents a Docker image that can be built
|
|
3
|
+
from a Dockerfile.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
_known_keys = {"dockerfile_str", "build_env", "build_args"}
|
|
7
|
+
|
|
8
|
+
@classmethod
|
|
9
|
+
def from_dockerfile_str(cls, text: str, **kwargs):
|
|
10
|
+
# Check for unknown keys and return them as a dict.
|
|
11
|
+
return dict(
|
|
12
|
+
dockerfile_str=text,
|
|
13
|
+
**{k: v for k, v in kwargs.items() if k in cls._known_keys},
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def from_dockerfile(cls, path: str, **kwargs):
|
|
18
|
+
with open(path) as fobj:
|
|
19
|
+
return cls.from_dockerfile_str(fobj.read(), **kwargs)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fal
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.6
|
|
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
|
-
Requires-Dist: isolate[build] <1.0,>=0.
|
|
9
|
-
Requires-Dist: isolate-proto ==0.
|
|
10
|
-
Requires-Dist: grpcio
|
|
8
|
+
Requires-Dist: isolate[build] <1.14.0,>=0.13.0
|
|
9
|
+
Requires-Dist: isolate-proto ==0.5.1
|
|
10
|
+
Requires-Dist: grpcio ==1.64.0
|
|
11
11
|
Requires-Dist: dill ==0.3.7
|
|
12
12
|
Requires-Dist: cloudpickle ==3.0.0
|
|
13
13
|
Requires-Dist: typing-extensions <5,>=4.7.1
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
fal/__init__.py,sha256=
|
|
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=T17ZEPR5Omt5RLA0TuZWTufRi58PzGIPek75nFcuMQY,411
|
|
4
4
|
fal/_serialization.py,sha256=7urrZXw99qmsK-RkjCurk6Va4TMEfDIMajkzKbSW4j4,7655
|
|
5
5
|
fal/_version.py,sha256=EBGqrknaf1WygENX-H4fBefLvHryvJBBGtVJetaB0NY,266
|
|
6
|
-
fal/api.py,sha256=
|
|
7
|
-
fal/app.py,sha256=
|
|
6
|
+
fal/api.py,sha256=oMf01QjADFjM4b2GInDlLoPd8Brhmmga3Ju1--pWM0M,38088
|
|
7
|
+
fal/app.py,sha256=Sublwqso-gRlJ7oNX00JY8YK0P0WLTrB2c57GQH8Oxw,13946
|
|
8
8
|
fal/apps.py,sha256=UhR6mq8jBiTAp-QvUnvbnMNcuJ5wHIKSqdlfyx8aBQ8,6829
|
|
9
|
+
fal/container.py,sha256=V7riyyq8AZGwEX9QaqRQDZyDN_bUKeRKV1OOZArXjL0,622
|
|
9
10
|
fal/flags.py,sha256=oWN_eidSUOcE9wdPK_77si3A1fpgOC0UEERPsvNLIMc,842
|
|
10
11
|
fal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
12
|
fal/rest_client.py,sha256=kGBGmuyHfX1lR910EoKCYPjsyU8MdXawT_cW2q8Sajc,568
|
|
@@ -92,8 +93,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
92
93
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
93
94
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
94
95
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
95
|
-
fal-1.0.
|
|
96
|
-
fal-1.0.
|
|
97
|
-
fal-1.0.
|
|
98
|
-
fal-1.0.
|
|
99
|
-
fal-1.0.
|
|
96
|
+
fal-1.0.6.dist-info/METADATA,sha256=D7_0K4_OHAcSxC9vDdZvvXiJCnCpuUp_-w-vaPx3L8I,3738
|
|
97
|
+
fal-1.0.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
98
|
+
fal-1.0.6.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
99
|
+
fal-1.0.6.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
100
|
+
fal-1.0.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|