NEWTRY / app.py
fanboyd13's picture
Upload 7 files
9f4de68 verified
import os, io, base64, threading, traceback
import torch
import numpy as np
from PIL import Image, ImageDraw
from fastapi import FastAPI, UploadFile, File
from fastapi.responses import HTMLResponse, JSONResponse
import uvicorn
app = FastAPI()
MODEL_LOADED = False
LOAD_ERROR = ""
pipe = None
def load_model():
global pipe, MODEL_LOADED, LOAD_ERROR
try:
print("πŸ“₯ Loading model on CPU...")
from diffusers import StableDiffusionInpaintPipeline
pipe = StableDiffusionInpaintPipeline.from_pretrained(
"runwayml/stable-diffusion-inpainting",
torch_dtype=torch.float32, # CPU needs float32
safety_checker=None,
requires_safety_checker=False,
)
# CPU ONLY β€” no .to("cuda"), no cpu_offload
pipe.enable_attention_slicing()
MODEL_LOADED = True
print("βœ… Model ready on CPU!")
except Exception as e:
LOAD_ERROR = str(e)
print(f"❌ {e}")
threading.Thread(target=load_model, daemon=True).start()
def pil_to_b64(img):
buf = io.BytesIO()
img.save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode()
def make_mask(size):
w, h = size
mask = Image.new("L", size, 0)
draw = ImageDraw.Draw(mask)
draw.rectangle([w*0.05, h*0.18, w*0.95, h*0.68], fill=255)
draw.rectangle([w*0.0, h*0.18, w*0.15, h*0.58], fill=255)
draw.rectangle([w*0.85, h*0.18, w*1.0, h*0.58], fill=255)
return mask.convert("RGB")
@app.get("/", response_class=HTMLResponse)
async def index():
return HTMLResponse(open("/app/index.html").read())
@app.get("/status")
async def status():
return {"loaded": MODEL_LOADED, "error": LOAD_ERROR}
@app.post("/tryon")
async def tryon(person: UploadFile = File(...), garment: UploadFile = File(...)):
if not MODEL_LOADED:
return JSONResponse({"status":"loading","message":"Model still loading, please wait and retry."}, status_code=503)
try:
SIZE = (512, 768)
person_img = Image.open(io.BytesIO(await person.read())).convert("RGB").resize(SIZE)
mask_img = make_mask(SIZE)
prompt = "Person wearing a clean stylish garment, photorealistic, high quality fashion photo, same pose, same background"
negative = "nude, deformed, blurry, bad anatomy, extra limbs, watermark, logo, text, disfigured"
result = pipe(
prompt=prompt,
negative_prompt=negative,
image=person_img,
mask_image=mask_img,
height=SIZE[1],
width=SIZE[0],
num_inference_steps=25,
guidance_scale=7.5,
strength=0.95,
).images[0]
return JSONResponse({"status":"ok","image": pil_to_b64(result)})
except Exception as e:
traceback.print_exc()
return JSONResponse({"status":"error","message":str(e)}, status_code=500)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)