Spaces:
Running
Running
| from fastapi import FastAPI, HTTPException, Query | |
| from fastapi.middleware.cors import CORSMiddleware | |
| import duckdb | |
| import threading | |
| from contextlib import asynccontextmanager | |
| import os | |
| # Thread-local storage β har thread ka apna connection hoga | |
| # Isse concurrent requests pe crash nahi hoga | |
| _local = threading.local() | |
| PARQUET_URL = "https://huggingface.co/datasets/CodeXDevloper/Inddatainonefile/resolve/main/users_data.parquet" | |
| def get_con(): | |
| """Har thread ke liye alag DuckDB connection dega""" | |
| if not hasattr(_local, 'con') or _local.con is None: | |
| con = duckdb.connect() | |
| con.execute("INSTALL httpfs; LOAD httpfs;") | |
| con.execute(f""" | |
| CREATE OR REPLACE VIEW users_view AS | |
| SELECT * FROM read_parquet('{PARQUET_URL}') | |
| """) | |
| _local.con = con | |
| return _local.con | |
| async def lifespan(app: FastAPI): | |
| print("API start ho rahi hai...") | |
| # Main thread ka connection startup pe bana lo | |
| try: | |
| con = get_con() | |
| # Ek test query β parquet file check karo | |
| con.execute("SELECT COUNT(*) FROM users_view").fetchone() | |
| print("β Parquet file load ho gayi! API ready hai.") | |
| except Exception as e: | |
| print(f"β οΈ Startup error: {e}") | |
| yield | |
| # Cleanup | |
| if hasattr(_local, 'con') and _local.con: | |
| _local.con.close() | |
| app = FastAPI(title="Super Fast Search API", lifespan=lifespan) | |
| # CORS β kisi bhi frontend se API call ho sake | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["GET"], | |
| allow_headers=["*"], | |
| ) | |
| def home(): | |
| return { | |
| "message": "Super Fast Search API online hai!", | |
| "usage": "/search?mobile=YOUR_NUMBER", | |
| "status": "running" | |
| } | |
| def health(): | |
| """Keep-alive ping ke liye yeh endpoint use karo""" | |
| return {"status": "ok"} | |
| async def search_mobile(mobile: str = Query(..., description="Enter mobile number to search")): | |
| if not mobile.strip().isdigit(): | |
| return {"status": "error", "message": "Sirf numbers enter karein."} | |
| try: | |
| con = get_con() # Thread-safe connection | |
| query = """ | |
| SELECT mobile, name, fname, address, alt, circle, id, email | |
| FROM users_view | |
| WHERE CAST(mobile AS VARCHAR) = ? | |
| LIMIT 1 | |
| """ | |
| result = con.execute(query, [mobile.strip()]).fetchall() | |
| if not result: | |
| return { | |
| "status": "error", | |
| "message": f"Mobile number {mobile} nahi mila." | |
| } | |
| columns = [desc[0] for desc in con.description] | |
| row_dict = dict(zip(columns, result[0])) | |
| return { | |
| "status": "success", | |
| "data": row_dict | |
| } | |
| except Exception as e: | |
| print(f"Query error: {e}") | |
| # Connection reset karo agar error aaye | |
| _local.con = None | |
| raise HTTPException(status_code=500, detail="Query process nahi ho payi. Dobara try karein.") |