Spaces:
Sleeping
Sleeping
ishworrsubedii
commited on
Commit
·
29dd018
1
Parent(s):
4275b3b
Username for oauth+ set session + login with token
Browse files- app.py +42 -53
- functions.py +9 -11
- requirements.txt +2 -1
app.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
import io
|
2 |
import tempfile
|
3 |
-
|
4 |
from click import option
|
|
|
5 |
from starlette import status
|
6 |
from functions import *
|
7 |
import pandas as pd
|
@@ -140,67 +141,55 @@ async def sign_in(email, password):
|
|
140 |
)
|
141 |
|
142 |
|
143 |
-
@app.post(
|
144 |
-
async def login_with_token(
|
145 |
try:
|
146 |
-
|
147 |
-
print(res)
|
148 |
-
user_id = res.user.id
|
149 |
-
access_token = res.session.access_token
|
150 |
-
refresh_token = res.session.refresh_token
|
151 |
-
|
152 |
-
store_session_check = supabase.table("Stores").select("*").filter("StoreID", "eq", user_id).execute()
|
153 |
-
store_id = None
|
154 |
-
|
155 |
-
if store_session_check and store_session_check.data:
|
156 |
-
store_id = store_session_check.data[0].get("StoreID")
|
157 |
-
|
158 |
-
if not store_id:
|
159 |
-
response = (
|
160 |
-
supabase.table("Stores").insert(
|
161 |
-
{
|
162 |
-
"AccessToken": access_token,
|
163 |
-
"StoreID": user_id,
|
164 |
-
"RefreshToken": refresh_token,
|
165 |
-
}
|
166 |
-
).execute()
|
167 |
-
)
|
168 |
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
|
178 |
-
|
179 |
-
|
180 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
181 |
-
detail="You are already signed in. Please sign out first to sign in again."
|
182 |
-
)
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
status_code=status.HTTP_400_BAD_REQUEST,
|
187 |
-
detail="Failed to sign in. Please check your credentials."
|
188 |
-
)
|
189 |
|
190 |
-
except HTTPException as http_exc:
|
191 |
-
raise http_exc
|
192 |
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
)
|
198 |
|
199 |
|
200 |
@app.post("/set-session-data")
|
201 |
-
async def set_session_data(access_token, refresh_token):
|
202 |
res = supabase.auth.set_session(access_token, refresh_token)
|
203 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
return res
|
205 |
|
206 |
|
@@ -221,7 +210,7 @@ async def sign_out(user_id):
|
|
221 |
@app.post("/oauth")
|
222 |
async def oauth():
|
223 |
res = supabase.auth.sign_in_with_oauth(
|
224 |
-
{"provider": "google", "options": {"redirect_to": "https://convers-ai-lac.vercel.app"}})
|
225 |
return res
|
226 |
|
227 |
|
|
|
1 |
import io
|
2 |
import tempfile
|
3 |
+
import jwt
|
4 |
from click import option
|
5 |
+
from jwt import ExpiredSignatureError, InvalidTokenError
|
6 |
from starlette import status
|
7 |
from functions import *
|
8 |
import pandas as pd
|
|
|
141 |
)
|
142 |
|
143 |
|
144 |
+
@app.post("/login_with_token")
|
145 |
+
async def login_with_token(access_token: str, refresh_token: str):
|
146 |
try:
|
147 |
+
decoded_token = jwt.decode(access_token, options={"verify_signature": False})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
|
149 |
+
json = {
|
150 |
+
"code": status.HTTP_200_OK,
|
151 |
+
"user_id": decoded_token.get("sub"),
|
152 |
+
"email": decoded_token.get("email"),
|
153 |
+
"access_token": access_token,
|
154 |
+
"refresh_token": refresh_token,
|
155 |
+
"issued_at": decoded_token.get("iat"),
|
156 |
+
"expires_at": decoded_token.get("exp")
|
157 |
|
158 |
+
}
|
159 |
+
return json
|
|
|
|
|
|
|
160 |
|
161 |
+
except (ExpiredSignatureError, InvalidTokenError) as e:
|
162 |
+
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(e))
|
|
|
|
|
|
|
163 |
|
|
|
|
|
164 |
|
165 |
+
@app.post("/user_name")
|
166 |
+
async def user_name_(username: str, user_id: str):
|
167 |
+
r_ = createUser(user_id=user_id, username=username)
|
168 |
+
return r_
|
|
|
169 |
|
170 |
|
171 |
@app.post("/set-session-data")
|
172 |
+
async def set_session_data(access_token, refresh_token, user_id):
|
173 |
res = supabase.auth.set_session(access_token, refresh_token)
|
174 |
+
store_session_check = supabase.table("Stores").select("*").filter("StoreID", "eq", user_id).execute()
|
175 |
+
store_id = None
|
176 |
+
if store_session_check and store_session_check.data:
|
177 |
+
store_id = store_session_check.data[0].get("StoreID")
|
178 |
+
if not store_id:
|
179 |
+
response = (
|
180 |
+
supabase.table("Stores").insert(
|
181 |
+
{
|
182 |
+
"AccessToken": access_token,
|
183 |
+
"StoreID": user_id,
|
184 |
+
"RefreshToken": refresh_token,
|
185 |
+
}
|
186 |
+
).execute()
|
187 |
+
)
|
188 |
+
res = {
|
189 |
+
"message": "success",
|
190 |
+
"code": 200,
|
191 |
+
"session_data": res,
|
192 |
+
}
|
193 |
return res
|
194 |
|
195 |
|
|
|
210 |
@app.post("/oauth")
|
211 |
async def oauth():
|
212 |
res = supabase.auth.sign_in_with_oauth(
|
213 |
+
{"provider": "google", "options": {"redirect_to": "https://convers-ai-lac.vercel.app/"}})
|
214 |
return res
|
215 |
|
216 |
|
functions.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
import pymupdf
|
2 |
from concurrent.futures import ThreadPoolExecutor
|
3 |
from langchain.retrievers.contextual_compression import ContextualCompressionRetriever
|
4 |
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
|
@@ -45,21 +45,18 @@ vectorEmbeddings = HuggingFaceEmbeddings(
|
|
45 |
encode_kwargs=encode_kwargs
|
46 |
)
|
47 |
reader = easyocr.Reader(['en'], gpu=True, model_storage_directory="/app/EasyOCRModels")
|
48 |
-
sparseEmbeddings = FastEmbedSparse(model="Qdrant/BM25", threads
|
49 |
prompt = """
|
50 |
INSTRUCTIONS:
|
51 |
=====================================
|
52 |
### Role
|
53 |
**Primary Function**: You are an AI chatbot designed to provide accurate and efficient assistance to users based on provided context data. Your responses must be reliable, friendly, and directly address user inquiries or issues. Always clarify any unclear questions, and conclude responses positively.
|
54 |
-
|
55 |
### Constraints
|
56 |
1. **No Data Disclosure**: Never reveal access to training data or any context explicitly.
|
57 |
2. **Maintaining Focus**: Politely redirect any off-topic conversations back to relevant issues without breaking character.
|
58 |
3. **Exclusive Reliance on Context Data**: Base all answers strictly on the provided context data. If the context doesn’t cover the query, use a fallback response. Always maintain a third-person perspective.
|
59 |
4. **Restrictive Role Focus**: Do not engage in tasks or answer questions unrelated to your role or context data.
|
60 |
-
|
61 |
Ensure all instructions are strictly followed. Responses must be meaningful and concise, within 512 words. Include sources to support your answers when possible.
|
62 |
-
|
63 |
CONTEXT:
|
64 |
=====================================
|
65 |
{context}
|
@@ -67,11 +64,9 @@ CONTEXT:
|
|
67 |
QUESTION:
|
68 |
=====================================
|
69 |
{question}
|
70 |
-
|
71 |
CHAT HISTORY:
|
72 |
=====================================
|
73 |
{chatHistory}
|
74 |
-
|
75 |
NOTE: Generate responses directly without using phrases like "Response:" or "Answer:". Do not mention the use of extracted context or provide unnecessary details.
|
76 |
"""
|
77 |
prompt = ChatPromptTemplate.from_template(prompt)
|
@@ -270,7 +265,7 @@ def getLinks(url: str, timeout=30):
|
|
270 |
else:
|
271 |
pass
|
272 |
links = [link for link in links if "#" not in link]
|
273 |
-
links = list(set(links))
|
274 |
else:
|
275 |
continue
|
276 |
return links
|
@@ -290,6 +285,7 @@ def getTextFromImagePDF(pdfBytes):
|
|
290 |
def getText(image):
|
291 |
global reader
|
292 |
return "\n".join([text[1] for text in reader.readtext(np.array(image), paragraph=True)])
|
|
|
293 |
allImages = convert_from_bytes(pdfBytes)
|
294 |
texts = [getText(image) for image in allImages]
|
295 |
return "\n\n\n".join(texts)
|
@@ -323,18 +319,19 @@ def analyzeData(query, dataframe):
|
|
323 |
return response
|
324 |
|
325 |
|
326 |
-
|
327 |
def extractTextFromPage(page):
|
328 |
return page.get_text()
|
329 |
|
|
|
330 |
def extractTextFromPdf(pdf_path):
|
331 |
doc = pymupdf.open(pdf_path)
|
332 |
pages = [doc.load_page(i) for i in range(len(doc))]
|
333 |
with ThreadPoolExecutor() as executor:
|
334 |
texts = list(executor.map(extractTextFromPage, pages))
|
335 |
-
doc.close()
|
336 |
return '.'.join(texts)
|
337 |
|
|
|
338 |
def extractTextFromUrl(url):
|
339 |
response = requests.get(url)
|
340 |
response.raise_for_status()
|
@@ -342,7 +339,8 @@ def extractTextFromUrl(url):
|
|
342 |
soup = BeautifulSoup(html, 'lxml')
|
343 |
return soup.get_text(separator=' ', strip=True)
|
344 |
|
|
|
345 |
def extractTextFromUrlList(urls):
|
346 |
with ThreadPoolExecutor() as executor:
|
347 |
texts = list(executor.map(extractTextFromUrl, urls))
|
348 |
-
return '.'.join(texts)
|
|
|
1 |
+
import pymupdf
|
2 |
from concurrent.futures import ThreadPoolExecutor
|
3 |
from langchain.retrievers.contextual_compression import ContextualCompressionRetriever
|
4 |
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
|
|
|
45 |
encode_kwargs=encode_kwargs
|
46 |
)
|
47 |
reader = easyocr.Reader(['en'], gpu=True, model_storage_directory="/app/EasyOCRModels")
|
48 |
+
sparseEmbeddings = FastEmbedSparse(model="Qdrant/BM25", threads=20, parallel=0)
|
49 |
prompt = """
|
50 |
INSTRUCTIONS:
|
51 |
=====================================
|
52 |
### Role
|
53 |
**Primary Function**: You are an AI chatbot designed to provide accurate and efficient assistance to users based on provided context data. Your responses must be reliable, friendly, and directly address user inquiries or issues. Always clarify any unclear questions, and conclude responses positively.
|
|
|
54 |
### Constraints
|
55 |
1. **No Data Disclosure**: Never reveal access to training data or any context explicitly.
|
56 |
2. **Maintaining Focus**: Politely redirect any off-topic conversations back to relevant issues without breaking character.
|
57 |
3. **Exclusive Reliance on Context Data**: Base all answers strictly on the provided context data. If the context doesn’t cover the query, use a fallback response. Always maintain a third-person perspective.
|
58 |
4. **Restrictive Role Focus**: Do not engage in tasks or answer questions unrelated to your role or context data.
|
|
|
59 |
Ensure all instructions are strictly followed. Responses must be meaningful and concise, within 512 words. Include sources to support your answers when possible.
|
|
|
60 |
CONTEXT:
|
61 |
=====================================
|
62 |
{context}
|
|
|
64 |
QUESTION:
|
65 |
=====================================
|
66 |
{question}
|
|
|
67 |
CHAT HISTORY:
|
68 |
=====================================
|
69 |
{chatHistory}
|
|
|
70 |
NOTE: Generate responses directly without using phrases like "Response:" or "Answer:". Do not mention the use of extracted context or provide unnecessary details.
|
71 |
"""
|
72 |
prompt = ChatPromptTemplate.from_template(prompt)
|
|
|
265 |
else:
|
266 |
pass
|
267 |
links = [link for link in links if "#" not in link]
|
268 |
+
links = list(set(links))
|
269 |
else:
|
270 |
continue
|
271 |
return links
|
|
|
285 |
def getText(image):
|
286 |
global reader
|
287 |
return "\n".join([text[1] for text in reader.readtext(np.array(image), paragraph=True)])
|
288 |
+
|
289 |
allImages = convert_from_bytes(pdfBytes)
|
290 |
texts = [getText(image) for image in allImages]
|
291 |
return "\n\n\n".join(texts)
|
|
|
319 |
return response
|
320 |
|
321 |
|
|
|
322 |
def extractTextFromPage(page):
|
323 |
return page.get_text()
|
324 |
|
325 |
+
|
326 |
def extractTextFromPdf(pdf_path):
|
327 |
doc = pymupdf.open(pdf_path)
|
328 |
pages = [doc.load_page(i) for i in range(len(doc))]
|
329 |
with ThreadPoolExecutor() as executor:
|
330 |
texts = list(executor.map(extractTextFromPage, pages))
|
331 |
+
doc.close()
|
332 |
return '.'.join(texts)
|
333 |
|
334 |
+
|
335 |
def extractTextFromUrl(url):
|
336 |
response = requests.get(url)
|
337 |
response.raise_for_status()
|
|
|
339 |
soup = BeautifulSoup(html, 'lxml')
|
340 |
return soup.get_text(separator=' ', strip=True)
|
341 |
|
342 |
+
|
343 |
def extractTextFromUrlList(urls):
|
344 |
with ThreadPoolExecutor() as executor:
|
345 |
texts = list(executor.map(extractTextFromUrl, urls))
|
346 |
+
return '.'.join(texts)
|
requirements.txt
CHANGED
@@ -94,4 +94,5 @@ pandasai
|
|
94 |
easyocr
|
95 |
youtube-transcript-api
|
96 |
pdf2image
|
97 |
-
PyPDF2
|
|
|
|
94 |
easyocr
|
95 |
youtube-transcript-api
|
96 |
pdf2image
|
97 |
+
PyPDF2
|
98 |
+
PyJWT
|