Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
@@ -10,8 +10,8 @@ import io
|
|
10 |
import base64
|
11 |
import spaces
|
12 |
|
13 |
-
# ComfyUI API endpoint
|
14 |
-
COMFY_API = "http://
|
15 |
WORKFLOW_PATH = "/app/workflows/Workflow_12_11.json"
|
16 |
|
17 |
# Load the workflow template
|
@@ -23,11 +23,23 @@ except Exception as e:
|
|
23 |
print(f"Error loading workflow template: {str(e)}")
|
24 |
workflow_template = {}
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
def queue_prompt(prompt):
|
27 |
"""Send a prompt to ComfyUI for processing"""
|
|
|
|
|
|
|
28 |
p = {"prompt": prompt}
|
29 |
try:
|
30 |
-
response = requests.post(f"{COMFY_API}/prompt", json=p)
|
31 |
return response.json()
|
32 |
except Exception as e:
|
33 |
print(f"Error queuing prompt: {str(e)}")
|
@@ -35,8 +47,11 @@ def queue_prompt(prompt):
|
|
35 |
|
36 |
def get_image(filename, subfolder, folder_type):
|
37 |
"""Get an image from ComfyUI's output folder"""
|
|
|
|
|
|
|
38 |
try:
|
39 |
-
response = requests.get(f"{COMFY_API}/view?filename={filename}&subfolder={subfolder}&type={folder_type}")
|
40 |
return Image.open(io.BytesIO(response.content))
|
41 |
except Exception as e:
|
42 |
print(f"Error getting image {filename}: {str(e)}")
|
@@ -44,6 +59,9 @@ def get_image(filename, subfolder, folder_type):
|
|
44 |
|
45 |
def upload_image(image, filename):
|
46 |
"""Upload an image to ComfyUI's input folder"""
|
|
|
|
|
|
|
47 |
try:
|
48 |
if isinstance(image, str): # Base64 string
|
49 |
image_data = base64.b64decode(image.split(",")[1])
|
@@ -57,16 +75,25 @@ def upload_image(image, filename):
|
|
57 |
img_byte_arr.seek(0)
|
58 |
files = {"image": (filename, img_byte_arr.getvalue())}
|
59 |
|
60 |
-
|
|
|
61 |
return response.json()
|
|
|
|
|
|
|
|
|
62 |
except Exception as e:
|
63 |
-
|
64 |
-
|
|
|
65 |
|
66 |
def check_progress(prompt_id):
|
67 |
"""Check the progress of a ComfyUI prompt"""
|
|
|
|
|
|
|
68 |
try:
|
69 |
-
response = requests.get(f"{COMFY_API}/history/{prompt_id}")
|
70 |
return response.json()
|
71 |
except Exception as e:
|
72 |
print(f"Error checking progress: {str(e)}")
|
@@ -75,49 +102,70 @@ def check_progress(prompt_id):
|
|
75 |
@spaces.GPU
|
76 |
def generate_avatar(player_image, pose_image, shirt_image, player_name, team_name, age_gender_bg, shirt_color, style):
|
77 |
"""Generate a football player avatar using ComfyUI workflow"""
|
|
|
|
|
|
|
78 |
# Upload images to ComfyUI
|
|
|
79 |
player_upload = upload_image(player_image, "player.png")
|
|
|
|
|
80 |
pose_upload = upload_image(pose_image, "pose.png")
|
|
|
|
|
81 |
shirt_upload = upload_image(shirt_image, "shirt.png")
|
82 |
|
83 |
if "error" in player_upload or "error" in pose_upload or "error" in shirt_upload:
|
84 |
-
|
|
|
|
|
|
|
|
|
85 |
|
86 |
# Create a copy of the workflow template
|
87 |
workflow = workflow_template.copy()
|
88 |
|
89 |
# Update workflow nodes with our parameters
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
# Queue the prompt in ComfyUI
|
|
|
115 |
prompt_response = queue_prompt(workflow)
|
116 |
|
117 |
if "error" in prompt_response:
|
118 |
-
|
|
|
|
|
119 |
|
120 |
prompt_id = prompt_response["prompt_id"]
|
|
|
121 |
|
122 |
# Wait for the processing to complete
|
123 |
status = "Generating avatar..."
|
@@ -130,6 +178,7 @@ def generate_avatar(player_image, pose_image, shirt_image, player_name, team_nam
|
|
130 |
|
131 |
if "error" in progress:
|
132 |
retries += 1
|
|
|
133 |
continue
|
134 |
|
135 |
if prompt_id in progress and len(progress[prompt_id]["outputs"]) > 0:
|
@@ -138,17 +187,26 @@ def generate_avatar(player_image, pose_image, shirt_image, player_name, team_nam
|
|
138 |
if node_id == "308" or node_id == "679": # Save Image nodes
|
139 |
image_filename = output.get("images", [{}])[0].get("filename", "")
|
140 |
if image_filename:
|
|
|
141 |
result_image = get_image(image_filename, "", "output")
|
142 |
-
masked_filename =
|
143 |
masked_image = get_image(masked_filename, "", "output")
|
144 |
|
145 |
# Return the masked image if available, otherwise the regular image
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
return None, "Completed, but couldn't find output image."
|
149 |
|
150 |
retries += 1
|
151 |
status = f"Generating avatar... (attempt {retries}/{max_retries})"
|
|
|
152 |
|
153 |
return None, "Timed out waiting for the avatar generation to complete."
|
154 |
|
@@ -193,6 +251,22 @@ def create_interface():
|
|
193 |
with gr.Column():
|
194 |
output_image = gr.Image(label="Generated Avatar")
|
195 |
status_text = gr.Textbox(label="Status", interactive=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
|
197 |
# Load default images for pose and shirt
|
198 |
try:
|
@@ -229,18 +303,19 @@ def create_interface():
|
|
229 |
if __name__ == "__main__":
|
230 |
# Check if ComfyUI is running
|
231 |
retry_count = 0
|
232 |
-
max_retries =
|
233 |
comfy_running = False
|
234 |
|
235 |
while retry_count < max_retries and not comfy_running:
|
236 |
try:
|
237 |
-
|
|
|
238 |
if response.status_code == 200:
|
239 |
print("ComfyUI is running, starting Gradio interface...")
|
240 |
comfy_running = True
|
241 |
break
|
242 |
-
except:
|
243 |
-
|
244 |
|
245 |
retry_count += 1
|
246 |
print(f"Waiting for ComfyUI to start... (attempt {retry_count}/{max_retries})")
|
@@ -248,7 +323,8 @@ if __name__ == "__main__":
|
|
248 |
|
249 |
if not comfy_running:
|
250 |
print("WARNING: Could not connect to ComfyUI server. The application may not function correctly.")
|
|
|
251 |
|
252 |
# Create and launch the interface
|
253 |
demo = create_interface()
|
254 |
-
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|
|
|
10 |
import base64
|
11 |
import spaces
|
12 |
|
13 |
+
# ComfyUI API endpoint - use localhost instead of 127.0.0.1
|
14 |
+
COMFY_API = "http://localhost:8188/api"
|
15 |
WORKFLOW_PATH = "/app/workflows/Workflow_12_11.json"
|
16 |
|
17 |
# Load the workflow template
|
|
|
23 |
print(f"Error loading workflow template: {str(e)}")
|
24 |
workflow_template = {}
|
25 |
|
26 |
+
def is_comfyui_running():
|
27 |
+
"""Check if ComfyUI server is running and accessible"""
|
28 |
+
try:
|
29 |
+
response = requests.get(f"{COMFY_API}/system_stats", timeout=5)
|
30 |
+
return response.status_code == 200
|
31 |
+
except Exception as e:
|
32 |
+
print(f"ComfyUI server check failed: {str(e)}")
|
33 |
+
return False
|
34 |
+
|
35 |
def queue_prompt(prompt):
|
36 |
"""Send a prompt to ComfyUI for processing"""
|
37 |
+
if not is_comfyui_running():
|
38 |
+
return {"error": "ComfyUI server is not running"}
|
39 |
+
|
40 |
p = {"prompt": prompt}
|
41 |
try:
|
42 |
+
response = requests.post(f"{COMFY_API}/prompt", json=p, timeout=30)
|
43 |
return response.json()
|
44 |
except Exception as e:
|
45 |
print(f"Error queuing prompt: {str(e)}")
|
|
|
47 |
|
48 |
def get_image(filename, subfolder, folder_type):
|
49 |
"""Get an image from ComfyUI's output folder"""
|
50 |
+
if not is_comfyui_running():
|
51 |
+
return None
|
52 |
+
|
53 |
try:
|
54 |
+
response = requests.get(f"{COMFY_API}/view?filename={filename}&subfolder={subfolder}&type={folder_type}", timeout=30)
|
55 |
return Image.open(io.BytesIO(response.content))
|
56 |
except Exception as e:
|
57 |
print(f"Error getting image {filename}: {str(e)}")
|
|
|
59 |
|
60 |
def upload_image(image, filename):
|
61 |
"""Upload an image to ComfyUI's input folder"""
|
62 |
+
if not is_comfyui_running():
|
63 |
+
return {"error": "ComfyUI server is not running"}
|
64 |
+
|
65 |
try:
|
66 |
if isinstance(image, str): # Base64 string
|
67 |
image_data = base64.b64decode(image.split(",")[1])
|
|
|
75 |
img_byte_arr.seek(0)
|
76 |
files = {"image": (filename, img_byte_arr.getvalue())}
|
77 |
|
78 |
+
# Use a longer timeout for uploading images
|
79 |
+
response = requests.post(f"{COMFY_API}/upload/image", files=files, timeout=60)
|
80 |
return response.json()
|
81 |
+
except requests.exceptions.ConnectionError as e:
|
82 |
+
error_msg = f"Connection error when uploading image: {str(e)}"
|
83 |
+
print(error_msg)
|
84 |
+
return {"error": error_msg}
|
85 |
except Exception as e:
|
86 |
+
error_msg = f"Error uploading image: {str(e)}"
|
87 |
+
print(error_msg)
|
88 |
+
return {"error": error_msg}
|
89 |
|
90 |
def check_progress(prompt_id):
|
91 |
"""Check the progress of a ComfyUI prompt"""
|
92 |
+
if not is_comfyui_running():
|
93 |
+
return {"error": "ComfyUI server is not running"}
|
94 |
+
|
95 |
try:
|
96 |
+
response = requests.get(f"{COMFY_API}/history/{prompt_id}", timeout=30)
|
97 |
return response.json()
|
98 |
except Exception as e:
|
99 |
print(f"Error checking progress: {str(e)}")
|
|
|
102 |
@spaces.GPU
|
103 |
def generate_avatar(player_image, pose_image, shirt_image, player_name, team_name, age_gender_bg, shirt_color, style):
|
104 |
"""Generate a football player avatar using ComfyUI workflow"""
|
105 |
+
if not is_comfyui_running():
|
106 |
+
return None, "Error: ComfyUI server is not running. Please try again later."
|
107 |
+
|
108 |
# Upload images to ComfyUI
|
109 |
+
print("Uploading player image...")
|
110 |
player_upload = upload_image(player_image, "player.png")
|
111 |
+
|
112 |
+
print("Uploading pose image...")
|
113 |
pose_upload = upload_image(pose_image, "pose.png")
|
114 |
+
|
115 |
+
print("Uploading shirt image...")
|
116 |
shirt_upload = upload_image(shirt_image, "shirt.png")
|
117 |
|
118 |
if "error" in player_upload or "error" in pose_upload or "error" in shirt_upload:
|
119 |
+
error_msg = f"Error uploading images: {player_upload.get('error', '')} {pose_upload.get('error', '')} {shirt_upload.get('error', '')}"
|
120 |
+
print(error_msg)
|
121 |
+
return None, error_msg
|
122 |
+
|
123 |
+
print("All images uploaded successfully")
|
124 |
|
125 |
# Create a copy of the workflow template
|
126 |
workflow = workflow_template.copy()
|
127 |
|
128 |
# Update workflow nodes with our parameters
|
129 |
+
try:
|
130 |
+
# Player image node
|
131 |
+
workflow["391"]["inputs"]["image"] = player_upload["name"]
|
132 |
+
|
133 |
+
# Pose image node
|
134 |
+
workflow["310"]["inputs"]["image"] = pose_upload["name"]
|
135 |
+
|
136 |
+
# Shirt image node
|
137 |
+
workflow["636"]["inputs"]["image"] = shirt_upload["name"]
|
138 |
+
|
139 |
+
# Player name node
|
140 |
+
workflow["471"]["inputs"]["string"] = f"_{player_name}"
|
141 |
+
|
142 |
+
# Team name node
|
143 |
+
workflow["667"]["inputs"]["string"] = team_name
|
144 |
+
|
145 |
+
# Age, gender, background prompt node
|
146 |
+
workflow["420"]["inputs"]["string"] = age_gender_bg
|
147 |
+
|
148 |
+
# Shirt color node
|
149 |
+
workflow["528"]["inputs"]["string"] = f"({shirt_color}:1.2) blank t-shirt, black shorts, "
|
150 |
+
|
151 |
+
# Style node
|
152 |
+
workflow["422"]["inputs"]["string"] = style
|
153 |
+
except KeyError as e:
|
154 |
+
error_msg = f"Error updating workflow parameters: {str(e)}. The workflow structure may have changed."
|
155 |
+
print(error_msg)
|
156 |
+
return None, error_msg
|
157 |
|
158 |
# Queue the prompt in ComfyUI
|
159 |
+
print("Queuing prompt in ComfyUI...")
|
160 |
prompt_response = queue_prompt(workflow)
|
161 |
|
162 |
if "error" in prompt_response:
|
163 |
+
error_msg = f"Error queuing prompt: {prompt_response['error']}"
|
164 |
+
print(error_msg)
|
165 |
+
return None, error_msg
|
166 |
|
167 |
prompt_id = prompt_response["prompt_id"]
|
168 |
+
print(f"Prompt queued with ID: {prompt_id}")
|
169 |
|
170 |
# Wait for the processing to complete
|
171 |
status = "Generating avatar..."
|
|
|
178 |
|
179 |
if "error" in progress:
|
180 |
retries += 1
|
181 |
+
print(f"Error checking progress (retry {retries}/{max_retries}): {progress['error']}")
|
182 |
continue
|
183 |
|
184 |
if prompt_id in progress and len(progress[prompt_id]["outputs"]) > 0:
|
|
|
187 |
if node_id == "308" or node_id == "679": # Save Image nodes
|
188 |
image_filename = output.get("images", [{}])[0].get("filename", "")
|
189 |
if image_filename:
|
190 |
+
print(f"Found output image: {image_filename}")
|
191 |
result_image = get_image(image_filename, "", "output")
|
192 |
+
masked_filename = image_filename.replace(".png", "_Masked.png")
|
193 |
masked_image = get_image(masked_filename, "", "output")
|
194 |
|
195 |
# Return the masked image if available, otherwise the regular image
|
196 |
+
if masked_image:
|
197 |
+
print("Returning masked image")
|
198 |
+
return masked_image, "Avatar generated successfully!"
|
199 |
+
elif result_image:
|
200 |
+
print("Returning regular image")
|
201 |
+
return result_image, "Avatar generated successfully!"
|
202 |
+
else:
|
203 |
+
return None, "Generated image could not be retrieved."
|
204 |
|
205 |
return None, "Completed, but couldn't find output image."
|
206 |
|
207 |
retries += 1
|
208 |
status = f"Generating avatar... (attempt {retries}/{max_retries})"
|
209 |
+
print(status)
|
210 |
|
211 |
return None, "Timed out waiting for the avatar generation to complete."
|
212 |
|
|
|
251 |
with gr.Column():
|
252 |
output_image = gr.Image(label="Generated Avatar")
|
253 |
status_text = gr.Textbox(label="Status", interactive=False)
|
254 |
+
|
255 |
+
# Add ComfyUI status indicator
|
256 |
+
comfy_status = gr.Textbox(label="ComfyUI Server Status", interactive=False)
|
257 |
+
check_comfy_button = gr.Button("Check ComfyUI Server Status")
|
258 |
+
|
259 |
+
def check_comfy_server():
|
260 |
+
if is_comfyui_running():
|
261 |
+
return "✅ ComfyUI server is running"
|
262 |
+
else:
|
263 |
+
return "❌ ComfyUI server is not running"
|
264 |
+
|
265 |
+
check_comfy_button.click(
|
266 |
+
fn=check_comfy_server,
|
267 |
+
inputs=[],
|
268 |
+
outputs=[comfy_status]
|
269 |
+
)
|
270 |
|
271 |
# Load default images for pose and shirt
|
272 |
try:
|
|
|
303 |
if __name__ == "__main__":
|
304 |
# Check if ComfyUI is running
|
305 |
retry_count = 0
|
306 |
+
max_retries = 12 # 2 minutes (10 seconds between retries)
|
307 |
comfy_running = False
|
308 |
|
309 |
while retry_count < max_retries and not comfy_running:
|
310 |
try:
|
311 |
+
print(f"Checking if ComfyUI is running (attempt {retry_count+1}/{max_retries})...")
|
312 |
+
response = requests.get(f"{COMFY_API}/system_stats", timeout=5)
|
313 |
if response.status_code == 200:
|
314 |
print("ComfyUI is running, starting Gradio interface...")
|
315 |
comfy_running = True
|
316 |
break
|
317 |
+
except Exception as e:
|
318 |
+
print(f"ComfyUI check failed: {str(e)}")
|
319 |
|
320 |
retry_count += 1
|
321 |
print(f"Waiting for ComfyUI to start... (attempt {retry_count}/{max_retries})")
|
|
|
323 |
|
324 |
if not comfy_running:
|
325 |
print("WARNING: Could not connect to ComfyUI server. The application may not function correctly.")
|
326 |
+
print("Starting Gradio interface anyway...")
|
327 |
|
328 |
# Create and launch the interface
|
329 |
demo = create_interface()
|
330 |
+
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|