zhtet/document-chat
0
1# Reference https://huggingface.co/spaces/johnmuchiri/anspro1/blob/main/app.py2# Resource https://python.langchain.com/docs/modules/chains3 4import streamlit as st5from langchain_community.document_loaders.pdf import PyPDFLoader6from langchain.text_splitter import RecursiveCharacterTextSplitter7from langchain_community.vectorstores.pinecone import Pinecone8from langchain_openai import OpenAIEmbeddings, ChatOpenAI9from langchain.memory import ConversationBufferMemory10from langchain_core.prompts import ChatPromptTemplate11from langchain.chains import ConversationalRetrievalChain, RetrievalQAWithSourcesChain12import openai13from dotenv import load_dotenv14import os15 16import pinecone17 18load_dotenv()19 20# please create a streamlit app on huggingface that uses openai api21# and langchain data framework, the user should be able to upload22# a document and ask questions about the document, the app should23# respond with an answer and also display where the response is24# referenced from using some sort of visual annotation on the document25 26# set the path where you want to save the uploaded PDF file27SAVE_DIR = "pdf"28 29 30def generate_response(pages, query_text, k, chain_type):31 if pages:32 pinecone.init(33 api_key=os.getenv("PINECONE_API_KEY"),34 environment=os.getenv("PINECONE_ENV_NAME"),35 )36 37 vector_db = Pinecone.from_documents(38 documents=pages, embedding=OpenAIEmbeddings(), index_name="document-chat"39 )40 41 retriever = vector_db.as_retriever(42 search_type="similarity", search_kwards={"k": k}43 )44 45 prompt_template = ChatPromptTemplate.from_messages(46 [47 (48 "system",49 "You are a helpful assistant that can answer questions regarding to a document provided by the user.",50 ),51 ("human", "Hello, how are you doing?"),52 ("ai", "I'm doing well, thanks!"),53 ("human", "{user_input}"),54 ]55 )56 57 llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)58 59 # create a chain to answer questions60 qa = RetrievalQAWithSourcesChain.from_chain_type(61 llm=llm,62 chain_type=chain_type,63 retriever=retriever,64 return_source_documents=True,65 # prompt_template=prompt_template,66 )67 68 response = qa({"question": query_text})69 return response70 71 72def visual_annotate(document, answer):73 # Implement this function according to your specific requirements74 # Highlight the part of the document where the answer was found75 start = document.find(answer)76 annotated_document = (77 document[:start]78 + "**"79 + document[start : start + len(answer)]80 + "**"81 + document[start + len(answer) :]82 )83 return annotated_document84 85 86st.set_page_config(page_title="๐ฆ๐ Ask the Doc App")87st.title("Document Question Answering App")88 89with st.sidebar.form(key="sidebar-form"):90 st.header("Configurations")91 92 openai_api_key = st.text_input("Enter OpenAI API key here", type="password")93 os.environ["OPENAI_API_KEY"] = openai_api_key94 95 pinecone_api_key = st.text_input(96 "Enter your Pinecone environment key", type="password"97 )98 os.environ["PINECONE_API_KEY"] = pinecone_api_key99 100 pinecone_env_name = st.text_input("Enter your Pinecone environment name")101 os.environ["PINECONE_ENV_NAME"] = pinecone_env_name102 103 submitted = st.form_submit_button(104 label="Submit",105 # disabled=not (openai_api_key and pinecone_api_key and pinecone_env_name),106 )107 108left_column, right_column = st.columns(2)109 110with left_column:111 uploaded_file = st.file_uploader("Choose a pdf file", type="pdf")112 pages = []113 114 if uploaded_file is not None:115 # save the uploaded file to the specified directory116 file_path = os.path.join(SAVE_DIR, uploaded_file.name)117 with open(file_path, "wb") as f:118 f.write(uploaded_file.getbuffer())119 st.success(f"File {uploaded_file.name} is saved at path {file_path}")120 121 loader = PyPDFLoader(file_path=file_path)122 text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)123 pages = loader.load_and_split(text_splitter=text_splitter)124 125 query_text = st.text_input(126 "Enter your question:", placeholder="Please provide a short summary."127 )128 129 chain_type = st.selectbox(130 "chain type", ("stuff", "map_reduce", "refine", "map_rerank")131 )132 133 k = st.slider("Number of relevant chunks", 1, 5)134 135 with st.spinner("Retrieving and generating a response ..."):136 response = generate_response(137 pages=pages, query_text=query_text, k=k, chain_type=chain_type138 )139 140 with right_column:141 st.write("Output of your question")142 143 if response:144 st.subheader("Result")145 st.write(response["answer"])146 print("response: ", response)147 148 st.subheader("source_documents")149 for each in response["source_documents"]:150 st.write("page: ", each.metadata["page"])151 st.write("source: ", each.metadata["source"])152 else:153 st.write("response not showing at the moment")154 155 156# with st.form("myform", clear_on_submit=True):157# openai_api_key = st.text_input(158# "OpenAI API Key", type="password", disabled=not (uploaded_file and query_text)159# )160# submitted = st.form_submit_button(161# "Submit", disabled=not (pages and query_text)162# )163# if submitted and openai_api_key.startswith("sk-"):164# with st.spinner("Calculating..."):165# response = generate_response(pages, openai_api_key, query_text)166# result.append(response)167# del openai_api_key168 169# if len(result):170# st.info(response)171 172# if st.button("Get Answer"):173# answer = get_answer(question, document)174# st.write(answer["answer"])175 176# # Visual annotation on the document177# annotated_document = visual_annotate(document, answer["answer"])178# st.markdown(annotated_document)179 