ishworrsubedii commited on
Commit
3eefc8f
·
1 Parent(s): 692f363

add: detail logging

Browse files
src/api/image_prep_api.py CHANGED
@@ -19,6 +19,7 @@ from fastapi.responses import JSONResponse
19
  from src.components.auto_crop import crop_transparent_image
20
  from src.components.color_extraction import ColorExtractionRMBG
21
  from src.components.title_des_gen import NecklaceProductListing
 
22
 
23
  preprocessing_router = APIRouter()
24
 
@@ -49,12 +50,16 @@ def replicate_enhancer(input):
49
 
50
  @preprocessing_router.post("/rem_bg")
51
  async def remove_background(image: UploadFile = File(...)):
 
 
52
  start_time = time.time()
53
 
54
  try:
55
  image_bytes = await image.read()
56
  image = Image.open(BytesIO(image_bytes)).convert("RGB")
 
57
  except Exception as e:
 
58
  return JSONResponse(status_code=500, content={"error": f"Error reading image: {str(e)}", "code": 500})
59
 
60
  try:
@@ -62,13 +67,17 @@ async def remove_background(image: UploadFile = File(...)):
62
  image.save(act_img_base_64, format="WEBP")
63
  image_bytes_ = base64.b64encode(act_img_base_64.getvalue()).decode("utf-8")
64
  image_data_uri = f"data:image/WEBP;base64,{image_bytes_}"
 
65
  except Exception as e:
 
66
  return JSONResponse(status_code=500,
67
  content={"error": f"Error converting image to base64: {str(e)}", "code": 500})
68
 
69
  try:
70
  output = replicate_bg({"image": image_data_uri})
 
71
  except Exception as e:
 
72
  return JSONResponse(status_code=500,
73
  content={"error": f"Error running background removal: {str(e)}", "code": 500})
74
 
@@ -84,21 +93,30 @@ async def remove_background(image: UploadFile = File(...)):
84
  "inference_time": total_inference_time,
85
  "code": 200
86
  }
 
 
 
 
87
  return JSONResponse(content=response, status_code=200)
88
 
89
  except Exception as e:
 
90
  return JSONResponse(status_code=500,
91
  content={"error": f"Error processing response: {str(e)}", "code": 500})
92
 
93
 
94
  @preprocessing_router.post("/upscale_image")
95
  async def upscale_image(image: UploadFile = File(...), scale: int = 1):
 
 
96
  start_time = time.time()
97
 
98
  try:
99
  image_bytes = await image.read()
100
  image = Image.open(BytesIO(image_bytes)).convert("RGBA")
 
101
  except Exception as e:
 
102
  return JSONResponse(status_code=500, content={"error": f"Error reading image: {str(e)}", "code": 500})
103
 
104
  try:
@@ -106,7 +124,9 @@ async def upscale_image(image: UploadFile = File(...), scale: int = 1):
106
  image.save(act_img_base_64, format="PNG")
107
  image_bytes_ = base64.b64encode(act_img_base_64.getvalue()).decode("utf-8")
108
  image_data_uri = f"data:image/png;base64,{image_bytes_}"
 
109
  except Exception as e:
 
110
  return JSONResponse(status_code=500,
111
  content={"error": f"Error converting image to base64: {str(e)}", "code": 500})
112
 
@@ -117,7 +137,9 @@ async def upscale_image(image: UploadFile = File(...), scale: int = 1):
117
  "face_enhance": False
118
  }
119
  output = replicate_enhancer(input)
 
120
  except Exception as e:
 
121
  return JSONResponse(status_code=500,
122
  content={"error": f"Error running image enhancement: {str(e)}", "code": 500})
123
 
@@ -133,29 +155,40 @@ async def upscale_image(image: UploadFile = File(...), scale: int = 1):
133
  "inference_time": total_inference_time,
134
  "code": 200
135
  }
 
 
 
 
136
  return JSONResponse(content=response, status_code=200)
137
 
138
  except Exception as e:
 
139
  return JSONResponse(status_code=500,
140
  content={"error": f"Error processing response: {str(e)}", "code": 500})
141
 
142
 
143
  @preprocessing_router.post("/crop_transparent")
144
  async def crop_transparent(image: UploadFile):
 
 
145
  start_time = time.time()
146
 
147
  try:
148
  if not image.content_type == "image/png":
 
149
  return JSONResponse(status_code=400,
150
  content={"error": "Only PNG files are supported", "code": 400})
151
  except Exception as e:
 
152
  return JSONResponse(status_code=500,
153
  content={"error": f"Error checking file type: {str(e)}", "code": 500})
154
 
155
  try:
156
  contents = await image.read()
157
  cropped_image_bytes, metadata = crop_transparent_image(contents)
 
158
  except Exception as e:
 
159
  return JSONResponse(status_code=500,
160
  content={"error": f"Error cropping image: {str(e)}", "code": 500})
161
 
@@ -165,6 +198,11 @@ async def crop_transparent(image: UploadFile):
165
 
166
  total_inference_time = round((time.time() - start_time), 2)
167
 
 
 
 
 
 
168
  return JSONResponse(content={
169
  "status": "success",
170
  "code": 200,
@@ -175,12 +213,15 @@ async def crop_transparent(image: UploadFile):
175
  }
176
  }, status_code=200)
177
  except Exception as e:
 
178
  return JSONResponse(status_code=500,
179
  content={"error": f"Error processing response: {str(e)}", "code": 500})
180
 
181
 
182
  @preprocessing_router.post("/background_replace")
183
  async def bg_replace(image: UploadFile = File(...), bg_image: UploadFile = File(...)):
 
 
184
  start_time = time.time()
185
 
186
  try:
@@ -188,7 +229,9 @@ async def bg_replace(image: UploadFile = File(...), bg_image: UploadFile = File(
188
  bg_bytes = await bg_image.read()
189
  image = Image.open(BytesIO(image_bytes)).convert("RGBA")
190
  bg_image = Image.open(BytesIO(bg_bytes)).convert("RGB")
 
191
  except Exception as e:
 
192
  return JSONResponse(status_code=500,
193
  content={"error": f"Error reading images: {str(e)}", "code": 500})
194
 
@@ -197,7 +240,9 @@ async def bg_replace(image: UploadFile = File(...), bg_image: UploadFile = File(
197
  background = Image.fromarray(np.array(bg_image)).resize((width, height))
198
  orig_img = Image.fromarray(np.array(image)).resize((width, height))
199
  background.paste(orig_img, (0, 0), mask=orig_img)
 
200
  except Exception as e:
 
201
  return JSONResponse(status_code=500,
202
  content={"error": f"Error processing images: {str(e)}", "code": 500})
203
 
@@ -209,12 +254,18 @@ async def bg_replace(image: UploadFile = File(...), bg_image: UploadFile = File(
209
 
210
  total_inference_time = round((time.time() - start_time), 2)
211
 
 
 
 
 
 
212
  return JSONResponse(content={
213
  "output": image_data_uri,
214
  "code": 200,
215
  "inference_time": total_inference_time
216
  }, status_code=200)
217
  except Exception as e:
 
218
  return JSONResponse(status_code=500,
219
  content={"error": f"Error creating response: {str(e)}", "code": 500})
220
 
@@ -223,20 +274,26 @@ async def bg_replace(image: UploadFile = File(...), bg_image: UploadFile = File(
223
  async def remove_background_color_extraction(image: UploadFile = File(...),
224
  hex_color: str = "#FFFFFF",
225
  threshold: int = 30):
 
 
226
  start_time = time.time()
227
 
228
  try:
229
  image_bytes = await image.read()
230
  image = Image.open(BytesIO(image_bytes)).convert("RGBA")
231
  image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
 
232
  except Exception as e:
 
233
  return JSONResponse(status_code=500,
234
  content={"error": f"Error reading image: {str(e)}", "code": 500})
235
 
236
  try:
237
  result = color_extraction_rmbg.extract_color(image, hex_color, threshold)
238
  result = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_RGB2BGRA)).convert("RGBA")
 
239
  except Exception as e:
 
240
  return JSONResponse(status_code=500,
241
  content={"error": f"Error extracting colors: {str(e)}", "code": 500})
242
 
@@ -248,24 +305,34 @@ async def remove_background_color_extraction(image: UploadFile = File(...),
248
 
249
  total_inference_time = round((time.time() - start_time), 2)
250
 
 
 
 
 
 
251
  return JSONResponse(content={
252
  "output": image_data_uri,
253
  "code": 200,
254
  "inference_time": total_inference_time
255
  }, status_code=200)
256
  except Exception as e:
 
257
  return JSONResponse(status_code=500,
258
  content={"error": f"Error creating response: {str(e)}", "code": 500})
259
 
260
 
261
  @preprocessing_router.post("/title_description_generator")
262
  async def product_title_description_generator(image: UploadFile = File(...)):
 
 
263
  start_time = time.time()
264
 
265
  try:
266
  image_bytes = await image.read()
267
  image = Image.open(BytesIO(image_bytes)).convert("RGB")
 
268
  except Exception as e:
 
269
  return JSONResponse(status_code=500,
270
  content={"error": f"Error reading image: {str(e)}", "code": 500})
271
 
@@ -273,7 +340,9 @@ async def product_title_description_generator(image: UploadFile = File(...)):
273
  result = product_listing_obj.gen_title_desc(image=image)
274
  title = result.split("Title:")[1].split("Description:")[0]
275
  description = result.split("Description:")[1]
 
276
  except Exception as e:
 
277
  return JSONResponse(status_code=500,
278
  content={"error": "Please make sure the image is clear and necklaces are visible",
279
  "code": 500})
@@ -281,6 +350,11 @@ async def product_title_description_generator(image: UploadFile = File(...)):
281
  try:
282
  total_inference_time = round((time.time() - start_time), 2)
283
 
 
 
 
 
 
284
  return JSONResponse(content={
285
  "code": 200,
286
  "title": title,
@@ -288,5 +362,6 @@ async def product_title_description_generator(image: UploadFile = File(...)):
288
  "inference_time": total_inference_time
289
  }, status_code=200)
290
  except Exception as e:
 
291
  return JSONResponse(status_code=500,
292
  content={"error": f"Error creating response: {str(e)}", "code": 500})
 
19
  from src.components.auto_crop import crop_transparent_image
20
  from src.components.color_extraction import ColorExtractionRMBG
21
  from src.components.title_des_gen import NecklaceProductListing
22
+ from src.utils import logger
23
 
24
  preprocessing_router = APIRouter()
25
 
 
50
 
51
  @preprocessing_router.post("/rem_bg")
52
  async def remove_background(image: UploadFile = File(...)):
53
+ logger.info("-" * 50)
54
+ logger.info(">>> REMOVE BACKGROUND STARTED <<<")
55
  start_time = time.time()
56
 
57
  try:
58
  image_bytes = await image.read()
59
  image = Image.open(BytesIO(image_bytes)).convert("RGB")
60
+ logger.info(">>> IMAGE LOADED SUCCESSFULLY <<<")
61
  except Exception as e:
62
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
63
  return JSONResponse(status_code=500, content={"error": f"Error reading image: {str(e)}", "code": 500})
64
 
65
  try:
 
67
  image.save(act_img_base_64, format="WEBP")
68
  image_bytes_ = base64.b64encode(act_img_base_64.getvalue()).decode("utf-8")
69
  image_data_uri = f"data:image/WEBP;base64,{image_bytes_}"
70
+ logger.info(">>> IMAGE ENCODING COMPLETED <<<")
71
  except Exception as e:
72
+ logger.error(f">>> IMAGE ENCODING ERROR: {str(e)} <<<")
73
  return JSONResponse(status_code=500,
74
  content={"error": f"Error converting image to base64: {str(e)}", "code": 500})
75
 
76
  try:
77
  output = replicate_bg({"image": image_data_uri})
78
+ logger.info(">>> BACKGROUND REMOVAL COMPLETED <<<")
79
  except Exception as e:
80
+ logger.error(f">>> BACKGROUND REMOVAL ERROR: {str(e)} <<<")
81
  return JSONResponse(status_code=500,
82
  content={"error": f"Error running background removal: {str(e)}", "code": 500})
83
 
 
93
  "inference_time": total_inference_time,
94
  "code": 200
95
  }
96
+ logger.info(">>> RESPONSE PREPARATION COMPLETED <<<")
97
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
98
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
99
+ logger.info("-" * 50)
100
  return JSONResponse(content=response, status_code=200)
101
 
102
  except Exception as e:
103
+ logger.error(f">>> RESPONSE PROCESSING ERROR: {str(e)} <<<")
104
  return JSONResponse(status_code=500,
105
  content={"error": f"Error processing response: {str(e)}", "code": 500})
106
 
107
 
108
  @preprocessing_router.post("/upscale_image")
109
  async def upscale_image(image: UploadFile = File(...), scale: int = 1):
110
+ logger.info("-" * 50)
111
+ logger.info(">>> IMAGE UPSCALING STARTED <<<")
112
  start_time = time.time()
113
 
114
  try:
115
  image_bytes = await image.read()
116
  image = Image.open(BytesIO(image_bytes)).convert("RGBA")
117
+ logger.info(">>> IMAGE LOADED SUCCESSFULLY <<<")
118
  except Exception as e:
119
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
120
  return JSONResponse(status_code=500, content={"error": f"Error reading image: {str(e)}", "code": 500})
121
 
122
  try:
 
124
  image.save(act_img_base_64, format="PNG")
125
  image_bytes_ = base64.b64encode(act_img_base_64.getvalue()).decode("utf-8")
126
  image_data_uri = f"data:image/png;base64,{image_bytes_}"
127
+ logger.info(">>> IMAGE ENCODING COMPLETED <<<")
128
  except Exception as e:
129
+ logger.error(f">>> IMAGE ENCODING ERROR: {str(e)} <<<")
130
  return JSONResponse(status_code=500,
131
  content={"error": f"Error converting image to base64: {str(e)}", "code": 500})
132
 
 
137
  "face_enhance": False
138
  }
139
  output = replicate_enhancer(input)
140
+ logger.info(">>> IMAGE ENHANCEMENT COMPLETED <<<")
141
  except Exception as e:
142
+ logger.error(f">>> IMAGE ENHANCEMENT ERROR: {str(e)} <<<")
143
  return JSONResponse(status_code=500,
144
  content={"error": f"Error running image enhancement: {str(e)}", "code": 500})
145
 
 
155
  "inference_time": total_inference_time,
156
  "code": 200
157
  }
158
+ logger.info(">>> RESPONSE PREPARATION COMPLETED <<<")
159
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
160
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
161
+ logger.info("-" * 50)
162
  return JSONResponse(content=response, status_code=200)
163
 
164
  except Exception as e:
165
+ logger.error(f">>> RESPONSE PROCESSING ERROR: {str(e)} <<<")
166
  return JSONResponse(status_code=500,
167
  content={"error": f"Error processing response: {str(e)}", "code": 500})
168
 
169
 
170
  @preprocessing_router.post("/crop_transparent")
171
  async def crop_transparent(image: UploadFile):
172
+ logger.info("-" * 50)
173
+ logger.info(">>> CROP TRANSPARENT STARTED <<<")
174
  start_time = time.time()
175
 
176
  try:
177
  if not image.content_type == "image/png":
178
+ logger.error(">>> INVALID FILE TYPE: NOT PNG <<<")
179
  return JSONResponse(status_code=400,
180
  content={"error": "Only PNG files are supported", "code": 400})
181
  except Exception as e:
182
+ logger.error(f">>> FILE TYPE CHECK ERROR: {str(e)} <<<")
183
  return JSONResponse(status_code=500,
184
  content={"error": f"Error checking file type: {str(e)}", "code": 500})
185
 
186
  try:
187
  contents = await image.read()
188
  cropped_image_bytes, metadata = crop_transparent_image(contents)
189
+ logger.info(">>> IMAGE CROPPING COMPLETED <<<")
190
  except Exception as e:
191
+ logger.error(f">>> IMAGE CROPPING ERROR: {str(e)} <<<")
192
  return JSONResponse(status_code=500,
193
  content={"error": f"Error cropping image: {str(e)}", "code": 500})
194
 
 
198
 
199
  total_inference_time = round((time.time() - start_time), 2)
200
 
201
+ logger.info(">>> RESPONSE PREPARATION COMPLETED <<<")
202
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
203
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
204
+ logger.info("-" * 50)
205
+
206
  return JSONResponse(content={
207
  "status": "success",
208
  "code": 200,
 
213
  }
214
  }, status_code=200)
215
  except Exception as e:
216
+ logger.error(f">>> RESPONSE PROCESSING ERROR: {str(e)} <<<")
217
  return JSONResponse(status_code=500,
218
  content={"error": f"Error processing response: {str(e)}", "code": 500})
219
 
220
 
221
  @preprocessing_router.post("/background_replace")
222
  async def bg_replace(image: UploadFile = File(...), bg_image: UploadFile = File(...)):
223
+ logger.info("-" * 50)
224
+ logger.info(">>> BACKGROUND REPLACE STARTED <<<")
225
  start_time = time.time()
226
 
227
  try:
 
229
  bg_bytes = await bg_image.read()
230
  image = Image.open(BytesIO(image_bytes)).convert("RGBA")
231
  bg_image = Image.open(BytesIO(bg_bytes)).convert("RGB")
232
+ logger.info(">>> IMAGES LOADED SUCCESSFULLY <<<")
233
  except Exception as e:
234
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
235
  return JSONResponse(status_code=500,
236
  content={"error": f"Error reading images: {str(e)}", "code": 500})
237
 
 
240
  background = Image.fromarray(np.array(bg_image)).resize((width, height))
241
  orig_img = Image.fromarray(np.array(image)).resize((width, height))
242
  background.paste(orig_img, (0, 0), mask=orig_img)
243
+ logger.info(">>> IMAGE PROCESSING COMPLETED <<<")
244
  except Exception as e:
245
+ logger.error(f">>> IMAGE PROCESSING ERROR: {str(e)} <<<")
246
  return JSONResponse(status_code=500,
247
  content={"error": f"Error processing images: {str(e)}", "code": 500})
248
 
 
254
 
255
  total_inference_time = round((time.time() - start_time), 2)
256
 
257
+ logger.info(">>> RESPONSE PREPARATION COMPLETED <<<")
258
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
259
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
260
+ logger.info("-" * 50)
261
+
262
  return JSONResponse(content={
263
  "output": image_data_uri,
264
  "code": 200,
265
  "inference_time": total_inference_time
266
  }, status_code=200)
267
  except Exception as e:
268
+ logger.error(f">>> RESPONSE PROCESSING ERROR: {str(e)} <<<")
269
  return JSONResponse(status_code=500,
270
  content={"error": f"Error creating response: {str(e)}", "code": 500})
271
 
 
274
  async def remove_background_color_extraction(image: UploadFile = File(...),
275
  hex_color: str = "#FFFFFF",
276
  threshold: int = 30):
277
+ logger.info("-" * 50)
278
+ logger.info(">>> COLOR EXTRACTION STARTED <<<")
279
  start_time = time.time()
280
 
281
  try:
282
  image_bytes = await image.read()
283
  image = Image.open(BytesIO(image_bytes)).convert("RGBA")
284
  image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
285
+ logger.info(">>> IMAGE LOADED SUCCESSFULLY <<<")
286
  except Exception as e:
287
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
288
  return JSONResponse(status_code=500,
289
  content={"error": f"Error reading image: {str(e)}", "code": 500})
290
 
291
  try:
292
  result = color_extraction_rmbg.extract_color(image, hex_color, threshold)
293
  result = Image.fromarray(cv2.cvtColor(result, cv2.COLOR_RGB2BGRA)).convert("RGBA")
294
+ logger.info(">>> COLOR EXTRACTION COMPLETED <<<")
295
  except Exception as e:
296
+ logger.error(f">>> COLOR EXTRACTION ERROR: {str(e)} <<<")
297
  return JSONResponse(status_code=500,
298
  content={"error": f"Error extracting colors: {str(e)}", "code": 500})
299
 
 
305
 
306
  total_inference_time = round((time.time() - start_time), 2)
307
 
308
+ logger.info(">>> RESPONSE PREPARATION COMPLETED <<<")
309
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
310
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
311
+ logger.info("-" * 50)
312
+
313
  return JSONResponse(content={
314
  "output": image_data_uri,
315
  "code": 200,
316
  "inference_time": total_inference_time
317
  }, status_code=200)
318
  except Exception as e:
319
+ logger.error(f">>> RESPONSE PROCESSING ERROR: {str(e)} <<<")
320
  return JSONResponse(status_code=500,
321
  content={"error": f"Error creating response: {str(e)}", "code": 500})
322
 
323
 
324
  @preprocessing_router.post("/title_description_generator")
325
  async def product_title_description_generator(image: UploadFile = File(...)):
326
+ logger.info("-" * 50)
327
+ logger.info(">>> TITLE DESCRIPTION GENERATION STARTED <<<")
328
  start_time = time.time()
329
 
330
  try:
331
  image_bytes = await image.read()
332
  image = Image.open(BytesIO(image_bytes)).convert("RGB")
333
+ logger.info(">>> IMAGE LOADED SUCCESSFULLY <<<")
334
  except Exception as e:
335
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
336
  return JSONResponse(status_code=500,
337
  content={"error": f"Error reading image: {str(e)}", "code": 500})
338
 
 
340
  result = product_listing_obj.gen_title_desc(image=image)
341
  title = result.split("Title:")[1].split("Description:")[0]
342
  description = result.split("Description:")[1]
343
+ logger.info(">>> TITLE AND DESCRIPTION GENERATION COMPLETED <<<")
344
  except Exception as e:
345
+ logger.error(">>> TITLE DESCRIPTION GENERATION ERROR <<<")
346
  return JSONResponse(status_code=500,
347
  content={"error": "Please make sure the image is clear and necklaces are visible",
348
  "code": 500})
 
350
  try:
351
  total_inference_time = round((time.time() - start_time), 2)
352
 
353
+ logger.info(">>> RESPONSE PREPARATION COMPLETED <<<")
354
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
355
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
356
+ logger.info("-" * 50)
357
+
358
  return JSONResponse(content={
359
  "code": 200,
360
  "title": title,
 
362
  "inference_time": total_inference_time
363
  }, status_code=200)
364
  except Exception as e:
365
+ logger.error(f">>> RESPONSE PROCESSING ERROR: {str(e)} <<<")
366
  return JSONResponse(status_code=500,
367
  content={"error": f"Error creating response: {str(e)}", "code": 500})
src/api/image_regeneration_api.py CHANGED
@@ -13,6 +13,7 @@ import requests
13
  from PIL import Image
14
  from fastapi import APIRouter, UploadFile, File, Form
15
  from fastapi.responses import JSONResponse
 
16
 
17
  image_regeneration_router = APIRouter()
18
 
@@ -48,6 +49,8 @@ async def image_re_gen(
48
  reference_image_c4_weight: Optional[float] = Form(default=0.0),
49
  reference_image_c4_stop: Optional[float] = Form(default=0.0),
50
  ):
 
 
51
  start_time = time.time()
52
 
53
  try:
@@ -60,8 +63,10 @@ async def image_re_gen(
60
  reference_image_b64 = base64.b64encode(ref_img_base64.getvalue()).decode("utf-8")
61
  return f"data:image/WEBP;base64,{reference_image_b64}"
62
  return None
 
63
  except Exception as e:
64
- return JSONResponse(status_code=500,
 
65
  content={"error": f"Error processing reference image: {str(e)}", "code": 500})
66
 
67
  try:
@@ -70,7 +75,9 @@ async def image_re_gen(
70
  img_base64 = BytesIO()
71
  image.save(img_base64, format="WEBP")
72
  image_data_uri = f"data:image/WEBP;base64,{base64.b64encode(img_base64.getvalue()).decode('utf-8')}"
 
73
  except Exception as e:
 
74
  return JSONResponse(status_code=500,
75
  content={"error": f"Error processing main image: {str(e)}", "code": 500})
76
 
@@ -81,7 +88,9 @@ async def image_re_gen(
81
  'c3': await process_reference_image(reference_image_c3),
82
  'c4': await process_reference_image(reference_image_c4)
83
  }
 
84
  except Exception as e:
 
85
  return JSONResponse(status_code=500,
86
  content={"error": f"Error processing reference images: {str(e)}", "code": 500})
87
 
@@ -106,7 +115,9 @@ async def image_re_gen(
106
  mask_image.save(mask_base64, format="WEBP")
107
  mask_image_data_uri = f"data:image/WEBP;base64,{base64.b64encode(mask_base64.getvalue()).decode('utf-8')}"
108
  input_data["inpaint_input_mask"] = mask_image_data_uri
 
109
  except Exception as e:
 
110
  return JSONResponse(status_code=500,
111
  content={"error": f"Error preparing input data: {str(e)}", "code": 500})
112
 
@@ -127,7 +138,9 @@ async def image_re_gen(
127
  stop_value = locals()[f'reference_image_{c}_stop']
128
  if stop_value != 0.0 or stop_value != 0:
129
  input_data[f"cn_stop{i}"] = stop_value
 
130
  except Exception as e:
 
131
  return JSONResponse(status_code=500,
132
  content={"error": f"Error processing reference image parameters: {str(e)}", "code": 500})
133
 
@@ -136,18 +149,24 @@ async def image_re_gen(
136
  response = requests.get(output[0])
137
  output_base64 = base64.b64encode(response.content).decode('utf-8')
138
  base64_prefix = image_data_uri.split(",")[0] + ","
 
139
  except Exception as e:
 
140
  return JSONResponse(status_code=500,
141
  content={"error": f"Error generating image: {str(e)}", "code": 500})
142
 
143
  try:
144
- inference_time = time.time() - start_time
145
  response = {
146
  "output": f"{base64_prefix}{output_base64}",
147
  "inference_time": inference_time,
148
  "code": 200,
149
  }
 
 
 
150
  return JSONResponse(content=response, status_code=200)
151
  except Exception as e:
 
152
  return JSONResponse(status_code=500,
153
  content={"error": f"Error creating response: {str(e)}", "code": 500})
 
13
  from PIL import Image
14
  from fastapi import APIRouter, UploadFile, File, Form
15
  from fastapi.responses import JSONResponse
16
+ from src.utils import logger
17
 
18
  image_regeneration_router = APIRouter()
19
 
 
49
  reference_image_c4_weight: Optional[float] = Form(default=0.0),
50
  reference_image_c4_stop: Optional[float] = Form(default=0.0),
51
  ):
52
+ logger.info("-" * 50)
53
+ logger.info(">>> IMAGE REDESIGN STARTED <<<")
54
  start_time = time.time()
55
 
56
  try:
 
63
  reference_image_b64 = base64.b64encode(ref_img_base64.getvalue()).decode("utf-8")
64
  return f"data:image/WEBP;base64,{reference_image_b64}"
65
  return None
66
+ logger.info(">>> REFERENCE IMAGE PROCESSING FUNCTION INITIALIZED <<<")
67
  except Exception as e:
68
+ logger.error(f">>> REFERENCE IMAGE PROCESSING ERROR: {str(e)} <<<")
69
+ return JSONResponse(status_code=500,
70
  content={"error": f"Error processing reference image: {str(e)}", "code": 500})
71
 
72
  try:
 
75
  img_base64 = BytesIO()
76
  image.save(img_base64, format="WEBP")
77
  image_data_uri = f"data:image/WEBP;base64,{base64.b64encode(img_base64.getvalue()).decode('utf-8')}"
78
+ logger.info(">>> MAIN IMAGE PROCESSED SUCCESSFULLY <<<")
79
  except Exception as e:
80
+ logger.error(f">>> MAIN IMAGE PROCESSING ERROR: {str(e)} <<<")
81
  return JSONResponse(status_code=500,
82
  content={"error": f"Error processing main image: {str(e)}", "code": 500})
83
 
 
88
  'c3': await process_reference_image(reference_image_c3),
89
  'c4': await process_reference_image(reference_image_c4)
90
  }
91
+ logger.info(">>> REFERENCE IMAGES PROCESSED SUCCESSFULLY <<<")
92
  except Exception as e:
93
+ logger.error(f">>> REFERENCE IMAGES PROCESSING ERROR: {str(e)} <<<")
94
  return JSONResponse(status_code=500,
95
  content={"error": f"Error processing reference images: {str(e)}", "code": 500})
96
 
 
115
  mask_image.save(mask_base64, format="WEBP")
116
  mask_image_data_uri = f"data:image/WEBP;base64,{base64.b64encode(mask_base64.getvalue()).decode('utf-8')}"
117
  input_data["inpaint_input_mask"] = mask_image_data_uri
118
+ logger.info(">>> INPUT DATA PREPARED SUCCESSFULLY <<<")
119
  except Exception as e:
120
+ logger.error(f">>> INPUT DATA PREPARATION ERROR: {str(e)} <<<")
121
  return JSONResponse(status_code=500,
122
  content={"error": f"Error preparing input data: {str(e)}", "code": 500})
123
 
 
138
  stop_value = locals()[f'reference_image_{c}_stop']
139
  if stop_value != 0.0 or stop_value != 0:
140
  input_data[f"cn_stop{i}"] = stop_value
141
+ logger.info(">>> REFERENCE IMAGE PARAMETERS PROCESSED <<<")
142
  except Exception as e:
143
+ logger.error(f">>> REFERENCE IMAGE PARAMETERS ERROR: {str(e)} <<<")
144
  return JSONResponse(status_code=500,
145
  content={"error": f"Error processing reference image parameters: {str(e)}", "code": 500})
146
 
 
149
  response = requests.get(output[0])
150
  output_base64 = base64.b64encode(response.content).decode('utf-8')
151
  base64_prefix = image_data_uri.split(",")[0] + ","
152
+ logger.info(">>> IMAGE REGENERATION COMPLETED <<<")
153
  except Exception as e:
154
+ logger.error(f">>> IMAGE REGENERATION ERROR: {str(e)} <<<")
155
  return JSONResponse(status_code=500,
156
  content={"error": f"Error generating image: {str(e)}", "code": 500})
157
 
158
  try:
159
+ inference_time = round(time.time() - start_time, 2)
160
  response = {
161
  "output": f"{base64_prefix}{output_base64}",
162
  "inference_time": inference_time,
163
  "code": 200,
164
  }
165
+ logger.info(f">>> TOTAL INFERENCE TIME: {inference_time}s <<<")
166
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
167
+ logger.info("-" * 50)
168
  return JSONResponse(content=response, status_code=200)
169
  except Exception as e:
170
+ logger.error(f">>> RESPONSE CREATION ERROR: {str(e)} <<<")
171
  return JSONResponse(status_code=500,
172
  content={"error": f"Error creating response: {str(e)}", "code": 500})
src/api/nto_api.py CHANGED
@@ -22,6 +22,7 @@ import os
22
  from pydantic import BaseModel
23
  import replicate
24
  import requests
 
25
 
26
  pipeline = Pipeline()
27
 
@@ -55,18 +56,25 @@ class NecklaceTryOnIDEntity(BaseModel):
55
 
56
  @nto_cto_router.post("/clothingTryOnV2")
57
  async def clothing_try_on_v2(image: UploadFile = File(...), clothing_type: str = Form(...)):
 
 
58
  start_time = time.time()
 
59
  try:
60
  image_bytes = await image.read()
61
  image = Image.open(BytesIO(image_bytes)).convert("RGB")
 
62
  except Exception as e:
 
63
  return JSONResponse(status_code=500, content={"error": f"Error reading image: {str(e)}", "code": 500})
64
 
65
  try:
66
  mask = await pipeline.shoulderPointMaskGeneration_(image=image)
 
67
  except Exception as e:
 
68
  return JSONResponse(status_code=500,
69
- content={"error": f"Error generating mask: {str(e)}", "code": 500})
70
 
71
  try:
72
  mask_img_base_64, act_img_base_64 = BytesIO(), BytesIO()
@@ -77,9 +85,11 @@ async def clothing_try_on_v2(image: UploadFile = File(...), clothing_type: str =
77
 
78
  mask_data_uri = f"data:image/webp;base64,{mask_bytes_}"
79
  image_data_uri = f"data:image/webp;base64,{image_bytes_}"
 
80
  except Exception as e:
 
81
  return JSONResponse(status_code=500,
82
- content={"error": f"Error converting images to base64: {str(e)}", "code": 500})
83
 
84
  input = {
85
  "mask": mask_data_uri,
@@ -91,10 +101,15 @@ async def clothing_try_on_v2(image: UploadFile = File(...), clothing_type: str =
91
 
92
  try:
93
  output = replicate_run_cto(input)
 
94
  except Exception as e:
 
95
  return JSONResponse(content={"error": f"Error running CTO Replicate: {str(e)}", "code": 500}, status_code=500)
96
 
97
  total_inference_time = round((time.time() - start_time), 2)
 
 
 
98
 
99
  response = {
100
  "code": 200,
@@ -108,12 +123,17 @@ async def clothing_try_on_v2(image: UploadFile = File(...), clothing_type: str =
108
  @nto_cto_router.post("/clothingTryOn")
109
  async def clothing_try_on(image: UploadFile = File(...),
110
  mask: UploadFile = File(...), clothing_type: str = Form(...)):
 
 
111
  start_time = time.time()
 
112
  try:
113
  image_bytes = await image.read()
114
  mask_bytes = await mask.read()
115
  image, mask = Image.open(BytesIO(image_bytes)).convert("RGB"), Image.open(BytesIO(mask_bytes)).convert("RGB")
 
116
  except Exception as e:
 
117
  return JSONResponse(status_code=500, content={"error": f"Error reading image or mask: {str(e)}", "code": 500})
118
 
119
  try:
@@ -129,7 +149,9 @@ async def clothing_try_on(image: UploadFile = File(...),
129
  arr[mask_y:, :] = 255
130
 
131
  mask = Image.fromarray(arr).resize((512, 512))
 
132
  except Exception as e:
 
133
  return JSONResponse(status_code=500,
134
  content={"error": f"Error processing image or mask: {str(e)}", "code": 500})
135
 
@@ -142,7 +164,9 @@ async def clothing_try_on(image: UploadFile = File(...),
142
 
143
  mask_data_uri = f"data:image/webp;base64,{mask_bytes_}"
144
  image_data_uri = f"data:image/webp;base64,{image_bytes_}"
 
145
  except Exception as e:
 
146
  return JSONResponse(status_code=500,
147
  content={"error": f"Error encoding images to base64: {str(e)}", "code": 500})
148
 
@@ -156,8 +180,11 @@ async def clothing_try_on(image: UploadFile = File(...),
156
 
157
  try:
158
  output = replicate_run_cto(input)
 
159
  except Exception as e:
 
160
  return JSONResponse(content={"error": f"Error running CTO Replicate: {str(e)}", "code": 500}, status_code=500)
 
161
  try:
162
  response = requests.get(output[0])
163
  output_image = Image.open(BytesIO(response.content)).resize(actual_image.size)
@@ -169,6 +196,7 @@ async def clothing_try_on(image: UploadFile = File(...),
169
  result.save(in_mem_file, format="WEBP", quality=85)
170
  base_64_output = base64.b64encode(in_mem_file.getvalue()).decode('utf-8')
171
  total_inference_time = round((time.time() - start_time), 2)
 
172
 
173
  response = {
174
  "output": f"data:image/WEBP;base64,{base_64_output}",
@@ -176,10 +204,14 @@ async def clothing_try_on(image: UploadFile = File(...),
176
  "inference_time": total_inference_time
177
  }
178
  except Exception as e:
 
179
  return JSONResponse(status_code=500, content={"error": f"Error processing output image: {str(e)}", "code": 500})
180
 
181
- return JSONResponse(content=response, status_code=200)
 
 
182
 
 
183
 
184
  @nto_cto_router.post("/productData/{storeId}")
185
  async def product_data(
@@ -327,21 +359,29 @@ async def parse_necklace_try_on_id(necklaceImageId: str = Form(...),
327
  @nto_cto_router.post("/necklaceTryOnID")
328
  async def necklace_try_on_id(necklace_try_on_id: NecklaceTryOnIDEntity = Depends(parse_necklace_try_on_id),
329
  image: UploadFile = File(...)):
 
 
330
  start_time = time.time()
 
331
  try:
332
  data, _ = supabase.table("APIKeyList").select("*").filter("API_KEY", "eq",
333
  necklace_try_on_id.api_token).execute()
334
  api_key_actual = data[1][0]['API_KEY']
335
  if api_key_actual != necklace_try_on_id.api_token:
 
336
  return JSONResponse(content={"error": "Invalid API Key"}, status_code=401)
 
337
  except Exception as e:
 
338
  return JSONResponse(content={"error": f"Error validating API key: {str(e)}", "code": 500}, status_code=500)
339
 
340
  try:
341
  imageBytes = await image.read()
342
  jewellery_url = f"https://lvuhhlrkcuexzqtsbqyu.supabase.co/storage/v1/object/public/Stores/{necklace_try_on_id.storename}/{necklace_try_on_id.necklaceCategory}/image/{necklace_try_on_id.necklaceImageId}.png"
343
  image, jewellery = Image.open(BytesIO(imageBytes)), Image.open(returnBytesData(url=jewellery_url))
 
344
  except Exception as e:
 
345
  return JSONResponse(content={
346
  "error": f"The requested resource (Image, necklace category, or store) is not available. Please verify the availability and try again. Error: {str(e)}",
347
  "code": 404}, status_code=404)
@@ -349,7 +389,9 @@ async def necklace_try_on_id(necklace_try_on_id: NecklaceTryOnIDEntity = Depends
349
  try:
350
  result, headetText, mask = await pipeline.necklaceTryOn_(image=image, jewellery=jewellery,
351
  storename=necklace_try_on_id.storename)
 
352
  except Exception as e:
 
353
  return JSONResponse(content={"error": f"Error during necklace try-on process: {str(e)}", "code": 500},
354
  status_code=500)
355
 
@@ -360,7 +402,9 @@ async def necklace_try_on_id(necklace_try_on_id: NecklaceTryOnIDEntity = Depends
360
  mask.save(inMemFileMask, format="WEBP", quality=85)
361
  outputBytes = inMemFile.getvalue()
362
  maskBytes = inMemFileMask.getvalue()
 
363
  except Exception as e:
 
364
  return JSONResponse(content={"error": f"Error saving result images: {str(e)}", "code": 500}, status_code=500)
365
 
366
  try:
@@ -373,22 +417,34 @@ async def necklace_try_on_id(necklace_try_on_id: NecklaceTryOnIDEntity = Depends
373
  "inference_time": total_backend_time
374
  }
375
  if creditResponse == "No Credits Available":
 
376
  response = {"error": "No Credits Remaining"}
377
  return JSONResponse(content=response, status_code=402)
 
378
  except Exception as e:
 
379
  return JSONResponse(content={"error": f"Error deducting credits: {str(e)}", "code": 500}, status_code=500)
380
 
381
- return JSONResponse(content=response, status_code=200)
 
 
382
 
 
383
 
384
  @nto_cto_router.post("/canvasPoints")
385
  async def canvas_points(necklace_try_on_id: NecklaceTryOnIDEntity = Depends(parse_necklace_try_on_id),
386
  image: UploadFile = File(...)):
 
 
 
 
387
  try:
388
  imageBytes = await image.read()
389
  jewellery_url = f"https://lvuhhlrkcuexzqtsbqyu.supabase.co/storage/v1/object/public/Stores/{necklace_try_on_id.storename}/{necklace_try_on_id.necklaceCategory}/image/{necklace_try_on_id.necklaceImageId}.png"
390
  image, jewellery = Image.open(BytesIO(imageBytes)), Image.open(returnBytesData(url=jewellery_url))
 
391
  except Exception as e:
 
392
  return JSONResponse(content={
393
  "error": f"The requested resource (Image, necklace category, or store) is not available. Please verify the availability and try again. Error: {str(e)}",
394
  "code": 404}, status_code=404)
@@ -396,18 +452,28 @@ async def canvas_points(necklace_try_on_id: NecklaceTryOnIDEntity = Depends(pars
396
  try:
397
  response = await pipeline.canvasPoint(image=image, jewellery=jewellery, storename=necklace_try_on_id.storename)
398
  response = {"code": 200, "output": response}
 
399
  except Exception as e:
 
400
  return JSONResponse(content={"error": f"Error during canvas point process: {str(e)}", "code": 500},
401
  status_code=500)
402
 
403
  try:
404
  creditResponse = deductAndTrackCredit(storename=necklace_try_on_id.storename, endpoint="/necklaceTryOnID")
405
  if creditResponse == "No Credits Available":
 
406
  return JSONResponse(content={"error": "No Credits Remaining", "code": 402}, status_code=402)
 
407
  except Exception as e:
 
408
  return JSONResponse(content={"error": f"Error deducting credits: {str(e)}", "code": 500}, status_code=500)
409
 
410
- return JSONResponse(status_code=200, content={response})
 
 
 
 
 
411
 
412
 
413
  @nto_cto_router.post("/necklaceTryOnWithPoints")
@@ -417,12 +483,17 @@ async def necklace_try_on_with_points(necklace_try_on_id: NecklaceTryOnIDEntity
417
  left_y: int = Form(...),
418
  right_x: int = Form(...),
419
  right_y: int = Form(...)):
 
 
420
  start_time = time.time()
 
421
  try:
422
  imageBytes = await image.read()
423
  jewellery_url = f"https://lvuhhlrkcuexzqtsbqyu.supabase.co/storage/v1/object/public/Stores/{necklace_try_on_id.storename}/{necklace_try_on_id.necklaceCategory}/image/{necklace_try_on_id.necklaceImageId}.png"
424
  image, jewellery = Image.open(BytesIO(imageBytes)), Image.open(returnBytesData(url=jewellery_url))
 
425
  except Exception as e:
 
426
  return JSONResponse(content={
427
  "error": f"The requested resource (Image, necklace category, or store) is not available. Please verify the availability and try again. Error: {str(e)}",
428
  "code": 404}, status_code=404)
@@ -432,7 +503,9 @@ async def necklace_try_on_with_points(necklace_try_on_id: NecklaceTryOnIDEntity
432
  image=image, jewellery=jewellery, left_shoulder=(left_x, left_y), right_shoulder=(right_x, right_y),
433
  storename=necklace_try_on_id.storename
434
  )
 
435
  except Exception as e:
 
436
  return JSONResponse(content={"error": f"Error during necklace try-on process: {str(e)}", "code": 500},
437
  status_code=500)
438
 
@@ -443,7 +516,9 @@ async def necklace_try_on_with_points(necklace_try_on_id: NecklaceTryOnIDEntity
443
  mask.save(inMemFileMask, format="WEBP", quality=85)
444
  outputBytes = inMemFile.getvalue()
445
  maskBytes = inMemFileMask.getvalue()
 
446
  except Exception as e:
 
447
  return JSONResponse(content={"error": f"Error saving result images: {str(e)}", "code": 500}, status_code=500)
448
 
449
  try:
@@ -456,9 +531,16 @@ async def necklace_try_on_with_points(necklace_try_on_id: NecklaceTryOnIDEntity
456
  "inference_time": total_inference_time
457
  }
458
  if creditResponse == "No Credits Available":
 
459
  response = {"error": "No Credits Remaining"}
460
  return JSONResponse(content=response, status_code=402)
 
461
  except Exception as e:
 
462
  return JSONResponse(content={"error": f"Error deducting credits: {str(e)}", "code": 500}, status_code=500)
463
 
 
 
 
 
464
  return JSONResponse(content=response, status_code=200)
 
22
  from pydantic import BaseModel
23
  import replicate
24
  import requests
25
+ from src.utils.logger import logger
26
 
27
  pipeline = Pipeline()
28
 
 
56
 
57
  @nto_cto_router.post("/clothingTryOnV2")
58
  async def clothing_try_on_v2(image: UploadFile = File(...), clothing_type: str = Form(...)):
59
+ logger.info("-" * 50)
60
+ logger.info(">>> CLOTHING TRY ON V2 STARTED <<<")
61
  start_time = time.time()
62
+
63
  try:
64
  image_bytes = await image.read()
65
  image = Image.open(BytesIO(image_bytes)).convert("RGB")
66
+ logger.info(">>> IMAGE LOADED SUCCESSFULLY <<<")
67
  except Exception as e:
68
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
69
  return JSONResponse(status_code=500, content={"error": f"Error reading image: {str(e)}", "code": 500})
70
 
71
  try:
72
  mask = await pipeline.shoulderPointMaskGeneration_(image=image)
73
+ logger.info(">>> MASK GENERATION COMPLETED <<<")
74
  except Exception as e:
75
+ logger.error(f">>> MASK GENERATION ERROR: {str(e)} <<<")
76
  return JSONResponse(status_code=500,
77
+ content={"error": f"Error generating mask: {str(e)}", "code": 500})
78
 
79
  try:
80
  mask_img_base_64, act_img_base_64 = BytesIO(), BytesIO()
 
85
 
86
  mask_data_uri = f"data:image/webp;base64,{mask_bytes_}"
87
  image_data_uri = f"data:image/webp;base64,{image_bytes_}"
88
+ logger.info(">>> IMAGE ENCODING COMPLETED <<<")
89
  except Exception as e:
90
+ logger.error(f">>> IMAGE ENCODING ERROR: {str(e)} <<<")
91
  return JSONResponse(status_code=500,
92
+ content={"error": f"Error converting images to base64: {str(e)}", "code": 500})
93
 
94
  input = {
95
  "mask": mask_data_uri,
 
101
 
102
  try:
103
  output = replicate_run_cto(input)
104
+ logger.info(">>> REPLICATE PROCESSING COMPLETED <<<")
105
  except Exception as e:
106
+ logger.error(f">>> REPLICATE PROCESSING ERROR: {str(e)} <<<")
107
  return JSONResponse(content={"error": f"Error running CTO Replicate: {str(e)}", "code": 500}, status_code=500)
108
 
109
  total_inference_time = round((time.time() - start_time), 2)
110
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
111
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
112
+ logger.info("-" * 50)
113
 
114
  response = {
115
  "code": 200,
 
123
  @nto_cto_router.post("/clothingTryOn")
124
  async def clothing_try_on(image: UploadFile = File(...),
125
  mask: UploadFile = File(...), clothing_type: str = Form(...)):
126
+ logger.info("-" * 50)
127
+ logger.info(">>> CLOTHING TRY ON STARTED <<<")
128
  start_time = time.time()
129
+
130
  try:
131
  image_bytes = await image.read()
132
  mask_bytes = await mask.read()
133
  image, mask = Image.open(BytesIO(image_bytes)).convert("RGB"), Image.open(BytesIO(mask_bytes)).convert("RGB")
134
+ logger.info(">>> IMAGES LOADED SUCCESSFULLY <<<")
135
  except Exception as e:
136
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
137
  return JSONResponse(status_code=500, content={"error": f"Error reading image or mask: {str(e)}", "code": 500})
138
 
139
  try:
 
149
  arr[mask_y:, :] = 255
150
 
151
  mask = Image.fromarray(arr).resize((512, 512))
152
+ logger.info(">>> IMAGE PROCESSING COMPLETED <<<")
153
  except Exception as e:
154
+ logger.error(f">>> IMAGE PROCESSING ERROR: {str(e)} <<<")
155
  return JSONResponse(status_code=500,
156
  content={"error": f"Error processing image or mask: {str(e)}", "code": 500})
157
 
 
164
 
165
  mask_data_uri = f"data:image/webp;base64,{mask_bytes_}"
166
  image_data_uri = f"data:image/webp;base64,{image_bytes_}"
167
+ logger.info(">>> IMAGE ENCODING COMPLETED <<<")
168
  except Exception as e:
169
+ logger.error(f">>> IMAGE ENCODING ERROR: {str(e)} <<<")
170
  return JSONResponse(status_code=500,
171
  content={"error": f"Error encoding images to base64: {str(e)}", "code": 500})
172
 
 
180
 
181
  try:
182
  output = replicate_run_cto(input)
183
+ logger.info(">>> REPLICATE PROCESSING COMPLETED <<<")
184
  except Exception as e:
185
+ logger.error(f">>> REPLICATE PROCESSING ERROR: {str(e)} <<<")
186
  return JSONResponse(content={"error": f"Error running CTO Replicate: {str(e)}", "code": 500}, status_code=500)
187
+
188
  try:
189
  response = requests.get(output[0])
190
  output_image = Image.open(BytesIO(response.content)).resize(actual_image.size)
 
196
  result.save(in_mem_file, format="WEBP", quality=85)
197
  base_64_output = base64.b64encode(in_mem_file.getvalue()).decode('utf-8')
198
  total_inference_time = round((time.time() - start_time), 2)
199
+ logger.info(">>> OUTPUT IMAGE PROCESSING COMPLETED <<<")
200
 
201
  response = {
202
  "output": f"data:image/WEBP;base64,{base_64_output}",
 
204
  "inference_time": total_inference_time
205
  }
206
  except Exception as e:
207
+ logger.error(f">>> OUTPUT IMAGE PROCESSING ERROR: {str(e)} <<<")
208
  return JSONResponse(status_code=500, content={"error": f"Error processing output image: {str(e)}", "code": 500})
209
 
210
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
211
+ logger.info(">>> REQUEST COMPLETED SUCCESSFULLY <<<")
212
+ logger.info("-" * 50)
213
 
214
+ return JSONResponse(content=response, status_code=200)
215
 
216
  @nto_cto_router.post("/productData/{storeId}")
217
  async def product_data(
 
359
  @nto_cto_router.post("/necklaceTryOnID")
360
  async def necklace_try_on_id(necklace_try_on_id: NecklaceTryOnIDEntity = Depends(parse_necklace_try_on_id),
361
  image: UploadFile = File(...)):
362
+ logger.info("-" * 50)
363
+ logger.info(f">>> NECKLACE TRY ON ID STARTED :: {necklace_try_on_id.storename} <<<")
364
  start_time = time.time()
365
+
366
  try:
367
  data, _ = supabase.table("APIKeyList").select("*").filter("API_KEY", "eq",
368
  necklace_try_on_id.api_token).execute()
369
  api_key_actual = data[1][0]['API_KEY']
370
  if api_key_actual != necklace_try_on_id.api_token:
371
+ logger.error(">>> API KEY VALIDATION FAILED <<<")
372
  return JSONResponse(content={"error": "Invalid API Key"}, status_code=401)
373
+ logger.info(">>> API KEY VALIDATION SUCCESSFUL <<<")
374
  except Exception as e:
375
+ logger.error(f">>> API KEY VALIDATION ERROR: {str(e)} <<<")
376
  return JSONResponse(content={"error": f"Error validating API key: {str(e)}", "code": 500}, status_code=500)
377
 
378
  try:
379
  imageBytes = await image.read()
380
  jewellery_url = f"https://lvuhhlrkcuexzqtsbqyu.supabase.co/storage/v1/object/public/Stores/{necklace_try_on_id.storename}/{necklace_try_on_id.necklaceCategory}/image/{necklace_try_on_id.necklaceImageId}.png"
381
  image, jewellery = Image.open(BytesIO(imageBytes)), Image.open(returnBytesData(url=jewellery_url))
382
+ logger.info(">>> IMAGES LOADED SUCCESSFULLY <<<")
383
  except Exception as e:
384
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
385
  return JSONResponse(content={
386
  "error": f"The requested resource (Image, necklace category, or store) is not available. Please verify the availability and try again. Error: {str(e)}",
387
  "code": 404}, status_code=404)
 
389
  try:
390
  result, headetText, mask = await pipeline.necklaceTryOn_(image=image, jewellery=jewellery,
391
  storename=necklace_try_on_id.storename)
392
+ logger.info(">>> NECKLACE TRY ON PROCESSING COMPLETED <<<")
393
  except Exception as e:
394
+ logger.error(f">>> NECKLACE TRY ON PROCESSING ERROR: {str(e)} <<<")
395
  return JSONResponse(content={"error": f"Error during necklace try-on process: {str(e)}", "code": 500},
396
  status_code=500)
397
 
 
402
  mask.save(inMemFileMask, format="WEBP", quality=85)
403
  outputBytes = inMemFile.getvalue()
404
  maskBytes = inMemFileMask.getvalue()
405
+ logger.info(">>> RESULT IMAGES SAVED <<<")
406
  except Exception as e:
407
+ logger.error(f">>> RESULT SAVING ERROR: {str(e)} <<<")
408
  return JSONResponse(content={"error": f"Error saving result images: {str(e)}", "code": 500}, status_code=500)
409
 
410
  try:
 
417
  "inference_time": total_backend_time
418
  }
419
  if creditResponse == "No Credits Available":
420
+ logger.error(">>> NO CREDITS REMAINING <<<")
421
  response = {"error": "No Credits Remaining"}
422
  return JSONResponse(content=response, status_code=402)
423
+ logger.info(">>> CREDITS DEDUCTED SUCCESSFULLY <<<")
424
  except Exception as e:
425
+ logger.error(f">>> CREDIT DEDUCTION ERROR: {str(e)} <<<")
426
  return JSONResponse(content={"error": f"Error deducting credits: {str(e)}", "code": 500}, status_code=500)
427
 
428
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_backend_time}s <<<")
429
+ logger.info(f">>> NECKLACE TRY ON COMPLETED :: {necklace_try_on_id.storename} <<<")
430
+ logger.info("-" * 50)
431
 
432
+ return JSONResponse(content=response, status_code=200)
433
 
434
  @nto_cto_router.post("/canvasPoints")
435
  async def canvas_points(necklace_try_on_id: NecklaceTryOnIDEntity = Depends(parse_necklace_try_on_id),
436
  image: UploadFile = File(...)):
437
+ logger.info("-" * 50)
438
+ logger.info(f">>> CANVAS POINTS STARTED :: {necklace_try_on_id.storename} <<<")
439
+ start_time = time.time()
440
+
441
  try:
442
  imageBytes = await image.read()
443
  jewellery_url = f"https://lvuhhlrkcuexzqtsbqyu.supabase.co/storage/v1/object/public/Stores/{necklace_try_on_id.storename}/{necklace_try_on_id.necklaceCategory}/image/{necklace_try_on_id.necklaceImageId}.png"
444
  image, jewellery = Image.open(BytesIO(imageBytes)), Image.open(returnBytesData(url=jewellery_url))
445
+ logger.info(">>> IMAGES LOADED SUCCESSFULLY <<<")
446
  except Exception as e:
447
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
448
  return JSONResponse(content={
449
  "error": f"The requested resource (Image, necklace category, or store) is not available. Please verify the availability and try again. Error: {str(e)}",
450
  "code": 404}, status_code=404)
 
452
  try:
453
  response = await pipeline.canvasPoint(image=image, jewellery=jewellery, storename=necklace_try_on_id.storename)
454
  response = {"code": 200, "output": response}
455
+ logger.info(">>> CANVAS POINTS PROCESSING COMPLETED <<<")
456
  except Exception as e:
457
+ logger.error(f">>> CANVAS POINTS PROCESSING ERROR: {str(e)} <<<")
458
  return JSONResponse(content={"error": f"Error during canvas point process: {str(e)}", "code": 500},
459
  status_code=500)
460
 
461
  try:
462
  creditResponse = deductAndTrackCredit(storename=necklace_try_on_id.storename, endpoint="/necklaceTryOnID")
463
  if creditResponse == "No Credits Available":
464
+ logger.error(">>> NO CREDITS REMAINING <<<")
465
  return JSONResponse(content={"error": "No Credits Remaining", "code": 402}, status_code=402)
466
+ logger.info(">>> CREDITS DEDUCTED SUCCESSFULLY <<<")
467
  except Exception as e:
468
+ logger.error(f">>> CREDIT DEDUCTION ERROR: {str(e)} <<<")
469
  return JSONResponse(content={"error": f"Error deducting credits: {str(e)}", "code": 500}, status_code=500)
470
 
471
+ total_inference_time = round((time.time() - start_time), 2)
472
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
473
+ logger.info(f">>> CANVAS POINTS COMPLETED :: {necklace_try_on_id.storename} <<<")
474
+ logger.info("-" * 50)
475
+
476
+ return JSONResponse(status_code=200, content=response)
477
 
478
 
479
  @nto_cto_router.post("/necklaceTryOnWithPoints")
 
483
  left_y: int = Form(...),
484
  right_x: int = Form(...),
485
  right_y: int = Form(...)):
486
+ logger.info("-" * 50)
487
+ logger.info(f">>> NECKLACE TRY ON WITH POINTS STARTED :: {necklace_try_on_id.storename} <<<")
488
  start_time = time.time()
489
+
490
  try:
491
  imageBytes = await image.read()
492
  jewellery_url = f"https://lvuhhlrkcuexzqtsbqyu.supabase.co/storage/v1/object/public/Stores/{necklace_try_on_id.storename}/{necklace_try_on_id.necklaceCategory}/image/{necklace_try_on_id.necklaceImageId}.png"
493
  image, jewellery = Image.open(BytesIO(imageBytes)), Image.open(returnBytesData(url=jewellery_url))
494
+ logger.info(">>> IMAGES LOADED SUCCESSFULLY <<<")
495
  except Exception as e:
496
+ logger.error(f">>> IMAGE LOADING ERROR: {str(e)} <<<")
497
  return JSONResponse(content={
498
  "error": f"The requested resource (Image, necklace category, or store) is not available. Please verify the availability and try again. Error: {str(e)}",
499
  "code": 404}, status_code=404)
 
503
  image=image, jewellery=jewellery, left_shoulder=(left_x, left_y), right_shoulder=(right_x, right_y),
504
  storename=necklace_try_on_id.storename
505
  )
506
+ logger.info(">>> NECKLACE TRY ON PROCESSING COMPLETED <<<")
507
  except Exception as e:
508
+ logger.error(f">>> NECKLACE TRY ON PROCESSING ERROR: {str(e)} <<<")
509
  return JSONResponse(content={"error": f"Error during necklace try-on process: {str(e)}", "code": 500},
510
  status_code=500)
511
 
 
516
  mask.save(inMemFileMask, format="WEBP", quality=85)
517
  outputBytes = inMemFile.getvalue()
518
  maskBytes = inMemFileMask.getvalue()
519
+ logger.info(">>> RESULT IMAGES SAVED <<<")
520
  except Exception as e:
521
+ logger.error(f">>> RESULT SAVING ERROR: {str(e)} <<<")
522
  return JSONResponse(content={"error": f"Error saving result images: {str(e)}", "code": 500}, status_code=500)
523
 
524
  try:
 
531
  "inference_time": total_inference_time
532
  }
533
  if creditResponse == "No Credits Available":
534
+ logger.error(">>> NO CREDITS REMAINING <<<")
535
  response = {"error": "No Credits Remaining"}
536
  return JSONResponse(content=response, status_code=402)
537
+ logger.info(">>> CREDITS DEDUCTED SUCCESSFULLY <<<")
538
  except Exception as e:
539
+ logger.error(f">>> CREDIT DEDUCTION ERROR: {str(e)} <<<")
540
  return JSONResponse(content={"error": f"Error deducting credits: {str(e)}", "code": 500}, status_code=500)
541
 
542
+ logger.info(f">>> TOTAL INFERENCE TIME: {total_inference_time}s <<<")
543
+ logger.info(f">>> NECKLACE TRY ON WITH POINTS COMPLETED :: {necklace_try_on_id.storename} <<<")
544
+ logger.info("-" * 50)
545
+
546
  return JSONResponse(content=response, status_code=200)