ishworrsubedii
commited on
Commit
·
69ae11d
1
Parent(s):
477d077
add: storedashboard nto
Browse files- app.py +7 -3
- src/api/nto_api.py +4 -2
- src/api/store_dashboard_api.py +97 -0
app.py
CHANGED
@@ -8,6 +8,9 @@ from datetime import datetime, timedelta, timezone
|
|
8 |
|
9 |
from fastapi import FastAPI, Depends, HTTPException
|
10 |
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
|
|
|
|
|
11 |
from src.api.batch_api import batch_router
|
12 |
from src.api.image_prep_api import preprocessing_router
|
13 |
from src.api.image_regeneration_api import image_regeneration_router
|
@@ -15,8 +18,7 @@ from src.api.makeup_tryon_api import makeup_tryon_router
|
|
15 |
from src.api.mannequin_to_model_api import mto_router
|
16 |
from src.api.nto_api import nto_cto_router
|
17 |
from src.api.nto_api import supabase
|
18 |
-
from
|
19 |
-
from starlette.responses import JSONResponse
|
20 |
|
21 |
security = HTTPBearer()
|
22 |
|
@@ -54,7 +56,9 @@ app.include_router(batch_router, tags=['Realtime'])
|
|
54 |
|
55 |
app.include_router(mto_router, tags=["MTO"])
|
56 |
|
57 |
-
app.include_router(makeup_tryon_router, tags=["
|
|
|
|
|
58 |
|
59 |
app.add_middleware(
|
60 |
CORSMiddleware,
|
|
|
8 |
|
9 |
from fastapi import FastAPI, Depends, HTTPException
|
10 |
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
11 |
+
from starlette.middleware.cors import CORSMiddleware
|
12 |
+
from starlette.responses import JSONResponse
|
13 |
+
|
14 |
from src.api.batch_api import batch_router
|
15 |
from src.api.image_prep_api import preprocessing_router
|
16 |
from src.api.image_regeneration_api import image_regeneration_router
|
|
|
18 |
from src.api.mannequin_to_model_api import mto_router
|
19 |
from src.api.nto_api import nto_cto_router
|
20 |
from src.api.nto_api import supabase
|
21 |
+
from src.api.store_dashboard_api import store_dashboard_router
|
|
|
22 |
|
23 |
security = HTTPBearer()
|
24 |
|
|
|
56 |
|
57 |
app.include_router(mto_router, tags=["MTO"])
|
58 |
|
59 |
+
app.include_router(makeup_tryon_router, tags=["Makeup_TryOn"])
|
60 |
+
|
61 |
+
app.include_router(store_dashboard_router, tags=['Store-Dashboard'])
|
62 |
|
63 |
app.add_middleware(
|
64 |
CORSMiddleware,
|
src/api/nto_api.py
CHANGED
@@ -583,7 +583,8 @@ async def clothing_and_necklace_try_on(
|
|
583 |
if result is None:
|
584 |
raise ValueError("Failed to process necklace try-on")
|
585 |
|
586 |
-
result_url = await supabase_upload_and_return_url(prefix="NTOCTO", image=result,
|
|
|
587 |
|
588 |
if not result_url:
|
589 |
raise ValueError("Failed to upload result image")
|
@@ -650,7 +651,8 @@ async def mannequin_nto(necklace_try_on_id: NecklaceTryOnIDEntity = Depends(pars
|
|
650 |
start_time_saving = time.time()
|
651 |
|
652 |
# Upload both images concurrently
|
653 |
-
upload_tasks = supabase_upload_and_return_url(prefix="MNTO", image=result,
|
|
|
654 |
result_url = await asyncio.gather(upload_tasks)
|
655 |
|
656 |
if result_url[0] is None:
|
|
|
583 |
if result is None:
|
584 |
raise ValueError("Failed to process necklace try-on")
|
585 |
|
586 |
+
result_url = await supabase_upload_and_return_url(prefix="NTOCTO", image=result,
|
587 |
+
necklace_id=necklaceImageId)
|
588 |
|
589 |
if not result_url:
|
590 |
raise ValueError("Failed to upload result image")
|
|
|
651 |
start_time_saving = time.time()
|
652 |
|
653 |
# Upload both images concurrently
|
654 |
+
upload_tasks = supabase_upload_and_return_url(prefix="MNTO", image=result,
|
655 |
+
necklace_id=necklace_try_on_id.necklaceImageId)
|
656 |
result_url = await asyncio.gather(upload_tasks)
|
657 |
|
658 |
if result_url[0] is None:
|
src/api/store_dashboard_api.py
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
project @ NTO-TCP-HF
|
3 |
+
created @ 2024-12-18
|
4 |
+
author @ github.com/ishworrsubedii
|
5 |
+
"""
|
6 |
+
import base64
|
7 |
+
import gc
|
8 |
+
import time
|
9 |
+
from io import BytesIO
|
10 |
+
|
11 |
+
from PIL import Image
|
12 |
+
from fastapi import File, UploadFile, APIRouter
|
13 |
+
from fastapi.responses import JSONResponse
|
14 |
+
|
15 |
+
from src.api.nto_api import pipeline
|
16 |
+
from src.utils.logger import logger
|
17 |
+
|
18 |
+
store_dashboard_router = APIRouter()
|
19 |
+
|
20 |
+
|
21 |
+
@store_dashboard_router.post("/necklace_try_on")
|
22 |
+
async def necklace_try_on(offset_x: float, offset_y: float, storename, image: UploadFile = File(...),
|
23 |
+
necklace: UploadFile = File(...)):
|
24 |
+
logger.info("-" * 50)
|
25 |
+
logger.info(">>> NECKLACE TRY ON ID STARTED <<<")
|
26 |
+
logger.info(f"Parameters: offset_x={offset_x}, offset_y={offset_x}")
|
27 |
+
logger.info(f"Parameters: storename={storename}")
|
28 |
+
|
29 |
+
start_time = time.time()
|
30 |
+
|
31 |
+
try:
|
32 |
+
image_loading_start = time.time()
|
33 |
+
imageBytes = await image.read()
|
34 |
+
jewelleryBytes = await necklace.read()
|
35 |
+
image, jewellery = Image.open(BytesIO(imageBytes)), Image.open(BytesIO(jewelleryBytes))
|
36 |
+
image_loading_time = round(time.time() - image_loading_start, 2)
|
37 |
+
logger.info(f">>> IMAGES LOADED SUCCESSFULLY in {image_loading_time}s <<<")
|
38 |
+
except Exception as e:
|
39 |
+
logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
|
40 |
+
return JSONResponse(content={
|
41 |
+
"error": f"The requested resource (Image, necklace category, or store) is not available. Please verify the availability and try again",
|
42 |
+
"code": 404}, status_code=404)
|
43 |
+
|
44 |
+
try:
|
45 |
+
nto_start_time = time.time()
|
46 |
+
result, headerText, mask = await pipeline.necklaceTryOnDynamicOffset_(
|
47 |
+
image=image,
|
48 |
+
jewellery=jewellery,
|
49 |
+
storename=storename,
|
50 |
+
offset=[offset_x, offset_y]
|
51 |
+
)
|
52 |
+
nto_time = round(time.time() - nto_start_time, 2)
|
53 |
+
logger.info(f">>> NECKLACE TRY ON PROCESSING COMPLETED in {nto_time}s <<<")
|
54 |
+
|
55 |
+
if result is None:
|
56 |
+
logger.error(">>> NO FACE DETECTED IN THE IMAGE <<<")
|
57 |
+
return JSONResponse(
|
58 |
+
content={"error": "No face detected in the image please try again with a different image",
|
59 |
+
"code": 400}, status_code=400)
|
60 |
+
|
61 |
+
except Exception as e:
|
62 |
+
logger.error(f">>> NECKLACE TRY ON PROCESSING ERROR: {str(e)} <<<")
|
63 |
+
return JSONResponse(content={"error": f"Error during necklace try-on process", "code": 500},
|
64 |
+
status_code=500)
|
65 |
+
result_base_64 = BytesIO()
|
66 |
+
result.save(result_base_64, format="WEBP")
|
67 |
+
result_bytes_ = base64.b64encode(result_base_64.getvalue()).decode("utf-8")
|
68 |
+
image_base64 = f"data:image/webp;base64,{result_bytes_}"
|
69 |
+
|
70 |
+
try:
|
71 |
+
total_time = round(time.time() - start_time, 2)
|
72 |
+
response = {
|
73 |
+
"code": 200,
|
74 |
+
"output": f"{image_base64}",
|
75 |
+
"timing": {
|
76 |
+
"image_loading": image_loading_time,
|
77 |
+
"nto_processing": nto_time,
|
78 |
+
"total": total_time
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
logger.info(f">>> TIMING BREAKDOWN <<<")
|
83 |
+
logger.info(f"Image Loading: {image_loading_time}s")
|
84 |
+
logger.info(f"NTO Processing: {nto_time}s")
|
85 |
+
logger.info(f"Total Time: {total_time}s")
|
86 |
+
logger.info(">>> NECKLACE TRY ON COMPLETED <<<")
|
87 |
+
logger.info("-" * 50)
|
88 |
+
|
89 |
+
return JSONResponse(content=response, status_code=200)
|
90 |
+
|
91 |
+
except Exception as e:
|
92 |
+
logger.error(f">>> RESPONSE GENERATION ERROR: {str(e)} <<<")
|
93 |
+
return JSONResponse(content={"error": f"Error generating response", "code": 500}, status_code=500)
|
94 |
+
|
95 |
+
finally:
|
96 |
+
if 'result' in locals(): del result
|
97 |
+
gc.collect()
|