fal 1.39.2__py3-none-any.whl → 1.40.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/app.py +1 -1
- fal/auth/__init__.py +9 -0
- fal/cli/main.py +2 -0
- fal/cli/queue.py +101 -0
- fal/logging/__init__.py +0 -2
- fal/toolkit/file/providers/fal.py +12 -0
- {fal-1.39.2.dist-info → fal-1.40.1.dist-info}/METADATA +1 -1
- {fal-1.39.2.dist-info → fal-1.40.1.dist-info}/RECORD +12 -12
- fal/logging/user.py +0 -25
- {fal-1.39.2.dist-info → fal-1.40.1.dist-info}/WHEEL +0 -0
- {fal-1.39.2.dist-info → fal-1.40.1.dist-info}/entry_points.txt +0 -0
- {fal-1.39.2.dist-info → fal-1.40.1.dist-info}/top_level.txt +0 -0
fal/_fal_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.40.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 40, 1)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
fal/app.py
CHANGED
|
@@ -300,7 +300,7 @@ def _print_python_packages() -> None:
|
|
|
300
300
|
class App(BaseServable):
|
|
301
301
|
requirements: ClassVar[list[str]] = []
|
|
302
302
|
local_python_modules: ClassVar[list[str]] = []
|
|
303
|
-
machine_type: ClassVar[str] = "S"
|
|
303
|
+
machine_type: ClassVar[str | list[str]] = "S"
|
|
304
304
|
num_gpus: ClassVar[int | None] = None
|
|
305
305
|
host_kwargs: ClassVar[dict[str, Any]] = {
|
|
306
306
|
"_scheduler": "nomad",
|
fal/auth/__init__.py
CHANGED
|
@@ -17,6 +17,15 @@ class GoogleColabState:
|
|
|
17
17
|
self.lock = Lock()
|
|
18
18
|
self.secret: Optional[str] = None
|
|
19
19
|
|
|
20
|
+
def __getstate__(self):
|
|
21
|
+
state = self.__dict__.copy()
|
|
22
|
+
state["lock"] = None # type: ignore
|
|
23
|
+
return state
|
|
24
|
+
|
|
25
|
+
def __setstate__(self, state):
|
|
26
|
+
self.__dict__.update(state)
|
|
27
|
+
self.lock = Lock()
|
|
28
|
+
|
|
20
29
|
|
|
21
30
|
_colab_state = GoogleColabState()
|
|
22
31
|
|
fal/cli/main.py
CHANGED
fal/cli/queue.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from http import HTTPStatus
|
|
5
|
+
|
|
6
|
+
import httpx
|
|
7
|
+
|
|
8
|
+
from fal.rest_client import REST_CLIENT
|
|
9
|
+
|
|
10
|
+
from .parser import FalClientParser, get_output_parser
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _queue_size(args):
|
|
14
|
+
from .deploy import _get_user
|
|
15
|
+
|
|
16
|
+
user = _get_user()
|
|
17
|
+
|
|
18
|
+
url = f"{REST_CLIENT.base_url}/applications/{user.username}/{args.app_name}/queue"
|
|
19
|
+
headers = REST_CLIENT.get_headers()
|
|
20
|
+
|
|
21
|
+
with httpx.Client(base_url=REST_CLIENT.base_url, headers=headers, timeout=300) as c:
|
|
22
|
+
resp = c.get(url)
|
|
23
|
+
|
|
24
|
+
if resp.status_code != HTTPStatus.OK:
|
|
25
|
+
try:
|
|
26
|
+
detail = resp.json().get("detail", resp.text)
|
|
27
|
+
except Exception:
|
|
28
|
+
detail = resp.text
|
|
29
|
+
raise RuntimeError(f"Failed to get queue size: {detail}")
|
|
30
|
+
|
|
31
|
+
data = resp.json()
|
|
32
|
+
size = data.get("size", 0)
|
|
33
|
+
|
|
34
|
+
if args.output == "json":
|
|
35
|
+
args.console.print(json.dumps({"size": size}))
|
|
36
|
+
else:
|
|
37
|
+
args.console.print(f"Queue size: {size}")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _queue_flush(args):
|
|
41
|
+
from .deploy import _get_user
|
|
42
|
+
|
|
43
|
+
user = _get_user()
|
|
44
|
+
|
|
45
|
+
url = f"{REST_CLIENT.base_url}/applications/{user.username}/{args.app_name}/queue"
|
|
46
|
+
headers = REST_CLIENT.get_headers()
|
|
47
|
+
|
|
48
|
+
with httpx.Client(base_url=REST_CLIENT.base_url, headers=headers, timeout=300) as c:
|
|
49
|
+
resp = c.delete(url)
|
|
50
|
+
|
|
51
|
+
if resp.status_code != HTTPStatus.OK:
|
|
52
|
+
try:
|
|
53
|
+
detail = resp.json().get("detail", resp.text)
|
|
54
|
+
except Exception:
|
|
55
|
+
detail = resp.text
|
|
56
|
+
raise RuntimeError(f"Failed to flush queue: {detail}")
|
|
57
|
+
|
|
58
|
+
args.console.print("Queue flushed successfully.")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def add_parser(main_subparsers, parents):
|
|
62
|
+
queue_help = "Manage application queues."
|
|
63
|
+
parser = main_subparsers.add_parser(
|
|
64
|
+
"queue",
|
|
65
|
+
description=queue_help,
|
|
66
|
+
help=queue_help,
|
|
67
|
+
parents=parents,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
subparsers = parser.add_subparsers(
|
|
71
|
+
title="Commands",
|
|
72
|
+
metavar="command",
|
|
73
|
+
required=True,
|
|
74
|
+
parser_class=FalClientParser,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
size_help = "Get queue size for an application."
|
|
78
|
+
size_parser = subparsers.add_parser(
|
|
79
|
+
"size",
|
|
80
|
+
description=size_help,
|
|
81
|
+
help=size_help,
|
|
82
|
+
parents=[*parents, get_output_parser()],
|
|
83
|
+
)
|
|
84
|
+
size_parser.add_argument(
|
|
85
|
+
"app_name",
|
|
86
|
+
help="Application name (do not prefix with owner).",
|
|
87
|
+
)
|
|
88
|
+
size_parser.set_defaults(func=_queue_size)
|
|
89
|
+
|
|
90
|
+
flush_help = "Flush all pending requests in an application queue."
|
|
91
|
+
flush_parser = subparsers.add_parser(
|
|
92
|
+
"flush",
|
|
93
|
+
description=flush_help,
|
|
94
|
+
help=flush_help,
|
|
95
|
+
parents=parents,
|
|
96
|
+
)
|
|
97
|
+
flush_parser.add_argument(
|
|
98
|
+
"app_name",
|
|
99
|
+
help="Application name.",
|
|
100
|
+
)
|
|
101
|
+
flush_parser.set_defaults(func=_queue_flush)
|
fal/logging/__init__.py
CHANGED
|
@@ -6,7 +6,6 @@ import structlog
|
|
|
6
6
|
from structlog.typing import EventDict, WrappedLogger
|
|
7
7
|
|
|
8
8
|
from .style import LEVEL_STYLES
|
|
9
|
-
from .user import AddUserIdProcessor
|
|
10
9
|
|
|
11
10
|
# Unfortunately structlog console processor does not support
|
|
12
11
|
# more general theming as a public API. Consider a PR on the
|
|
@@ -43,7 +42,6 @@ structlog.configure(
|
|
|
43
42
|
structlog.stdlib.PositionalArgumentsFormatter(),
|
|
44
43
|
structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S"),
|
|
45
44
|
structlog.processors.StackInfoRenderer(),
|
|
46
|
-
AddUserIdProcessor(),
|
|
47
45
|
_console_log_output,
|
|
48
46
|
],
|
|
49
47
|
wrapper_class=structlog.stdlib.BoundLogger,
|
|
@@ -159,6 +159,18 @@ class FalV2TokenManager:
|
|
|
159
159
|
expires_at=datetime.fromisoformat(result["expires_at"]),
|
|
160
160
|
)
|
|
161
161
|
|
|
162
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
163
|
+
state = self.__dict__.copy()
|
|
164
|
+
# Remove the lock from the state dictionary
|
|
165
|
+
del state["_lock"]
|
|
166
|
+
return state
|
|
167
|
+
|
|
168
|
+
def __setstate__(self, state: dict[str, Any]) -> None:
|
|
169
|
+
# Restore the instance attributes
|
|
170
|
+
self.__dict__.update(state)
|
|
171
|
+
# Recreate the lock
|
|
172
|
+
self._lock = threading.Lock()
|
|
173
|
+
|
|
162
174
|
|
|
163
175
|
class FalV3TokenManager(FalV2TokenManager):
|
|
164
176
|
token_cls: type[FalV2Token] = FalV3Token
|
|
@@ -1,10 +1,10 @@
|
|
|
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=XulopT_VgT2mWr-TUuH1VMduLqKc7_3J0NxfyFwMu44,706
|
|
4
4
|
fal/_serialization.py,sha256=npXNsFJ5G7jzBeBIyVMH01Ww34mGY4XWhHpRbSrTtnQ,7598
|
|
5
5
|
fal/_version.py,sha256=1BbTFnucNC_6ldKJ_ZoC722_UkW4S9aDBSW9L0fkKAw,2315
|
|
6
6
|
fal/api.py,sha256=U_TBUBhkIvA5wFVOeqQejk-8Yxhy4pgWY4DLoelWxjU,49369
|
|
7
|
-
fal/app.py,sha256=
|
|
7
|
+
fal/app.py,sha256=V4aBmtRpn7ysiuoX2ojSu4FyJ-T6ee14koIJ1VSQ0Dw,25990
|
|
8
8
|
fal/apps.py,sha256=pzCd2mrKl5J_4oVc40_pggvPtFahXBCdrZXWpnaEJVs,12130
|
|
9
9
|
fal/config.py,sha256=1HRaOJFOAjB7fbQoEPCSH85gMvEEMIMPeupVWgrHVgU,3572
|
|
10
10
|
fal/container.py,sha256=FTsa5hOW4ars-yV1lUoc0BNeIIvAZcpw7Ftyt3A4m_w,2000
|
|
@@ -17,7 +17,7 @@ fal/sdk.py,sha256=iKpyL4RrWCdaFMK4wiIM3zOuM2H0VsN0wv8wF9OBxHM,28099
|
|
|
17
17
|
fal/sync.py,sha256=ZuIJA2-hTPNANG9B_NNJZUsO68EIdTH0dc9MzeVE2VU,4340
|
|
18
18
|
fal/utils.py,sha256=iQTBG3-i6JZgHkkwbY_I4210g0xoW-as51yrke608u0,2208
|
|
19
19
|
fal/workflows.py,sha256=Zl4f6Bs085hY40zmqScxDUyCu7zXkukDbW02iYOLTTI,14805
|
|
20
|
-
fal/auth/__init__.py,sha256=
|
|
20
|
+
fal/auth/__init__.py,sha256=mtyQou8DGHC-COjW9WbtRyyzjyt7fMlhVmsB4U-CBh4,6509
|
|
21
21
|
fal/auth/auth0.py,sha256=g5OgEKe4rsbkLQp6l7EauOAVL6WsmKjuA1wmzmyvvhc,5354
|
|
22
22
|
fal/auth/local.py,sha256=sndkM6vKpeVny6NHTacVlTbiIFqaksOmw0Viqs_RN1U,1790
|
|
23
23
|
fal/cli/__init__.py,sha256=padK4o0BFqq61kxAA1qQ0jYr2SuhA2mf90B3AaRkmJA,37
|
|
@@ -32,9 +32,10 @@ fal/cli/deploy.py,sha256=aezafp-g8vvLoARl1i84uGd-zIR1TtlSKi9E0dm-Z7E,8703
|
|
|
32
32
|
fal/cli/doctor.py,sha256=8SZrYG9Ku0F6LLUHtFdKopdIgZfFkw5E3Mwrxa9KOSk,1613
|
|
33
33
|
fal/cli/files.py,sha256=-j0q4g53A7CWSczGLdfeUCTSd4zXoV3pfZFdman7JOw,3450
|
|
34
34
|
fal/cli/keys.py,sha256=iQVMr3WT8CUqSQT3qeCCiy6rRwoux9F-UEaC4bCwMWo,3754
|
|
35
|
-
fal/cli/main.py,sha256=
|
|
35
|
+
fal/cli/main.py,sha256=LDy3gze9TRsvGa4uSNc8NMFmWMLpsyoC-msteICNiso,3371
|
|
36
36
|
fal/cli/parser.py,sha256=PZi5MWS4Z-3YSPe6np_F87ay4kF6gaYxlP0avByPr-0,5222
|
|
37
37
|
fal/cli/profile.py,sha256=PAY_ffifCT71VJ8VxfDVaXPT0U1oN8drvWZDFRXwvek,6678
|
|
38
|
+
fal/cli/queue.py,sha256=9Kid3zR6VOFfAdDgnqi2TNN4ocIv5Vs61ASEZnwMa9o,2713
|
|
38
39
|
fal/cli/run.py,sha256=nAC12Qss4Fg1XmV0qOS9RdGNLYcdoHeRgQMvbTN4P9I,1202
|
|
39
40
|
fal/cli/runners.py,sha256=AXUB2pq9Ot0VU2cOeJydSgmgTlUm4i6iNgJOClO7ZZw,6533
|
|
40
41
|
fal/cli/secrets.py,sha256=HfIeO2IZpCEiBC6Cs5Kpi3zckfDnc7GsLwLdgj3NnPU,3085
|
|
@@ -46,11 +47,10 @@ fal/exceptions/__init__.py,sha256=m2okJEpax11mnwmoqO_pCGtbt-FvzKiiuMhKo2ok-_8,27
|
|
|
46
47
|
fal/exceptions/_base.py,sha256=LwzpMaW_eYQEC5s26h2qGXbNA-S4bOqC8s-bMCX6HjE,1491
|
|
47
48
|
fal/exceptions/_cuda.py,sha256=L3qvDNaPTthp95IFSBI6pMt3YbRfn1H0inQkj_7NKF8,1719
|
|
48
49
|
fal/exceptions/auth.py,sha256=fHea3SIeguInJVB5M33IuP4I5e_pVEifck1C_XJTYvc,351
|
|
49
|
-
fal/logging/__init__.py,sha256=
|
|
50
|
+
fal/logging/__init__.py,sha256=U7DhMpnNqmVdC2XCT5xZkNmYhpL0Q85iDYPeSo_56LU,1532
|
|
50
51
|
fal/logging/isolate.py,sha256=jIryi46ZVlJ1mfan4HLNQQ3jwMi8z-WwfqqLlttQVkc,2449
|
|
51
52
|
fal/logging/style.py,sha256=ckIgHzvF4DShM5kQh8F133X53z_vF46snuDHVmo_h9g,386
|
|
52
53
|
fal/logging/trace.py,sha256=OhzB6d4rQZimBc18WFLqH_9BGfqFFumKKTAGSsmWRMg,1904
|
|
53
|
-
fal/logging/user.py,sha256=H7Pg-nqhpzsUb5f6uXyZUeLWAsr3oImQEaYSCIIAlqo,818
|
|
54
54
|
fal/toolkit/__init__.py,sha256=GR5KxAsNODlhs-DTarJcb5raujActubn0afR7FPueWs,886
|
|
55
55
|
fal/toolkit/exceptions.py,sha256=8-EMuqDXEofPu-eVoWowc7WEM-ifusithyv6tnsm2MM,301
|
|
56
56
|
fal/toolkit/kv.py,sha256=5kMk-I5PMRORK4TYc0jqqowjqKkbk7zUIgz9rAIztxE,2364
|
|
@@ -61,7 +61,7 @@ fal/toolkit/audio/audio.py,sha256=gt458h989iQ-EhQSH-mCuJuPBY4RneLJE05f_QWU1E0,57
|
|
|
61
61
|
fal/toolkit/file/__init__.py,sha256=FbNl6wD-P0aSSTUwzHt4HujBXrbC3ABmaigPQA4hRfg,70
|
|
62
62
|
fal/toolkit/file/file.py,sha256=_KCKmtmBkBIKD_gFOZALV10dCtOFZTC9MQw2qmdeevw,11013
|
|
63
63
|
fal/toolkit/file/types.py,sha256=MMAH_AyLOhowQPesOv1V25wB4qgbJ3vYNlnTPbdSv1M,2304
|
|
64
|
-
fal/toolkit/file/providers/fal.py,sha256=
|
|
64
|
+
fal/toolkit/file/providers/fal.py,sha256=P9hm11uKVe6ilmL7CjFztBHswZEHOm4k-K4B36UZe6M,47543
|
|
65
65
|
fal/toolkit/file/providers/gcp.py,sha256=DKeZpm1MjwbvEsYvkdXUtuLIJDr_UNbqXj_Mfv3NTeo,2437
|
|
66
66
|
fal/toolkit/file/providers/r2.py,sha256=YqnYkkAo_ZKIa-xoSuDnnidUFwJWHdziAR34PE6irdI,3061
|
|
67
67
|
fal/toolkit/file/providers/s3.py,sha256=EI45T54Mox7lHZKROss_O8o0DIn3CHP9k1iaNYVrxvg,2714
|
|
@@ -143,8 +143,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
143
143
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
144
144
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
145
145
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
146
|
-
fal-1.
|
|
147
|
-
fal-1.
|
|
148
|
-
fal-1.
|
|
149
|
-
fal-1.
|
|
150
|
-
fal-1.
|
|
146
|
+
fal-1.40.1.dist-info/METADATA,sha256=JyaMRBK_S1vsn84l7jgkGVST0XHgPRdRtMXTu0puPPY,4132
|
|
147
|
+
fal-1.40.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
148
|
+
fal-1.40.1.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
149
|
+
fal-1.40.1.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
150
|
+
fal-1.40.1.dist-info/RECORD,,
|
fal/logging/user.py
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from structlog.typing import EventDict, WrappedLogger
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class AddUserIdProcessor:
|
|
7
|
-
def __init__(self):
|
|
8
|
-
from fal.auth import UserAccess
|
|
9
|
-
|
|
10
|
-
self.user_access = UserAccess()
|
|
11
|
-
|
|
12
|
-
def __call__(
|
|
13
|
-
self, logger: WrappedLogger, method_name: str, event_dict: EventDict
|
|
14
|
-
) -> EventDict:
|
|
15
|
-
"""The structlog processor that sends the logged user id on every log"""
|
|
16
|
-
user_id: str | None = None
|
|
17
|
-
try:
|
|
18
|
-
user_id = self.user_access.info.get("sub")
|
|
19
|
-
except Exception:
|
|
20
|
-
# logs are fail-safe, so any exception is safe to ignore
|
|
21
|
-
# this is expected to happen only when user is logged out
|
|
22
|
-
# or there's no internet connection
|
|
23
|
-
pass
|
|
24
|
-
event_dict["usr.id"] = user_id
|
|
25
|
-
return event_dict
|
|
File without changes
|
|
File without changes
|
|
File without changes
|