Akshajzclap commited on
Commit
bd55a25
·
verified ·
1 Parent(s): 7e12844

Upload 89 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. .gitignore +55 -0
  3. README.md +29 -13
  4. app/__pycache__/main.cpython-310.pyc +0 -0
  5. app/__pycache__/main.cpython-38.pyc +0 -0
  6. app/api/__init__.py +0 -0
  7. app/api/__pycache__/__init__.cpython-310.pyc +0 -0
  8. app/api/__pycache__/__init__.cpython-38.pyc +0 -0
  9. app/api/routers/v1/__init__.py +0 -0
  10. app/api/routers/v1/__pycache__/__init__.cpython-310.pyc +0 -0
  11. app/api/routers/v1/__pycache__/__init__.cpython-38.pyc +0 -0
  12. app/api/routers/v1/__pycache__/background_edit.cpython-310.pyc +0 -0
  13. app/api/routers/v1/__pycache__/detail_shots.cpython-310.pyc +0 -0
  14. app/api/routers/v1/__pycache__/editorial.cpython-310.pyc +0 -0
  15. app/api/routers/v1/__pycache__/health.cpython-310.pyc +0 -0
  16. app/api/routers/v1/__pycache__/mannequin.cpython-310.pyc +0 -0
  17. app/api/routers/v1/__pycache__/multi_view.cpython-310.pyc +0 -0
  18. app/api/routers/v1/__pycache__/occasion.cpython-310.pyc +0 -0
  19. app/api/routers/v1/__pycache__/outfitmatch.cpython-310.pyc +0 -0
  20. app/api/routers/v1/__pycache__/outfitmatch.cpython-38.pyc +0 -0
  21. app/api/routers/v1/__pycache__/size_comparision.cpython-310.pyc +0 -0
  22. app/api/routers/v1/__pycache__/tryon.cpython-310.pyc +0 -0
  23. app/api/routers/v1/__pycache__/two_object_size.cpython-310.pyc +0 -0
  24. app/api/routers/v1/__pycache__/whatfits.cpython-310.pyc +0 -0
  25. app/api/routers/v1/background_edit.py +70 -0
  26. app/api/routers/v1/detail_shots.py +37 -0
  27. app/api/routers/v1/editorial.py +81 -0
  28. app/api/routers/v1/health.py +7 -0
  29. app/api/routers/v1/mannequin.py +37 -0
  30. app/api/routers/v1/multi_view.py +37 -0
  31. app/api/routers/v1/occasion.py +84 -0
  32. app/api/routers/v1/outfitmatch.py +84 -0
  33. app/api/routers/v1/size_comparision.py +68 -0
  34. app/api/routers/v1/tryon.py +84 -0
  35. app/api/routers/v1/two_object_size.py +65 -0
  36. app/api/routers/v1/whatfits.py +56 -0
  37. app/core/__pycache__/config.cpython-310.pyc +0 -0
  38. app/core/config.py +13 -0
  39. app/furniture/beds/bed - 2.jpg +0 -0
  40. app/furniture/beds/bed -1.jpeg +0 -0
  41. app/furniture/sofa/sofa-1.jpeg +3 -0
  42. app/furniture/sofa/sofa-2.jpg +0 -0
  43. app/schemas/__pycache__/common_schemas.cpython-310.pyc +0 -0
  44. app/schemas/common_schemas.py +45 -0
  45. app/services/__init__.py +0 -0
  46. app/services/__pycache__/__init__.cpython-310.pyc +0 -0
  47. app/services/__pycache__/__init__.cpython-38.pyc +0 -0
  48. app/services/__pycache__/image_generation_service.cpython-310.pyc +0 -0
  49. app/services/__pycache__/image_generation_service.cpython-38.pyc +0 -0
  50. app/services/__pycache__/prompt_factory.cpython-310.pyc +0 -0
.gitattributes CHANGED
@@ -35,3 +35,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  vendor-usecase-app/app/furniture/sofa/sofa-1.jpeg filter=lfs diff=lfs merge=lfs -text
37
  vendor-usecase-app/generated_image.png filter=lfs diff=lfs merge=lfs -text
 
 
 
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  vendor-usecase-app/app/furniture/sofa/sofa-1.jpeg filter=lfs diff=lfs merge=lfs -text
37
  vendor-usecase-app/generated_image.png filter=lfs diff=lfs merge=lfs -text
38
+ app/furniture/sofa/sofa-1.jpeg filter=lfs diff=lfs merge=lfs -text
39
+ generated_image.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # These are some examples of commonly ignored file patterns.
2
+ # You should customize this list as applicable to your project.
3
+ # Learn more about .gitignore:
4
+ # https://www.atlassian.com/git/tutorials/saving-changes/gitignore
5
+
6
+ # Node artifact files
7
+ node_modules/
8
+ dist/
9
+
10
+ # Compiled Java class files
11
+ *.class
12
+
13
+ # Compiled Python bytecode
14
+ *.py[cod]
15
+
16
+ # Log files
17
+ *.log
18
+
19
+ # Package files
20
+ *.jar
21
+
22
+ # Maven
23
+ target/
24
+ dist/
25
+
26
+ # JetBrains IDE
27
+ .idea/
28
+
29
+ # Unit test reports
30
+ TEST*.xml
31
+
32
+ # Generated by MacOS
33
+ .DS_Store
34
+
35
+ # Generated by Windows
36
+ Thumbs.db
37
+
38
+ # Applications
39
+ *.app
40
+ *.exe
41
+ *.war
42
+
43
+ # Large media files
44
+ *.mp4
45
+ *.tiff
46
+ *.avi
47
+ *.flv
48
+ *.mov
49
+ *.wmv
50
+
51
+ .env
52
+ generated_image*
53
+ sample_images/
54
+ test.py
55
+ pqr.py
README.md CHANGED
@@ -1,13 +1,29 @@
1
- ---
2
- title: VTO
3
- emoji:
4
- colorFrom: gray
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.49.1
8
- app_file: app.py
9
- pinned: false
10
- license: apache-2.0
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # README #
2
+
3
+ This README would normally document whatever steps are necessary to get your application up and running.
4
+
5
+ ### What is this repository for? ###
6
+
7
+ * Quick summary
8
+ * Version
9
+ * [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
10
+
11
+ ### How do I get set up? ###
12
+
13
+ * Summary of set up
14
+ * Configuration
15
+ * Dependencies
16
+ * Database configuration
17
+ * How to run tests
18
+ * Deployment instructions
19
+
20
+ ### Contribution guidelines ###
21
+
22
+ * Writing tests
23
+ * Code review
24
+ * Other guidelines
25
+
26
+ ### Who do I talk to? ###
27
+
28
+ * Repo owner or admin
29
+ * Other community or team contact
app/__pycache__/main.cpython-310.pyc ADDED
Binary file (1.26 kB). View file
 
app/__pycache__/main.cpython-38.pyc ADDED
Binary file (1.13 kB). View file
 
app/api/__init__.py ADDED
File without changes
app/api/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (166 Bytes). View file
 
app/api/__pycache__/__init__.cpython-38.pyc ADDED
Binary file (164 Bytes). View file
 
app/api/routers/v1/__init__.py ADDED
File without changes
app/api/routers/v1/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (177 Bytes). View file
 
app/api/routers/v1/__pycache__/__init__.cpython-38.pyc ADDED
Binary file (175 Bytes). View file
 
app/api/routers/v1/__pycache__/background_edit.cpython-310.pyc ADDED
Binary file (2.62 kB). View file
 
app/api/routers/v1/__pycache__/detail_shots.cpython-310.pyc ADDED
Binary file (1.63 kB). View file
 
app/api/routers/v1/__pycache__/editorial.cpython-310.pyc ADDED
Binary file (2.8 kB). View file
 
app/api/routers/v1/__pycache__/health.cpython-310.pyc ADDED
Binary file (449 Bytes). View file
 
app/api/routers/v1/__pycache__/mannequin.cpython-310.pyc ADDED
Binary file (1.62 kB). View file
 
app/api/routers/v1/__pycache__/multi_view.cpython-310.pyc ADDED
Binary file (1.63 kB). View file
 
app/api/routers/v1/__pycache__/occasion.cpython-310.pyc ADDED
Binary file (2.8 kB). View file
 
app/api/routers/v1/__pycache__/outfitmatch.cpython-310.pyc ADDED
Binary file (2.9 kB). View file
 
app/api/routers/v1/__pycache__/outfitmatch.cpython-38.pyc ADDED
Binary file (2.86 kB). View file
 
app/api/routers/v1/__pycache__/size_comparision.cpython-310.pyc ADDED
Binary file (2.27 kB). View file
 
app/api/routers/v1/__pycache__/tryon.cpython-310.pyc ADDED
Binary file (2.87 kB). View file
 
app/api/routers/v1/__pycache__/two_object_size.cpython-310.pyc ADDED
Binary file (2.16 kB). View file
 
app/api/routers/v1/__pycache__/whatfits.cpython-310.pyc ADDED
Binary file (1.93 kB). View file
 
app/api/routers/v1/background_edit.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import BACKGROUND_EDIT_TEMPLATE
5
+ from app.schemas.common_schemas import ModelSchema, CameraSchema,GarmentType,SurfaceType
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/background_edit", tags=["Background_edit"])
12
+ async def background_edit(
13
+ garment_type: Annotated[str, Form()],
14
+ surface_type: Annotated[str, Form()],
15
+ camera_view_angle: Annotated[str, Form()],
16
+ camera_distance_meters: Annotated[float, Form()],
17
+ camera_focal_length_mm: Annotated[float, Form()],
18
+ camera_aperture_f_number: Annotated[float, Form()],
19
+ camera_lighting_condition: Annotated[str, Form()],
20
+ camera_background: Annotated[str, Form()],
21
+ garment_images: List[UploadFile] = File(..., description="Exactly one image of the garments (e.g., dress /bag/shoes).", min_items=1, max_items=1),
22
+ ):
23
+ """
24
+ Generate a try-on image based on garment images, model characteristics, and camera settings.
25
+ """
26
+ try:
27
+ garment=GarmentType(garment_type=garment_type)
28
+ surface=SurfaceType(surface_type=surface_type)
29
+ camera_settings = CameraSchema(
30
+ view_angle=camera_view_angle,
31
+ distance_meters=camera_distance_meters,
32
+ focal_length_mm=camera_focal_length_mm,
33
+ aperture_f_number=camera_aperture_f_number,
34
+ lighting_condition=camera_lighting_condition,
35
+ background=camera_background
36
+ )
37
+ except Exception as e:
38
+ raise HTTPException(status_code=400, detail=f"Invalid model or camera attributes: {e}")
39
+
40
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
41
+ if not garment_images or len(garment_images) != 1:
42
+ raise HTTPException(status_code=400, detail="Exactly one garment images are required for outfit match.")
43
+
44
+ image_bytes_list = []
45
+ for image_file in garment_images: # No need to check if garment_images is None here
46
+ if not image_file.content_type.startswith("image/"):
47
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
48
+ content = await image_file.read()
49
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
50
+
51
+ prompt=BACKGROUND_EDIT_TEMPLATE.format(
52
+ garment_type=garment.garment_type,
53
+ surface_type=surface.surface_type,
54
+ camera_view_angle=camera_settings.view_angle,
55
+ camera_distance_meters=camera_settings.distance_meters,
56
+ camera_focal_length_mm=camera_settings.focal_length_mm,
57
+ camera_aperture_f_number=camera_settings.aperture_f_number,
58
+ camera_lighting_condition=camera_settings.lighting_condition,
59
+ camera_background=camera_settings.background
60
+ )
61
+
62
+ generated_image_data = await generate_image_from_files_and_prompt(
63
+ image_files=image_bytes_list,
64
+ prompt=prompt
65
+ )
66
+
67
+ if generated_image_data:
68
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
69
+ else:
70
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/detail_shots.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import DETAIL_SHOTS_TEMPLATE
5
+ from app.schemas.common_schemas import ModelSchema, CameraSchema,GarmentType
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/detail", tags=["details-shots"])
12
+ async def detail(
13
+ garment_images: List[UploadFile] = File(..., description="Exactly one image of the garments (e.g., dress /bag/shoes).", min_items=1, max_items=1),
14
+ ):
15
+
16
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
17
+ if not garment_images or len(garment_images) != 1:
18
+ raise HTTPException(status_code=400, detail="Exactly one garment images are required for outfit match.")
19
+
20
+ image_bytes_list = []
21
+ for image_file in garment_images: # No need to check if garment_images is None here
22
+ if not image_file.content_type.startswith("image/"):
23
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
24
+ content = await image_file.read()
25
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
26
+
27
+ prompt=DETAIL_SHOTS_TEMPLATE
28
+
29
+ generated_image_data = await generate_image_from_files_and_prompt(
30
+ image_files=image_bytes_list,
31
+ prompt=prompt
32
+ )
33
+
34
+ if generated_image_data:
35
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
36
+ else:
37
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/editorial.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import EDITORIAL_PROMPT_TEMPLATE
5
+ from app.schemas.common_schemas import ModelSchema, CameraSchema,GarmentType
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/editorial", tags=["Editorial"])
12
+ async def tryon(
13
+ model_gender: Annotated[str, Form()],
14
+ model_age_range: Annotated[str, Form()],
15
+ model_body_shape: Annotated[str, Form()],
16
+ model_race_ethnicity: Annotated[str, Form()],
17
+ model_pose: Annotated[str, Form()],
18
+ camera_view_angle: Annotated[str, Form()],
19
+ camera_distance_meters: Annotated[float, Form()],
20
+ camera_focal_length_mm: Annotated[float, Form()],
21
+ camera_aperture_f_number: Annotated[float, Form()],
22
+ camera_lighting_condition: Annotated[str, Form()],
23
+ camera_background: Annotated[str, Form()],
24
+ garment_images: List[UploadFile] = File(..., description="Exactly one image of the garments (e.g., dress /bag/shoes).", min_items=1, max_items=1),
25
+ ):
26
+ """
27
+ Generate a editorial style image based on garment images, model characteristics, and camera settings.
28
+ """
29
+ try:
30
+ model_attributes = ModelSchema(
31
+ gender=model_gender,
32
+ age_range=model_age_range,
33
+ body_shape=model_body_shape,
34
+ race_ethnicity=model_race_ethnicity,
35
+ pose=model_pose
36
+ )
37
+ camera_settings = CameraSchema(
38
+ view_angle=camera_view_angle,
39
+ distance_meters=camera_distance_meters,
40
+ focal_length_mm=camera_focal_length_mm,
41
+ aperture_f_number=camera_aperture_f_number,
42
+ lighting_condition=camera_lighting_condition,
43
+ background=camera_background
44
+ )
45
+ except Exception as e:
46
+ raise HTTPException(status_code=400, detail=f"Invalid model or camera attributes: {e}")
47
+
48
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
49
+ if not garment_images or len(garment_images) != 1:
50
+ raise HTTPException(status_code=400, detail="Exactly one garment images are required for outfit match.")
51
+
52
+ image_bytes_list = []
53
+ for image_file in garment_images: # No need to check if garment_images is None here
54
+ if not image_file.content_type.startswith("image/"):
55
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
56
+ content = await image_file.read()
57
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
58
+
59
+ prompt=EDITORIAL_PROMPT_TEMPLATE.format(
60
+ model_gender=model_attributes.gender,
61
+ model_age_range=model_attributes.age_range,
62
+ model_race_ethnicity=model_attributes.race_ethnicity,
63
+ model_body_shape=model_attributes.body_shape,
64
+ model_pose=model_attributes.pose,
65
+ camera_view_angle=camera_settings.view_angle,
66
+ camera_distance_meters=camera_settings.distance_meters,
67
+ camera_focal_length_mm=camera_settings.focal_length_mm,
68
+ camera_aperture_f_number=camera_settings.aperture_f_number,
69
+ camera_lighting_condition=camera_settings.lighting_condition,
70
+ camera_background=camera_settings.background
71
+ )
72
+
73
+ generated_image_data = await generate_image_from_files_and_prompt(
74
+ image_files=image_bytes_list,
75
+ prompt=prompt
76
+ )
77
+
78
+ if generated_image_data:
79
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
80
+ else:
81
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/health.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter
2
+
3
+ router = APIRouter()
4
+
5
+ @router.get("/health", tags=["Health"])
6
+ async def health_check():
7
+ return {"status": "healthy", "message": "API is up and running!"}
app/api/routers/v1/mannequin.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import MANNEQUIN_TEMPLATE
5
+ from app.schemas.common_schemas import ModelSchema, CameraSchema,GarmentType
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/mannequin", tags=["MANNEQUIN"])
12
+ async def mannequin(
13
+ garment_images: List[UploadFile] = File(..., description="Exactly one image of the garments (e.g., dress /bag/shoes).", min_items=1, max_items=1),
14
+ ):
15
+
16
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
17
+ if not garment_images or len(garment_images) != 1:
18
+ raise HTTPException(status_code=400, detail="Exactly one garment images are required for outfit match.")
19
+
20
+ image_bytes_list = []
21
+ for image_file in garment_images: # No need to check if garment_images is None here
22
+ if not image_file.content_type.startswith("image/"):
23
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
24
+ content = await image_file.read()
25
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
26
+
27
+ prompt=MANNEQUIN_TEMPLATE
28
+
29
+ generated_image_data = await generate_image_from_files_and_prompt(
30
+ image_files=image_bytes_list,
31
+ prompt=prompt
32
+ )
33
+
34
+ if generated_image_data:
35
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
36
+ else:
37
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/multi_view.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import MULTI_VIEW_TEMPLATE
5
+ from app.schemas.common_schemas import ModelSchema, CameraSchema,GarmentType
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/multi_view", tags=["Multi_view"])
12
+ async def multi_view(
13
+ garment_images: List[UploadFile] = File(..., description="Exactly one image of the garments (e.g., dress /bag/shoes).", min_items=1, max_items=1),
14
+ ):
15
+
16
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
17
+ if not garment_images or len(garment_images) != 1:
18
+ raise HTTPException(status_code=400, detail="Exactly one garment images are required for outfit match.")
19
+
20
+ image_bytes_list = []
21
+ for image_file in garment_images: # No need to check if garment_images is None here
22
+ if not image_file.content_type.startswith("image/"):
23
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
24
+ content = await image_file.read()
25
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
26
+
27
+ prompt=MULTI_VIEW_TEMPLATE
28
+
29
+ generated_image_data = await generate_image_from_files_and_prompt(
30
+ image_files=image_bytes_list,
31
+ prompt=prompt
32
+ )
33
+
34
+ if generated_image_data:
35
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
36
+ else:
37
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/occasion.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import OCCASION_BASED_PROMPT_TEMPLATE
5
+ from app.schemas.common_schemas import ModelSchema, CameraSchema,GarmentType
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/occasion", tags=["occasion-based-styling"])
12
+ async def occasion_based(
13
+ garment_type: Annotated[str, Form()],
14
+ model_gender: Annotated[str, Form()],
15
+ model_age_range: Annotated[str, Form()],
16
+ model_body_shape: Annotated[str, Form()],
17
+ model_race_ethnicity: Annotated[str, Form()],
18
+ model_pose: Annotated[str, Form()],
19
+ camera_view_angle: Annotated[str, Form()],
20
+ camera_distance_meters: Annotated[float, Form()],
21
+ camera_focal_length_mm: Annotated[float, Form()],
22
+ camera_aperture_f_number: Annotated[float, Form()],
23
+ camera_lighting_condition: Annotated[str, Form()],
24
+ camera_background: Annotated[str, Form()],
25
+ garment_images: List[UploadFile] = File(..., description="Exactly one image of the garments (e.g., dress /bag/shoes).", min_items=1, max_items=1),
26
+ ):
27
+ # """
28
+ # Generate a try-on image based on garment images, model characteristics, and camera settings.
29
+ # """
30
+ try:
31
+ garment=GarmentType(garment_type=garment_type)
32
+ model_attributes = ModelSchema(
33
+ gender=model_gender,
34
+ age_range=model_age_range,
35
+ body_shape=model_body_shape,
36
+ race_ethnicity=model_race_ethnicity,
37
+ pose=model_pose
38
+ )
39
+ camera_settings = CameraSchema(
40
+ view_angle=camera_view_angle,
41
+ distance_meters=camera_distance_meters,
42
+ focal_length_mm=camera_focal_length_mm,
43
+ aperture_f_number=camera_aperture_f_number,
44
+ lighting_condition=camera_lighting_condition,
45
+ background=camera_background
46
+ )
47
+ except Exception as e:
48
+ raise HTTPException(status_code=400, detail=f"Invalid model or camera attributes: {e}")
49
+
50
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
51
+ if not garment_images or len(garment_images) != 1:
52
+ raise HTTPException(status_code=400, detail="Exactly one garment images are required for outfit match.")
53
+
54
+ image_bytes_list = []
55
+ for image_file in garment_images: # No need to check if garment_images is None here
56
+ if not image_file.content_type.startswith("image/"):
57
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
58
+ content = await image_file.read()
59
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
60
+
61
+ prompt=OCCASION_BASED_PROMPT_TEMPLATE.format(
62
+ garment_type=garment.garment_type,
63
+ model_gender=model_attributes.gender,
64
+ model_age_range=model_attributes.age_range,
65
+ model_race_ethnicity=model_attributes.race_ethnicity,
66
+ model_body_shape=model_attributes.body_shape,
67
+ model_pose=model_attributes.pose,
68
+ camera_view_angle=camera_settings.view_angle,
69
+ camera_distance_meters=camera_settings.distance_meters,
70
+ camera_focal_length_mm=camera_settings.focal_length_mm,
71
+ camera_aperture_f_number=camera_settings.aperture_f_number,
72
+ camera_lighting_condition=camera_settings.lighting_condition,
73
+ camera_background=camera_settings.background
74
+ )
75
+
76
+ generated_image_data = await generate_image_from_files_and_prompt(
77
+ image_files=image_bytes_list,
78
+ prompt=prompt
79
+ )
80
+
81
+ if generated_image_data:
82
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
83
+ else:
84
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/outfitmatch.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.schemas.common_schemas import ModelSchema, CameraSchema, GarmentType
5
+ from app.services.prompt_factory import OUTFIT_MATCH_PROMPT_TEMPLATE
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/outfit-match", tags=["Outfit Match"])
12
+ async def outfit_match_tryon(
13
+ garment_type: Annotated[str, Form()],
14
+ model_gender: Annotated[str, Form()],
15
+ model_age_range: Annotated[str, Form()],
16
+ model_body_shape: Annotated[str, Form()],
17
+ model_race_ethnicity: Annotated[str, Form()],
18
+ model_pose: Annotated[str, Form()],
19
+ camera_view_angle: Annotated[str, Form()],
20
+ camera_distance_meters: Annotated[float, Form()],
21
+ camera_focal_length_mm: Annotated[float, Form()],
22
+ camera_aperture_f_number: Annotated[float, Form()],
23
+ camera_lighting_condition: Annotated[str, Form()],
24
+ camera_background: Annotated[str, Form()],
25
+ garment_images: List[UploadFile] = File(..., description="Exactly two images of the garments (e.g., dress and bag).", min_items=2, max_items=2),
26
+ ):
27
+ """
28
+ Generate a try-on image based on garment images, model characteristics, and camera settings.
29
+ """
30
+ try:
31
+ garment=GarmentType(garment_type=garment_type)
32
+ model_attributes = ModelSchema(
33
+ gender=model_gender,
34
+ age_range=model_age_range,
35
+ body_shape=model_body_shape,
36
+ race_ethnicity=model_race_ethnicity,
37
+ pose=model_pose
38
+ )
39
+ camera_settings = CameraSchema(
40
+ view_angle=camera_view_angle,
41
+ distance_meters=camera_distance_meters,
42
+ focal_length_mm=camera_focal_length_mm,
43
+ aperture_f_number=camera_aperture_f_number,
44
+ lighting_condition=camera_lighting_condition,
45
+ background=camera_background
46
+ )
47
+ except Exception as e:
48
+ raise HTTPException(status_code=400, detail=f"Invalid model or camera attributes: {e}")
49
+
50
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
51
+ if not garment_images or len(garment_images) != 2:
52
+ raise HTTPException(status_code=400, detail="Exactly two garment images are required for outfit match.")
53
+
54
+ image_bytes_list = []
55
+ for image_file in garment_images: # No need to check if garment_images is None here
56
+ if not image_file.content_type.startswith("image/"):
57
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
58
+ content = await image_file.read()
59
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
60
+
61
+ prompt=OUTFIT_MATCH_PROMPT_TEMPLATE.format(
62
+ garment_type=garment.garment_type,
63
+ model_gender=model_attributes.gender,
64
+ model_age_range=model_attributes.age_range,
65
+ model_race_ethnicity=model_attributes.race_ethnicity,
66
+ model_body_shape=model_attributes.body_shape,
67
+ model_pose=model_attributes.pose,
68
+ camera_view_angle=camera_settings.view_angle,
69
+ camera_distance_meters=camera_settings.distance_meters,
70
+ camera_focal_length_mm=camera_settings.focal_length_mm,
71
+ camera_aperture_f_number=camera_settings.aperture_f_number,
72
+ camera_lighting_condition=camera_settings.lighting_condition,
73
+ camera_background=camera_settings.background
74
+ )
75
+
76
+ generated_image_data = await generate_image_from_files_and_prompt(
77
+ image_files=image_bytes_list,
78
+ prompt=prompt
79
+ )
80
+
81
+ if generated_image_data:
82
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
83
+ else:
84
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/size_comparision.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import SIZE_COMPARISION_TEMPLATE, JEWELLERY_SIZE_COMPARISION_TEMPLATE
5
+ from app.schemas.common_schemas import DimensionSchema,GarmentType
6
+ import io
7
+ from typing import Annotated, List, Optional
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/size", tags=["size-comparision"])
12
+ async def size(
13
+ garment_type: str = Form(...),
14
+ product_height: Optional[float] = Form(default=None),
15
+ product_width: Optional[float] = Form(default=None),
16
+ product_length: Optional[float] = Form(default=None),
17
+ garment_images: List[UploadFile] = File(..., description="Front-shot image of the handbag/jewellery", min_items=1, max_items=1),
18
+ ):
19
+ # """
20
+ # Generate what fits inside the bag
21
+ # """
22
+ try:
23
+ product_dimensions=DimensionSchema(
24
+ height_cm=product_height,
25
+ width_cm=product_width,
26
+ length_cm=product_length
27
+ )
28
+ except Exception as e:
29
+ raise HTTPException(status_code=400, detail=f"Invalid dimensions: {e}")
30
+
31
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
32
+ if not garment_images or len(garment_images) != 1:
33
+ raise HTTPException(status_code=400, detail="Exactly one front shot of the image")
34
+
35
+ image_bytes_list = []
36
+ for image_file in garment_images: # No need to check if garment_images is None here
37
+ if not image_file.content_type.startswith("image/"):
38
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
39
+ content = await image_file.read()
40
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
41
+
42
+ if garment_type=="handbags":
43
+ prompt = SIZE_COMPARISION_TEMPLATE.format(
44
+ height_cm=product_dimensions.height_cm if product_dimensions.height_cm is not None else "N/A",
45
+ width_cm=product_dimensions.width_cm if product_dimensions.width_cm is not None else "N/A",
46
+ length_cm=product_dimensions.length_cm if product_dimensions.length_cm is not None else "N/A"
47
+ )
48
+
49
+ elif garment_type=="jewellery and watches":
50
+ prompt=JEWELLERY_SIZE_COMPARISION_TEMPLATE.format(
51
+ height_cm=product_dimensions.height_cm if product_dimensions.height_cm is not None else "N/A",
52
+ width_cm=product_dimensions.width_cm if product_dimensions.width_cm is not None else "N/A",
53
+ length_cm=product_dimensions.length_cm if product_dimensions.length_cm is not None else "N/A"
54
+ )
55
+ else:
56
+ raise HTTPException(status_code=400, detail=f"Invalid garment type")
57
+
58
+
59
+
60
+ generated_image_data = await generate_image_from_files_and_prompt(
61
+ image_files=image_bytes_list,
62
+ prompt=prompt
63
+ )
64
+
65
+ if generated_image_data:
66
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
67
+ else:
68
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/tryon.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import LIFESTYLE_TRYON_PROMPT_TEMPLATE
5
+ from app.schemas.common_schemas import ModelSchema, CameraSchema,GarmentType
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/tryon", tags=["TRY-ON"])
12
+ async def tryon(
13
+ garment_type: Annotated[str, Form()],
14
+ model_gender: Annotated[str, Form()],
15
+ model_age_range: Annotated[str, Form()],
16
+ model_body_shape: Annotated[str, Form()],
17
+ model_race_ethnicity: Annotated[str, Form()],
18
+ model_pose: Annotated[str, Form()],
19
+ camera_view_angle: Annotated[str, Form()],
20
+ camera_distance_meters: Annotated[float, Form()],
21
+ camera_focal_length_mm: Annotated[float, Form()],
22
+ camera_aperture_f_number: Annotated[float, Form()],
23
+ camera_lighting_condition: Annotated[str, Form()],
24
+ camera_background: Annotated[str, Form()],
25
+ garment_images: List[UploadFile] = File(..., description="Exactly one image of the garments (e.g., dress /bag/shoes).", min_items=1, max_items=1),
26
+ ):
27
+ """
28
+ Generate a try-on image based on garment images, model characteristics, and camera settings.
29
+ """
30
+ try:
31
+ garment=GarmentType(garment_type=garment_type)
32
+ model_attributes = ModelSchema(
33
+ gender=model_gender,
34
+ age_range=model_age_range,
35
+ body_shape=model_body_shape,
36
+ race_ethnicity=model_race_ethnicity,
37
+ pose=model_pose
38
+ )
39
+ camera_settings = CameraSchema(
40
+ view_angle=camera_view_angle,
41
+ distance_meters=camera_distance_meters,
42
+ focal_length_mm=camera_focal_length_mm,
43
+ aperture_f_number=camera_aperture_f_number,
44
+ lighting_condition=camera_lighting_condition,
45
+ background=camera_background
46
+ )
47
+ except Exception as e:
48
+ raise HTTPException(status_code=400, detail=f"Invalid model or camera attributes: {e}")
49
+
50
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
51
+ if not garment_images or len(garment_images) != 1:
52
+ raise HTTPException(status_code=400, detail="Exactly one garment images are required for outfit match.")
53
+
54
+ image_bytes_list = []
55
+ for image_file in garment_images: # No need to check if garment_images is None here
56
+ if not image_file.content_type.startswith("image/"):
57
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
58
+ content = await image_file.read()
59
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
60
+
61
+ prompt=LIFESTYLE_TRYON_PROMPT_TEMPLATE.format(
62
+ garment_type=garment.garment_type,
63
+ model_gender=model_attributes.gender,
64
+ model_age_range=model_attributes.age_range,
65
+ model_race_ethnicity=model_attributes.race_ethnicity,
66
+ model_body_shape=model_attributes.body_shape,
67
+ model_pose=model_attributes.pose,
68
+ camera_view_angle=camera_settings.view_angle,
69
+ camera_distance_meters=camera_settings.distance_meters,
70
+ camera_focal_length_mm=camera_settings.focal_length_mm,
71
+ camera_aperture_f_number=camera_settings.aperture_f_number,
72
+ camera_lighting_condition=camera_settings.lighting_condition,
73
+ camera_background=camera_settings.background
74
+ )
75
+
76
+ generated_image_data = await generate_image_from_files_and_prompt(
77
+ image_files=image_bytes_list,
78
+ prompt=prompt
79
+ )
80
+
81
+ if generated_image_data:
82
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
83
+ else:
84
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/two_object_size.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import WALLET_SIZE_COMPARISION_TEMPLATE
5
+ from app.schemas.common_schemas import DimensionSchema
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/walletsize", tags=["wallet-size-comparision"])
12
+ async def size(
13
+ product_height1: Annotated[float, Form()],
14
+ product_width1: Annotated[float, Form()],
15
+ product_length1: Annotated[float, Form()],
16
+ product_height2: Annotated[float, Form()],
17
+ product_width2: Annotated[float, Form()],
18
+ product_length2: Annotated[float, Form()],
19
+ garment_images: List[UploadFile] = File(..., description="Front-shot images of the two handbags", min_items=2, max_items=2),
20
+ ):
21
+ """
22
+ Compare two wallets
23
+ """
24
+ try:
25
+
26
+ product_dimensions=DimensionSchema(
27
+ height_cm1=product_height1,
28
+ width_cm1=product_width1,
29
+ length_cm1=product_length1,
30
+ height_cm2=product_height2,
31
+ width_cm2=product_width2,
32
+ length_cm2=product_length2
33
+ )
34
+ except Exception as e:
35
+ raise HTTPException(status_code=400, detail=f"Invalid dimensions: {e}")
36
+
37
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
38
+ if not garment_images or len(garment_images) != 2:
39
+ raise HTTPException(status_code=400, detail="Exactly two front shot images of wallet")
40
+
41
+ image_bytes_list = []
42
+ for image_file in garment_images: # No need to check if garment_images is None here
43
+ if not image_file.content_type.startswith("image/"):
44
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
45
+ content = await image_file.read()
46
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
47
+
48
+ prompt=WALLET_SIZE_COMPARISION_TEMPLATE.format(
49
+ height_cm1=product_dimensions.height_cm1,
50
+ width_cm1=product_dimensions.width_cm1,
51
+ length_cm1=product_dimensions.length_cm1,
52
+ height_cm2=product_dimensions.height_cm2,
53
+ width_cm2=product_dimensions.width_cm2,
54
+ length_cm2=product_dimensions.length_cm2
55
+ )
56
+
57
+ generated_image_data = await generate_image_from_files_and_prompt(
58
+ image_files=image_bytes_list,
59
+ prompt=prompt
60
+ )
61
+
62
+ if generated_image_data:
63
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
64
+ else:
65
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/api/routers/v1/whatfits.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, File, UploadFile, HTTPException, Form
2
+ from fastapi.responses import StreamingResponse
3
+ from app.services.image_generation_service import generate_image_from_files_and_prompt
4
+ from app.services.prompt_factory import WHAT_FITS_INSIDE_TEMPLATE
5
+ from app.schemas.common_schemas import DimensionSchema
6
+ import io
7
+ from typing import List, Annotated
8
+
9
+ router = APIRouter()
10
+
11
+ @router.post("/whatfits", tags=["what-fits"])
12
+ async def whatfits(
13
+ product_height: Annotated[float, Form()],
14
+ product_width: Annotated[float, Form()],
15
+ product_length: Annotated[float, Form()],
16
+ garment_images: List[UploadFile] = File(..., description="Top-shot image of the handbag", min_items=1, max_items=1),
17
+ ):
18
+ """
19
+ Generate what fits inside the bag
20
+ """
21
+ try:
22
+
23
+ product_dimensions=DimensionSchema(
24
+ height_cm=product_height,
25
+ width_cm=product_width,
26
+ length_cm=product_length
27
+ )
28
+ except Exception as e:
29
+ raise HTTPException(status_code=400, detail=f"Invalid dimensions: {e}")
30
+
31
+ # Validation for exactly two files (FastAPI also handles min_items/max_items for File, but explicit check is fine)
32
+ if not garment_images or len(garment_images) != 1:
33
+ raise HTTPException(status_code=400, detail="Exactly one top shot of the image")
34
+
35
+ image_bytes_list = []
36
+ for image_file in garment_images: # No need to check if garment_images is None here
37
+ if not image_file.content_type.startswith("image/"):
38
+ raise HTTPException(status_code=400, detail=f"Invalid file type for garment: {image_file.filename}. Must be an image.")
39
+ content = await image_file.read()
40
+ image_bytes_list.append((content, image_file.filename)) # Store as tuple (bytes, filename)
41
+
42
+ prompt=WHAT_FITS_INSIDE_TEMPLATE.format(
43
+ height_cm=product_dimensions.height_cm,
44
+ width_cm=product_dimensions.width_cm,
45
+ length_cm=product_dimensions.length_cm
46
+ )
47
+
48
+ generated_image_data = await generate_image_from_files_and_prompt(
49
+ image_files=image_bytes_list,
50
+ prompt=prompt
51
+ )
52
+
53
+ if generated_image_data:
54
+ return StreamingResponse(io.BytesIO(generated_image_data), media_type="image/png")
55
+ else:
56
+ raise HTTPException(status_code=500, detail="Failed to generate image. Check service logs.")
app/core/__pycache__/config.cpython-310.pyc ADDED
Binary file (660 Bytes). View file
 
app/core/config.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic_settings import BaseSettings, SettingsConfigDict
2
+ import os
3
+
4
+ class Settings(BaseSettings):
5
+ GEMINI_API_KEY: str
6
+ IMAGE_GEN_MODEL: str = "gemini-2.0-flash-preview-image-generation"
7
+
8
+ # Pydantic-settings will automatically look for a .env file
9
+ # and load variables from there if they match the field names.
10
+ model_config = SettingsConfigDict(env_file=".env", env_file_encoding='utf-8', extra='ignore')
11
+
12
+ # Create a single instance of the settings to be used throughout the application
13
+ settings = Settings()
app/furniture/beds/bed - 2.jpg ADDED
app/furniture/beds/bed -1.jpeg ADDED
app/furniture/sofa/sofa-1.jpeg ADDED

Git LFS Details

  • SHA256: 14c060918ba58721823c73938152a62c5cc35340cae72cc1af4a39eb1b2969c7
  • Pointer size: 131 Bytes
  • Size of remote file: 439 kB
app/furniture/sofa/sofa-2.jpg ADDED
app/schemas/__pycache__/common_schemas.cpython-310.pyc ADDED
Binary file (3.19 kB). View file
 
app/schemas/common_schemas.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+
3
+ class GarmentType(BaseModel):
4
+ garment_type: str =Field(description="The type of product", enum=["clothing","jewellery and watches","wallet","shoes","handbags"])
5
+
6
+ class ModelSchema(BaseModel):
7
+ gender: str = Field(description="The gender of the person in the image", enum=["female"])
8
+ age_range: str = Field(description="The age range of the person in the image", enum=["teen", "18-25", "26-35", "36-45", "46-55", "56-65", "66+"])
9
+ body_shape: str = Field(description="The body shape of the person in the image", enum=["rectangle", "pear", "hourglass", "inverted_triangle"])
10
+ race_ethnicity: str = Field(description="The race and ethnicity of the person in the image", enum=["white", "black", "asian", "latino", "mixed"])
11
+ pose: str = Field(description="The pose of the person in the image", enum=["standing", "sitting", "lying down", "dancing", "running", "jumping", "walking", "bending", "twisting", "stretching", "flexing", "posing"])
12
+
13
+ class CameraSchema(BaseModel):
14
+ view_angle: str = Field(description="The view angle of the camera", enum=["front", "45deg", "left", "right", "back"])
15
+ distance_meters: float = Field(description="The distance of the camera from the person in the image")
16
+ focal_length_mm: float = Field(description="The focal length of the camera in millimeters")
17
+ aperture_f_number: float = Field(description="The aperture f-number of the camera")
18
+ lighting_condition: str = Field(description="The lighting condition of the image", enum=["studio_softbox", "outdoor_sunny", "indoor_warm", "flat"])
19
+ background: str = Field(
20
+ description="The background of the image",
21
+ enum=[
22
+ "White",
23
+ "Lifestyle",
24
+ "Beach Settings",
25
+ "Cafe Environment",
26
+ "Spring Garden",
27
+ "Winter Snow",
28
+ "Professional Settings"
29
+ ]
30
+ )
31
+
32
+
33
+ class DimensionSchema(BaseModel):
34
+ height_cm: float | None = Field(None, description="Height of the product in centimeters.")
35
+ width_cm: float | None = Field(None, description="Width of the product in centimeters.")
36
+ length_cm: float | None = Field(None, description="Length of the product in centimeters.")
37
+ height_cm1: float | None = Field(None, description="Height of the product in centimeters.")
38
+ width_cm1: float | None = Field(None, description="Width of the product in centimeters.")
39
+ length_cm1: float | None = Field(None, description="Length of the product in centimeters.")
40
+ height_cm2: float | None = Field(None, description="Height of the product in centimeters.")
41
+ width_cm2: float | None = Field(None, description="Width of the product in centimeters.")
42
+ length_cm2: float | None = Field(None, description="Length of the product in centimeters.")
43
+
44
+ class SurfaceType(BaseModel):
45
+ surface_type: str = Field(description="The background surface of the image", enum=["beach mat", "café table" ,"bar table"])
app/services/__init__.py ADDED
File without changes
app/services/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (171 Bytes). View file
 
app/services/__pycache__/__init__.cpython-38.pyc ADDED
Binary file (169 Bytes). View file
 
app/services/__pycache__/image_generation_service.cpython-310.pyc ADDED
Binary file (4.03 kB). View file
 
app/services/__pycache__/image_generation_service.cpython-38.pyc ADDED
Binary file (3.46 kB). View file
 
app/services/__pycache__/prompt_factory.cpython-310.pyc ADDED
Binary file (10.6 kB). View file