tejani commited on
Commit
151ae95
·
verified ·
1 Parent(s): 1ca5b3b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -266
app.py CHANGED
@@ -1,268 +1,33 @@
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/edge"
99
-
100
- headers = {
101
- "accept": "*/*",
102
- "accept-language": "en-GB,en-US;q=0.9,en;q=0.8,gu;q=0.7",
103
- "f": "ab6023da0b46850091054b4ce804ecd4",
104
- "origin": "https://changeclothesai.online",
105
- "priority": "u=1, i",
106
- "referer": "https://changeclothesai.online/",
107
- "sec-ch-ua": '"Not)A;Brand";v="8", "Chromium";v="138", "Google Chrome";v="138"',
108
- "sec-ch-ua-mobile": "?1",
109
- "sec-ch-ua-platform": '"Android"',
110
- "sec-fetch-dest": "empty",
111
- "sec-fetch-mode": "cors",
112
- "sec-fetch-site": "same-origin",
113
- "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"
114
- }
115
-
116
- data = {
117
- "humanImg": human_img_url,
118
- "garment": garment_url,
119
- "garmentDesc": garment_desc,
120
- "category": category
121
- }
122
-
123
- logger.info(f"Forwarding request to {url} with data: {data}")
124
-
125
- # Forward request to the original API
126
- response = requests.post(url, headers=headers, cookies={}, data=data)
127
- logger.info(f"API response status: {response.status_code}, content: {response.text}")
128
- response.raise_for_status()
129
-
130
- return {
131
- "status_code": response.status_code,
132
- "response": response.json() if response.headers.get('content-type') == 'application/json' else response.text,
133
- "human_img_url": human_img_url,
134
- "garment_url": garment_url
135
- }
136
- except requests.exceptions.RequestException as e:
137
- logger.error(f"Error forwarding request: {str(e)}")
138
- raise HTTPException(status_code=500, detail=f"Error forwarding request: {str(e)}")
139
- except Exception as e:
140
- logger.error(f"Error in try_on endpoint: {str(e)}")
141
- raise HTTPException(status_code=500, detail=f"Error processing request: {str(e)}")
142
-
143
- # Health check endpoint
144
- @app.get("/")
145
- async def root():
146
- return {"message": "FastAPI proxy for try-on API with file upload is running"}
147
-
148
- # Debug endpoint to list stored files
149
- @app.get("/list-files")
150
- async def list_files():
151
- try:
152
- files = [str(f) for f in STATIC_DIR.glob("*") if f.is_file()]
153
- logger.info(f"Files in {STATIC_DIR}: {files}")
154
- return {"files": files}
155
- except Exception as e:
156
- logger.error(f"Error listing files: {str(e)}")
157
- raise HTTPException(status_code=500, detail=f"Error listing files: {str(e)}")
158
-
159
- # Debug endpoint to manually serve a file
160
- @app.get("/get-file/{filename}")
161
- async def get_file(filename: str):
162
- try:
163
- file_path = STATIC_DIR / filename
164
- if not file_path.exists():
165
- logger.error(f"File {file_path} not found")
166
- raise HTTPException(status_code=404, detail="File not found")
167
-
168
- with file_path.open("rb") as f:
169
- content = f.read()
170
- return Response(content=content, media_type="image/jpeg")
171
- except Exception as e:
172
- logger.error(f"Error serving file {filename}: {str(e)}")
173
- raise HTTPException(status_code=500, detail=f"Error serving file: {str(e)}")
174
-
175
- # Debug endpoint to check file existence and permissions
176
- @app.get("/check-file/{filename}")
177
- async def check_file(filename: str):
178
- try:
179
- file_path = STATIC_DIR / filename
180
- if not file_path.exists():
181
- logger.error(f"File {file_path} not found")
182
- raise HTTPException(status_code=404, detail="File not found")
183
-
184
- stats = os.stat(file_path)
185
- permissions = oct(stats.st_mode)[-3:]
186
- logger.info(f"File {file_path} exists with permissions {permissions}")
187
- return {
188
- "file": str(file_path),
189
- "exists": True,
190
- "permissions": permissions
191
- }
192
- except Exception as e:
193
- logger.error(f"Error checking file {filename}: {str(e)}")
194
- raise HTTPException(status_code=500, detail=f"Error checking file: {str(e)}")
195
-
196
- # Endpoint to clean stored files
197
- @app.get("/clean-files")
198
- async def clean_files():
199
- try:
200
- for f in STATIC_DIR.glob("*"):
201
- if f.is_file():
202
- f.unlink()
203
- logger.info(f"Cleaned all files in {STATIC_DIR}")
204
- return {"message": "Files cleaned"}
205
- except Exception as e:
206
- logger.error(f"Error cleaning files: {str(e)}")
207
- raise HTTPException(status_code=500, detail=f"Error cleaning files: {str(e)}")
208
-
209
- # Frontend for testing file uploads
210
- @app.get("/test-upload", response_class=HTMLResponse)
211
- async def test_upload_form():
212
- html_content = """
213
- <html>
214
- <head>
215
- <title>Test File Upload</title>
216
- <style>
217
- body { font-family: Arial, sans-serif; margin: 20px; }
218
- .response { margin-top: 20px; padding: 10px; border: 1px solid #ccc; }
219
- pre { background: #f4f4f4; padding: 10px; max-height: 300px; overflow: auto; }
220
- </style>
221
- </head>
222
- <body>
223
- <h1>Test File Upload</h1>
224
- <form action="/try-on" method="post" enctype="multipart/form-data" onsubmit="showResponse(event)">
225
- <label for="human_img">Human Image (JPG/PNG, <1MB):</label><br>
226
- <input type="file" id="human_img" name="human_img" accept=".jpg,.jpeg,.png" required><br><br>
227
- <label for="garment">Garment Image (JPG/PNG, <1MB):</label><br>
228
- <input type="file" id="garment" name="garment" accept=".jpg,.jpeg,.png" required><br><br>
229
- <label for="garment_desc">Garment Description:</label><br>
230
- <input type="text" id="garment_desc" name="garment_desc" value=""><br><br>
231
- <label for="category">Category:</label><br>
232
- <input type="text" id="category" name="category" value="upper_body"><br><br>
233
- <input type="submit" value="Upload and Try On">
234
- </form>
235
- <div id="response" class="response" style="display: none;"></div>
236
- <h2>Debug Tools</h2>
237
- <p><a href="/list-files">List Stored Files</a></p>
238
- <p><a href="/clean-files">Clean Stored Files</a></p>
239
- <script>
240
- async function showResponse(event) {
241
- event.preventDefault();
242
- const form = event.target;
243
- const formData = new FormData(form);
244
- try {
245
- const response = await fetch('/try-on', {
246
- method: 'POST',
247
- body: formData
248
- });
249
- const result = await response.json();
250
- const responseDiv = document.getElementById('response');
251
- responseDiv.style.display = 'block';
252
- responseDiv.innerHTML = `
253
- <h3>Response</h3>
254
- <p><strong>Status Code:</strong> ${result.status_code}</p>
255
- <p><strong>Human Image URL:</strong> <a href="${result.human_img_url}" target="_blank">${result.human_img_url}</a></p>
256
- <p><strong>Garment URL:</strong> <a href="${result.garment_url}" target="_blank">${result.garment_url}</a></p>
257
- <p><strong>API Response:</strong> <pre>${JSON.stringify(result.response, null, 2)}</pre></p>
258
- `;
259
- } catch (error) {
260
- document.getElementById('response').style.display = 'block';
261
- document.getElementById('response').innerHTML = `<p><strong>Error:</strong> ${error.message}</p>`;
262
- }
263
- }
264
- </script>
265
- </body>
266
- </html>
267
- """
268
- return HTMLResponse(content=html_content)
 
 
 
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": "ab6023da0b46850091054b4ce804ecd4",
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://tejani-tryapi.hf.space/static/28a23b98-3363-46a2-8ce3-8d17e89a27b8.jpg",
25
+ "garment": "https://tejani-tryapi.hf.space/static/1e0efc82-599f-4bad-b539-c44b0059aa94.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)