1
- import platform as os_platform
2
1
import shutil
3
2
import subprocess
4
- import tarfile
5
3
from pathlib import Path
6
4
from typing import Optional
7
5
8
6
import requests
9
- from rich .live import Live
10
- from rich .progress import Progress , TextColumn
11
- from rich .table import Table
12
7
13
8
from comfy_cli .constants import OS , PROC
14
9
from comfy_cli .typing import PathLike
15
- from comfy_cli .utils import download_progress , get_os , get_proc
10
+ from comfy_cli .utils import create_tarball , download_url , extract_tarball , get_os , get_proc
16
11
from comfy_cli .uv import DependencyCompiler
17
12
18
13
_here = Path (__file__ ).expanduser ().resolve ().parent
@@ -37,6 +32,7 @@ def download_standalone_python(
37
32
tag : str = "latest" ,
38
33
flavor : str = "install_only" ,
39
34
cwd : PathLike = "." ,
35
+ show_progress : bool = True ,
40
36
) -> PathLike :
41
37
"""grab a pre-built distro from the python-build-standalone project. See
42
38
https://gregoryszorc.com/docs/python-build-standalone/main/"""
@@ -59,9 +55,9 @@ def download_standalone_python(
59
55
60
56
name = f"cpython-{ version } +{ tag } -{ target } -{ flavor } "
61
57
fname = f"{ name } .tar.gz"
62
- url = f"{ asset_url_prefix } /{ fname } "
58
+ url = f"{ asset_url_prefix . rstrip ( '/' ) } /{ fname . lstrip ( '/' ) } "
63
59
64
- return download_progress (url , fname , cwd = cwd )
60
+ return download_url (url , fname , cwd = cwd , show_progress = show_progress )
65
61
66
62
67
63
class StandalonePython :
@@ -74,43 +70,32 @@ def FromDistro(
74
70
flavor : str = "install_only" ,
75
71
cwd : PathLike = "." ,
76
72
name : PathLike = "python" ,
77
- ):
73
+ show_progress : bool = True ,
74
+ ) -> "StandalonePython" :
78
75
fpath = download_standalone_python (
79
76
platform = platform ,
80
77
proc = proc ,
81
78
version = version ,
82
79
tag = tag ,
83
80
flavor = flavor ,
84
81
cwd = cwd ,
82
+ show_progress = show_progress ,
85
83
)
86
84
return StandalonePython .FromTarball (fpath , name )
87
85
88
86
@staticmethod
89
- def FromTarball (fpath : PathLike , name : PathLike = "python" ) -> "StandalonePython" :
87
+ def FromTarball (fpath : PathLike , name : PathLike = "python" , show_progress : bool = True ) -> "StandalonePython" :
90
88
fpath = Path (fpath )
91
-
92
- with tarfile .open (fpath ) as tar :
93
- info = tar .next ()
94
- old_name = info .name .split ("/" )[0 ]
95
-
96
- old_rpath = fpath .parent / old_name
97
89
rpath = fpath .parent / name
98
90
99
- # clean the tar file expand target and the final target
100
- shutil .rmtree (old_rpath , ignore_errors = True )
101
- shutil .rmtree (rpath , ignore_errors = True )
102
-
103
- with tarfile .open (fpath ) as tar :
104
- tar .extractall ()
105
-
106
- shutil .move (old_rpath , rpath )
91
+ extract_tarball (inPath = fpath , outPath = rpath , show_progress = show_progress )
107
92
108
93
return StandalonePython (rpath = rpath )
109
94
110
95
def __init__ (self , rpath : PathLike ):
111
96
self .rpath = Path (rpath )
112
97
self .name = self .rpath .name
113
- if os_platform . system () == "Windows" :
98
+ if get_os () == OS . WINDOWS :
114
99
self .bin = self .rpath
115
100
self .executable = self .bin / "python.exe"
116
101
else :
@@ -170,48 +155,18 @@ def dehydrate_comfy_deps(
170
155
extraSpecs = extraSpecs ,
171
156
)
172
157
self .dep_comp .compile_deps ()
173
- self .dep_comp .fetch_dep_wheels ()
158
+
159
+ skip_uv = get_os () == OS .WINDOWS
160
+ self .dep_comp .fetch_dep_wheels (skip_uv = skip_uv )
174
161
175
162
def rehydrate_comfy_deps (self ):
176
163
self .dep_comp = DependencyCompiler (
177
164
executable = self .executable , outDir = self .rpath , reqFilesCore = [], reqFilesExt = []
178
165
)
179
166
self .dep_comp .install_wheels_directly ()
180
167
181
- def to_tarball (self , outPath : Optional [PathLike ] = None , progress : bool = True ):
182
- outPath = self .rpath .with_suffix (".tgz" ) if outPath is None else Path (outPath )
183
-
184
- # do a little clean up prep
185
- outPath .unlink (missing_ok = True )
168
+ def to_tarball (self , outPath : Optional [PathLike ] = None , show_progress : bool = True ):
169
+ # remove any __pycache__ before creating archive
186
170
self .clean ()
187
171
188
- if progress :
189
- fileSize = sum (f .stat ().st_size for f in self .rpath .glob ("**/*" ))
190
-
191
- barProg = Progress ()
192
- addTar = barProg .add_task ("[cyan]Creating tarball..." , total = fileSize )
193
- pathProg = Progress (TextColumn ("{task.description}" ))
194
- pathTar = pathProg .add_task ("" )
195
-
196
- progress_table = Table .grid ()
197
- progress_table .add_row (barProg )
198
- progress_table .add_row (pathProg )
199
-
200
- _size = 0
201
-
202
- def _filter (tinfo : tarfile .TarInfo ):
203
- nonlocal _size
204
- pathProg .update (pathTar , description = tinfo .path )
205
- barProg .advance (addTar , _size )
206
- _size = Path (tinfo .path ).stat ().st_size
207
- return tinfo
208
- else :
209
- _filter = None
210
-
211
- with Live (progress_table , refresh_per_second = 10 ):
212
- with tarfile .open (outPath , "w:gz" ) as tar :
213
- tar .add (self .rpath .relative_to (Path ("." ).expanduser ().resolve ()), filter = _filter )
214
-
215
- if progress :
216
- barProg .advance (addTar , _size )
217
- pathProg .update (pathTar , description = "" )
172
+ create_tarball (inPath = self .rpath , outPath = outPath , show_progress = show_progress )
0 commit comments