|  |  | 
					
						
						|  | import os | 
					
						
						|  | import shutil | 
					
						
						|  | import textwrap | 
					
						
						|  | import streamlit as st | 
					
						
						|  | from huggingface_hub import hf_hub_download | 
					
						
						|  |  | 
					
						
						|  | from rag_pipeline import ( | 
					
						
						|  | load_vectorstore, | 
					
						
						|  | search_chunks, | 
					
						
						|  | generate_answer, | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | VSTORE_DIR = "./vectorstore" | 
					
						
						|  | NEEDED = ["index.faiss", "meta.jsonl"] | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def ensure_vectorstore(vstore_dir: str = VSTORE_DIR) -> None: | 
					
						
						|  | os.makedirs(vstore_dir, exist_ok=True) | 
					
						
						|  |  | 
					
						
						|  | missing = [f for f in NEEDED if not os.path.exists(os.path.join(vstore_dir, f))] | 
					
						
						|  | if not missing: | 
					
						
						|  | return | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | space_id = os.getenv("SPACE_ID") | 
					
						
						|  | if not space_id: | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | return | 
					
						
						|  |  | 
					
						
						|  | for fname in missing: | 
					
						
						|  | repo_path = f"vectorstore/{fname}" | 
					
						
						|  | try: | 
					
						
						|  | downloaded = hf_hub_download( | 
					
						
						|  | repo_id=space_id, | 
					
						
						|  | filename=repo_path, | 
					
						
						|  | repo_type="space", | 
					
						
						|  | ) | 
					
						
						|  | shutil.copyfile(downloaded, os.path.join(vstore_dir, fname)) | 
					
						
						|  | except Exception as e: | 
					
						
						|  |  | 
					
						
						|  | raise FileNotFoundError( | 
					
						
						|  | f"'{repo_path}' indirilemedi veya bulunamadı. " | 
					
						
						|  | f"Lütfen bu dosyayı Space deposunda 'vectorstore/' klasörüne yükleyin." | 
					
						
						|  | ) from e | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | st.set_page_config( | 
					
						
						|  | page_title="Turkish Wikipedia Q&A (Gemini RAG)", | 
					
						
						|  | page_icon="🧠", | 
					
						
						|  | layout="centered", | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | @st.cache_resource(show_spinner=False) | 
					
						
						|  | def _load_vdb(): | 
					
						
						|  |  | 
					
						
						|  | ensure_vectorstore(VSTORE_DIR) | 
					
						
						|  |  | 
					
						
						|  | return load_vectorstore(VSTORE_DIR) | 
					
						
						|  |  | 
					
						
						|  | st.title("🧠 Turkish Wikipedia Q&A") | 
					
						
						|  |  | 
					
						
						|  | with st.expander("⚙️ Ayarlar", expanded=False): | 
					
						
						|  | top_k = st.slider("Top K (kaç pasaj getirilsin?)", 2, 8, 5) | 
					
						
						|  | show_passages = st.checkbox("Getirilen pasaj özetini göster", value=True) | 
					
						
						|  | has_gemini = bool(os.getenv("GOOGLE_API_KEY") or st.secrets.get("GOOGLE_API_KEY", None)) | 
					
						
						|  | st.info(f"LLM: {'Gemini ✅' if has_gemini else 'Yapılandırılmadı ❌'}") | 
					
						
						|  |  | 
					
						
						|  | query = st.text_input("📝 Sorunuzu yazın (ör. “Türkiye'nin ilk kadın pilotu kimdir?”)") | 
					
						
						|  |  | 
					
						
						|  | if st.button("Cevabı Getir", type="primary", use_container_width=True) and query.strip(): | 
					
						
						|  | try: | 
					
						
						|  | with st.spinner("Aranıyor ve cevap oluşturuluyor..."): | 
					
						
						|  | index, records = _load_vdb() | 
					
						
						|  | answer = generate_answer(query.strip(), index, records, top_k=top_k) | 
					
						
						|  | hits = search_chunks(query.strip(), index, records, top_k=top_k) | 
					
						
						|  |  | 
					
						
						|  | st.subheader("✅ Yanıt") | 
					
						
						|  | st.write(answer if answer else "_Cevap üretilemedi._") | 
					
						
						|  |  | 
					
						
						|  | st.subheader("🔎 Kaynaklar") | 
					
						
						|  | if hits: | 
					
						
						|  | for i, h in enumerate(hits, 1): | 
					
						
						|  | title = h.get("title") or "(başlık yok)" | 
					
						
						|  | url   = h.get("source") or "" | 
					
						
						|  | score = float(h.get("score_rerank", h.get("score_boosted", 0.0))) | 
					
						
						|  | lead  = textwrap.shorten((h.get("text") or "").replace("\n", " "), width=220, placeholder="…") | 
					
						
						|  |  | 
					
						
						|  | if url: | 
					
						
						|  | st.markdown(f"**{i}.** [{title}]({url})  \nRerank skoru: `{score:.3f}`") | 
					
						
						|  | else: | 
					
						
						|  | st.markdown(f"**{i}.** {title}  \nRerank skoru: `{score:.3f}`") | 
					
						
						|  |  | 
					
						
						|  | if show_passages and lead: | 
					
						
						|  | st.caption(lead) | 
					
						
						|  | st.markdown("---") | 
					
						
						|  | else: | 
					
						
						|  | st.write("_Kaynak bulunamadı._") | 
					
						
						|  |  | 
					
						
						|  | except FileNotFoundError as e: | 
					
						
						|  | st.error( | 
					
						
						|  | "Vektör deposu bulunamadı. `vectorstore/index.faiss` ve `vectorstore/meta.jsonl` " | 
					
						
						|  | "dosyalarının Space'in kökünde `vectorstore/` klasöründe olduğundan emin olun." | 
					
						
						|  | ) | 
					
						
						|  | st.code(str(e)) | 
					
						
						|  | except Exception as e: | 
					
						
						|  | st.error("Bir hata oluştu.") | 
					
						
						|  | st.exception(e) |