aniketkumar1106 commited on
Commit
86ccee3
·
verified ·
1 Parent(s): 6ef5fea

Update server.py

Browse files
Files changed (1) hide show
  1. server.py +56 -80
server.py CHANGED
@@ -1,14 +1,14 @@
1
  import os
2
- import zipfile
3
  import shutil
4
  from fastapi import FastAPI, File, UploadFile, Form, HTTPException
5
  from fastapi.middleware.cors import CORSMiddleware
6
  from fastapi.staticfiles import StaticFiles
7
- from huggingface_hub import hf_hub_download
8
 
9
- app = FastAPI(title="ORBIT Visual Search Engine")
10
 
11
- # 1. Enable Global CORS for Netlify communication
 
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
@@ -17,96 +17,68 @@ app.add_middleware(
17
  allow_headers=["*"],
18
  )
19
 
20
- # --- CONFIGURATION (UPDATE THESE) ---
21
  DATASET_REPO = "aniketkumar1106/orbit-data"
22
- ZIP_FILENAME = "orbiitt_db"
23
  IMAGE_DIR = "Productimages"
 
24
 
25
- def setup_resources():
26
- """Downloads, Deep-Scans, and Extracts data from private HF Dataset."""
27
  token = os.environ.get("HF_TOKEN")
28
  if not token:
29
- print("CRITICAL: HF_TOKEN secret is missing!")
30
  return
31
 
32
- # Clean start: Create image directory if missing
33
- if not os.path.exists(IMAGE_DIR):
34
- os.makedirs(IMAGE_DIR)
35
-
36
  try:
37
- # 1. Download zip from private dataset
38
- print(f"Fetching {ZIP_FILENAME} from {DATASET_REPO}...")
39
- zip_path = hf_hub_download(
 
40
  repo_id=DATASET_REPO,
41
- filename=ZIP_FILENAME,
42
  repo_type="dataset",
43
  token=token,
44
- local_dir="."
 
45
  )
46
-
47
- # 2. Extract to a temporary folder
48
- temp_extract = "temp_data"
49
- if os.path.exists(temp_extract):
50
- shutil.rmtree(temp_extract)
51
-
52
- with zipfile.ZipFile(zip_path, 'r') as zip_ref:
53
- zip_ref.extractall(temp_extract)
54
-
55
- # 3. DEEP SCAN: Recursively find orbiitt.db and images
56
- print("Scanning extracted files...")
57
- for root, dirs, files in os.walk(temp_extract):
58
- for file in files:
59
- file_lower = file.lower()
60
- source_path = os.path.join(root, file)
61
-
62
- # If we find the database, move it to the root
63
- if file == "orbiitt.db":
64
- shutil.move(source_path, "./orbiitt.db")
65
- print(f"Moved {file} to root.")
66
-
67
- # If we find images, move them to Productimages
68
- elif file_lower.endswith(('.png', '.jpg', '.jpeg', '.webp')):
69
- target_path = os.path.join(IMAGE_DIR, file)
70
- # Move only if it doesn't exist yet
71
- if not os.path.exists(target_path):
72
- shutil.move(source_path, target_path)
73
-
74
- # 4. Cleanup temp folder
75
- shutil.rmtree(temp_extract)
76
- print("Setup complete. Environment is organized.")
77
-
78
  except Exception as e:
79
- print(f"Initialization Failed: {e}")
80
 
81
- # Run setup before mounting or engine loading
82
- setup_resources()
83
 
84
- # 2. Mount Static Files (Frontend access to images)
 
85
  if os.path.exists(IMAGE_DIR):
86
  app.mount(f"/{IMAGE_DIR}", StaticFiles(directory=IMAGE_DIR), name=IMAGE_DIR)
87
 
88
- # 3. Load the OrbiittEngine
89
  engine = None
90
  try:
91
  from orbiitt_engine import OrbiittEngine
92
- # Ensure database is present before starting engine
93
- if os.path.exists("orbiitt.db"):
94
  engine = OrbiittEngine()
95
- print("Engine successfully connected to orbiitt.db")
96
  else:
97
- print("Engine NOT loaded: orbiitt.db is missing.")
98
  except Exception as e:
99
- print(f"Error initializing OrbiittEngine: {e}")
 
 
 
 
100
 
101
  @app.get("/")
102
- def health_check():
103
- """Diagnostic check for frontend and debugging."""
 
104
  return {
105
  "status": "online",
106
- "database_ready": os.path.exists("orbiitt.db"),
107
- "images_count": len(os.listdir(IMAGE_DIR)) if os.path.exists(IMAGE_DIR) else 0,
108
- "engine_ready": engine is not None,
109
- "root_files": os.listdir(".")[:10]
110
  }
111
 
112
  @app.post("/search")
@@ -116,30 +88,34 @@ async def search_endpoint(
116
  file: UploadFile = File(None)
117
  ):
118
  if not engine:
119
- raise HTTPException(status_code=503, detail="Search engine is not initialized.")
120
 
121
- temp_path = None
122
  try:
123
- # Save search image if provided
124
  if file:
125
- temp_path = f"search_input_{file.filename}"
126
- with open(temp_path, "wb") as buffer:
127
  buffer.write(await file.read())
128
 
129
- # Perform the actual search
130
- results = engine.search(text_query=text, image_file=temp_path, text_weight=weight)
131
-
132
- # Ensure result URLs point correctly to the mounted folder
 
 
133
  return {"results": results}
134
 
135
  except Exception as e:
136
- print(f"Search Error: {e}")
137
- raise HTTPException(status_code=500, detail="An internal search error occurred.")
 
138
  finally:
139
- # Cleanup temp search file
140
- if temp_path and os.path.exists(temp_path):
141
- os.remove(temp_path)
142
 
143
  if __name__ == "__main__":
144
  import uvicorn
 
145
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  import os
 
2
  import shutil
3
  from fastapi import FastAPI, File, UploadFile, Form, HTTPException
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.staticfiles import StaticFiles
6
+ from huggingface_hub import snapshot_download
7
 
8
+ app = FastAPI(title="ORBIT Visual Engine")
9
 
10
+ # --- 1. GLOBALLY ENABLE CORS ---
11
+ # Required for your Netlify frontend to talk to this API
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
 
17
  allow_headers=["*"],
18
  )
19
 
20
+ # --- 2. DATASET CONFIGURATION ---
21
  DATASET_REPO = "aniketkumar1106/orbit-data"
 
22
  IMAGE_DIR = "Productimages"
23
+ DB_FILE = "orbiitt.db"
24
 
25
+ def sync_dataset():
26
+ """Syncs the database and images from the HF private dataset folder."""
27
  token = os.environ.get("HF_TOKEN")
28
  if not token:
29
+ print("CRITICAL ERROR: HF_TOKEN not found in Space Secrets.")
30
  return
31
 
 
 
 
 
32
  try:
33
+ print(f"Syncing folder-based dataset from {DATASET_REPO}...")
34
+
35
+ # snapshot_download downloads the folder structure as-is
36
+ snapshot_download(
37
  repo_id=DATASET_REPO,
 
38
  repo_type="dataset",
39
  token=token,
40
+ local_dir=".",
41
+ allow_patterns=[DB_FILE, f"{IMAGE_DIR}/*"]
42
  )
43
+
44
+ print("Sync Successful.")
45
+ print(f"Files found in root: {os.listdir('.')}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  except Exception as e:
47
+ print(f"Sync Failed: {e}")
48
 
49
+ # Run sync before anything else starts
50
+ sync_dataset()
51
 
52
+ # --- 3. MOUNT STATIC IMAGES ---
53
+ # Allows the frontend to access images at: https://your-space.hf.space/Productimages/1.jpg
54
  if os.path.exists(IMAGE_DIR):
55
  app.mount(f"/{IMAGE_DIR}", StaticFiles(directory=IMAGE_DIR), name=IMAGE_DIR)
56
 
57
+ # --- 4. INITIALIZE SEARCH ENGINE ---
58
  engine = None
59
  try:
60
  from orbiitt_engine import OrbiittEngine
61
+ if os.path.exists(DB_FILE):
 
62
  engine = OrbiittEngine()
63
+ print("OrbiittEngine: Ready and Connected.")
64
  else:
65
+ print(f"OrbiittEngine Error: {DB_FILE} not found after sync.")
66
  except Exception as e:
67
+ print(f"Engine initialization failed: {e}")
68
+
69
+
70
+
71
+ # --- 5. API ENDPOINTS ---
72
 
73
  @app.get("/")
74
+ def health_status():
75
+ """Dashboard for checking if the server has the files it needs."""
76
+ img_count = len(os.listdir(IMAGE_DIR)) if os.path.exists(IMAGE_DIR) else 0
77
  return {
78
  "status": "online",
79
+ "database_ready": os.path.exists(DB_FILE),
80
+ "images_count": img_count,
81
+ "engine_ready": engine is not None
 
82
  }
83
 
84
  @app.post("/search")
 
88
  file: UploadFile = File(None)
89
  ):
90
  if not engine:
91
+ raise HTTPException(status_code=503, detail="Search engine is not available.")
92
 
93
+ temp_image_path = None
94
  try:
95
+ # If an image was uploaded for search, save it temporarily
96
  if file:
97
+ temp_image_path = f"tmp_search_{file.filename}"
98
+ with open(temp_image_path, "wb") as buffer:
99
  buffer.write(await file.read())
100
 
101
+ # Perform the search
102
+ results = engine.search(
103
+ text_query=text,
104
+ image_file=temp_image_path,
105
+ text_weight=weight
106
+ )
107
  return {"results": results}
108
 
109
  except Exception as e:
110
+ print(f"Runtime Search Error: {e}")
111
+ raise HTTPException(status_code=500, detail="An internal error occurred during search.")
112
+
113
  finally:
114
+ # Always clean up the uploaded search image
115
+ if temp_image_path and os.path.exists(temp_image_path):
116
+ os.remove(temp_image_path)
117
 
118
  if __name__ == "__main__":
119
  import uvicorn
120
+ # Use 7860 as it is the default port for Hugging Face Spaces
121
  uvicorn.run(app, host="0.0.0.0", port=7860)