Views
No views yet
app.py logic - as well as a few changes to the aimakerspace package to get things working smoothly with Chainlit.NOTE: If you want to run this locally - be sure to useuv run chainlit run app.pyto start the application outside of Docker.

NOTE: Simply put, the decorators (in Chainlit) are just ways we can "plug-in" to the functionality in Chainlit.
uv run chainlit run app.py1import os
2from typing import List
3from chainlit.types import AskFileResponse
4from aimakerspace.text_utils import CharacterTextSplitter, TextFileLoader
5from aimakerspace.openai_utils.prompts import (
6 UserRolePrompt,
7 SystemRolePrompt,
8 AssistantRolePrompt,
9)
10from aimakerspace.openai_utils.embedding import EmbeddingModel
11from aimakerspace.vectordatabase import VectorDatabase
12from aimakerspace.openai_utils.chatmodel import ChatOpenAI
13import chainlit as cl1system_template = """\
2Use the following context to answer a users question. If you cannot find the answer in the context, say you don't know the answer."""
3system_role_prompt = SystemRolePrompt(system_template)
4
5user_prompt_template = """\
6Context:
7{context}
8
9Question:
10{question}
11"""
12user_role_prompt = UserRolePrompt(user_prompt_template)NOTE: You'll notice that these are the exact same prompt templates we used from the Pythonic RAG Notebook in Week 1 Day 2!
1class RetrievalAugmentedQAPipeline:
2 def __init__(self, llm: ChatOpenAI(), vector_db_retriever: VectorDatabase) -> None:
3 self.llm = llm
4 self.vector_db_retriever = vector_db_retriever
5
6 async def arun_pipeline(self, user_query: str):
7 ### RETRIEVAL
8 context_list = self.vector_db_retriever.search_by_text(user_query, k=4)
9
10 context_prompt = ""
11 for context in context_list:
12 context_prompt += context[0] + "\n"
13
14 ### AUGMENTED
15 formatted_system_prompt = system_role_prompt.create_message()
16
17 formatted_user_prompt = user_role_prompt.create_message(question=user_query, context=context_prompt)
18
19
20 ### GENERATION
21 async def generate_response():
22 async for chunk in self.llm.astream([formatted_system_prompt, formatted_user_prompt]):
23 yield chunk
24
25 return {"response": generate_response(), "context": context_list}RetrievalAugmentedQAPipeline from the initial notebook to support streaming.async again!CharacterTextSplitter.text_splitter = CharacterTextSplitter()1def process_file(file: AskFileResponse):
2 import tempfile
3 import shutil
4
5 print(f"Processing file: {file.name}")
6
7 # Create a temporary file with the correct extension
8 suffix = f".{file.name.split('.')[-1]}"
9 with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
10 # Copy the uploaded file content to the temporary file
11 shutil.copyfile(file.path, temp_file.name)
12 print(f"Created temporary file at: {temp_file.name}")
13
14 # Create appropriate loader
15 if file.name.lower().endswith('.pdf'):
16 loader = PDFLoader(temp_file.name)
17 else:
18 loader = TextFileLoader(temp_file.name)
19
20 try:
21 # Load and process the documents
22 documents = loader.load_documents()
23 texts = text_splitter.split_texts(documents)
24 return texts
25 finally:
26 # Clean up the temporary file
27 try:
28 os.unlink(temp_file.name)
29 except Exception as e:
30 print(f"Error cleaning up temporary file: {e}")TextFileLoader and then split it with our TextSplitter, and returns that list of strings!1while files == None:
2 files = await cl.AskFileMessage(
3 content="Please upload a Text or PDF file to begin!",
4 accept=["text/plain", "application/pdf"],
5 max_size_mb=2,
6 timeout=180,
7 ).send()VectorDatabase and populate it with our processed chunks and their related embeddings!1vector_db = VectorDatabase()
2vector_db = await vector_db.abuild_from_list(texts)1retrieval_augmented_qa_pipeline = RetrievalAugmentedQAPipeline(
2 vector_db_retriever=vector_db,
3 llm=chat_openai
4 )NOTE: Chainlit has some great documentation about User Session.
chain = cl.user_session.get("chain")1msg = cl.Message(content="")
2result = await chain.arun_pipeline(message.content)
3
4async for stream_resp in result["response"]:
5 await msg.stream_token(stream_resp)NOTE: If you wish to go through the local deployments usingchainlit run app.pyand Docker - please feel free to do so!
Spaces tab.
Create new Space


NOTE: The address is the component that starts withgit@hf.co:spaces/.
git remote add hf HF_SPACE_SSH_ADDRESS_HEREgit pull hf main --no-rebase --allow-unrelated-histories -X oursgit add .git commit -m "Deploying Pythonic RAG"git push hf mainNOTE: The build will fail before you complete the following steps!

Variables and secrets on the Settings page and click New secret:
Name field - input OPENAI_API_KEY in the Value (private) field, put your OpenAI API Key.