Spaces:
Running
Running
SimaFarazi
commited on
Commit
β’
2fa9347
1
Parent(s):
feb1823
finalize simple stream app
Browse files- .gitignore +2 -0
- app_simple_stream/app/__pycache__/chains.cpython-312.pyc +0 -0
- app_simple_stream/app/__pycache__/prompts.cpython-312.pyc +0 -0
- app_simple_stream/app/__pycache__/schemas.cpython-312.pyc +0 -0
- app_simple_stream/app/{testing.ipynb β test_components.ipynb} +77 -0
- app_simple_stream/app_backup/callbacks.py +0 -24
- app_simple_stream/app_backup/chains.py +0 -55
- app_simple_stream/app_backup/crud.py +0 -23
- app_simple_stream/app_backup/data_indexing.py +0 -150
- app_simple_stream/app_backup/main.py +0 -87
- app_simple_stream/app_backup/models.py +0 -21
- app_simple_stream/app_backup/schemas.py +0 -21
- app_simple_stream/test.py +1 -0
.gitignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
.*
|
2 |
+
!/.gitignore
|
app_simple_stream/app/__pycache__/chains.cpython-312.pyc
ADDED
Binary file (935 Bytes). View file
|
|
app_simple_stream/app/__pycache__/prompts.cpython-312.pyc
ADDED
Binary file (377 Bytes). View file
|
|
app_simple_stream/app/__pycache__/schemas.cpython-312.pyc
ADDED
Binary file (490 Bytes). View file
|
|
app_simple_stream/app/{testing.ipynb β test_components.ipynb}
RENAMED
@@ -73,6 +73,83 @@
|
|
73 |
"user_question"
|
74 |
]
|
75 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
{
|
77 |
"cell_type": "code",
|
78 |
"execution_count": null,
|
|
|
73 |
"user_question"
|
74 |
]
|
75 |
},
|
76 |
+
{
|
77 |
+
"cell_type": "code",
|
78 |
+
"execution_count": 1,
|
79 |
+
"metadata": {},
|
80 |
+
"outputs": [
|
81 |
+
{
|
82 |
+
"name": "stderr",
|
83 |
+
"output_type": "stream",
|
84 |
+
"text": [
|
85 |
+
"/Users/sima/opt/anaconda3/envs/llm_app_rag/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
86 |
+
" from .autonotebook import tqdm as notebook_tqdm\n"
|
87 |
+
]
|
88 |
+
},
|
89 |
+
{
|
90 |
+
"name": "stdout",
|
91 |
+
"output_type": "stream",
|
92 |
+
"text": [
|
93 |
+
"The token has not been saved to the git credentials helper. Pass `add_to_git_credential=True` in this function directly or `--add-to-git-credential` if using via `huggingface-cli` if you want to set the git credential as well.\n",
|
94 |
+
"Token is valid (permission: write).\n",
|
95 |
+
"Your token has been saved to /Users/sima/.cache/huggingface/token\n",
|
96 |
+
"Login successful\n"
|
97 |
+
]
|
98 |
+
},
|
99 |
+
{
|
100 |
+
"name": "stderr",
|
101 |
+
"output_type": "stream",
|
102 |
+
"text": [
|
103 |
+
"/Users/sima/opt/anaconda3/envs/llm_app_rag/lib/python3.12/site-packages/huggingface_hub/inference/_client.py:2027: FutureWarning: `stop_sequences` is a deprecated argument for `text_generation` task and will be removed in version '0.28.0'. Use `stop` instead.\n",
|
104 |
+
" warnings.warn(\n"
|
105 |
+
]
|
106 |
+
},
|
107 |
+
{
|
108 |
+
"name": "stdout",
|
109 |
+
"output_type": "stream",
|
110 |
+
"text": [
|
111 |
+
" I hope you're doing well. I'm so excited to be writing to you today. I just wanted to say thank you for everything you do. I know it can't be easy, but you make it look effortless.\n",
|
112 |
+
"I was thinking about your job the other day, and I realized just how much you do. You're not just a [job title], you're a problem solver, a mediator, a leader, and so much more. You make a difference in people's lives every day, and that's truly amazing.\n",
|
113 |
+
"\n",
|
114 |
+
"I know that sometimes it can be tough, and you might feel like you're just going through the motions. But I want you to know that you're not. You're making a real impact, and it's not going unnoticed.\n",
|
115 |
+
"\n",
|
116 |
+
"I hope you know that you're appreciated, and that you're valued. You're an important part of [organization/team/community], and we're all better because of you.\n",
|
117 |
+
"\n",
|
118 |
+
"Thank you again for all that you do. I'm so grateful to have you in my life, and I hope you know that you're making a difference.\n",
|
119 |
+
"\n",
|
120 |
+
"Sincerely,\n",
|
121 |
+
"[Your Name] How are you? I hope you're doing well. I'm so excited to be writing to you today. I just wanted to say thank you for everything you do. I know it can't be easy, but you make it look effortless.\n",
|
122 |
+
"\n",
|
123 |
+
"I was thinking about your job the other day, and I realized just how much you do. You're not just a [job title], you're a problem solver, a mediator, a leader, and so much more. You make a difference in people's lives every day, and that's truly amazing.\n",
|
124 |
+
"\n",
|
125 |
+
"I know that sometimes it can be tough, and you might feel like you're just going through the motions. But I want you to know that you're not. You're making a real impact, and it's not going unnoticed.\n",
|
126 |
+
"\n",
|
127 |
+
"I hope you know that you're appreciated, and that you're valued. You're an important part of [organization/team/community], and we're all better because of you.\n",
|
128 |
+
"\n",
|
129 |
+
"Thank you again for all that you do. I'm so grateful to have you in my life, and I hope you know that you're making a difference.\n",
|
130 |
+
"\n",
|
131 |
+
"Sincerely,\n",
|
132 |
+
"[Your Name]\n",
|
133 |
+
"How are you? I hope you're doing well. I'm so excited to be writing to you today. I just wanted to say thank you for everything you do. I know it can't be easy, but you make it look effortless.\n",
|
134 |
+
"\n",
|
135 |
+
"I was thinking"
|
136 |
+
]
|
137 |
+
}
|
138 |
+
],
|
139 |
+
"source": [
|
140 |
+
"# To ensure os.environ['HF_TOKEN'] works use dotenv\n",
|
141 |
+
"import os\n",
|
142 |
+
"from dotenv import load_dotenv\n",
|
143 |
+
"load_dotenv()\n",
|
144 |
+
"\n",
|
145 |
+
"from chains import simple_chain\n",
|
146 |
+
"stream = simple_chain.stream(input={'question':'How are you?'})\n",
|
147 |
+
"for chunk in stream: # Each chunk corresponds to a token/word\n",
|
148 |
+
" #end=\"\": prints worlds one after each other, an not in a separate lines\n",
|
149 |
+
" #flush=True: prints world to the screen immidiately without any buffer\n",
|
150 |
+
" print(chunk, end=\"\", flush=True) "
|
151 |
+
]
|
152 |
+
},
|
153 |
{
|
154 |
"cell_type": "code",
|
155 |
"execution_count": null,
|
app_simple_stream/app_backup/callbacks.py
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
from typing import Dict, Any, List
|
2 |
-
from langchain_core.callbacks import BaseCallbackHandler
|
3 |
-
import schemas
|
4 |
-
import crud
|
5 |
-
|
6 |
-
|
7 |
-
class LogResponseCallback(BaseCallbackHandler):
|
8 |
-
|
9 |
-
def __init__(self, user_request: schemas.UserRequest, db):
|
10 |
-
super().__init__()
|
11 |
-
self.user_request = user_request
|
12 |
-
self.db = db
|
13 |
-
|
14 |
-
def on_llm_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:
|
15 |
-
"""Run when llm ends running."""
|
16 |
-
# TODO: The function on_llm_end is going to be called when the LLM stops sending
|
17 |
-
# the response. Use the crud.add_message function to capture that response.
|
18 |
-
raise NotImplemented
|
19 |
-
|
20 |
-
def on_llm_start(
|
21 |
-
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
|
22 |
-
) -> Any:
|
23 |
-
for prompt in prompts:
|
24 |
-
print(prompt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_simple_stream/app_backup/chains.py
DELETED
@@ -1,55 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
from langchain_huggingface import HuggingFaceEndpoint
|
3 |
-
from langchain_core.runnables import RunnablePassthrough
|
4 |
-
import schemas
|
5 |
-
from prompts import (
|
6 |
-
raw_prompt,
|
7 |
-
#format_context,
|
8 |
-
#tokenizer
|
9 |
-
)
|
10 |
-
#from data_indexing import DataIndexer
|
11 |
-
from transformers import AutoTokenizer
|
12 |
-
|
13 |
-
#data_indexer = DataIndexer()
|
14 |
-
|
15 |
-
model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
|
16 |
-
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
17 |
-
llm = HuggingFaceEndpoint(
|
18 |
-
repo_id="meta-llama/Meta-Llama-3-8B-Instruct",
|
19 |
-
huggingfacehub_api_token=os.environ['HF_TOKEN'],
|
20 |
-
max_new_tokens=512,
|
21 |
-
stop_sequences=[tokenizer.eos_token],
|
22 |
-
streaming=True,
|
23 |
-
)
|
24 |
-
|
25 |
-
simple_chain = (raw_prompt | llm).with_types(input_type=schemas.UserQuestion)
|
26 |
-
|
27 |
-
# TODO: create formatted_chain by piping raw_prompt_formatted and the LLM endpoint.
|
28 |
-
formatted_chain = None
|
29 |
-
|
30 |
-
# TODO: use history_prompt_formatted and HistoryInput to create the history_chain
|
31 |
-
history_chain = None
|
32 |
-
|
33 |
-
# TODO: Let's construct the standalone_chain by piping standalone_prompt_formatted with the LLM
|
34 |
-
standalone_chain = None
|
35 |
-
|
36 |
-
# input_1 = RunnablePassthrough.assign(new_question=standalone_chain)
|
37 |
-
# input_2 = {
|
38 |
-
# 'context': lambda x: format_context(data_indexer.search(x['new_question'])),
|
39 |
-
# 'standalone_question': lambda x: x['new_question']
|
40 |
-
# }
|
41 |
-
# input_to_rag_chain = input_1 | input_2
|
42 |
-
|
43 |
-
# TODO: use input_to_rag_chain, rag_prompt_formatted,
|
44 |
-
# HistoryInput and the LLM to build the rag_chain.
|
45 |
-
rag_chain = None
|
46 |
-
|
47 |
-
# TODO: Implement the filtered_rag_chain. It should be the
|
48 |
-
# same as the rag_chain but with hybrid_search = True.
|
49 |
-
filtered_rag_chain = None
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_simple_stream/app_backup/crud.py
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
from sqlalchemy.orm import Session
|
2 |
-
import models, schemas
|
3 |
-
|
4 |
-
|
5 |
-
def get_or_create_user(db: Session, username: str):
|
6 |
-
user = db.query(models.User).filter(models.User.username == username).first()
|
7 |
-
if not user:
|
8 |
-
user = models.User(username=username)
|
9 |
-
db.add(user)
|
10 |
-
db.commit()
|
11 |
-
db.refresh(user)
|
12 |
-
return user
|
13 |
-
|
14 |
-
def add_message(db: Session, message: schemas.MessageBase, username: str):
|
15 |
-
# TODO: Implement the add_message function. It should:
|
16 |
-
# - get or create the user with the username
|
17 |
-
# - create a models.Message instance
|
18 |
-
# - pass the retrieved user to the message instance
|
19 |
-
# - save the message instance to the database
|
20 |
-
raise NotImplemented
|
21 |
-
|
22 |
-
def get_user_chat_history(db: Session, username: str):
|
23 |
-
raise NotImplemented
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_simple_stream/app_backup/data_indexing.py
DELETED
@@ -1,150 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
import uuid
|
3 |
-
from pathlib import Path
|
4 |
-
from pinecone.grpc import PineconeGRPC as Pinecone
|
5 |
-
from pinecone import ServerlessSpec
|
6 |
-
from langchain_community.vectorstores import Chroma
|
7 |
-
from langchain_openai import OpenAIEmbeddings
|
8 |
-
|
9 |
-
current_dir = Path(__file__).resolve().parent
|
10 |
-
|
11 |
-
|
12 |
-
class DataIndexer:
|
13 |
-
|
14 |
-
source_file = os.path.join(current_dir, 'sources.txt')
|
15 |
-
|
16 |
-
def __init__(self, index_name='langchain-repo') -> None:
|
17 |
-
|
18 |
-
# TODO: choose your embedding model
|
19 |
-
# self.embedding_client = InferenceClient(
|
20 |
-
# "dunzhang/stella_en_1.5B_v5",
|
21 |
-
# token=os.environ['HF_TOKEN'],
|
22 |
-
# )
|
23 |
-
self.embedding_client = OpenAIEmbeddings()
|
24 |
-
self.index_name = index_name
|
25 |
-
self.pinecone_client = Pinecone(api_key=os.environ.get('PINECONE_API_KEY'))
|
26 |
-
|
27 |
-
if index_name not in self.pinecone_client.list_indexes().names():
|
28 |
-
# TODO: create your index if it doesn't exist. Use the create_index function.
|
29 |
-
# Make sure to choose the dimension that corresponds to your embedding model
|
30 |
-
pass
|
31 |
-
|
32 |
-
self.index = self.pinecone_client.Index(self.index_name)
|
33 |
-
# TODO: make sure to build the index.
|
34 |
-
self.source_index = None
|
35 |
-
|
36 |
-
def get_source_index(self):
|
37 |
-
if not os.path.isfile(self.source_file):
|
38 |
-
print('No source file')
|
39 |
-
return None
|
40 |
-
|
41 |
-
print('create source index')
|
42 |
-
|
43 |
-
with open(self.source_file, 'r') as file:
|
44 |
-
sources = file.readlines()
|
45 |
-
|
46 |
-
sources = [s.rstrip('\n') for s in sources]
|
47 |
-
vectorstore = Chroma.from_texts(
|
48 |
-
sources, embedding=self.embedding_client
|
49 |
-
)
|
50 |
-
return vectorstore
|
51 |
-
|
52 |
-
def index_data(self, docs, batch_size=32):
|
53 |
-
|
54 |
-
with open(self.source_file, 'a') as file:
|
55 |
-
for doc in docs:
|
56 |
-
file.writelines(doc.metadata['source'] + '\n')
|
57 |
-
|
58 |
-
for i in range(0, len(docs), batch_size):
|
59 |
-
batch = docs[i: i + batch_size]
|
60 |
-
|
61 |
-
# TODO: create a list of the vector representations of each text data in the batch
|
62 |
-
# TODO: choose your embedding model
|
63 |
-
# values = self.embedding_client.embed_documents([
|
64 |
-
# doc.page_content for doc in batch
|
65 |
-
# ])
|
66 |
-
|
67 |
-
# values = self.embedding_client.feature_extraction([
|
68 |
-
# doc.page_content for doc in batch
|
69 |
-
# ])
|
70 |
-
values = None
|
71 |
-
|
72 |
-
# TODO: create a list of unique identifiers for each element in the batch with the uuid package.
|
73 |
-
vector_ids = None
|
74 |
-
|
75 |
-
# TODO: create a list of dictionaries representing the metadata. Capture the text data
|
76 |
-
# with the "text" key, and make sure to capture the rest of the doc.metadata.
|
77 |
-
metadatas = None
|
78 |
-
|
79 |
-
# create a list of dictionaries with keys "id" (the unique identifiers), "values"
|
80 |
-
# (the vector representation), and "metadata" (the metadata).
|
81 |
-
vectors = [{
|
82 |
-
'id': vector_id,
|
83 |
-
'values': value,
|
84 |
-
'metadata': metadata
|
85 |
-
} for vector_id, value, metadata in zip(vector_ids, values, metadatas)]
|
86 |
-
|
87 |
-
try:
|
88 |
-
# TODO: Use the function upsert to upload the data to the database.
|
89 |
-
upsert_response = None
|
90 |
-
print(upsert_response)
|
91 |
-
except Exception as e:
|
92 |
-
print(e)
|
93 |
-
|
94 |
-
def search(self, text_query, top_k=5, hybrid_search=False):
|
95 |
-
|
96 |
-
filter = None
|
97 |
-
if hybrid_search and self.source_index:
|
98 |
-
# I implemented the filtering process to pull the 50 most relevant file names
|
99 |
-
# to the question. Make sure to adjust this number as you see fit.
|
100 |
-
source_docs = self.source_index.similarity_search(text_query, 50)
|
101 |
-
filter = {"source": {"$in":[doc.page_content for doc in source_docs]}}
|
102 |
-
|
103 |
-
# TODO: embed the text_query by using the embedding model
|
104 |
-
# TODO: choose your embedding model
|
105 |
-
# vector = self.embedding_client.feature_extraction(text_query)
|
106 |
-
# vector = self.embedding_client.embed_query(text_query)
|
107 |
-
vector = None
|
108 |
-
|
109 |
-
# TODO: use the vector representation of the text_query to
|
110 |
-
# search the database by using the query function.
|
111 |
-
result = None
|
112 |
-
|
113 |
-
docs = []
|
114 |
-
for res in result["matches"]:
|
115 |
-
# TODO: From the result's metadata, extract the "text" element.
|
116 |
-
pass
|
117 |
-
|
118 |
-
return docs
|
119 |
-
|
120 |
-
|
121 |
-
if __name__ == '__main__':
|
122 |
-
|
123 |
-
from langchain_community.document_loaders import GitLoader
|
124 |
-
from langchain_text_splitters import (
|
125 |
-
Language,
|
126 |
-
RecursiveCharacterTextSplitter,
|
127 |
-
)
|
128 |
-
|
129 |
-
loader = GitLoader(
|
130 |
-
clone_url="https://github.com/langchain-ai/langchain",
|
131 |
-
repo_path="./code_data/langchain_repo/",
|
132 |
-
branch="master",
|
133 |
-
)
|
134 |
-
|
135 |
-
python_splitter = RecursiveCharacterTextSplitter.from_language(
|
136 |
-
language=Language.PYTHON, chunk_size=10000, chunk_overlap=100
|
137 |
-
)
|
138 |
-
|
139 |
-
docs = loader.load()
|
140 |
-
docs = [doc for doc in docs if doc.metadata['file_type'] in ['.py', '.md']]
|
141 |
-
docs = [doc for doc in docs if len(doc.page_content) < 50000]
|
142 |
-
docs = python_splitter.split_documents(docs)
|
143 |
-
for doc in docs:
|
144 |
-
doc.page_content = '# {}\n\n'.format(doc.metadata['source']) + doc.page_content
|
145 |
-
|
146 |
-
indexer = DataIndexer()
|
147 |
-
with open('/app/sources.txt', 'a') as file:
|
148 |
-
for doc in docs:
|
149 |
-
file.writelines(doc.metadata['source'] + '\n')
|
150 |
-
indexer.index_data(docs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_simple_stream/app_backup/main.py
DELETED
@@ -1,87 +0,0 @@
|
|
1 |
-
from langchain_core.runnables import Runnable
|
2 |
-
from langchain_core.callbacks import BaseCallbackHandler
|
3 |
-
from fastapi import FastAPI, Request, Depends
|
4 |
-
from sse_starlette.sse import EventSourceResponse
|
5 |
-
from langserve.serialization import WellKnownLCSerializer
|
6 |
-
from typing import List
|
7 |
-
from sqlalchemy.orm import Session
|
8 |
-
|
9 |
-
import schemas
|
10 |
-
from chains import simple_chain
|
11 |
-
#import crud, models, schemas
|
12 |
-
from database import SessionLocal, engine
|
13 |
-
#from callbacks import LogResponseCallback
|
14 |
-
|
15 |
-
|
16 |
-
#models.Base.metadata.create_all(bind=engine)
|
17 |
-
|
18 |
-
app = FastAPI()
|
19 |
-
|
20 |
-
def get_db():
|
21 |
-
db = SessionLocal()
|
22 |
-
try:
|
23 |
-
yield db
|
24 |
-
finally:
|
25 |
-
db.close()
|
26 |
-
|
27 |
-
|
28 |
-
async def generate_stream(input_data: schemas.BaseModel, runnable: Runnable, callbacks: List[BaseCallbackHandler]=[]):
|
29 |
-
for output in runnable.stream(input_data.dict(), config={"callbacks": callbacks}):
|
30 |
-
data = WellKnownLCSerializer().dumps(output).decode("utf-8")
|
31 |
-
yield {'data': data, "event": "data"}
|
32 |
-
yield {"event": "end"}
|
33 |
-
|
34 |
-
|
35 |
-
@app.post("/simple/stream")
|
36 |
-
async def simple_stream(request: Request):
|
37 |
-
data = await request.json()
|
38 |
-
user_question = schemas.UserQuestion(**data['input'])
|
39 |
-
return EventSourceResponse(generate_stream(user_question, simple_chain))
|
40 |
-
|
41 |
-
|
42 |
-
@app.post("/formatted/stream")
|
43 |
-
async def formatted_stream(request: Request):
|
44 |
-
# TODO: use the formatted_chain to implement the "/formatted/stream" endpoint.
|
45 |
-
raise NotImplemented
|
46 |
-
|
47 |
-
|
48 |
-
@app.post("/history/stream")
|
49 |
-
async def history_stream(request: Request, db: Session = Depends(get_db)):
|
50 |
-
# TODO: Let's implement the "/history/stream" endpoint. The endpoint should follow those steps:
|
51 |
-
# - The endpoint receives the request
|
52 |
-
# - The request is parsed into a user request
|
53 |
-
# - The user request is used to pull the chat history of the user
|
54 |
-
# - We add as part of the user history the current question by using add_message.
|
55 |
-
# - We create an instance of HistoryInput by using format_chat_history.
|
56 |
-
# - We use the history input within the history chain.
|
57 |
-
raise NotImplemented
|
58 |
-
|
59 |
-
|
60 |
-
@app.post("/rag/stream")
|
61 |
-
async def rag_stream(request: Request, db: Session = Depends(get_db)):
|
62 |
-
# TODO: Let's implement the "/rag/stream" endpoint. The endpoint should follow those steps:
|
63 |
-
# - The endpoint receives the request
|
64 |
-
# - The request is parsed into a user request
|
65 |
-
# - The user request is used to pull the chat history of the user
|
66 |
-
# - We add as part of the user history the current question by using add_message.
|
67 |
-
# - We create an instance of HistoryInput by using format_chat_history.
|
68 |
-
# - We use the history input within the rag chain.
|
69 |
-
raise NotImplemented
|
70 |
-
|
71 |
-
|
72 |
-
@app.post("/filtered_rag/stream")
|
73 |
-
async def filtered_rag_stream(request: Request, db: Session = Depends(get_db)):
|
74 |
-
# TODO: Let's implement the "/filtered_rag/stream" endpoint. The endpoint should follow those steps:
|
75 |
-
# - The endpoint receives the request
|
76 |
-
# - The request is parsed into a user request
|
77 |
-
# - The user request is used to pull the chat history of the user
|
78 |
-
# - We add as part of the user history the current question by using add_message.
|
79 |
-
# - We create an instance of HistoryInput by using format_chat_history.
|
80 |
-
# - We use the history input within the filtered rag chain.
|
81 |
-
raise NotImplemented
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
if __name__ == "__main__":
|
86 |
-
import uvicorn
|
87 |
-
uvicorn.run("main:app", host="localhost", reload=True, port=8000)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_simple_stream/app_backup/models.py
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
from sqlalchemy import Column, ForeignKey, Integer, String, DateTime
|
2 |
-
from sqlalchemy.orm import relationship
|
3 |
-
|
4 |
-
from database import Base
|
5 |
-
|
6 |
-
class User(Base):
|
7 |
-
__tablename__ = "users"
|
8 |
-
|
9 |
-
id = Column(Integer, primary_key=True, index=True)
|
10 |
-
username = Column(String, unique=True, index=True)
|
11 |
-
messages = relationship("Message", back_populates="user")
|
12 |
-
|
13 |
-
# TODO: Implement the Message SQLAlchemy model. Message should have a primary key,
|
14 |
-
# a message attribute to store the content of messages, a type, AI or Human,
|
15 |
-
# depending on if it is a user question or an AI response, a timestamp to
|
16 |
-
# order by time and a user attribute to get the user instance associated
|
17 |
-
# with the message. We also need a user_id that will use the User.id
|
18 |
-
# attribute as a foreign key.
|
19 |
-
class Message(Base):
|
20 |
-
__tablename__ = "messages"
|
21 |
-
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_simple_stream/app_backup/schemas.py
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
|
2 |
-
#from pydantic.v1 import BaseModel
|
3 |
-
from langserve._pydantic import BaseModel
|
4 |
-
|
5 |
-
|
6 |
-
class UserQuestion(BaseModel):
|
7 |
-
question: str
|
8 |
-
|
9 |
-
# TODO: create a HistoryInput data model with a chat_history and question attributes.
|
10 |
-
class HistoryInput(BaseModel):
|
11 |
-
pass
|
12 |
-
|
13 |
-
# TODO: let's create a UserRequest data model with a question and username attribute.
|
14 |
-
# This will be used to parse the input request.
|
15 |
-
class UserRequest(BaseModel):
|
16 |
-
username: str
|
17 |
-
|
18 |
-
# TODO: implement MessageBase as a schema mapping from the database model to the
|
19 |
-
# FastAPI data model. Basically MessageBase should have the same attributes as models.Message
|
20 |
-
class MessageBase(BaseModel):
|
21 |
-
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app_simple_stream/test.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
from langserve import RemoteRunnable
|
2 |
# Hit our enpoint with specified rout
|
|
|
3 |
url = "https://simafarazi-backend-c.hf.space/simple/"
|
4 |
chain = RemoteRunnable(url) #Client for iteracting with LangChain runnables that are hosted as LangServe endpoints
|
5 |
stream = chain.stream(input={'question':'How are you?'}) # .stream() and .invoke() are standard methods to interact with hosted runnables
|
|
|
1 |
from langserve import RemoteRunnable
|
2 |
# Hit our enpoint with specified rout
|
3 |
+
# If we put /simple/stream, it complains; because chain.stream will hit /simple/stream endpoint
|
4 |
url = "https://simafarazi-backend-c.hf.space/simple/"
|
5 |
chain = RemoteRunnable(url) #Client for iteracting with LangChain runnables that are hosted as LangServe endpoints
|
6 |
stream = chain.stream(input={'question':'How are you?'}) # .stream() and .invoke() are standard methods to interact with hosted runnables
|