RSHVR commited on
Commit
01608ce
·
verified ·
1 Parent(s): 8474ed7

Delete custom-api.py

Browse files
Files changed (1) hide show
  1. custom-api.py +0 -209
custom-api.py DELETED
@@ -1,209 +0,0 @@
1
- """
2
- Image Extractor API
3
-
4
- A FastAPI application for extracting high-resolution product images from web pages.
5
- """
6
-
7
- from fastapi import FastAPI, HTTPException, Depends, Request
8
- from fastapi.responses import JSONResponse
9
- from fastapi.middleware.cors import CORSMiddleware
10
- from fastapi.openapi.utils import get_openapi
11
- from pydantic import BaseModel, HttpUrl, Field
12
- import os
13
- import uuid
14
- from typing import Dict, Any, Optional, List, Union
15
- import logging
16
- import uvicorn
17
- import time
18
-
19
- # Import from our refactored image_extractor module
20
- from image_extractor import extract_images_from_url, download_image, process_product_page
21
-
22
- # Configure logging
23
- logging.basicConfig(
24
- level=logging.INFO,
25
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
26
- )
27
- logger = logging.getLogger(__name__)
28
-
29
- # Define API Models
30
- class ExtractImageRequest(BaseModel):
31
- """Request model for image extraction"""
32
- url: HttpUrl = Field(..., description="URL of the product page to extract images from")
33
- download_images: bool = Field(True, description="Whether to download the images or just return URLs")
34
- custom_output_dir: Optional[str] = Field(None, description="Optional custom directory to save images to")
35
-
36
- class Config:
37
- schema_extra = {
38
- "example": {
39
- "url": "https://www.ikea.com/us/en/p/poaeng-armchair-birch-veneer-knisa-light-beige-s49388439/",
40
- "download_images": True,
41
- "custom_output_dir": "my_images/poaeng"
42
- }
43
- }
44
-
45
- class ImageInfo(BaseModel):
46
- """Image information model"""
47
- id: str = Field(..., description="Unique identifier for the image")
48
- url: str = Field(..., description="URL of the image")
49
- alt: str = Field(..., description="Alt text of the image")
50
- type: str = Field(..., description="Type of image (main, measurement, etc.)")
51
- path: Optional[str] = Field(None, description="Local path where image is saved (if downloaded)")
52
-
53
- class ExtractImageResponse(BaseModel):
54
- """Response model for image extraction"""
55
- request_id: str = Field(..., description="Unique identifier for this request")
56
- images: Dict[str, Dict[str, Any]] = Field(..., description="Dictionary of extracted images")
57
- output_dir: Optional[str] = Field(None, description="Directory where images were saved (if downloaded)")
58
- measurements: Optional[Dict[str, str]] = Field(None, description="Product measurements extracted from the page")
59
- materials: Optional[Dict[str, str]] = Field(None, description="Product materials extracted from the page")
60
-
61
- class ErrorResponse(BaseModel):
62
- """Error response model"""
63
- detail: str
64
-
65
- # Create API application
66
- app = FastAPI(
67
- title="Image Extractor API",
68
- description="API for extracting high-resolution product images from web pages",
69
- version="1.0.0",
70
- docs_url="/docs",
71
- redoc_url="/redoc",
72
- openapi_url="/openapi.json",
73
- responses={
74
- 500: {"model": ErrorResponse}
75
- }
76
- )
77
-
78
- # Add CORS middleware
79
- app.add_middleware(
80
- CORSMiddleware,
81
- allow_origins=["*"], # In production, replace with specific origins
82
- allow_credentials=True,
83
- allow_methods=["*"],
84
- allow_headers=["*"],
85
- )
86
-
87
- # Custom OpenAPI schema
88
- def custom_openapi():
89
- if app.openapi_schema:
90
- return app.openapi_schema
91
-
92
- openapi_schema = get_openapi(
93
- title=app.title,
94
- version=app.version,
95
- description=app.description,
96
- routes=app.routes,
97
- )
98
-
99
- # Custom schema customizations can be added here
100
-
101
- app.openapi_schema = openapi_schema
102
- return app.openapi_schema
103
-
104
- app.openapi = custom_openapi
105
-
106
- # Middleware for request timing and logging
107
- @app.middleware("http")
108
- async def log_requests(request: Request, call_next):
109
- """Log requests and their timing"""
110
- start_time = time.time()
111
-
112
- # Process the request
113
- response = await call_next(request)
114
-
115
- # Calculate duration
116
- duration = time.time() - start_time
117
-
118
- # Log the request details
119
- logger.info(
120
- f"Request {request.method} {request.url.path} "
121
- f"completed in {duration:.3f}s with status {response.status_code}"
122
- )
123
-
124
- return response
125
-
126
- # API Routes
127
- @app.get("/", summary="Welcome endpoint", tags=["General"])
128
- def read_root():
129
- """Welcome endpoint for the API"""
130
- return {"message": "Welcome to the Image Extractor API"}
131
-
132
- @app.post(
133
- "/extract",
134
- response_model=ExtractImageResponse,
135
- responses={
136
- 200: {"description": "Successfully extracted images"},
137
- 500: {"description": "Server error", "model": ErrorResponse}
138
- },
139
- summary="Extract images from a URL",
140
- tags=["Extraction"]
141
- )
142
- async def extract_images(request: ExtractImageRequest):
143
- """
144
- Extract high-resolution images from a product URL.
145
-
146
- - **url**: URL of the product page to extract images from
147
- - **download_images**: Whether to download the images or just return URLs
148
- - **custom_output_dir**: Optional custom directory to save images to
149
-
150
- Returns information about extracted images and product measurements.
151
- """
152
- try:
153
- logger.info(f"Processing extraction request for URL: {request.url}")
154
- url = str(request.url) # Convert from Pydantic HttpUrl to string
155
-
156
- if request.download_images:
157
- # Process the page and download images
158
- logger.info(f"Downloading images to {'custom directory' if request.custom_output_dir else 'default directory'}")
159
- result = process_product_page(url, request.custom_output_dir)
160
- return result
161
- else:
162
- # Only extract image URLs without downloading
163
- logger.info("Extracting image URLs without downloading")
164
- extraction_result = extract_images_from_url(url)
165
-
166
- # Convert the result to match our response model
167
- return {
168
- "request_id": extraction_result.request_id if hasattr(extraction_result, 'request_id') else extraction_result["requestId"],
169
- "images": {
170
- img_id: {
171
- "id": img_id,
172
- "url": img_info["url"] if isinstance(img_info, dict) else img_info.url,
173
- "alt": img_info["alt"] if isinstance(img_info, dict) else img_info.alt,
174
- "type": img_info["type"] if isinstance(img_info, dict) else img_info.type
175
- }
176
- for img_id, img_info in (extraction_result.images.items() if hasattr(extraction_result, 'images') else extraction_result["images"].items())
177
- },
178
- "measurements": (
179
- extraction_result.measurements
180
- if hasattr(extraction_result, 'measurements')
181
- else extraction_result.get("measurements", {})
182
- ),
183
- "materials": (
184
- extraction_result.materials
185
- if hasattr(extraction_result, 'materials')
186
- else extraction_result.get("materials", {})
187
- ),
188
- }
189
-
190
- except Exception as e:
191
- logger.error(f"Error processing URL: {str(e)}", exc_info=True)
192
- raise HTTPException(
193
- status_code=500,
194
- detail=f"Error processing URL: {str(e)}"
195
- )
196
-
197
- @app.get("/health", summary="Health check endpoint", tags=["Monitoring"])
198
- def health_check():
199
- """
200
- Health check endpoint for monitoring the API status.
201
-
202
- Returns a simple status message indicating the API is healthy.
203
- """
204
- return {"status": "healthy", "timestamp": time.time()}
205
-
206
- # Run the server directly if the file is executed
207
- if __name__ == "__main__":
208
- logger.info("Starting Image Extractor API server")
209
- uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)