Keramo's picture
Create app.py
73f605a verified
Raw
History Blame Contribute Delete
3.18 kB
from fastapi import FastAPI, File, UploadFile, HTTPException, Header, Form, BackgroundTasks
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from typing import Optional
import os
import asyncio
from models.color import extract_color_palette
from models.classifier import get_classifier
from models.material import detect_material_clip
from models.embeddings import get_image_embedding
from models.attribute_parser import generate_caption
from llm_utils import generate_description # same as before, calls Seller Assistant
app = FastAPI(title="Advanced Product Intelligence Service")
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
@app.post("/api/v1/product-intelligence")
async def product_intelligence(
file: UploadFile = File(...),
generate_seo: Optional[bool] = Form(False),
generate_caption: Optional[bool] = Form(False), # BLIP caption
api_key: Optional[str] = Header(None)
):
contents = await file.read()
# Run all models in parallel (some can be run concurrently)
tasks = [
extract_color_palette(contents),
asyncio.to_thread(lambda: get_classifier().predict(contents)),
asyncio.to_thread(lambda: detect_material_clip(contents)),
asyncio.to_thread(get_image_embedding, contents)
]
if generate_caption:
tasks.append(asyncio.to_thread(generate_caption, contents))
results = await asyncio.gather(*tasks)
palette_info, classifier_output, material_info, embedding, caption = results[0], results[1], results[2], results[3], results[4] if generate_caption else None
response = {
"colors": palette_info,
"category": classifier_output["category"],
"category_confidence": classifier_output["category_confidence"],
"attributes": classifier_output["attributes"],
"material": material_info["primary_material"],
"material_confidence": material_info["confidence"],
"material_all_scores": material_info["all_scores"],
"embedding": embedding, # 512-dim vector
"suggested_tags": [classifier_output["category"], material_info["primary_material"]] + palette_info["all_hex"][:2]
}
if generate_caption and caption:
response["caption"] = caption
if generate_seo:
if not api_key:
response["seo_title"] = f"Premium {material_info['primary_material']} {classifier_output['category']}"
response["seo_description"] = f"High-quality {material_info['primary_material']} {classifier_output['category']} with {', '.join(palette_info['all_names'][:2])} tones."
else:
seo = await generate_description(
classifier_output["category"],
material_info["primary_material"],
palette_info["all_hex"],
api_key
)
response["seo_title"] = seo.get("title", "")
response["seo_description"] = seo.get("description", "")
return JSONResponse(content=response)
@app.get("/health")
async def health():
return {"status": "advanced intelligence ready"}