parthislive commited on
Commit
aa36d8b
Β·
verified Β·
1 Parent(s): 764ade6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +153 -20
app.py CHANGED
@@ -1,12 +1,17 @@
1
  from fastapi import FastAPI, Query, HTTPException
2
  import duckdb
3
  import time
4
- import os
5
 
6
- app = FastAPI(title="PK DB API")
 
 
 
7
 
 
8
  PARQUET_URL = "https://huggingface.co/datasets/parthislive/pk-db/resolve/main/parts/*.parquet"
9
 
 
10
  _con = None
11
 
12
  def get_con():
@@ -21,72 +26,200 @@ def get_con():
21
  return _con
22
 
23
 
24
- @app.get("/")
 
 
 
25
  def root():
26
- return {"app": "PK DB API", "endpoints": ["/api/number", "/api/cnic", "/api/name", "/api/address"]}
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- @app.get("/health")
 
29
  def health():
30
  return {"status": "ok"}
31
 
32
- @app.get("/api/number")
 
33
  def api_number(number: str = Query(...)):
34
  try:
35
  start = time.time()
36
  con = get_con()
37
- sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE NUMBER = ? LIMIT 10"
 
 
 
 
 
38
  result = con.execute(sql, [int(number)]).fetchdf()
39
  elapsed = round(time.time() - start, 2)
40
  if result.empty:
41
  raise HTTPException(404, f"No data for NUMBER={number}")
42
- return {"status": "success", "number": number, "count": len(result), "time": f"{elapsed}s", "data": result.to_dict(orient="records")}
 
 
 
 
 
 
43
  except HTTPException:
44
  raise
45
  except Exception as e:
46
  raise HTTPException(500, str(e))
47
 
48
- @app.get("/api/cnic")
 
49
  def api_cnic(cnic: str = Query(...)):
50
  try:
51
  start = time.time()
52
  con = get_con()
53
- sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE CNIC = ? LIMIT 10"
 
 
 
 
 
54
  result = con.execute(sql, [str(cnic).strip()]).fetchdf()
55
  elapsed = round(time.time() - start, 2)
56
  if result.empty:
57
  raise HTTPException(404, f"No data for CNIC={cnic}")
58
- return {"status": "success", "cnic": cnic, "count": len(result), "time": f"{elapsed}s", "data": result.to_dict(orient="records")}
 
 
 
 
 
 
59
  except HTTPException:
60
  raise
61
  except Exception as e:
62
  raise HTTPException(500, str(e))
63
 
64
- @app.get("/api/name")
 
65
  def api_name(name: str = Query(...)):
66
  try:
67
  start = time.time()
68
  con = get_con()
69
- sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE NAME ILIKE ? LIMIT 50"
 
 
 
 
 
70
  result = con.execute(sql, [f"%{name}%"]).fetchdf()
71
  elapsed = round(time.time() - start, 2)
72
- return {"status": "success" if not result.empty else "not_found", "name": name, "count": len(result), "time": f"{elapsed}s", "data": result.to_dict(orient="records")}
 
 
 
 
 
 
73
  except Exception as e:
74
  raise HTTPException(500, str(e))
75
 
76
- @app.get("/api/address")
 
77
  def api_address(address: str = Query(...)):
78
  try:
79
  start = time.time()
80
  con = get_con()
81
- sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE ADDRESS ILIKE ? LIMIT 50"
 
 
 
 
 
82
  result = con.execute(sql, [f"%{address}%"]).fetchdf()
83
  elapsed = round(time.time() - start, 2)
84
- return {"status": "success" if not result.empty else "not_found", "address": address, "count": len(result), "time": f"{elapsed}s", "data": result.to_dict(orient="records")}
 
 
 
 
 
 
85
  except Exception as e:
86
  raise HTTPException(500, str(e))
87
 
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  if __name__ == "__main__":
90
- import uvicorn
91
- port = int(os.environ.get("PORT", 7860))
92
- uvicorn.run(app, host="0.0.0.0", port=port)
 
1
  from fastapi import FastAPI, Query, HTTPException
2
  import duckdb
3
  import time
4
+ import gradio as gr
5
 
6
+ # ============================================================
7
+ # FASTAPI APP
8
+ # ============================================================
9
+ fastapi_app = FastAPI(title="PK DB API")
10
 
11
+ # ---------- CONFIG ----------
12
  PARQUET_URL = "https://huggingface.co/datasets/parthislive/pk-db/resolve/main/parts/*.parquet"
13
 
14
+ # ---------- DUCKDB ----------
15
  _con = None
16
 
17
  def get_con():
 
26
  return _con
27
 
28
 
29
+ # ============================================================
30
+ # FASTAPI ROUTES
31
+ # ============================================================
32
+ @fastapi_app.get("/")
33
  def root():
34
+ return {
35
+ "app": "PK DB API",
36
+ "dataset": "parthislive/pk-db",
37
+ "columns": ["NUMBER", "CNIC", "NAME", "ADDRESS"],
38
+ "endpoints": {
39
+ "/api/number?number=<num>": "Search by NUMBER",
40
+ "/api/cnic?cnic=<cnic>": "Search by CNIC",
41
+ "/api/name?name=<name>": "Search by NAME",
42
+ "/api/address?address=<addr>": "Search by ADDRESS",
43
+ "/ui": "Gradio UI"
44
+ }
45
+ }
46
 
47
+
48
+ @fastapi_app.get("/health")
49
  def health():
50
  return {"status": "ok"}
51
 
52
+
53
+ @fastapi_app.get("/api/number")
54
  def api_number(number: str = Query(...)):
55
  try:
56
  start = time.time()
57
  con = get_con()
58
+ sql = f"""
59
+ SELECT NUMBER, CNIC, NAME, ADDRESS
60
+ FROM read_parquet('{PARQUET_URL}')
61
+ WHERE NUMBER = ?
62
+ LIMIT 10
63
+ """
64
  result = con.execute(sql, [int(number)]).fetchdf()
65
  elapsed = round(time.time() - start, 2)
66
  if result.empty:
67
  raise HTTPException(404, f"No data for NUMBER={number}")
68
+ return {
69
+ "status": "success",
70
+ "number": number,
71
+ "count": len(result),
72
+ "time": f"{elapsed}s",
73
+ "data": result.to_dict(orient="records")
74
+ }
75
  except HTTPException:
76
  raise
77
  except Exception as e:
78
  raise HTTPException(500, str(e))
79
 
80
+
81
+ @fastapi_app.get("/api/cnic")
82
  def api_cnic(cnic: str = Query(...)):
83
  try:
84
  start = time.time()
85
  con = get_con()
86
+ sql = f"""
87
+ SELECT NUMBER, CNIC, NAME, ADDRESS
88
+ FROM read_parquet('{PARQUET_URL}')
89
+ WHERE CNIC = ?
90
+ LIMIT 10
91
+ """
92
  result = con.execute(sql, [str(cnic).strip()]).fetchdf()
93
  elapsed = round(time.time() - start, 2)
94
  if result.empty:
95
  raise HTTPException(404, f"No data for CNIC={cnic}")
96
+ return {
97
+ "status": "success",
98
+ "cnic": cnic,
99
+ "count": len(result),
100
+ "time": f"{elapsed}s",
101
+ "data": result.to_dict(orient="records")
102
+ }
103
  except HTTPException:
104
  raise
105
  except Exception as e:
106
  raise HTTPException(500, str(e))
107
 
108
+
109
+ @fastapi_app.get("/api/name")
110
  def api_name(name: str = Query(...)):
111
  try:
112
  start = time.time()
113
  con = get_con()
114
+ sql = f"""
115
+ SELECT NUMBER, CNIC, NAME, ADDRESS
116
+ FROM read_parquet('{PARQUET_URL}')
117
+ WHERE NAME ILIKE ?
118
+ LIMIT 50
119
+ """
120
  result = con.execute(sql, [f"%{name}%"]).fetchdf()
121
  elapsed = round(time.time() - start, 2)
122
+ return {
123
+ "status": "success" if not result.empty else "not_found",
124
+ "name": name,
125
+ "count": len(result),
126
+ "time": f"{elapsed}s",
127
+ "data": result.to_dict(orient="records")
128
+ }
129
  except Exception as e:
130
  raise HTTPException(500, str(e))
131
 
132
+
133
+ @fastapi_app.get("/api/address")
134
  def api_address(address: str = Query(...)):
135
  try:
136
  start = time.time()
137
  con = get_con()
138
+ sql = f"""
139
+ SELECT NUMBER, CNIC, NAME, ADDRESS
140
+ FROM read_parquet('{PARQUET_URL}')
141
+ WHERE ADDRESS ILIKE ?
142
+ LIMIT 50
143
+ """
144
  result = con.execute(sql, [f"%{address}%"]).fetchdf()
145
  elapsed = round(time.time() - start, 2)
146
+ return {
147
+ "status": "success" if not result.empty else "not_found",
148
+ "address": address,
149
+ "count": len(result),
150
+ "time": f"{elapsed}s",
151
+ "data": result.to_dict(orient="records")
152
+ }
153
  except Exception as e:
154
  raise HTTPException(500, str(e))
155
 
156
 
157
+ # ============================================================
158
+ # GRADIO UI
159
+ # ============================================================
160
+ def search_ui(query, field):
161
+ if not query or not query.strip():
162
+ return "⚠️ Kuch toh search karo bhai."
163
+
164
+ query = query.strip()
165
+ con = get_con()
166
+
167
+ try:
168
+ if field == "NUMBER":
169
+ sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE NUMBER = ? LIMIT 10"
170
+ result = con.execute(sql, [int(query)]).fetchdf()
171
+ elif field == "CNIC":
172
+ sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE CNIC = ? LIMIT 10"
173
+ result = con.execute(sql, [query]).fetchdf()
174
+ elif field == "NAME":
175
+ sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE NAME ILIKE ? LIMIT 20"
176
+ result = con.execute(sql, [f"%{query}%"]).fetchdf()
177
+ else: # ADDRESS
178
+ sql = f"SELECT NUMBER, CNIC, NAME, ADDRESS FROM read_parquet('{PARQUET_URL}') WHERE ADDRESS ILIKE ? LIMIT 20"
179
+ result = con.execute(sql, [f"%{query}%"]).fetchdf()
180
+
181
+ if result.empty:
182
+ return f"❌ Kuch nahi mila for {field}={query}"
183
+
184
+ return result.to_string()
185
+ except Exception as e:
186
+ return f"❌ Error: {e}"
187
+
188
+
189
+ with gr.Blocks(title="PK DB Search") as demo:
190
+ gr.Markdown("# πŸ” PK DB Search")
191
+ gr.Markdown("Search **218M Pakistan records** β€” NUMBER, CNIC, NAME, ADDRESS")
192
+
193
+ with gr.Row():
194
+ query_input = gr.Textbox(
195
+ label="Search Query",
196
+ placeholder="NUMBER, CNIC, NAME ya ADDRESS daalo...",
197
+ lines=1,
198
+ )
199
+ field_select = gr.Radio(
200
+ choices=["NUMBER", "CNIC", "NAME", "ADDRESS"],
201
+ label="Search Field",
202
+ value="NUMBER",
203
+ )
204
+
205
+ search_btn = gr.Button("πŸ” Search", variant="primary", size="lg")
206
+ output = gr.Textbox(label="Results", lines=20)
207
+
208
+ search_btn.click(fn=search_ui, inputs=[query_input, field_select], outputs=output)
209
+ query_input.submit(fn=search_ui, inputs=[query_input, field_select], outputs=output)
210
+
211
+ gr.Markdown("---")
212
+ gr.Markdown("**API Endpoints:** `/api/number`, `/api/cnic`, `/api/name`, `/api/address`")
213
+
214
+
215
+ # ============================================================
216
+ # MOUNT GRADIO ON FASTAPI
217
+ # ============================================================
218
+ app = gr.mount_gradio_app(fastapi_app, demo, path="/ui")
219
+
220
+
221
+ # ============================================================
222
+ # LAUNCH (HF Space Ke Liye)
223
+ # ============================================================
224
  if __name__ == "__main__":
225
+ demo.launch(server_name="0.0.0.0", server_port=7860)