tejani commited on
Commit
a3abe18
·
verified ·
1 Parent(s): 5bf4c97

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +255 -31
app.py CHANGED
@@ -1,33 +1,257 @@
 
 
1
  import requests
 
 
 
 
 
 
 
 
2
 
3
- url = "https://changeclothesai.online/api/try-on/edge"
4
-
5
- cookies = {}
6
-
7
- headers = {
8
- "accept": "*/*",
9
- "accept-language": "en-GB,en-US;q=0.9,en;q=0.8,gu;q=0.7",
10
- "f": "ab6023da0b46850091054b4ce804ecf4",
11
- "origin": "https://changeclothesai.online",
12
- "priority": "u=1, i",
13
- "referer": "https://changeclothesai.online/",
14
- "sec-ch-ua": '"Not)A;Brand";v="8", "Chromium";v="138", "Google Chrome";v="138"',
15
- "sec-ch-ua-mobile": "?1",
16
- "sec-ch-ua-platform": '"Android"',
17
- "sec-fetch-dest": "empty",
18
- "sec-fetch-mode": "cors",
19
- "sec-fetch-site": "same-origin",
20
- "user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Mobile Safari/537.36"
21
- }
22
-
23
- data = {
24
- "humanImg": "https://jallenjia-change-clothes-ai.hf.space/file=/tmp/gradio/ba40a133e16016041aec2390aa6899fede197af6/Jensen.jpeg",
25
- "garment": "https://jallenjia-change-clothes-ai.hf.space/file=/tmp/gradio/7cb2f03c3ae9feb724a711d71a5fc58c1570b3c3/Girl%20outfits%205.jpg",
26
- "garmentDesc": "",
27
- "category": "upper_body"
28
- }
29
-
30
- response = requests.post(url, headers=headers, cookies=cookies, data=data)
31
-
32
- print(response.status_code)
33
- print(response.text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, UploadFile, File, Response
2
+ from pydantic import BaseModel
3
  import requests
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ from fastapi.staticfiles import StaticFiles
6
+ from fastapi.responses import HTMLResponse
7
+ import uuid
8
+ from pathlib import Path
9
+ import logging
10
+ import os
11
+ import stat
12
 
13
+ # Set up logging
14
+ logging.basicConfig(level=logging.INFO)
15
+ logger = logging.getLogger(__name__)
16
+
17
+ app = FastAPI()
18
+
19
+ # Add CORS middleware
20
+ app.add_middleware(
21
+ CORSMiddleware,
22
+ allow_origins=["*"], # Adjust for production
23
+ allow_credentials=True,
24
+ allow_methods=["*"],
25
+ allow_headers=["*"],
26
+ )
27
+
28
+ # Mount static directory for serving files
29
+ STATIC_DIR = Path("/home/user/app/static")
30
+ STATIC_DIR.mkdir(parents=True, exist_ok=True)
31
+ try:
32
+ os.chmod(STATIC_DIR, stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH)
33
+ except Exception as e:
34
+ logger.error(f"Failed to set permissions for {STATIC_DIR}: {str(e)}")
35
+ app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
36
+
37
+ # Define the request model
38
+ class TryOnRequest(BaseModel):
39
+ garmentDesc: str
40
+ category: str
41
+
42
+ # Allowed file extensions
43
+ ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png"}
44
+
45
+ # Helper function to save file and generate public URL
46
+ async def save_file_and_get_url(file: UploadFile) -> str:
47
+ try:
48
+ # Validate file extension
49
+ file_extension = f".{file.filename.split('.')[-1].lower()}"
50
+ if file_extension not in ALLOWED_EXTENSIONS:
51
+ logger.error(f"Invalid file extension for {file.filename}: {file_extension}")
52
+ raise HTTPException(status_code=400, detail=f"File extension {file_extension} not allowed. Use JPG or PNG.")
53
+
54
+ # Generate unique filename
55
+ unique_filename = f"{uuid.uuid4()}{file_extension}"
56
+ file_path = STATIC_DIR / unique_filename
57
+
58
+ # Save file
59
+ logger.info(f"Saving file to {file_path}")
60
+ with file_path.open("wb") as buffer:
61
+ content = await file.read()
62
+ buffer.write(content)
63
+
64
+ # Verify file exists and set permissions
65
+ if not file_path.exists():
66
+ logger.error(f"File {file_path} was not saved correctly")
67
+ raise HTTPException(status_code=500, detail="Failed to save file")
68
+ try:
69
+ os.chmod(file_path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH)
70
+ logger.info(f"Set permissions for {file_path}")
71
+ except Exception as e:
72
+ logger.error(f"Failed to set permissions for {file_path}: {str(e)}")
73
+
74
+ # Generate public URL
75
+ space_id = "tejani-tryapi"
76
+ public_url = f"https://{space_id}.hf.space/static/{unique_filename}"
77
+ logger.info(f"Generated public URL: {public_url}")
78
+
79
+ return public_url
80
+ except Exception as e:
81
+ logger.error(f"Error in save_file_and_get_url: {str(e)}")
82
+ raise HTTPException(status_code=500, detail=f"Error processing file: {str(e)}")
83
+
84
+ # Endpoint to handle file uploads and proxy the request
85
+ @app.post("/try-on")
86
+ async def try_on(
87
+ human_img: UploadFile = File(...),
88
+ garment: UploadFile = File(...),
89
+ garment_desc: str = "",
90
+ category: str = "upper_body"
91
+ ):
92
+ try:
93
+ # Save files and get public URLs
94
+ human_img_url = await save_file_and_get_url(human_img)
95
+ garment_url = await save_file_and_get_url(garment)
96
+
97
+ # Original API endpoint
98
+ url = "https://changeclothesai.online/api/try-on/"
99
+
100
+ headers = {
101
+ "accept": "*/*",
102
+ "f": "sdfdsfsKaVgUoxa5j1jzcFtziPx",
103
+ }
104
+
105
+ data = {
106
+ "humanImg": human_img_url,
107
+ "garment": garment_url,
108
+ "garmentDesc": garment_desc,
109
+ "category": category
110
+ }
111
+
112
+ logger.info(f"Forwarding request to {url} with data: {data}")
113
+
114
+ # Forward request to the original API
115
+ response = requests.post(url, headers=headers, cookies={}, data=data)
116
+ logger.info(f"API response status: {response.status_code}, content: {response.text}")
117
+ response.raise_for_status()
118
+
119
+ return {
120
+ "status_code": response.status_code,
121
+ "response": response.json() if response.headers.get('content-type') == 'application/json' else response.text,
122
+ "human_img_url": human_img_url,
123
+ "garment_url": garment_url
124
+ }
125
+ except requests.exceptions.RequestException as e:
126
+ logger.error(f"Error forwarding request: {str(e)}")
127
+ raise HTTPException(status_code=500, detail=f"Error forwarding request: {str(e)}")
128
+ except Exception as e:
129
+ logger.error(f"Error in try_on endpoint: {str(e)}")
130
+ raise HTTPException(status_code=500, detail=f"Error processing request: {str(e)}")
131
+
132
+ # Health check endpoint
133
+ @app.get("/")
134
+ async def root():
135
+ return {"message": "FastAPI proxy for try-on API with file upload is running"}
136
+
137
+ # Debug endpoint to list stored files
138
+ @app.get("/list-files")
139
+ async def list_files():
140
+ try:
141
+ files = [str(f) for f in STATIC_DIR.glob("*") if f.is_file()]
142
+ logger.info(f"Files in {STATIC_DIR}: {files}")
143
+ return {"files": files}
144
+ except Exception as e:
145
+ logger.error(f"Error listing files: {str(e)}")
146
+ raise HTTPException(status_code=500, detail=f"Error listing files: {str(e)}")
147
+
148
+ # Debug endpoint to manually serve a file
149
+ @app.get("/get-file/{filename}")
150
+ async def get_file(filename: str):
151
+ try:
152
+ file_path = STATIC_DIR / filename
153
+ if not file_path.exists():
154
+ logger.error(f"File {file_path} not found")
155
+ raise HTTPException(status_code=404, detail="File not found")
156
+
157
+ with file_path.open("rb") as f:
158
+ content = f.read()
159
+ return Response(content=content, media_type="image/jpeg")
160
+ except Exception as e:
161
+ logger.error(f"Error serving file {filename}: {str(e)}")
162
+ raise HTTPException(status_code=500, detail=f"Error serving file: {str(e)}")
163
+
164
+ # Debug endpoint to check file existence and permissions
165
+ @app.get("/check-file/{filename}")
166
+ async def check_file(filename: str):
167
+ try:
168
+ file_path = STATIC_DIR / filename
169
+ if not file_path.exists():
170
+ logger.error(f"File {file_path} not found")
171
+ raise HTTPException(status_code=404, detail="File not found")
172
+
173
+ stats = os.stat(file_path)
174
+ permissions = oct(stats.st_mode)[-3:]
175
+ logger.info(f"File {file_path} exists with permissions {permissions}")
176
+ return {
177
+ "file": str(file_path),
178
+ "exists": True,
179
+ "permissions": permissions
180
+ }
181
+ except Exception as e:
182
+ logger.error(f"Error checking file {filename}: {str(e)}")
183
+ raise HTTPException(status_code=500, detail=f"Error checking file: {str(e)}")
184
+
185
+ # Endpoint to clean stored files
186
+ @app.get("/clean-files")
187
+ async def clean_files():
188
+ try:
189
+ for f in STATIC_DIR.glob("*"):
190
+ if f.is_file():
191
+ f.unlink()
192
+ logger.info(f"Cleaned all files in {STATIC_DIR}")
193
+ return {"message": "Files cleaned"}
194
+ except Exception as e:
195
+ logger.error(f"Error cleaning files: {str(e)}")
196
+ raise HTTPException(status_code=500, detail=f"Error cleaning files: {str(e)}")
197
+
198
+ # Frontend for testing file uploads
199
+ @app.get("/test-upload", response_class=HTMLResponse)
200
+ async def test_upload_form():
201
+ html_content = """
202
+ <html>
203
+ <head>
204
+ <title>Test File Upload</title>
205
+ <style>
206
+ body { font-family: Arial, sans-serif; margin: 20px; }
207
+ .response { margin-top: 20px; padding: 10px; border: 1px solid #ccc; }
208
+ pre { background: #f4f4f4; padding: 10px; max-height: 300px; overflow: auto; }
209
+ </style>
210
+ </head>
211
+ <body>
212
+ <h1>Test File Upload</h1>
213
+ <form action="/try-on" method="post" enctype="multipart/form-data" onsubmit="showResponse(event)">
214
+ <label for="human_img">Human Image (JPG/PNG, <1MB):</label><br>
215
+ <input type="file" id="human_img" name="human_img" accept=".jpg,.jpeg,.png" required><br><br>
216
+ <label for="garment">Garment Image (JPG/PNG, <1MB):</label><br>
217
+ <input type="file" id="garment" name="garment" accept=".jpg,.jpeg,.png" required><br><br>
218
+ <label for="garment_desc">Garment Description:</label><br>
219
+ <input type="text" id="garment_desc" name="garment_desc" value=""><br><br>
220
+ <label for="category">Category:</label><br>
221
+ <input type="text" id="category" name="category" value="upper_body"><br><br>
222
+ <input type="submit" value="Upload and Try On">
223
+ </form>
224
+ <div id="response" class="response" style="display: none;"></div>
225
+ <h2>Debug Tools</h2>
226
+ <p><a href="/list-files">List Stored Files</a></p>
227
+ <p><a href="/clean-files">Clean Stored Files</a></p>
228
+ <script>
229
+ async function showResponse(event) {
230
+ event.preventDefault();
231
+ const form = event.target;
232
+ const formData = new FormData(form);
233
+ try {
234
+ const response = await fetch('/try-on', {
235
+ method: 'POST',
236
+ body: formData
237
+ });
238
+ const result = await response.json();
239
+ const responseDiv = document.getElementById('response');
240
+ responseDiv.style.display = 'block';
241
+ responseDiv.innerHTML = `
242
+ <h3>Response</h3>
243
+ <p><strong>Status Code:</strong> ${result.status_code}</p>
244
+ <p><strong>Human Image URL:</strong> <a href="${result.human_img_url}" target="_blank">${result.human_img_url}</a></p>
245
+ <p><strong>Garment URL:</strong> <a href="${result.garment_url}" target="_blank">${result.garment_url}</a></p>
246
+ <p><strong>API Response:</strong> <pre>${JSON.stringify(result.response, null, 2)}</pre></p>
247
+ `;
248
+ } catch (error) {
249
+ document.getElementById('response').style.display = 'block';
250
+ document.getElementById('response').innerHTML = `<p><strong>Error:</strong> ${error.message}</p>`;
251
+ }
252
+ }
253
+ </script>
254
+ </body>
255
+ </html>
256
+ """
257
+ return HTMLResponse(content=html_content)