File size: 3,050 Bytes
72c0ebf
2c070a4
002a8d0
2c070a4
478cd9e
2c070a4
b893af5
2c070a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b893af5
478cd9e
 
2c070a4
 
 
 
 
 
 
 
 
f869bfc
2c070a4
 
 
478cd9e
dddde97
a9de8bd
2c070a4
 
 
 
 
 
 
 
3b04732
 
2c070a4
 
 
 
 
 
 
 
 
 
b893af5
dddde97
487e6cc
2c070a4
 
 
b893af5
2c070a4
 
002a8d0
 
 
2c070a4
487e6cc
002a8d0
2c070a4
 
dddde97
 
2c070a4
487e6cc
dddde97
2c070a4
dddde97
 
2c070a4
feb7cfb
dddde97
 
feb7cfb
2c070a4
13593b2
2c070a4
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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.")