tejani commited on
Commit
1e171d4
·
verified ·
1 Parent(s): 5038bf8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -71
app.py CHANGED
@@ -1,81 +1,66 @@
1
- from fastapi import FastAPI, File, UploadFile, Request
2
  from fastapi.responses import JSONResponse
3
  from pydantic import BaseModel
4
  import httpx
5
- import io
6
- import uuid
7
  import os
8
  from sse_starlette.sse import EventSourceResponse
9
  import asyncio
10
 
11
- app = FastAPI()
 
 
 
 
 
 
 
 
 
12
 
13
  @app.get("/")
14
  async def root():
15
- return {"message": "FastAPI to forward image to external API"}
16
-
17
 
18
- @app.post("/forward-upload")
19
  async def forward_upload(file: UploadFile = File(...)):
20
- if file.content_type not in ["image/png", "image/jpeg"]:
21
- return JSONResponse(status_code=400, content={"error": "Invalid file type. Only PNG or JPEG allowed."})
 
22
 
23
- target_url = "https://kwai-kolors-kolors-virtual-try-on.hf.space/upload?upload_id=r9ywzifblvk"
 
24
 
25
  try:
26
  file_content = await file.read()
27
  files = {"files": (file.filename, file_content, file.content_type)}
28
-
29
  async with httpx.AsyncClient() as client:
30
- response = await client.post(
31
- target_url,
32
- files=files,
33
- headers={
34
- "accept": "*/*",
35
- "accept-language": "en-GB,en-US;q=0.9,en;q=0.8,gu;q=0.7",
36
- "origin": "https://kwai-kolors-kolors-virtual-try-on.hf.space",
37
- "referer": "https://kwai-kolors-kolors-virtual-try-on.hf.space/?__theme=system",
38
- "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1",
39
- },
40
- )
41
-
42
- if response.status_code == 200:
43
- return JSONResponse(content={"status": "Success", "response": response.json()})
44
- else:
45
- return JSONResponse(status_code=response.status_code, content={"error": response.text})
46
-
47
  except httpx.HTTPError as e:
48
- return JSONResponse(status_code=500, content={"error": f"HTTP error occurred: {str(e)}"})
49
  except Exception as e:
50
- return JSONResponse(status_code=500, content={"error": f"An error occurred: {str(e)}"})
51
-
52
-
53
- class TryOnRequest(BaseModel):
54
- person_image_path: str
55
- garment_image_path: str
56
- session_hash: str
57
-
58
- @app.post("/virtual-try-on")
59
- async def join(request: TryOnRequest):
60
- url = "https://kwai-kolors-kolors-virtual-try-on.hf.space/queue/join?__theme=system"
61
 
 
 
 
 
62
  headers = {
63
  "accept": "*/*",
64
- "content-type": "application/json",
65
  }
66
 
67
- # Extract orig_name from file path
68
- person_orig_name = os.path.basename(request.person_image_path)
69
- garment_orig_name = os.path.basename(request.garment_image_path)
70
-
71
- #session_hash = str(uuid.uuid4())[:11]
72
-
73
  payload = {
74
  "data": [
75
  {
76
  "path": request.person_image_path,
77
- "url": f"https://kwai-kolors-kolors-virtual-try-on.hf.space/file={request.person_image_path}",
78
- "orig_name": person_orig_name,
79
  "size": None,
80
  "mime_type": None,
81
  "is_stream": False,
@@ -83,8 +68,8 @@ async def join(request: TryOnRequest):
83
  },
84
  {
85
  "path": request.garment_image_path,
86
- "url": f"https://kwai-kolors-kolors-virtual-try-on.hf.space/file={request.garment_image_path}",
87
- "orig_name": garment_orig_name,
88
  "size": None,
89
  "mime_type": None,
90
  "is_stream": False,
@@ -102,31 +87,35 @@ async def join(request: TryOnRequest):
102
  try:
103
  async with httpx.AsyncClient() as client:
104
  response = await client.post(url, headers=headers, json=payload)
105
-
106
- if response.status_code == 200:
107
  return response.json()
108
- else:
109
- raise HTTPException(status_code=response.status_code, detail=response.text)
110
-
111
- except httpx.RequestError as e:
112
- raise HTTPException(status_code=500, detail=f"Request failed: {str(e)}")
113
-
114
-
115
- async def event_generator(session_hash: str, request: Request):
116
- SSE_URL = f"https://kwai-kolors-kolors-virtual-try-on.hf.space/queue/data?session_hash={session_hash}"
117
 
 
 
 
118
  headers = {
119
  "accept": "text/event-stream",
120
- "content-type": "application/json",
121
  }
122
 
123
- async with httpx.AsyncClient(timeout=None) as client:
124
- async with client.stream("GET", SSE_URL, headers=headers) as response:
125
- async for line in response.aiter_lines():
126
- if line.startswith("data:"):
127
- yield line.removeprefix("data:").strip()
128
- await asyncio.sleep(0.01)
 
 
 
129
 
130
- @app.get("/sse-proxy")
131
  async def sse_proxy(session_hash: str, request: Request):
132
- return EventSourceResponse(event_generator(session_hash, request))
 
 
1
+ from fastapi import FastAPI, File, UploadFile, Request, HTTPException
2
  from fastapi.responses import JSONResponse
3
  from pydantic import BaseModel
4
  import httpx
 
 
5
  import os
6
  from sse_starlette.sse import EventSourceResponse
7
  import asyncio
8
 
9
+ app = FastAPI(title="Virtual Try-On API", description="API to forward images and handle virtual try-on requests")
10
+
11
+ # Configuration
12
+ ALLOWED_IMAGE_TYPES = {"image/png", "image/jpeg"}
13
+ BASE_URL = "https://kwai-kolors-kolors-virtual-try-on.hf.space"
14
+
15
+ class TryOnRequest(BaseModel):
16
+ person_image_path: str
17
+ garment_image_path: str
18
+ session_hash: str
19
 
20
  @app.get("/")
21
  async def root():
22
+ return {"message": "Virtual Try-On API"}
 
23
 
24
+ @app.post("/upload")
25
  async def forward_upload(file: UploadFile = File(...)):
26
+ """Upload an image file to the external API."""
27
+ if file.content_type not in ALLOWED_IMAGE_TYPES:
28
+ raise HTTPException(status_code=400, detail="Invalid file type. Only PNG or JPEG allowed.")
29
 
30
+ target_url = f"{BASE_URL}/upload"
31
+ headers = {"accept": "*/*",}
32
 
33
  try:
34
  file_content = await file.read()
35
  files = {"files": (file.filename, file_content, file.content_type)}
36
+
37
  async with httpx.AsyncClient() as client:
38
+ response = await client.post(target_url, files=files, headers=headers)
39
+ response.raise_for_status()
40
+ return {"status": "success", "response": response.json()}
41
+
42
+ except httpx.HTTPStatusError as e:
43
+ raise HTTPException(status_code=e.response.status_code, detail=str(e.response.text))
 
 
 
 
 
 
 
 
 
 
 
44
  except httpx.HTTPError as e:
45
+ raise HTTPException(status_code=500, detail=f"HTTP error occurred: {str(e)}")
46
  except Exception as e:
47
+ raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
 
 
 
 
 
 
 
 
 
 
48
 
49
+ @app.post("join")
50
+ async def virtual_try_on(request: TryOnRequest):
51
+ """Process virtual try-on request with person and garment images."""
52
+ url = f"{BASE_URL}/queue/join"
53
  headers = {
54
  "accept": "*/*",
55
+ "content-type": "application/json"
56
  }
57
 
 
 
 
 
 
 
58
  payload = {
59
  "data": [
60
  {
61
  "path": request.person_image_path,
62
+ "url": f"{BASE_URL}/file={request.person_image_path}",
63
+ "orig_name": os.path.basename(request.person_image_path),
64
  "size": None,
65
  "mime_type": None,
66
  "is_stream": False,
 
68
  },
69
  {
70
  "path": request.garment_image_path,
71
+ "url": f"{BASE_URL}/file={request.garment_image_path}",
72
+ "orig_name": os.path.basename(request.garment_image_path),
73
  "size": None,
74
  "mime_type": None,
75
  "is_stream": False,
 
87
  try:
88
  async with httpx.AsyncClient() as client:
89
  response = await client.post(url, headers=headers, json=payload)
90
+ response.raise_for_status()
 
91
  return response.json()
92
+
93
+ except httpx.HTTPStatusError as e:
94
+ raise HTTPException(status_code=e.response.status_code, detail=str(e.response.text))
95
+ except httpx.HTTPError as e:
96
+ raise HTTPException(status_code=500, detail=f"HTTP error occurred: {str(e)}")
97
+ except Exception as e:
98
+ raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
 
 
99
 
100
+ async def event_generator(session_hash: str):
101
+ """Generate Server-Sent Events for the given session hash."""
102
+ sse_url = f"{BASE_URL}/queue/data?session_hash={session_hash}"
103
  headers = {
104
  "accept": "text/event-stream",
105
+ "content-type": "application/json"
106
  }
107
 
108
+ try:
109
+ async with httpx.AsyncClient(timeout=None) as client:
110
+ async with client.stream("GET", sse_url, headers=headers) as response:
111
+ async for line in response.aiter_lines():
112
+ if line.startswith("data:"):
113
+ yield line.removeprefix("data:").strip()
114
+ await asyncio.sleep(0.01)
115
+ except Exception as e:
116
+ yield f"data: {{'error': 'SSE stream error: {str(e)}'}}"
117
 
118
+ @app.get("/sse")
119
  async def sse_proxy(session_hash: str, request: Request):
120
+ """Proxy Server-Sent Events for the virtual try-on process."""
121
+ return EventSourceResponse(event_generator(session_hash))