Spaces:
Sleeping
Sleeping
File size: 5,059 Bytes
936d254 c259257 c9a21eb 59be948 282d1fe 3bc7125 c259257 546bec9 c9a21eb c259257 546bec9 5a0beb1 c9a21eb c259257 3bc7125 287c85c c9a21eb 546bec9 975a47e 546bec9 c9a21eb 287c85c c259257 3bc7125 c9a21eb 546bec9 c9a21eb 546bec9 c5f63ef 5a0beb1 3bc7125 c9a21eb 282d1fe 3bc7125 59be948 282d1fe 59be948 282d1fe 59be948 3bc7125 c9a21eb c5f63ef 282d1fe 546bec9 c5f63ef 59be948 282d1fe 546bec9 3bc7125 c5f63ef 5a0beb1 c5f63ef 3bc7125 c5f63ef 282d1fe 5a0beb1 c9a21eb 546bec9 c5f63ef c9a21eb c5f63ef 546bec9 3bc7125 c9a21eb c5f63ef | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | import os
import streamlit as st
from dotenv import load_dotenv
import PyPDF2
import numpy as np
from openai import OpenAI
import openai # لا نستورد error مباشرة
# Load environment
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
st.set_page_config(
page_title="📚 المكتبة المريدية الذكية",
page_icon="🚀",
layout="wide"
)
# RTL + Styling
st.markdown("""
<style>
body { direction: rtl; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f9fafb; }
.stButton>button { border-radius: 12px; background-color: #2563eb; color: white; font-weight: bold; }
.stTextInput>div>div>input { border-radius: 10px; }
h1, h2, h3 { color: #1e3a8a; }
.stChatMessage { direction: rtl; }
.stExpanderHeader { font-weight: bold; color: #1e40af; }
</style>
""", unsafe_allow_html=True)
# Sidebar
with st.sidebar:
st.header("⚙️ الإعدادات / Settings")
language = st.radio("اختر اللغة / Choose Language / Choisir la langue:", ["العربية", "English", "Français"])
temperature = st.slider("Creativity / الإبداع", 0.0, 1.0, 0.2)
st.markdown("---")
st.info("قم برفع ملفات PDF الخاصة بك وابدأ بالبحث")
# PDF Upload
uploaded_files = st.file_uploader("📄 Upload PDF(s) / رفع ملفات PDF", type="pdf", accept_multiple_files=True)
# Simple VectorStore
class SimpleVectorStore:
def __init__(self):
self.embeddings = []
self.documents = []
def add_document(self, content, embedding):
self.documents.append(content)
self.embeddings.append(embedding)
def query(self, query_embedding, top_k=4):
if not self.embeddings:
return []
sims = np.dot(np.array(self.embeddings), query_embedding)
top_indices = sims.argsort()[-top_k:][::-1]
return [self.documents[i] for i in top_indices]
# Extract text
def extract_text_from_pdf(file):
reader = PyPDF2.PdfReader(file)
text = ""
for page in reader.pages:
text += page.extract_text() + "\n"
return text
# Build VectorStore
@st.cache_resource
def build_vectorstore(files):
vectorstore = SimpleVectorStore()
client = OpenAI(api_key=OPENAI_API_KEY)
for file in files:
text = extract_text_from_pdf(file)
chunks = [text[i:i+1000] for i in range(0, len(text), 1000)]
for chunk in chunks:
try:
embedding = client.embeddings.create(
input=chunk,
model="text-embedding-3-small"
)['data'][0]['embedding']
vectorstore.add_document(chunk, np.array(embedding))
except Exception as e: # بديل عن RateLimitError
st.warning(f"⚠️ بعض المستندات لم تُعالج: {str(e)}")
return vectorstore
# Chat Memory
if "messages" not in st.session_state:
st.session_state.messages = []
# Main Logic
if uploaded_files:
vectorstore = build_vectorstore(uploaded_files)
client = OpenAI(api_key=OPENAI_API_KEY)
for msg in st.session_state.messages:
with st.chat_message(msg["role"]):
st.markdown(msg["content"])
if prompt := st.chat_input("اكتب سؤالك هنا / Type your question:"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
with st.spinner("🤖 جاري معالجة السؤال..."):
try:
query_embedding = client.embeddings.create(
input=prompt,
model="text-embedding-3-small"
)['data'][0]['embedding']
top_docs = vectorstore.query(np.array(query_embedding), top_k=4)
context = "\n\n".join(top_docs)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "أنت مساعد بحثي."},
{"role": "user", "content": f"استعن بالنصوص التالية للإجابة:\n{context}\n\nسؤال: {prompt}"}
],
temperature=temperature
)
answer = response.choices[0].message.content
st.markdown(answer)
with st.expander("📚 المصادر / Sources"):
for i, doc in enumerate(top_docs):
st.write(f"المصدر {i+1}: {doc[:500]}...")
st.session_state.messages.append({"role": "assistant", "content": answer})
except Exception as e:
st.error(f"⚠️ حدث خطأ أثناء الاتصال بـ OpenAI: {str(e)}")
else:
st.warning("📂 الرجاء رفع ملف PDF واحد على الأقل للبدء.")
|