fal 1.22.0__py3-none-any.whl → 1.23.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/container.py +2 -0
- fal/toolkit/exceptions.py +6 -0
- fal/toolkit/kv.py +85 -0
- fal/toolkit/utils/download_utils.py +13 -4
- {fal-1.22.0.dist-info → fal-1.23.1.dist-info}/METADATA +1 -1
- {fal-1.22.0.dist-info → fal-1.23.1.dist-info}/RECORD +10 -9
- {fal-1.22.0.dist-info → fal-1.23.1.dist-info}/WHEEL +0 -0
- {fal-1.22.0.dist-info → fal-1.23.1.dist-info}/entry_points.txt +0 -0
- {fal-1.22.0.dist-info → fal-1.23.1.dist-info}/top_level.txt +0 -0
fal/_fal_version.py
CHANGED
fal/container.py
CHANGED
|
@@ -19,6 +19,7 @@ class ContainerImage:
|
|
|
19
19
|
builder: Optional[Builder] = field(default=None)
|
|
20
20
|
compression: str = DEFAULT_COMPRESSION
|
|
21
21
|
force_compression: bool = DEFAULT_FORCE_COMPRESSION
|
|
22
|
+
secrets: Dict[str, str] = field(default_factory=dict)
|
|
22
23
|
|
|
23
24
|
def __post_init__(self) -> None:
|
|
24
25
|
if self.registries:
|
|
@@ -51,4 +52,5 @@ class ContainerImage:
|
|
|
51
52
|
"builder": self.builder,
|
|
52
53
|
"compression": self.compression,
|
|
53
54
|
"force_compression": self.force_compression,
|
|
55
|
+
"secrets": self.secrets,
|
|
54
56
|
}
|
fal/toolkit/exceptions.py
CHANGED
fal/toolkit/kv.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
from urllib.error import HTTPError
|
|
4
|
+
from urllib.request import Request
|
|
5
|
+
|
|
6
|
+
from fal.toolkit.exceptions import KVStoreException
|
|
7
|
+
from fal.toolkit.file.providers.fal import _maybe_retry_request, fal_v3_token_manager
|
|
8
|
+
|
|
9
|
+
FAL_KV_HOST = "https://kv.fal.media"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class KVStore:
|
|
13
|
+
"""A key-value store client for interacting with the FAL KV service.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
db_name: The name of the database/namespace to use for this KV store.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, db_name: str):
|
|
20
|
+
self.db_name = db_name
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def auth_headers(self) -> Dict[str, str]:
|
|
24
|
+
token = fal_v3_token_manager.get_token()
|
|
25
|
+
return {
|
|
26
|
+
"Authorization": f"{token.token_type} {token.token}",
|
|
27
|
+
"User-Agent": "fal/0.1.0",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
def get(self, key: str) -> Optional[str]:
|
|
31
|
+
"""Retrieve a value from the key-value store.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
key: The key to retrieve the value for.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
The value associated with the key, or None if the key doesn't exist.
|
|
38
|
+
"""
|
|
39
|
+
response = self._send_request(
|
|
40
|
+
method="GET",
|
|
41
|
+
path=f"/get/{self.db_name}/{key}",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
if response is None:
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
return response["value"]
|
|
48
|
+
|
|
49
|
+
def set(self, key: str, value: str) -> None:
|
|
50
|
+
"""Store a value in the key-value store.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
key: The key to store the value under.
|
|
54
|
+
value: The value to store.
|
|
55
|
+
"""
|
|
56
|
+
self._send_request(
|
|
57
|
+
method="PUT",
|
|
58
|
+
path=f"/set/{self.db_name}/{key}",
|
|
59
|
+
data=value.encode(),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def _send_request(
|
|
63
|
+
self,
|
|
64
|
+
method: str,
|
|
65
|
+
path: str,
|
|
66
|
+
data: Optional[bytes] = None,
|
|
67
|
+
) -> Optional[Dict[str, Any]]:
|
|
68
|
+
headers = {
|
|
69
|
+
**self.auth_headers,
|
|
70
|
+
"Accept": "application/json",
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
url = FAL_KV_HOST + path
|
|
74
|
+
request = Request(url, headers=headers, method=method, data=data)
|
|
75
|
+
try:
|
|
76
|
+
with _maybe_retry_request(request) as response:
|
|
77
|
+
result = json.load(response)
|
|
78
|
+
except HTTPError as e:
|
|
79
|
+
if e.status == 404:
|
|
80
|
+
return None
|
|
81
|
+
raise KVStoreException(
|
|
82
|
+
f"Error sending request. Status {e.status}: {e.reason}"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
return result
|
|
@@ -427,13 +427,22 @@ def clone_repository(
|
|
|
427
427
|
if repo_name is None:
|
|
428
428
|
repo_name = Path(https_url).stem
|
|
429
429
|
if commit_hash:
|
|
430
|
+
if len(commit_hash) < 8:
|
|
431
|
+
raise ValueError(f"Commit hash '{commit_hash}' is too short.")
|
|
430
432
|
repo_name += f"-{commit_hash[:8]}"
|
|
431
433
|
|
|
432
434
|
local_repo_path = Path(target_dir) / repo_name # type: ignore[arg-type]
|
|
433
435
|
|
|
434
436
|
if local_repo_path.exists():
|
|
435
|
-
local_repo_commit_hash =
|
|
436
|
-
|
|
437
|
+
local_repo_commit_hash = _git_rev_parse(local_repo_path, "HEAD")
|
|
438
|
+
full_commit_hash = (
|
|
439
|
+
_git_rev_parse(local_repo_path, commit_hash) if commit_hash else None
|
|
440
|
+
)
|
|
441
|
+
if (
|
|
442
|
+
full_commit_hash
|
|
443
|
+
and local_repo_commit_hash == full_commit_hash
|
|
444
|
+
and not force
|
|
445
|
+
):
|
|
437
446
|
if include_to_path:
|
|
438
447
|
__add_local_path_to_sys_path(local_repo_path)
|
|
439
448
|
return local_repo_path
|
|
@@ -516,12 +525,12 @@ def __add_local_path_to_sys_path(local_path: Path | str):
|
|
|
516
525
|
sys.path.insert(0, local_path_str)
|
|
517
526
|
|
|
518
527
|
|
|
519
|
-
def
|
|
528
|
+
def _git_rev_parse(repo_path: Path, ref: str) -> str:
|
|
520
529
|
import subprocess
|
|
521
530
|
|
|
522
531
|
try:
|
|
523
532
|
return subprocess.check_output(
|
|
524
|
-
["git", "rev-parse",
|
|
533
|
+
["git", "rev-parse", ref],
|
|
525
534
|
cwd=repo_path,
|
|
526
535
|
text=True,
|
|
527
536
|
stderr=subprocess.STDOUT,
|
|
@@ -1,13 +1,13 @@
|
|
|
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=-TCybTpn5d1ogABxKp1Mlx4Oiz9LQCNVDc5ZmAiLfyE,513
|
|
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=vTYWeKnNg3japot1vOV_JSk812aeB6a2Y7lC1ed-VmM,47277
|
|
7
7
|
fal/app.py,sha256=pMf7P9iVEcw5HiFCYgSdHkjX6f-1SPe06EOwYH1ImGA,24079
|
|
8
8
|
fal/apps.py,sha256=pzCd2mrKl5J_4oVc40_pggvPtFahXBCdrZXWpnaEJVs,12130
|
|
9
9
|
fal/config.py,sha256=BEMH10B2bfWJ9yNawnLG6v3kBLnLmkhMe201EAODzs4,3124
|
|
10
|
-
fal/container.py,sha256=
|
|
10
|
+
fal/container.py,sha256=FTsa5hOW4ars-yV1lUoc0BNeIIvAZcpw7Ftyt3A4m_w,2000
|
|
11
11
|
fal/files.py,sha256=1eOyrj1M0hTixZdbtQ1ogJqWpLd7UfiOt1Rxihnqh8g,3565
|
|
12
12
|
fal/flags.py,sha256=QonyDM7R2GqfAB1bJr46oriu-fHJCkpUwXuSdanePWg,987
|
|
13
13
|
fal/project.py,sha256=QgfYfMKmNobMPufrAP_ga1FKcIAlSbw18Iar1-0qepo,2650
|
|
@@ -52,7 +52,8 @@ fal/logging/style.py,sha256=ckIgHzvF4DShM5kQh8F133X53z_vF46snuDHVmo_h9g,386
|
|
|
52
52
|
fal/logging/trace.py,sha256=OhzB6d4rQZimBc18WFLqH_9BGfqFFumKKTAGSsmWRMg,1904
|
|
53
53
|
fal/logging/user.py,sha256=H7Pg-nqhpzsUb5f6uXyZUeLWAsr3oImQEaYSCIIAlqo,818
|
|
54
54
|
fal/toolkit/__init__.py,sha256=GR5KxAsNODlhs-DTarJcb5raujActubn0afR7FPueWs,886
|
|
55
|
-
fal/toolkit/exceptions.py,sha256=
|
|
55
|
+
fal/toolkit/exceptions.py,sha256=8-EMuqDXEofPu-eVoWowc7WEM-ifusithyv6tnsm2MM,301
|
|
56
|
+
fal/toolkit/kv.py,sha256=5kMk-I5PMRORK4TYc0jqqowjqKkbk7zUIgz9rAIztxE,2364
|
|
56
57
|
fal/toolkit/optimize.py,sha256=p75sovF0SmRP6zxzpIaaOmqlxvXB_xEz3XPNf59EF7w,1339
|
|
57
58
|
fal/toolkit/types.py,sha256=kkbOsDKj1qPGb1UARTBp7yuJ5JUuyy7XQurYUBCdti8,4064
|
|
58
59
|
fal/toolkit/audio/__init__.py,sha256=sqNVfrKbppWlIGLoFTaaNTxLpVXsFHxOSHLA5VG547A,35
|
|
@@ -73,7 +74,7 @@ fal/toolkit/image/nsfw_filter/inference.py,sha256=BhIPF_zxRLetThQYxDDF0sdx9VRwvu
|
|
|
73
74
|
fal/toolkit/image/nsfw_filter/model.py,sha256=63mu8D15z_IosoRUagRLGHy6VbLqFmrG-yZqnu2vVm4,457
|
|
74
75
|
fal/toolkit/image/nsfw_filter/requirements.txt,sha256=3Pmrd0Ny6QAeBqUNHCgffRyfaCARAPJcfSCX5cRYpbM,37
|
|
75
76
|
fal/toolkit/utils/__init__.py,sha256=CrmM9DyCz5-SmcTzRSm5RaLgxy3kf0ZsSEN9uhnX2Xo,97
|
|
76
|
-
fal/toolkit/utils/download_utils.py,sha256=
|
|
77
|
+
fal/toolkit/utils/download_utils.py,sha256=0OtZoiLGQZUXlYG7MxiTSZgfT7L4qOxQIflvmbPcqSs,20501
|
|
77
78
|
fal/toolkit/utils/endpoint.py,sha256=5EXoshA2PD_brjEfhNWAWasjqLOCRrjBnfhj6QGuMt8,782
|
|
78
79
|
fal/toolkit/utils/retry.py,sha256=0pnKqs1Y2dADMAk2944FZr68ZL3wQC_5hqApfgyMf_8,1531
|
|
79
80
|
fal/toolkit/video/__init__.py,sha256=YV0jWpuvoA_CDFQXhd3zOvilFLKH7DYARrbzR7hWhpE,35
|
|
@@ -141,8 +142,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
141
142
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
142
143
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
143
144
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
144
|
-
fal-1.
|
|
145
|
-
fal-1.
|
|
146
|
-
fal-1.
|
|
147
|
-
fal-1.
|
|
148
|
-
fal-1.
|
|
145
|
+
fal-1.23.1.dist-info/METADATA,sha256=MvSJ1DBSdozdRvsUUw-9ycHm1yWWuZ--JvifArmgOMo,4085
|
|
146
|
+
fal-1.23.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
147
|
+
fal-1.23.1.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
148
|
+
fal-1.23.1.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
149
|
+
fal-1.23.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|