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 @asynccontextmanager 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=["*"], ) @app.get("/") def home(): return { "message": "Super Fast Search API online hai!", "usage": "/search?mobile=YOUR_NUMBER", "status": "running" } @app.get("/health") def health(): """Keep-alive ping ke liye yeh endpoint use karo""" return {"status": "ok"} @app.get("/search") 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.")