yahya1912 commited on
Commit
ff61ae6
·
verified ·
1 Parent(s): 8cb98fa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -43
app.py CHANGED
@@ -1,12 +1,14 @@
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
  import json, re, os, requests
 
 
4
 
5
- # المفاتيح من إعدادات الـ Space
6
  hf_token = os.getenv("HF_TOKEN")
7
  google_key = os.getenv("GOOGLE_MAPS_API_KEY")
8
 
9
- # إنشاء العميل
10
  client = InferenceClient("Qwen/Qwen2.5-7B-Instruct", token=hf_token)
11
 
12
  SYSTEM_PROMPT = """Analyze the Arabic map query and return ONLY a JSON object with these exact keys:
@@ -31,7 +33,15 @@ SYSTEM_PROMPT = """Analyze the Arabic map query and return ONLY a JSON object wi
31
 
32
  Examples:
33
  Input: "أرخص وأقرب مستشفى طوارئ في جدة"
34
- Output: {"location": "جدة", "category": "مستشفى", "sub_type": "طوارئ", "features": ["أرخص", "أقرب"], "sort_by": "price"}"""
 
 
 
 
 
 
 
 
35
 
36
  def build_search_query(parsed_data):
37
  """بناء جملة بحث محسّنة"""
@@ -64,7 +74,7 @@ def search_google_maps_new_api(parsed_data):
64
  query = build_search_query(parsed_data)
65
 
66
  if not query.strip():
67
- query = f"{parsed_data.get('category', '')} {parsed_data.get('location', '')}"
68
 
69
  # Places API (New) - Text Search v1
70
  url = "https://places.googleapis.com/v1/places:searchText"
@@ -143,7 +153,7 @@ def search_google_maps_new_api(parsed_data):
143
  types = place.get("types", [])
144
  place_type = ", ".join([t.replace("_", " ").replace("restaurant", "مطعم").replace("cafe", "مقهى")
145
  .replace("hospital", "مستشفى").replace("park", "حديقة")
146
- .replace("store", "متجر").replace("gas_station", "محطة وقود")[:15]
147
  for t in types[:2]])
148
 
149
  card = f"""### {i}. 📍 {name}
@@ -163,6 +173,9 @@ def search_google_maps_new_api(parsed_data):
163
 
164
  def search_google_maps_legacy(parsed_data, query=None):
165
  """الرجوع إلى Legacy API كاحتياط"""
 
 
 
166
  if not query:
167
  query = build_search_query(parsed_data)
168
 
@@ -178,7 +191,7 @@ def search_google_maps_legacy(parsed_data, query=None):
178
  data = response.json()
179
 
180
  if data.get("status") != "OK":
181
- return f"⚠️ خطأ في Legacy API أيضاً: {data.get('status')}. الرجاء تفعيل Places API (New) في Google Cloud Console."
182
 
183
  results = data.get("results", [])
184
 
@@ -253,11 +266,66 @@ def main_process(user_query):
253
  if "error" in parsed_data:
254
  return parsed_data, f"⚠️ {parsed_data.get('error', 'خطأ غير معروف')}"
255
 
256
- # استخدام الـ New API مع fallback للـ Legacy
257
  map_results = search_google_maps_new_api(parsed_data)
258
 
259
  return parsed_data, map_results
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  # ==================== واجهة المستخدم ====================
262
 
263
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
@@ -268,41 +336,58 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
268
  ⚠️ **تأكد من تفعيل Places API (New) في Google Cloud Console**
269
  """)
270
 
271
- with gr.Row():
272
- input_text = gr.Textbox(
273
- label="📝 ماذا تبحث عنه؟",
274
- placeholder="مثال: أرخص مستشفى طوارئ في جدة، أو حديقة أطفال نظيفة في الرياض",
275
- lines=2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  )
277
-
278
- btn = gr.Button("🔍 ابحث الآن", variant="primary")
279
-
280
- with gr.Row():
281
- with gr.Column(scale=1):
282
- output_json = gr.JSON(label="⚙️ تحليل الذكاء الاصطناعي")
283
- with gr.Column(scale=2):
284
- output_map = gr.Markdown(label="🗺️ نتائج Google Maps")
285
-
286
- gr.Markdown("### 💡 أمثلة للبحث:")
287
- examples = [
288
- "أرخص وأقرب مستشفى طوارئ في جدة",
289
- "حديقة أطفال نظيفة في الرياض",
290
- "أفضل فندق 5 نجوم في دبي",
291
- "مقهى هادئ للعمل في الخبر",
292
- "محطة وقود 24 ساعة رخيصة",
293
- "صيدلية قريبة مفتوحة الآن"
294
- ]
295
-
296
- with gr.Row():
297
- for ex in examples[:3]:
298
- btn_ex = gr.Button(ex, size="sm")
299
- btn_ex.click(lambda x=ex: x, None, input_text)
300
-
301
- with gr.Row():
302
- for ex in examples[3:]:
303
- btn_ex = gr.Button(ex, size="sm")
304
- btn_ex.click(lambda x=ex: x, None, input_text)
305
-
306
- btn.click(fn=main_process, inputs=input_text, outputs=[output_json, output_map])
307
 
308
- demo.launch()
 
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
  import json, re, os, requests
4
+ import csv
5
+ from io import StringIO
6
 
7
+ # API Keys from Space settings
8
  hf_token = os.getenv("HF_TOKEN")
9
  google_key = os.getenv("GOOGLE_MAPS_API_KEY")
10
 
11
+ # Initialize Client
12
  client = InferenceClient("Qwen/Qwen2.5-7B-Instruct", token=hf_token)
13
 
14
  SYSTEM_PROMPT = """Analyze the Arabic map query and return ONLY a JSON object with these exact keys:
 
33
 
34
  Examples:
35
  Input: "أرخص وأقرب مستشفى طوارئ في جدة"
36
+ Output: {"location": "جدة", "category": "مستشفى", "sub_type": "طوارئ", "features": ["أرخص", "أقرب"], "sort_by": "price"}
37
+ Input: "حديقة أطفال نظيفة في الرياض"
38
+ Output: {"location": "الرياض", "category": "حديقة", "sub_type": "أطفال", "features": ["نظيفة"], "sort_by": "relevance"}
39
+ Input: "أفضل فندق 5 نجوم قريب من المطار في دبي"
40
+ Output: {"location": "دبي", "category": "فندق", "sub_type": "5 نجوم", "features": ["أفضل", "قريب من المطار"], "sort_by": "rating"}
41
+ Input: "محطة وقود 24 ساعة رخيصة"
42
+ Output: {"location": "near me", "category": "محطة وقود", "sub_type": null, "features": ["24 ساعة", "رخيصة"], "sort_by": "price"}
43
+ Input: "مقهى هادئ للعمل في الرياض"
44
+ Output: {"location": "الرياض", "category": "مقهى", "sub_type": null, "features": ["هادئ", "للعمل"], "sort_by": "relevance"}"""
45
 
46
  def build_search_query(parsed_data):
47
  """بناء جملة بحث محسّنة"""
 
74
  query = build_search_query(parsed_data)
75
 
76
  if not query.strip():
77
+ query = f"{parsed_data.get("category", "")} {parsed_data.get("location", "")}"
78
 
79
  # Places API (New) - Text Search v1
80
  url = "https://places.googleapis.com/v1/places:searchText"
 
153
  types = place.get("types", [])
154
  place_type = ", ".join([t.replace("_", " ").replace("restaurant", "مطعم").replace("cafe", "مقهى")
155
  .replace("hospital", "مستشفى").replace("park", "حديقة")
156
+ .replace("store", "متجر").replace("gas_station", "محطة وقود")
157
  for t in types[:2]])
158
 
159
  card = f"""### {i}. 📍 {name}
 
173
 
174
  def search_google_maps_legacy(parsed_data, query=None):
175
  """الرجوع إلى Legacy API كاحتياط"""
176
+ if not google_key:
177
+ return "⚠️ الرجاء إضافة GOOGLE_MAPS_API_KEY في إعدادات الـ Space."
178
+
179
  if not query:
180
  query = build_search_query(parsed_data)
181
 
 
191
  data = response.json()
192
 
193
  if data.get("status") != "OK":
194
+ return f"⚠️ خطأ في Legacy API أيضاً: {data.get("status")}. الرجاء تفعيل Places API (New) في Google Cloud Console."
195
 
196
  results = data.get("results", [])
197
 
 
266
  if "error" in parsed_data:
267
  return parsed_data, f"⚠️ {parsed_data.get('error', 'خطأ غير معروف')}"
268
 
 
269
  map_results = search_google_maps_new_api(parsed_data)
270
 
271
  return parsed_data, map_results
272
 
273
+ def process_batch_queries(file_obj, progress=gr.Progress()):
274
+ if file_obj is None:
275
+ return None, "❌ الرجاء تحميل ملف للاستعلامات الجماعية."
276
+
277
+ queries = []
278
+ try:
279
+ with open(file_obj.name, 'r', encoding='utf-8') as f:
280
+ for line in f:
281
+ query = line.strip()
282
+ if query:
283
+ queries.append(query)
284
+ except Exception as e:
285
+ return None, f"❌ خطأ في قراءة الملف: {str(e)}"
286
+
287
+ if not queries:
288
+ return None, "❌ الملف فارغ أو لا يحتوي على استعلامات صالحة."
289
+
290
+ results = []
291
+ for i, query in enumerate(progress.tqdm(queries, desc="معالجة الاستعلامات")):
292
+ parsed_data, map_results = main_process(query)
293
+
294
+ # Flatten parsed_data for CSV, handle errors
295
+ parsed_json_str = json.dumps(parsed_data, ensure_ascii=False) if "error" not in parsed_data else parsed_data.get("error", "")
296
+
297
+ # Extract top result name if available, otherwise indicate no results
298
+ top_result_name = ""
299
+ if "نتائج البحث عن" in map_results and "📍" in map_results:
300
+ match = re.search(r'### \d+\. 📍 ([^\n]+)', map_results)
301
+ if match:
302
+ top_result_name = match.group(1).strip()
303
+ elif "لم يتم العثور على نتائج" in map_results:
304
+ top_result_name = "لا توجد نتائج"
305
+ elif "خطأ" in map_results:
306
+ top_result_name = f"خطأ في API: {map_results}"
307
+
308
+ results.append({
309
+ "Original Query": query,
310
+ "Parsed JSON": parsed_json_str,
311
+ "Top Map Result": top_result_name,
312
+ "Full Map Results": map_results.replace('\n', ' ') # Replace newlines for CSV readability
313
+ })
314
+
315
+ # Write results to a CSV in memory
316
+ output_buffer = StringIO()
317
+ fieldnames = ["Original Query", "Parsed JSON", "Top Map Result", "Full Map Results"]
318
+ writer = csv.DictWriter(output_buffer, fieldnames=fieldnames)
319
+ writer.writeheader()
320
+ writer.writerows(results)
321
+
322
+ # Save to a temporary file for Gradio to handle
323
+ output_filepath = "./batch_results.csv"
324
+ with open(output_filepath, 'w', encoding='utf-8') as f:
325
+ f.write(output_buffer.getvalue())
326
+
327
+ return output_filepath, "✅ تم الانتهاء من معالجة الدفعة. يمكنك تحميل النتائج."
328
+
329
  # ==================== واجهة المستخدم ====================
330
 
331
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
 
336
  ⚠️ **تأكد من تفعيل Places API (New) في Google Cloud Console**
337
  """)
338
 
339
+ with gr.Tab("استعلام فردي"):
340
+ with gr.Row():
341
+ input_text = gr.Textbox(
342
+ label="📝 ماذا تبحث عنه؟",
343
+ placeholder="مثال: أرخص مستشفى طوارئ في جدة، أو حديقة أطفال نظيفة في الرياض، أو فندق 5 نجوم في دبي",
344
+ lines=2
345
+ )
346
+
347
+ btn = gr.Button("🔍 ابحث الآن", variant="primary")
348
+
349
+ with gr.Row():
350
+ with gr.Column(scale=1):
351
+ output_json = gr.JSON(label="⚙️ تحليل الذكاء الاصطناعي")
352
+ with gr.Column(scale=2):
353
+ output_map = gr.Markdown(label="🗺️ نتائج Google Maps")
354
+
355
+ gr.Markdown("### 💡 أمثلة للبحث:")
356
+ examples = [
357
+ "أرخص وأقرب مستشفى طوارئ في جدة",
358
+ "حديقة أطفال نظيفة في الرياض",
359
+ "أفضل فندق 5 نجوم في دبي",
360
+ "مقهى هادئ للعمل في الخبر",
361
+ "محطة وقود 24 ساعة رخيصة",
362
+ "صيدلية قريبة مفتوحة الآن"
363
+ ]
364
+
365
+ with gr.Row():
366
+ for ex in examples[:3]:
367
+ btn_ex = gr.Button(ex, size="sm")
368
+ btn_ex.click(lambda x=ex: x, None, input_text)
369
+
370
+ with gr.Row():
371
+ for ex in examples[3:]:
372
+ btn_ex = gr.Button(ex, size="sm")
373
+ btn_ex.click(lambda x=ex: x, None, input_text)
374
+
375
+ btn.click(fn=main_process, inputs=input_text, outputs=[output_json, output_map])
376
+
377
+ with gr.Tab("معالجة دفعة"):
378
+ gr.Markdown("""
379
+ ### ⬆️ تحميل ملف الاستعلامات
380
+ قم بتحميل ملف نصي (.txt) أو CSV يحتوي على استعلام واحد في كل سطر.
381
+ """)
382
+ file_input = gr.File(label="ملف الاستعلامات (TXT/CSV)", file_count="single", type="filepath")
383
+ batch_btn = gr.Button("🚀 ابدأ معالجة الدفعة", variant="primary")
384
+ batch_output_file = gr.File(label="ملف نتائج الدفعة (CSV)")
385
+ batch_status_message = gr.Markdown(label="الحالة")
386
+
387
+ batch_btn.click(
388
+ fn=process_batch_queries,
389
+ inputs=file_input,
390
+ outputs=[batch_output_file, batch_status_message]
391
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
 
393
+ demo.launch()