| import io |
| import json |
| import uuid |
| import urllib.request |
| import urllib.parse |
| import websocket |
|
|
| from fastapi import FastAPI, File, UploadFile, HTTPException |
| from fastapi.responses import StreamingResponse |
|
|
| |
| |
| COMFYUI_SERVER_ADDRESS = "127.0.0.1:8188" |
| |
| CLIENT_ID = str(uuid.uuid4()) |
|
|
| |
| app = FastAPI(title="Clarity AI Upscaler API") |
|
|
| def get_image(filename, subfolder, folder_type): |
| """Lấy file ảnh từ máy chủ ComfyUI.""" |
| data = {"filename": filename, "subfolder": subfolder, "type": folder_type} |
| url_values = urllib.parse.urlencode(data) |
| with urllib.request.urlopen(f"http://{COMFYUI_SERVER_ADDRESS}/view?{url_values}") as response: |
| return response.read() |
|
|
| def queue_prompt(prompt_workflow): |
| """Gửi yêu cầu thực thi quy trình đến ComfyUI.""" |
| p = {"prompt": prompt_workflow, "client_id": CLIENT_ID} |
| data = json.dumps(p).encode('utf-8') |
| req = urllib.request.Request(f"http://{COMFYUI_SERVER_ADDRESS}/prompt", data=data) |
| return json.loads(urllib.request.urlopen(req).read()) |
|
|
| def upload_image(image_bytes: bytes, filename: str = "input_image.png"): |
| """Tải ảnh lên thư mục input của ComfyUI.""" |
| import requests |
| files = {"image": (filename, image_bytes, 'image/png'), "overwrite": (None, 'true')} |
| response = requests.post(f"http://{COMFYUI_SERVER_ADDRESS}/upload/image", files=files) |
| if response.status_code == 200: |
| return response.json() |
| else: |
| raise HTTPException(status_code=500, detail=f"Failed to upload image: {response.text}") |
|
|
| def get_history(prompt_id): |
| """Lấy lịch sử thực thi của một prompt.""" |
| with urllib.request.urlopen(f"http://{COMFYUI_SERVER_ADDRESS}/history/{prompt_id}") as response: |
| return json.loads(response.read()) |
|
|
| def track_execution_and_get_output(prompt_id): |
| """Theo dõi tiến trình qua WebSocket và lấy ảnh kết quả.""" |
| ws_url = f"ws://{COMFYUI_SERVER_ADDRESS}/ws?clientId={CLIENT_ID}" |
| ws = websocket.WebSocket() |
| ws.connect(ws_url) |
| |
| while True: |
| out = ws.recv() |
| if isinstance(out, str): |
| message = json.loads(out) |
| if message['type'] == 'executing': |
| data = message['data'] |
| if data['node'] is None and data['prompt_id'] == prompt_id: |
| break |
| else: |
| continue |
| ws.close() |
|
|
| history = get_history(prompt_id)[prompt_id] |
| for node_id, node_output in history['outputs'].items(): |
| if 'images' in node_output: |
| for image in node_output['images']: |
| if image['type'] == 'output': |
| image_data = get_image(image['filename'], image['subfolder'], image['type']) |
| return image_data |
| raise HTTPException(status_code=500, detail="Không tìm thấy ảnh kết quả.") |
|
|
| @app.post("/upscale/", |
| summary="Nâng cấp và tinh chỉnh hình ảnh", |
| response_description="Hình ảnh đã được xử lý ở định dạng PNG") |
| async def upscale_image(file: UploadFile = File(..., description="File ảnh cần xử lý.")): |
| """ |
| Nhận một file ảnh, xử lý nó thông qua quy trình ComfyUI, và trả về kết quả. |
| """ |
| try: |
| |
| with open("workflow_api.json", "r", encoding="utf-8") as f: |
| prompt_workflow = json.load(f) |
|
|
| |
| image_bytes = await file.read() |
| upload_response = upload_image(image_bytes) |
| input_filename = upload_response['name'] |
|
|
| |
| |
| |
| prompt_workflow["17"]["inputs"]["image"] = input_filename |
|
|
| |
| queue_response = queue_prompt(prompt_workflow) |
| prompt_id = queue_response['prompt_id'] |
|
|
| |
| result_image_bytes = track_execution_and_get_output(prompt_id) |
|
|
| |
| return StreamingResponse(io.BytesIO(result_image_bytes), media_type="image/png") |
|
|
| except FileNotFoundError: |
| raise HTTPException(status_code=500, detail="Không tìm thấy file workflow_api.json.") |
| except Exception as e: |
| raise HTTPException(status_code=500, detail=f"Đã xảy ra lỗi: {str(e)}") |
|
|
| |
| |
|
|