File size: 2,853 Bytes
ed956cf
 
 
 
ae146c8
ed956cf
c833d59
4c08fc0
7ac2e0b
2de9eb7
4c08fc0
992f6e2
75883f9
4c08fc0
992f6e2
4c08fc0
75883f9
4c08fc0
ed956cf
4c08fc0
992f6e2
ed956cf
 
 
 
 
 
 
 
 
 
 
 
 
 
75883f9
a77e897
ae146c8
 
 
a77e897
 
 
 
 
 
 
 
 
 
ed956cf
4c08fc0
 
ed956cf
4c08fc0
 
 
 
75883f9
4c08fc0
 
 
bf31785
4c08fc0
 
 
 
 
 
 
 
 
bf31785
4c08fc0
 
992f6e2
75883f9
4c08fc0
 
 
 
 
 
ac558c7
992f6e2
4c08fc0
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
import os
from langchain.chains import RetrievalQA
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_openai import ChatOpenAI
from langchain_community.vectorstores import FAISS
import gradio as gr

# Load secrets
openai_api_key = os.environ.get("OPENAI_API_KEY")
app_password = os.environ.get("APP_PASSWORD")
app_username = os.environ.get("APP_USERNAME", "user")

if not openai_api_key:
    raise ValueError("OPENAI_API_KEY is not set.")
if not app_password:
    raise ValueError("APP_PASSWORD is not set.")

# Load vectorstore
def load_vectorstore():
    embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
    return FAISS.load_local(".", embeddings, allow_dangerous_deserialization=True)

vectorstore = load_vectorstore()

# Load LLM
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.1)

# Setup QA chain
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=vectorstore.as_retriever(),
    return_source_documents=True
)
def chat_with_pdf(query):
    if not query.strip():
        return "โ— Please enter a question."
    
    result = qa_chain.invoke({"query": query})
    answer = result["result"]
    sources = result.get("source_documents", [])

    if sources:
        formatted_sources = "".join(
            f"\n\n๐Ÿ“„ Source {i+1}:\n{doc.page_content.strip()}"
            for i, doc in enumerate(sources)
        )
        return f"๐Ÿง  **Answer:**\n{answer}{formatted_sources}"
    else:
        return f"๐Ÿง  **Answer:**\n{answer}\n\nโ„น๏ธ No source documents found."


# App state
authenticated_users = set()

def login(username, password):
    if username == app_username and password == app_password:
        authenticated_users.add(username)
        return gr.update(visible=True), gr.update(visible=False), "", ""
    else:
        return gr.update(visible=False), gr.update(visible=True), "", "โŒ Invalid credentials."

with gr.Blocks() as demo:
    gr.Markdown("# ๐Ÿ” Secure  Chatbot")

    with gr.Group(visible=True) as login_box:
        gr.Markdown("### Login to access the chatbot")
        login_user = gr.Textbox(label="Username")
        login_pass = gr.Textbox(label="Password", type="password")
        login_button = gr.Button("Login")
        login_message = gr.Markdown("")

    with gr.Group(visible=False) as chat_box:
        gr.Markdown("## ๐Ÿ“š Ask questions ")
        query_input = gr.Textbox(label="Question", lines=2, placeholder="Type your question here...")
        submit_button = gr.Button("Submit")
        output = gr.Markdown()

    login_button.click(
        fn=login,
        inputs=[login_user, login_pass],
        outputs=[chat_box, login_box, login_user, login_message]
    )
    submit_button.click(fn=chat_with_pdf, inputs=query_input, outputs=output)

if __name__ == "__main__":
    demo.launch(share=True)