| import os |
| import tempfile |
| import logging |
| import urllib.parse |
|
|
| import requests |
| import streamlit as st |
| from gtts import gTTS |
| from dotenv import load_dotenv |
| from translatepy import Translator |
|
|
| |
| load_dotenv() |
|
|
| |
| WIKIPEDIA_API_BASE_URL_PREFIX = ".wikipedia.org/w/api.php" |
| ENGLISH_SUMMARY_SENTENCES = 5 |
| WIKIMEDIA_HEADERS = { |
| 'User-Agent': 'WikiHealthNavigator/1.0 (contact@example.com)' |
| } |
| REQUEST_TIMEOUT = 30 |
| translator = Translator() |
|
|
| logger = logging.getLogger(__name__) |
| logger.setLevel(logging.DEBUG) |
|
|
| |
| @st.cache_data(ttl=3600) |
| def fetch_wikipedia_content(query, lang="en", is_fallback=False): |
| if not query: |
| return None, None, lang |
|
|
| title = query.strip() |
| encoded_title = urllib.parse.quote(title, safe="") |
|
|
| rest_url = f"https://{lang}.wikipedia.org/api/rest_v1/page/summary/{encoded_title}" |
| try: |
| resp = requests.get(rest_url, headers=WIKIMEDIA_HEADERS, timeout=REQUEST_TIMEOUT) |
| resp.raise_for_status() |
| j = resp.json() |
| summary = j.get("extract") or j.get("description") |
| full_url = j.get("content_urls", {}).get("desktop", {}).get("page") |
| if summary: |
| return summary, full_url, lang |
| except Exception as e: |
| logger.debug("REST failed: %s", e) |
|
|
| try: |
| api = f"https://{lang}{WIKIPEDIA_API_BASE_URL_PREFIX}" |
| params = { |
| "action": "query", |
| "format": "json", |
| "formatversion": 2, |
| "prop": "extracts|info", |
| "inprop": "url", |
| "titles": title, |
| "redirects": 1, |
| "explaintext": True, |
| **({"exsentences": ENGLISH_SUMMARY_SENTENCES} if lang == "en" else {}) |
| } |
| res = requests.get(api, params=params, headers=WIKIMEDIA_HEADERS, timeout=REQUEST_TIMEOUT) |
| res.raise_for_status() |
| pages = res.json().get("query", {}).get("pages", []) |
| if pages and not pages[0].get("missing"): |
| return pages[0].get("extract"), pages[0].get("fullurl"), lang |
| except Exception as e: |
| logger.debug("Query API failed: %s", e) |
|
|
| if not is_fallback and lang != "en": |
| return fetch_wikipedia_content(query, lang="en", is_fallback=True) |
|
|
| return None, None, lang |
|
|
| |
| @st.cache_data(ttl=3600) |
| def fetch_wikipedia_images(query, lang="en", max_images=3): |
| if not query: |
| return [] |
|
|
| api = f"https://{lang}.wikipedia.org/w/api.php" |
| params = { |
| "action": "query", |
| "format": "json", |
| "prop": "pageimages", |
| "piprop": "original", |
| "titles": query, |
| "redirects": 1 |
| } |
|
|
| try: |
| res = requests.get(api, params=params, headers=WIKIMEDIA_HEADERS, timeout=REQUEST_TIMEOUT) |
| res.raise_for_status() |
| pages = res.json().get("query", {}).get("pages", {}) |
| images = [] |
|
|
| for page in pages.values(): |
| if "original" in page: |
| images.append(page["original"]["source"]) |
|
|
| return images[:max_images] |
| except Exception as e: |
| logger.debug("Image fetch failed: %s", e) |
| return [] |
|
|
| |
| def narrate_text(text, lang_code): |
| try: |
| clean = text.strip().replace("\n", " ") |
| if not clean: |
| st.warning("Nothing to narrate.") |
| return |
|
|
| tts = gTTS(text=clean, lang=lang_code) |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as fp: |
| tts.save(fp.name) |
| audio_path = fp.name |
|
|
| st.audio(audio_path, format="audio/mp3") |
| except Exception as e: |
| st.error(f"Narration error: {e}") |
|
|
| |
| def translate_summary(text, target_lang): |
| try: |
| return translator.translate(text, target_lang).result |
| except Exception: |
| return text |
|
|
| |
| st.set_page_config(page_title="WikiHealth Navigator", layout="centered") |
| st.title("🩺 WikiHealth Navigator") |
| st.markdown("Search health topics using Wikipedia (with images & audio)") |
|
|
| languages = { |
| "English": "en", |
| "हिन्दी": "hi", |
| "తెలుగు": "te", |
| "தமிழ்": "ta" |
| } |
|
|
| col1, col2 = st.columns([2, 3]) |
| with col1: |
| selected = st.selectbox("Select Language:", list(languages.keys())) |
| lang_code = languages[selected] |
| with col2: |
| query = st.text_input("Enter a health topic:") |
|
|
| if st.button("🔍 Search") and query: |
| with st.spinner("Searching Wikipedia..."): |
| summary, url, actual_lang = fetch_wikipedia_content(query, lang_code) |
|
|
| if summary: |
| if actual_lang != lang_code: |
| summary = translate_summary(summary, lang_code) |
|
|
| st.subheader("📝 Summary") |
| st.write(summary) |
|
|
| st.subheader("🖼️ Related Images") |
| images = fetch_wikipedia_images(query, lang_code) |
|
|
| if images: |
| cols = st.columns(len(images)) |
| for col, img in zip(cols, images): |
| col.image(img, use_container_width=True) |
| else: |
| st.info("No images found.") |
|
|
| if st.button("🔊 Narrate Summary"): |
| narrate_text(summary, lang_code) |
|
|
| if url: |
| st.markdown(f"[Read full article on Wikipedia]({url})") |
| else: |
| st.warning("No information found.") |
|
|