gkdivya commited on
Commit
300b404
·
verified ·
1 Parent(s): 2158266

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -67
app.py CHANGED
@@ -1,11 +1,14 @@
1
- # tavily_kys_space.py
2
- # Gradio app for Hugging Face Spaces (Tavily API key textbox + Save key in session)
3
 
4
  import gradio as gr
5
  import requests
6
  import pandas as pd
 
 
7
 
8
  KYS_SAMPLE = "https://kys.udiseplus.gov.in/webapp/api/search-schools?searchType=3&searchParam={udise}"
 
9
 
10
 
11
  def call_kys_by_udise(udise_code):
@@ -19,29 +22,17 @@ def call_kys_by_udise(udise_code):
19
  return {"ok": False, "error": str(e), "url": url}
20
 
21
 
22
- def call_tavily(tavily_url, api_key, payload_text):
23
- headers = {"Accept": "application/json"}
24
- if api_key:
25
- headers["Authorization"] = api_key
26
- body = {"query": payload_text}
27
-
28
  try:
29
- resp = requests.post(tavily_url, json=body, headers=headers, timeout=12)
30
- resp.raise_for_status()
31
- return {"ok": True, "url": tavily_url, "status_code": resp.status_code, "data": resp.json()}
32
  except Exception as e:
33
- try:
34
- params = {"q": payload_text}
35
- resp = requests.get(tavily_url, params=params, headers=headers, timeout=12)
36
- resp.raise_for_status()
37
- return {"ok": True, "url": resp.url, "status_code": resp.status_code, "data": resp.json()}
38
- except Exception as e2:
39
- return {"ok": False, "error": f"POST failed: {e}; GET failed: {e2}"}
40
 
41
 
42
- def extract_udise_candidates_from_tavily(tavily_json):
43
  found = set()
44
-
45
  def walk(obj):
46
  if isinstance(obj, dict):
47
  for v in obj.values():
@@ -55,8 +46,7 @@ def extract_udise_candidates_from_tavily(tavily_json):
55
  for t in tokens:
56
  if t.isdigit() and 6 <= len(t) <= 14:
57
  found.add(t)
58
-
59
- walk(tavily_json)
60
  return sorted(list(found))
61
 
62
 
@@ -86,79 +76,78 @@ def to_table_from_kys(kys_json):
86
  return pd.DataFrame()
87
 
88
 
89
- def search_workflow(school_name_or_udise, tavily_url, tavily_key, use_tavily, use_kys):
90
- out = {"kys": None, "tavily": None, "suggestions": []}
 
91
 
92
- if use_tavily and tavily_url:
93
- tavily_res = call_tavily(tavily_url, tavily_key, school_name_or_udise or "")
94
- out["tavily"] = tavily_res
95
- if tavily_res.get("ok"):
96
- candidates = extract_udise_candidates_from_tavily(tavily_res["data"])
97
  out["suggestions"] = candidates
98
  else:
99
- out["tavily"] = {"ok": False, "error": "Tavily disabled or no URL provided"}
100
 
101
- if use_kys and school_name_or_udise and school_name_or_udise.strip().isdigit() and 6 <= len(school_name_or_udise.strip()) <= 14:
102
- kys_res = call_kys_by_udise(school_name_or_udise.strip())
103
  out["kys"] = kys_res
104
 
105
  return out
106
 
107
 
108
  with gr.Blocks() as demo:
109
- # Fixed: properly terminated Markdown strings
110
- gr.Markdown('''# Tavily + KYS Search (Hugging Face Space)
 
111
 
112
- Enter a school name or a UDISE code, Tavily endpoint, and optionally an API key.
113
- Use the 'Save key in session' toggle to keep the key for the current browser session.''')
 
 
114
 
115
  with gr.Row():
116
- inp = gr.Textbox(label="School name", placeholder="'Govt High School...'", lines=1)
117
- tavily_url = gr.Textbox(label="Tavily endpoint URL (POST/GET)", placeholder="https://your-tavily.example/api/search")
118
 
119
- # Tavily API key textbox + save toggle
120
- tavily_key = gr.Textbox(label="Tavily API Key (optional)", placeholder="Bearer ... or APIKEY ...", lines=1)
121
  save_key_toggle = gr.Checkbox(value=False, label="Save key in session (keeps key between interactions)")
122
  clear_key_btn = gr.Button("Clear saved key")
123
 
124
  with gr.Row():
125
- use_tavily = gr.Checkbox(value=True, label="Call Tavily")
126
  use_kys = gr.Checkbox(value=True, label="Call KYS by UDISE")
127
 
128
- run = gr.Button("Search Tavily")
129
 
130
- output_json = gr.JSON(label="Raw Tavily Output (JSON)")
131
- tavily_table = gr.DataFrame(headers=None, label="Search Results (table)")
132
 
133
- gr.Markdown("### UDISE candidates found in search results")
134
- suggestions_dropdown = gr.Dropdown(choices=[], label="UDISE candidates")
135
  udise_input = gr.Textbox(label="UDISE to lookup (editable)", placeholder="Pick a candidate or type a UDISE code...", lines=1)
136
  lookup_btn = gr.Button("Lookup UDISE (Call KYS)")
137
 
138
  kys_output_json = gr.JSON(label="KYS Raw Output")
139
  kys_table = gr.DataFrame(headers=None, label="KYS results (table)")
140
 
141
- # A small gr.State to persist the saved key value inside the session
142
  saved_key_state = gr.State("")
143
 
144
- def on_run(school, turl, tkey, save_key, utav, ukys, saved_key):
145
- # Determine effective key: if save_key and saved_key present use saved_key, else use tkey
146
- effective_key = saved_key if saved_key else tkey
147
- res = search_workflow(school, turl, effective_key, utav, ukys)
148
- tav_df = pd.DataFrame()
149
- if res.get("tavily") and res["tavily"].get("ok"):
150
- tav_df = json_to_table(res["tavily"]["data"])
151
  suggestions = res.get("suggestions", [])
152
- # If user asked to save the key for session, return it into saved_key_state and keep the textbox value
153
  new_saved_key = saved_key
154
- textbox_value = tkey
155
  if save_key:
156
- new_saved_key = tkey or saved_key
157
  textbox_value = new_saved_key
158
- return res.get("tavily"), tav_df, suggestions, new_saved_key, textbox_value
159
 
160
- # run.click outputs: tavily json, tavily table, suggestions dropdown, saved_key_state, tavily_key (textbox)
161
- run.click(on_run, inputs=[inp, tavily_url, tavily_key, save_key_toggle, use_tavily, use_kys, saved_key_state], outputs=[output_json, tavily_table, suggestions_dropdown, saved_key_state, tavily_key])
162
 
163
  def on_select_suggestion(choice):
164
  return choice or ""
@@ -176,18 +165,20 @@ Use the 'Save key in session' toggle to keep the key for the current browser ses
176
 
177
  lookup_btn.click(on_lookup_udise, inputs=[udise_input], outputs=[kys_output_json, kys_table])
178
 
179
- # Clear saved key handler: empties both the saved_key_state and the textbox
180
  def on_clear_key(_):
181
  return "", ""
182
 
183
- clear_key_btn.click(on_clear_key, inputs=[saved_key_state], outputs=[saved_key_state, tavily_key])
184
 
185
- gr.Markdown('''---
 
 
186
  **Notes:**
187
- - The 'Save key in session' toggle will keep the key active for the current browser session and across interactions in the Space UI.
188
- - The key is stored only in-memory for the session (not written to disk) and is not logged.
189
- - Use the 'Clear saved key' button to remove it from the session.''')
190
-
 
191
 
192
  if __name__ == "__main__":
193
  demo.launch()
 
1
+ # search_kys_space.py
2
+ # Gradio app for Hugging Face Spaces (uses Search API via Tavily SDK internally)
3
 
4
  import gradio as gr
5
  import requests
6
  import pandas as pd
7
+ import json
8
+ from tavily import TavilyClient
9
 
10
  KYS_SAMPLE = "https://kys.udiseplus.gov.in/webapp/api/search-schools?searchType=3&searchParam={udise}"
11
+ STATES = ["Arunachal Pradesh", "Assam", "Karnataka", "Kerala", "Tamil Nadu", "Maharashtra"]
12
 
13
 
14
  def call_kys_by_udise(udise_code):
 
22
  return {"ok": False, "error": str(e), "url": url}
23
 
24
 
25
+ def call_search_sdk(api_key, payload_text):
 
 
 
 
 
26
  try:
27
+ client = TavilyClient(api_key)
28
+ resp = client.search(query=payload_text)
29
+ return {"ok": True, "data": resp}
30
  except Exception as e:
31
+ return {"ok": False, "error": str(e)}
 
 
 
 
 
 
32
 
33
 
34
+ def extract_udise_candidates_from_search(search_json):
35
  found = set()
 
36
  def walk(obj):
37
  if isinstance(obj, dict):
38
  for v in obj.values():
 
46
  for t in tokens:
47
  if t.isdigit() and 6 <= len(t) <= 14:
48
  found.add(t)
49
+ walk(search_json)
 
50
  return sorted(list(found))
51
 
52
 
 
76
  return pd.DataFrame()
77
 
78
 
79
+ def search_workflow(school_name, state_name, search_key, use_search, use_kys):
80
+ out = {"kys": None, "search": None, "suggestions": []}
81
+ payload_text = f"{school_name or ''} {state_name or ''} UDISE code".strip()
82
 
83
+ if use_search:
84
+ search_res = call_search_sdk(search_key, payload_text)
85
+ out["search"] = search_res
86
+ if search_res.get("ok"):
87
+ candidates = extract_udise_candidates_from_search(search_res["data"])
88
  out["suggestions"] = candidates
89
  else:
90
+ out["search"] = {"ok": False, "error": "Search disabled or SDK not used"}
91
 
92
+ if use_kys and school_name and school_name.strip().isdigit() and 6 <= len(school_name.strip()) <= 14:
93
+ kys_res = call_kys_by_udise(school_name.strip())
94
  out["kys"] = kys_res
95
 
96
  return out
97
 
98
 
99
  with gr.Blocks() as demo:
100
+ gr.Markdown(
101
+ """
102
+ # Provide your API key in the textbox.
103
 
104
+ Enter a school name and select the state; the app calls Search
105
+ with the combined query `<school> <state> UDISE code`, then optionally calls KYS.
106
+ """
107
+ )
108
 
109
  with gr.Row():
110
+ inp = gr.Textbox(label="School name", placeholder="e.g. GOVT SEC SCHOOL DARLONG", lines=1)
111
+ state_dropdown = gr.Dropdown(choices=STATES, label="State", value=STATES[0] if STATES else "", interactive=True, searchable=True)
112
 
113
+ search_key = gr.Textbox(label="Search API Key (required)", placeholder="api-key...", lines=1)
 
114
  save_key_toggle = gr.Checkbox(value=False, label="Save key in session (keeps key between interactions)")
115
  clear_key_btn = gr.Button("Clear saved key")
116
 
117
  with gr.Row():
118
+ use_search = gr.Checkbox(value=True, label="Call Search API")
119
  use_kys = gr.Checkbox(value=True, label="Call KYS by UDISE")
120
 
121
+ run = gr.Button("Search")
122
 
123
+ output_json = gr.JSON(label="Raw Search Output (JSON)")
124
+ search_table = gr.DataFrame(headers=None, label="Search results (table)")
125
 
126
+ gr.Markdown("### UDISE candidates found in Search results")
127
+ suggestions_dropdown = gr.Dropdown(choices=[], label="UDISE candidates (from Search)")
128
  udise_input = gr.Textbox(label="UDISE to lookup (editable)", placeholder="Pick a candidate or type a UDISE code...", lines=1)
129
  lookup_btn = gr.Button("Lookup UDISE (Call KYS)")
130
 
131
  kys_output_json = gr.JSON(label="KYS Raw Output")
132
  kys_table = gr.DataFrame(headers=None, label="KYS results (table)")
133
 
 
134
  saved_key_state = gr.State("")
135
 
136
+ def on_run(school, state, key, save_key, use_s, use_k, saved_key):
137
+ effective_key = saved_key if saved_key else key
138
+ res = search_workflow(school, state, effective_key, use_s, use_k)
139
+ tbl = pd.DataFrame()
140
+ if res.get("search") and res["search"].get("ok"):
141
+ tbl = json_to_table(res["search"]["data"])
 
142
  suggestions = res.get("suggestions", [])
 
143
  new_saved_key = saved_key
144
+ textbox_value = key
145
  if save_key:
146
+ new_saved_key = key or saved_key
147
  textbox_value = new_saved_key
148
+ return res.get("search"), tbl, suggestions, new_saved_key, textbox_value
149
 
150
+ run.click(on_run, inputs=[inp, state_dropdown, search_key, save_key_toggle, use_search, use_kys, saved_key_state], outputs=[output_json, search_table, suggestions_dropdown, saved_key_state, search_key])
 
151
 
152
  def on_select_suggestion(choice):
153
  return choice or ""
 
165
 
166
  lookup_btn.click(on_lookup_udise, inputs=[udise_input], outputs=[kys_output_json, kys_table])
167
 
 
168
  def on_clear_key(_):
169
  return "", ""
170
 
171
+ clear_key_btn.click(on_clear_key, inputs=[saved_key_state], outputs=[saved_key_state, search_key])
172
 
173
+ gr.Markdown(
174
+ """
175
+ ---
176
  **Notes:**
177
+ - The 'Save key in session' toggle keeps the key active for the current session.
178
+ - The key is stored only in-memory (not written to disk) and is not logged.
179
+ - Use 'Clear saved key' to remove it from the session.
180
+ """
181
+ )
182
 
183
  if __name__ == "__main__":
184
  demo.launch()