Update app.py
Browse files
app.py
CHANGED
@@ -95,7 +95,7 @@ def fetch_flight_data(lat_min, lat_max, lon_min, lon_max):
|
|
95 |
return {'states': [], 'time': 0}
|
96 |
|
97 |
# Hugging Face model configuration
|
98 |
-
HF_API_URL = "https://api-inference.huggingface.co/models/
|
99 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
100 |
headers = {"Authorization": f"Bearer {HF_TOKEN}"}
|
101 |
|
@@ -104,20 +104,69 @@ def query_llm(prompt):
|
|
104 |
payload = {
|
105 |
"inputs": prompt,
|
106 |
"parameters": {
|
107 |
-
"
|
108 |
"temperature": 0.1,
|
109 |
"top_p": 0.95,
|
110 |
-
"
|
111 |
}
|
112 |
}
|
113 |
|
114 |
response = requests.post(HF_API_URL, headers=headers, json=payload)
|
115 |
response.raise_for_status()
|
116 |
return response.json()[0]['generated_text']
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
except Exception as e:
|
118 |
st.error(f"Error querying language model: {str(e)}")
|
119 |
return None
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
def query_flight_data(geo_df, question):
|
122 |
# Preprocess the question to extract key information
|
123 |
question = question.lower().strip()
|
@@ -182,10 +231,28 @@ def query_flight_data(geo_df, question):
|
|
182 |
except:
|
183 |
pass
|
184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
if flight_data is None or flight_data.empty:
|
186 |
-
|
|
|
|
|
|
|
|
|
187 |
|
188 |
-
# Prepare flight data for
|
189 |
flight_info = {}
|
190 |
for col in flight_data.columns:
|
191 |
if col in flight_data.columns:
|
@@ -209,27 +276,27 @@ def query_flight_data(geo_df, question):
|
|
209 |
if not flight_info:
|
210 |
return f"No information available for flight {identifier}."
|
211 |
|
212 |
-
#
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
|
217 |
-
|
218 |
{json.dumps(flight_info, indent=2)}
|
219 |
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
|
|
|
|
|
|
224 |
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
for key, value in flight_info.items():
|
231 |
-
response += f"- {key.replace('_', ' ').title()}: {value}\n"
|
232 |
-
return response
|
233 |
|
234 |
def flight_tracking(flight_view_level, country, local_time_zone, flight_info, airport, color):
|
235 |
# Get cached location data
|
|
|
95 |
return {'states': [], 'time': 0}
|
96 |
|
97 |
# Hugging Face model configuration
|
98 |
+
HF_API_URL = "https://api-inference.huggingface.co/models/google/flan-t5-large"
|
99 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
100 |
headers = {"Authorization": f"Bearer {HF_TOKEN}"}
|
101 |
|
|
|
104 |
payload = {
|
105 |
"inputs": prompt,
|
106 |
"parameters": {
|
107 |
+
"max_length": 250,
|
108 |
"temperature": 0.1,
|
109 |
"top_p": 0.95,
|
110 |
+
"do_sample": False
|
111 |
}
|
112 |
}
|
113 |
|
114 |
response = requests.post(HF_API_URL, headers=headers, json=payload)
|
115 |
response.raise_for_status()
|
116 |
return response.json()[0]['generated_text']
|
117 |
+
except requests.exceptions.HTTPError as e:
|
118 |
+
if e.response.status_code == 403:
|
119 |
+
st.warning("Language model access is currently restricted. Using direct flight data display instead.")
|
120 |
+
else:
|
121 |
+
st.error(f"Error querying language model: {str(e)}")
|
122 |
+
return None
|
123 |
except Exception as e:
|
124 |
st.error(f"Error querying language model: {str(e)}")
|
125 |
return None
|
126 |
|
127 |
+
def create_flight_embeddings(geo_df):
|
128 |
+
"""Create embeddings for flight data to enable semantic search"""
|
129 |
+
try:
|
130 |
+
from sentence_transformers import SentenceTransformer
|
131 |
+
model = SentenceTransformer('all-MiniLM-L6-v2')
|
132 |
+
|
133 |
+
# Create text representations of flight data
|
134 |
+
flight_texts = []
|
135 |
+
for _, row in geo_df.iterrows():
|
136 |
+
text = f"Flight {row['callsign']} from {row['origin_country']} "
|
137 |
+
text += f"at altitude {row['baro_altitude']}m, speed {row['velocity']}m/s, "
|
138 |
+
text += f"heading {row['true_track']}°"
|
139 |
+
flight_texts.append(text)
|
140 |
+
|
141 |
+
# Generate embeddings
|
142 |
+
embeddings = model.encode(flight_texts)
|
143 |
+
return embeddings, flight_texts
|
144 |
+
except Exception as e:
|
145 |
+
st.warning(f"Could not create embeddings: {str(e)}")
|
146 |
+
return None, None
|
147 |
+
|
148 |
+
def find_similar_flights(identifier, geo_df, embeddings, flight_texts, threshold=0.7):
|
149 |
+
"""Find similar flights using semantic search"""
|
150 |
+
try:
|
151 |
+
from sentence_transformers import SentenceTransformer
|
152 |
+
model = SentenceTransformer('all-MiniLM-L6-v2')
|
153 |
+
|
154 |
+
# Create query embedding
|
155 |
+
query_embedding = model.encode([identifier])
|
156 |
+
|
157 |
+
# Calculate similarities
|
158 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
159 |
+
similarities = cosine_similarity(query_embedding, embeddings)[0]
|
160 |
+
|
161 |
+
# Find similar flights
|
162 |
+
similar_indices = [i for i, sim in enumerate(similarities) if sim > threshold]
|
163 |
+
if similar_indices:
|
164 |
+
return geo_df.iloc[similar_indices]
|
165 |
+
return None
|
166 |
+
except Exception as e:
|
167 |
+
st.warning(f"Error in semantic search: {str(e)}")
|
168 |
+
return None
|
169 |
+
|
170 |
def query_flight_data(geo_df, question):
|
171 |
# Preprocess the question to extract key information
|
172 |
question = question.lower().strip()
|
|
|
231 |
except:
|
232 |
pass
|
233 |
|
234 |
+
# If still no match, try semantic search using RAG
|
235 |
+
if flight_data is None or flight_data.empty:
|
236 |
+
try:
|
237 |
+
# Create embeddings for all flights
|
238 |
+
embeddings, flight_texts = create_flight_embeddings(geo_df)
|
239 |
+
if embeddings is not None:
|
240 |
+
# Try to find similar flights
|
241 |
+
similar_flights = find_similar_flights(identifier, geo_df, embeddings, flight_texts)
|
242 |
+
if similar_flights is not None and not similar_flights.empty:
|
243 |
+
flight_data = similar_flights
|
244 |
+
st.info(f"Found similar flight(s) to {identifier}")
|
245 |
+
except Exception as e:
|
246 |
+
st.warning(f"Semantic search failed: {str(e)}")
|
247 |
+
|
248 |
if flight_data is None or flight_data.empty:
|
249 |
+
# If still no match, show available flights
|
250 |
+
available_flights = geo_df['callsign'].dropna().unique()
|
251 |
+
if len(available_flights) > 0:
|
252 |
+
return f"Could not find flight {identifier}. Available flights: {', '.join(available_flights[:10])}..."
|
253 |
+
return f"Could not find flight {identifier}. No flights currently available in the selected area."
|
254 |
|
255 |
+
# Prepare flight data for display
|
256 |
flight_info = {}
|
257 |
for col in flight_data.columns:
|
258 |
if col in flight_data.columns:
|
|
|
276 |
if not flight_info:
|
277 |
return f"No information available for flight {identifier}."
|
278 |
|
279 |
+
# Try to get LLM response, but fall back to direct display if it fails
|
280 |
+
try:
|
281 |
+
# Create a prompt for the LLM
|
282 |
+
prompt = f"""Answer this question about flight {identifier}: {question}
|
283 |
|
284 |
+
Available flight data:
|
285 |
{json.dumps(flight_info, indent=2)}
|
286 |
|
287 |
+
Provide a clear and concise answer focusing on the specific information requested."""
|
288 |
+
|
289 |
+
llm_response = query_llm(prompt)
|
290 |
+
if llm_response:
|
291 |
+
return llm_response
|
292 |
+
except:
|
293 |
+
pass
|
294 |
|
295 |
+
# Fallback to direct data display
|
296 |
+
response = f"Flight Information for {identifier}:\n"
|
297 |
+
for key, value in flight_info.items():
|
298 |
+
response += f"- {key.replace('_', ' ').title()}: {value}\n"
|
299 |
+
return response
|
|
|
|
|
|
|
300 |
|
301 |
def flight_tracking(flight_view_level, country, local_time_zone, flight_info, airport, color):
|
302 |
# Get cached location data
|