fal 1.2.0__py3-none-any.whl → 1.2.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/logging/isolate.py +20 -0
- fal/toolkit/utils/download_utils.py +48 -39
- {fal-1.2.0.dist-info → fal-1.2.1.dist-info}/METADATA +1 -1
- {fal-1.2.0.dist-info → fal-1.2.1.dist-info}/RECORD +8 -8
- {fal-1.2.0.dist-info → fal-1.2.1.dist-info}/WHEEL +0 -0
- {fal-1.2.0.dist-info → fal-1.2.1.dist-info}/entry_points.txt +0 -0
- {fal-1.2.0.dist-info → fal-1.2.1.dist-info}/top_level.txt +0 -0
fal/_fal_version.py
CHANGED
fal/logging/isolate.py
CHANGED
|
@@ -17,11 +17,31 @@ class IsolateLogPrinter:
|
|
|
17
17
|
|
|
18
18
|
def __init__(self, debug: bool = False) -> None:
|
|
19
19
|
self.debug = debug
|
|
20
|
+
self._current_source: LogSource | None = None
|
|
21
|
+
|
|
22
|
+
def _maybe_print_header(self, source: LogSource):
|
|
23
|
+
from fal.console import console
|
|
24
|
+
|
|
25
|
+
if source == self._current_source:
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
msg = {
|
|
29
|
+
LogSource.BUILDER: "Building the environment",
|
|
30
|
+
LogSource.BRIDGE: "Unpacking user code",
|
|
31
|
+
LogSource.USER: "Running",
|
|
32
|
+
}.get(source)
|
|
33
|
+
|
|
34
|
+
if msg:
|
|
35
|
+
console.print(f"==> {msg}", style="bold green")
|
|
36
|
+
|
|
37
|
+
self._current_source = source
|
|
20
38
|
|
|
21
39
|
def print(self, log: Log):
|
|
22
40
|
if log.level < LogLevel.INFO and not self.debug:
|
|
23
41
|
return
|
|
24
42
|
|
|
43
|
+
self._maybe_print_header(log.source)
|
|
44
|
+
|
|
25
45
|
if log.source == LogSource.USER:
|
|
26
46
|
stream = sys.stderr if log.level == LogLevel.STDERR else sys.stdout
|
|
27
47
|
print(log.message, file=stream)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import hashlib
|
|
4
|
+
import os
|
|
4
5
|
import shutil
|
|
5
6
|
import subprocess
|
|
6
7
|
import sys
|
|
7
8
|
from pathlib import Path, PurePath
|
|
8
|
-
from tempfile import TemporaryDirectory
|
|
9
|
+
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
|
9
10
|
from urllib.parse import urlparse
|
|
10
11
|
from urllib.request import Request, urlopen
|
|
11
12
|
|
|
@@ -215,10 +216,14 @@ def _download_file_python(
|
|
|
215
216
|
Returns:
|
|
216
217
|
The path where the downloaded file has been saved.
|
|
217
218
|
"""
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
with
|
|
219
|
+
basename = os.path.basename(target_path)
|
|
220
|
+
# NOTE: using the same directory to avoid potential copies across temp fs and target
|
|
221
|
+
# fs, and also to be able to atomically rename a downloaded file into place.
|
|
222
|
+
with NamedTemporaryFile(
|
|
223
|
+
delete=False,
|
|
224
|
+
dir=os.path.dirname(target_path),
|
|
225
|
+
prefix=f"{basename}.tmp",
|
|
226
|
+
) as temp_file:
|
|
222
227
|
try:
|
|
223
228
|
file_path = temp_file.name
|
|
224
229
|
|
|
@@ -232,13 +237,14 @@ def _download_file_python(
|
|
|
232
237
|
|
|
233
238
|
print(progress_msg, end="\r\n")
|
|
234
239
|
|
|
235
|
-
#
|
|
236
|
-
#
|
|
237
|
-
#
|
|
238
|
-
|
|
240
|
+
# NOTE: Atomically renaming the file into place when the file is downloaded
|
|
241
|
+
# completely.
|
|
242
|
+
#
|
|
243
|
+
# Since the file used is temporary, in a case of an interruption, the
|
|
244
|
+
# downloaded content will be lost. So, it is safe to redownload the file in
|
|
245
|
+
# such cases.
|
|
246
|
+
os.rename(file_path, target_path)
|
|
239
247
|
|
|
240
|
-
except Exception as error:
|
|
241
|
-
raise error
|
|
242
248
|
finally:
|
|
243
249
|
Path(temp_file.name).unlink(missing_ok=True)
|
|
244
250
|
|
|
@@ -403,35 +409,38 @@ def clone_repository(
|
|
|
403
409
|
print(f"Removing the existing repository: {local_repo_path} ")
|
|
404
410
|
shutil.rmtree(local_repo_path)
|
|
405
411
|
|
|
406
|
-
#
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
"
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
subprocess.check_call(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
412
|
+
# NOTE: using the target_dir to be able to avoid potential copies across temp fs
|
|
413
|
+
# and target fs, and also to be able to atomically rename repo_name dir into place
|
|
414
|
+
# when we are done setting it up.
|
|
415
|
+
os.makedirs(target_dir, exist_ok=True) # type: ignore[arg-type]
|
|
416
|
+
with TemporaryDirectory(
|
|
417
|
+
dir=target_dir,
|
|
418
|
+
suffix=f"{local_repo_path.name}.tmp",
|
|
419
|
+
) as temp_dir:
|
|
420
|
+
try:
|
|
421
|
+
print(f"Cloning the repository '{https_url}' .")
|
|
422
|
+
|
|
423
|
+
# Clone with disabling the logs and advices for detached HEAD state.
|
|
424
|
+
clone_command = [
|
|
425
|
+
"git",
|
|
426
|
+
"clone",
|
|
427
|
+
"--recursive",
|
|
428
|
+
https_url,
|
|
429
|
+
temp_dir,
|
|
430
|
+
]
|
|
431
|
+
subprocess.check_call(clone_command)
|
|
432
|
+
|
|
433
|
+
if commit_hash:
|
|
434
|
+
checkout_command = ["git", "checkout", commit_hash]
|
|
435
|
+
subprocess.check_call(checkout_command, cwd=temp_dir)
|
|
436
|
+
|
|
437
|
+
# NOTE: Atomically renaming the repository directory into place when the
|
|
438
|
+
# clone and checkout are done.
|
|
439
|
+
os.rename(temp_dir, local_repo_path)
|
|
433
440
|
|
|
434
|
-
|
|
441
|
+
except Exception as error:
|
|
442
|
+
print(f"{error}\nFailed to clone repository '{https_url}' .")
|
|
443
|
+
raise error
|
|
435
444
|
|
|
436
445
|
if include_to_path:
|
|
437
446
|
__add_local_path_to_sys_path(local_repo_path)
|
|
@@ -1,6 +1,6 @@
|
|
|
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=2U0Gn26fYI3Vgj5hgkLM8I3wI6YEVdffJGllaVW-sSc,411
|
|
4
4
|
fal/_serialization.py,sha256=rD2YiSa8iuzCaZohZwN_MPEB-PpSKbWRDeaIDpTEjyY,7653
|
|
5
5
|
fal/_version.py,sha256=EBGqrknaf1WygENX-H4fBefLvHryvJBBGtVJetaB0NY,266
|
|
6
6
|
fal/api.py,sha256=x60GlBWynDd1yhHsVWeqf07WVTzgbwNC6cqCjhlTiFQ,40556
|
|
@@ -35,7 +35,7 @@ fal/exceptions/__init__.py,sha256=x3fp97qMr5zCQJghMq6k2ESXWSrkWumO1BZebh3pWsI,92
|
|
|
35
35
|
fal/exceptions/_base.py,sha256=oF2XfitbiDGObmSF1IX50uAdV8IUvOfR-YsGmMQSE0A,161
|
|
36
36
|
fal/exceptions/auth.py,sha256=gxRago5coI__vSIcdcsqhhq1lRPkvCnwPAueIaXTAdw,329
|
|
37
37
|
fal/logging/__init__.py,sha256=snqprf7-sKw6oAATS_Yxklf-a3XhLg0vIHICPwLp6TM,1583
|
|
38
|
-
fal/logging/isolate.py,sha256=
|
|
38
|
+
fal/logging/isolate.py,sha256=jJSgDHkFg4sB0xElYSqCYF6IAxy6jEgSfjwFuKJIZbA,2305
|
|
39
39
|
fal/logging/style.py,sha256=ckIgHzvF4DShM5kQh8F133X53z_vF46snuDHVmo_h9g,386
|
|
40
40
|
fal/logging/trace.py,sha256=OhzB6d4rQZimBc18WFLqH_9BGfqFFumKKTAGSsmWRMg,1904
|
|
41
41
|
fal/logging/user.py,sha256=0Xvb8n6tSb9l_V51VDzv6SOdYEFNouV_6nF_W9e7uNQ,642
|
|
@@ -51,7 +51,7 @@ fal/toolkit/file/providers/r2.py,sha256=WxmOHF5WxHt6tKMcFjWj7ZWO8a1EXysO9lfYv_tB
|
|
|
51
51
|
fal/toolkit/image/__init__.py,sha256=qNLyXsBWysionUjbeWbohLqWlw3G_UpzunamkZd_JLQ,71
|
|
52
52
|
fal/toolkit/image/image.py,sha256=UDIHgkxae8LzmCvWBM9GayMnK8c0JMMfsrVlLnW5rto,4234
|
|
53
53
|
fal/toolkit/utils/__init__.py,sha256=CrmM9DyCz5-SmcTzRSm5RaLgxy3kf0ZsSEN9uhnX2Xo,97
|
|
54
|
-
fal/toolkit/utils/download_utils.py,sha256=
|
|
54
|
+
fal/toolkit/utils/download_utils.py,sha256=9WMpn0mFIhkFelQpPj5KG-pC7RMyyOzGHbNRDSyz07o,17664
|
|
55
55
|
openapi_fal_rest/__init__.py,sha256=ziculmF_i6trw63LzZGFX-6W3Lwq9mCR8_UpkpvpaHI,152
|
|
56
56
|
openapi_fal_rest/client.py,sha256=G6BpJg9j7-JsrAUGddYwkzeWRYickBjPdcVgXoPzxuE,2817
|
|
57
57
|
openapi_fal_rest/errors.py,sha256=8mXSxdfSGzxT82srdhYbR0fHfgenxJXaUtMkaGgb6iU,470
|
|
@@ -115,8 +115,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
115
115
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
116
116
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
117
117
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
118
|
-
fal-1.2.
|
|
119
|
-
fal-1.2.
|
|
120
|
-
fal-1.2.
|
|
121
|
-
fal-1.2.
|
|
122
|
-
fal-1.2.
|
|
118
|
+
fal-1.2.1.dist-info/METADATA,sha256=1ViXkmFXOXQqD52q0HPxP-BuzHL5RzQ6x6MC__GOXn4,3777
|
|
119
|
+
fal-1.2.1.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
120
|
+
fal-1.2.1.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
121
|
+
fal-1.2.1.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
122
|
+
fal-1.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|