0504ankitsharma commited on
Commit
ce5090a
·
1 Parent(s): a8db048

Add application file

Browse files
Files changed (3) hide show
  1. Dockerfile +16 -0
  2. app.py +159 -0
  3. requirements.txt +10 -0
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV PATH="/home/user/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=user ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+
15
+ COPY --chown=user . /app
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from fastapi import FastAPI, HTTPException
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from pydantic import BaseModel
5
+ from langchain.embeddings import OpenAIEmbeddings
6
+ from langchain.chat_models import ChatOpenAI
7
+ from langchain.vectorstores import Pinecone
8
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
9
+ from langchain.document_loaders import UnstructuredWordDocumentLoader as DocxLoader
10
+ from langchain.chains import ConversationalRetrievalChain
11
+ from langchain.prompts import ChatPromptTemplate
12
+ from langchain.memory import ConversationBufferMemory
13
+ from pinecone import Pinecone as PC, ServerlessSpec
14
+ import time
15
+ import re
16
+ from dotenv import load_dotenv
17
+
18
+ # Load environment variables
19
+ load_dotenv()
20
+
21
+ app = FastAPI()
22
+
23
+ app.add_middleware(
24
+ CORSMiddleware,
25
+ allow_origins=["*"],
26
+ allow_credentials=True,
27
+ allow_methods=["*"],
28
+ allow_headers=["*"],
29
+ )
30
+
31
+ # Initialize Pinecone
32
+ pinecone_api_key = os.environ.get("PINECONE_API_KEY")
33
+ if not pinecone_api_key:
34
+ raise HTTPException(status_code=500, detail="PINECONE_API_KEY environment variable is not set")
35
+
36
+ try:
37
+ pc = PC(api_key=pinecone_api_key)
38
+ except Exception as e:
39
+ raise HTTPException(status_code=500, detail=f"Failed to initialize Pinecone: {str(e)}")
40
+
41
+ index_name = "rag-project" # Replace with your actual index name
42
+
43
+ # Initialize OpenAI
44
+ openai_api_key = os.environ.get("OPENAI_API_KEY")
45
+ if not openai_api_key:
46
+ raise HTTPException(status_code=500, detail="OPENAI_API_KEY environment variable is not set")
47
+
48
+ try:
49
+ embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key)
50
+ llm = ChatOpenAI(api_key=openai_api_key, model="gpt-4")
51
+ except Exception as e:
52
+ raise HTTPException(status_code=500, detail=f"Failed to initialize OpenAI: {str(e)}")
53
+
54
+ class Query(BaseModel):
55
+ query_text: str
56
+ session_id: str
57
+
58
+ def clean_response(response):
59
+ cleaned = response.strip()
60
+ cleaned = re.sub(r'^["\']+|["\']+$', '', cleaned)
61
+ cleaned = re.sub(r'\n+', '\n', cleaned)
62
+ cleaned = cleaned.replace('\\n', '')
63
+ return cleaned
64
+
65
+ prompt = ChatPromptTemplate.from_template(
66
+ """
67
+ You are a helpful assistant designed specifically for the Thapar Institute of Engineering and Technology (TIET), a renowned technical college. Your task is to answer all queries related to TIET. Every response you provide should be relevant to the context of TIET. If a question falls outside of this context, please decline by stating, 'Sorry, I cannot help with that.' If you do not know the answer to a question, do not attempt to fabricate a response; instead, politely decline.
68
+ You may elaborate on your answers slightly to provide more information, but avoid sounding boastful or exaggerating. Stay focused on the context provided.
69
+ Previous conversation:
70
+ {chat_history}
71
+ Context: {context}
72
+ Human: {question}
73
+ Assistant: Let's approach this step-by-step:
74
+ """
75
+ )
76
+
77
+ # Store conversation histories
78
+ conversation_histories = {}
79
+
80
+ @app.get("/")
81
+ def read_root():
82
+ return {"Hello": "World"}
83
+
84
+ @app.post("/query")
85
+ def read_item(query: Query):
86
+ try:
87
+ vectorstore = Pinecone.from_existing_index(index_name, embeddings)
88
+ except Exception as e:
89
+ print(f"Error loading vector store: {str(e)}")
90
+ return {"response": "Vector Store Not Found or Error Loading. Please run /setup first."}
91
+
92
+ if query.query_text:
93
+ start = time.process_time()
94
+
95
+ # Get or create a new conversation memory for this session
96
+ if query.session_id not in conversation_histories:
97
+ conversation_histories[query.session_id] = ConversationBufferMemory(
98
+ memory_key="chat_history",
99
+ return_messages=True
100
+ )
101
+
102
+ memory = conversation_histories[query.session_id]
103
+
104
+ qa_chain = ConversationalRetrievalChain.from_llm(
105
+ llm=llm,
106
+ retriever=vectorstore.as_retriever(),
107
+ memory=memory,
108
+ combine_docs_chain_kwargs={"prompt": prompt}
109
+ )
110
+
111
+ response = qa_chain({"question": query.query_text})
112
+ print("Response time:", time.process_time() - start)
113
+
114
+ cleaned_response = clean_response(response['answer'])
115
+ print("Cleaned response:", repr(cleaned_response))
116
+
117
+ return {"response": cleaned_response}
118
+ else:
119
+ return {"response": "No Query Found"}
120
+
121
+ @app.get("/setup")
122
+ def setup():
123
+ try:
124
+ file_path = "./data/data.docx"
125
+ if not os.path.exists(file_path):
126
+ print(f"The file {file_path} does not exist.")
127
+ return {"response": "Error: Data file not found"}
128
+
129
+ loader = DocxLoader(file_path)
130
+ documents = loader.load()
131
+
132
+ print(f"Loaded document: {file_path}")
133
+
134
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
135
+ chunks = text_splitter.split_documents(documents)
136
+
137
+ print(f"Created {len(chunks)} chunks.")
138
+
139
+ # Check if the index exists, if not, create it
140
+ if index_name not in pc.list_indexes().names():
141
+ pc.create_index(
142
+ name=index_name,
143
+ dimension=1536, # This should match the dimension of your embeddings
144
+ metric='cosine',
145
+ spec=ServerlessSpec(cloud='aws', region='us-west-2') # Adjust as needed
146
+ )
147
+
148
+ vectorstore = Pinecone.from_documents(chunks, embeddings, index_name=index_name)
149
+
150
+ print("Vector store created and saved successfully.")
151
+ return {"response": "Vector Store in Pinecone Is Ready"}
152
+
153
+ except Exception as e:
154
+ print(f"An error occurred: {str(e)}")
155
+ return {"response": f"Error: {str(e)}"}
156
+
157
+ if __name__ == "__main__":
158
+ import uvicorn
159
+ uvicorn.run(app, host="0.0.0.0", port=8000)
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ langchain
4
+ langchain_openai
5
+ pinecone-client
6
+ python-dotenv
7
+ langchain_community
8
+ unstructured[pdf]
9
+ python-docx
10
+ openai