Add image runtime installation and profile deletion controls
This commit is contained in:
+8
-5
@@ -39,7 +39,7 @@ def workflow(prompt,params,seed):
|
||||
|
||||
class ImageTests:
|
||||
def __init__(self,root,profiles):
|
||||
self.root=Path(root);self.profiles=profiles;self.lock=threading.RLock();self.process=None;self.cancel=threading.Event();self.job=None
|
||||
self.root=Path(root);self.profiles=profiles;self.runtime=None;self.lock=threading.RLock();self.process=None;self.cancel=threading.Event();self.job=None
|
||||
if (self.root/'status.json').exists():
|
||||
self.job=json.loads((self.root/'status.json').read_text())
|
||||
if self.job.get('state')=='running':self.job.update(state='interrupted',phase='Deck wurde neu gestartet; Test erneut starten.')
|
||||
@@ -50,7 +50,9 @@ class ImageTests:
|
||||
with self.lock:
|
||||
self.job['phase']=text;self._save()
|
||||
def status(self):
|
||||
with self.lock:return dict(job=dict(self.job) if self.job else None,runtime_installed=PYTHON.is_file() and (COMFY/'main.py').is_file())
|
||||
with self.lock:
|
||||
python,comfy=self.runtime.paths() if self.runtime else (PYTHON,COMFY)
|
||||
return dict(job=dict(self.job) if self.job else None,runtime_installed=python.is_file() and (comfy/'main.py').is_file())
|
||||
def stop(self):
|
||||
self.cancel.set()
|
||||
with self.lock:process=self.process
|
||||
@@ -67,6 +69,7 @@ class ImageTests:
|
||||
if not isinstance(prompt,str) or not 1<=len(prompt.strip())<=4000:raise ValueError('Bitte einen Prompt mit 1–4000 Zeichen eingeben.')
|
||||
with self.lock:
|
||||
if self.job and self.job['state']=='running':raise ValueError('Ein Bildtest läuft bereits.')
|
||||
if self.runtime and (self.runtime.status()['job'] or {}).get('state')=='running':raise ValueError('Die Bildlaufzeit wird gerade installiert.')
|
||||
if not self.status()['runtime_installed']:raise ValueError('Die eigene ComfyUI-Bildlaufzeit ist noch nicht installiert.')
|
||||
profile=next((p for p in self.profiles.status()['profiles'] if p['id']==profile_id),None)
|
||||
if not profile or profile['kind']!='image' or not profile['model']:raise ValueError('Bildprofil nicht verfügbar.')
|
||||
@@ -104,10 +107,10 @@ class ImageTests:
|
||||
(directory/'paths.json').write_text(json.dumps(config)) # JSON is valid YAML.
|
||||
with socket.socket() as sock:sock.bind(('127.0.0.1',0));port=sock.getsockname()[1]
|
||||
env=dict(os.environ,CUDA_VISIBLE_DEVICES=gpu['uuid'],OMP_NUM_THREADS='2',MKL_NUM_THREADS='2',HOME=str(directory),HF_HUB_OFFLINE='1',TRANSFORMERS_OFFLINE='1',PYTHONDONTWRITEBYTECODE='1')
|
||||
args=[str(PYTHON),str(COMFY/'main.py'),'--listen','127.0.0.1','--port',str(port),'--disable-auto-launch','--disable-metadata','--lowvram','--reserve-vram','1.5','--extra-model-paths-config',str(directory/'paths.json'),'--output-directory',str(directory/'output'),'--temp-directory',str(directory/'temp'),'--user-directory',str(directory/'user'),'--input-directory',str(directory/'input')]
|
||||
args=[str(self.runtime.paths()[0] if self.runtime else PYTHON),str((self.runtime.paths()[1] if self.runtime else COMFY)/'main.py'),'--listen','127.0.0.1','--port',str(port),'--disable-auto-launch','--disable-metadata','--lowvram','--reserve-vram','1.5','--extra-model-paths-config',str(directory/'paths.json'),'--output-directory',str(directory/'output'),'--temp-directory',str(directory/'temp'),'--user-directory',str(directory/'user'),'--input-directory',str(directory/'input')]
|
||||
with self.lock:
|
||||
if self.cancel.is_set():raise InterruptedError()
|
||||
process=subprocess.Popen(args,cwd=COMFY,env=env,stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,start_new_session=True);self.process=process
|
||||
process=subprocess.Popen(args,cwd=self.runtime.paths()[1] if self.runtime else COMFY,env=env,stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,start_new_session=True);self.process=process
|
||||
def request(path,data=None):
|
||||
req=urllib.request.Request(f'http://127.0.0.1:{port}'+path,data=json.dumps(data).encode() if data is not None else None,headers={'Content-Type':'application/json'})
|
||||
with urllib.request.urlopen(req,timeout=5) as r:
|
||||
@@ -129,7 +132,7 @@ class ImageTests:
|
||||
nodes=request('/object_info')
|
||||
required={'UnetLoaderGGUF','CLIPLoader','VAELoader','TextEncodeQwenImage21','EmptyLatentImage','KSampler','VAEDecode','SaveImage'}
|
||||
if not required.issubset(nodes):raise ValueError('Der installierten Bildlaufzeit fehlen erforderliche Qwen/GGUF-Nodes.')
|
||||
self._phase('Modell und Textencoder laden · Bild wird erzeugt')
|
||||
self._phase('Auftrag wird verarbeitet · Textencoder auf CPU, Bildberechnung auf GPU')
|
||||
response=request('/prompt',{'prompt':workflow(prompt,params,seed),'client_id':'deck-'+job_id});prompt_id=response['prompt_id']
|
||||
deadline=time.monotonic()+1800
|
||||
while time.monotonic()<deadline:
|
||||
|
||||
Reference in New Issue
Block a user