sooolee commited on
Commit
ba34941
1 Parent(s): 84a0700

Initial Model

Browse files
Files changed (5) hide show
  1. app.py +61 -0
  2. chain.py +50 -0
  3. images/octo.jpeg +0 -0
  4. ingest.py +74 -0
  5. requirement.txt +10 -0
app.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pickle
3
+ from chain import get_chain
4
+
5
+
6
+ with open("db.pkl", "rb") as f:
7
+ global vectorstore
8
+ vectorstore = pickle.load(f)
9
+
10
+ chain = get_chain()
11
+
12
+ def chat(inp, history):
13
+ history = history or []
14
+ output = chain({'input_documents': vectorstore.similarity_search(inp, k=4), 'query': inp}, return_only_outputs=True)
15
+ response = output['output_text']
16
+ history.append((inp, response))
17
+ return history, history
18
+
19
+
20
+ block = gr.Blocks(css=".gradio-container {background-color: lightgray}")
21
+
22
+ with block:
23
+ with gr.Row():
24
+ with gr.Column(scale=1):
25
+ # gr.Markdown("""<img src=https://huggingface.co/spaces/.jpeg></left>""")
26
+ gr.Markdown("""<img alt="Image" title="icon" src="./images/octo.jpeg" />""")
27
+ with gr.Column(scale=15):
28
+ gr.Markdown("<h1><left>Your Beer Sommelier</left></h1>")
29
+ gr.Markdown("""<h3><left> Your friendly beer sommelier is here to help you choose the right beer for you!</left></h3>""")
30
+
31
+ chatbot = gr.Chatbot()
32
+
33
+ with gr.Row():
34
+ message = gr.Textbox(
35
+ label="What's your question?",
36
+ placeholder="Do you have any recommendations for IPA with tropical fruite flavors?",
37
+ lines=1,
38
+ )
39
+ with gr.Row():
40
+ submit = gr.Button(value="Send", variant="secondary", size="lg")
41
+
42
+ gr.Examples(
43
+ examples=[
44
+ "What does Bock taste like? Do you recommend it?",
45
+ "I like Lagunitas IPA. Do you have anything similar?",
46
+ "Do you have any recommendations for Pilsner?",
47
+ "What kind of German beers do you have?"
48
+ ],
49
+ inputs=message,
50
+ )
51
+
52
+ state = gr.State()
53
+
54
+ message.submit(chat, inputs=[message, state], outputs=[chatbot, state])
55
+ message.submit(lambda x: gr.update(value=''), [], [message])
56
+
57
+ submit.click(chat, inputs=[message, state], outputs=[chatbot, state])
58
+ submit.click(lambda x: gr.update(value=''), [], [message])
59
+
60
+
61
+ block.launch(debug=True, share=True)
chain.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Generate QA Chain to answer the question given matches (db)"""
2
+ import os
3
+ import openai
4
+ from langchain.chains.question_answering import load_qa_chain
5
+ from langchain.chat_models import ChatOpenAI
6
+ from langchain.llms import OpenAI
7
+ from langchain.memory import ConversationBufferMemory, ConversationBufferWindowMemory
8
+ from langchain.prompts import PromptTemplate
9
+ from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
10
+
11
+ openai.api_key = os.environ['OPENAI_API_KEY']
12
+
13
+ def get_chain():
14
+ template = """
15
+ You are a ChatBot at a restaurant with expertise in beers and good at making recommendations based on the user's preferences.
16
+ You are a given a context delimited by "=========", which is extracted part of the restaurant's beer list.
17
+ Customer's question is given below delimited by "```````".
18
+
19
+ Based on the context, question and chat history, please respond in a friendly, conversational manner based on the context, describing features of beers.
20
+ When asked to make recommendations, make three to four. Do not mention ABV or IBU unless asked about it. Remember you are trying to promote your beers.
21
+
22
+ If asked about something that is not related to beers in any absolute way, say you are only good at recommending beers in a witty way and redirect the conversation
23
+ by asking about customer's preferences such as beer style, flavor, etc..
24
+
25
+ If you don't find the answer to the user's question with the context provided to you below,
26
+ answer that you don't have the requested beer and ask about customer's preferences such as beer style, flavor, etc..
27
+ Finish by proposing your help for anything else.
28
+
29
+ CONTEXT:
30
+ =========
31
+ {context}
32
+ =========
33
+
34
+ QUESTION:
35
+ ````````
36
+ {query}
37
+ ````````
38
+ CHAT HISTORY:
39
+ {chat_history}
40
+
41
+ ANSWER:
42
+ """
43
+
44
+ prompt = PromptTemplate(input_variables=["chat_history", "query", "context"], template=template)
45
+ memory = ConversationBufferMemory(memory_key="chat_history", input_key="query")
46
+ chat = ChatOpenAI(temperature=0, streaming=True)
47
+
48
+ chain = load_qa_chain(llm=chat, chain_type="stuff", memory=memory, prompt=prompt)
49
+
50
+ return chain
images/octo.jpeg ADDED
ingest.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Scrape selected data from the 'untapped' website, put them in a list of dictionaries,
2
+ embed and store them into a vectorstore."""
3
+
4
+ import requests
5
+ import os
6
+ import openai
7
+ from bs4 import BeautifulSoup
8
+ from langchain.embeddings.openai import OpenAIEmbeddings
9
+ from langchain.embeddings import CohereEmbeddings, HuggingFaceHubEmbeddings
10
+ from langchain.vectorstores import FAISS, Annoy, DocArrayInMemorySearch
11
+ from langchain.document_loaders import CSVLoader
12
+ import csv
13
+ import pickle
14
+
15
+ openai.api_key = os.environ['OPENAI_API_KEY']
16
+
17
+
18
+ def ingest_data():
19
+ headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
20
+ url='https://untappd.com/v/gourmet-haus-staudt/15392'
21
+ response = requests.get(url, headers=headers)
22
+ soup = BeautifulSoup(response.text, 'html.parser')
23
+
24
+ links = soup.find_all('a', attrs={'data-track':'menu', 'data-href': ":"})
25
+
26
+ beer_list = []
27
+
28
+ for link in links:
29
+ page_url = 'https://untappd.com' + link.get('href')
30
+
31
+ if page_url:
32
+ page_response = requests.get(page_url, headers=headers)
33
+ page_soup = BeautifulSoup(page_response.text, 'html.parser')
34
+
35
+ # Extract the "relevant" page content
36
+ box_info = page_soup.find('div', class_="box b_info")
37
+
38
+ if box_info:
39
+ name = box_info.find('h1').get_text()
40
+ brewery = box_info.find(class_="brewery").get_text().strip()
41
+ style = box_info.find(class_="style").get_text()
42
+ description = box_info.find(class_="beer-descrption-read-less")
43
+ description.find('a').extract()
44
+ description = description.get_text().strip()
45
+ abv = box_info.find(class_="abv").get_text().strip()
46
+ ibu = box_info.find(class_="ibu").get_text().strip()
47
+ ratings = box_info.find(class_="num").get_text().replace("(", "").replace(")", "")
48
+ n_ratings = box_info.find(class_="raters").get_text().strip()
49
+
50
+ beer_dict = {"name": name, "brewery": brewery, "style": style, "description": description, "alcohol_by_volume": abv, "ibu_bitterness_unit": ibu, "ratings": ratings, "n_ratings": n_ratings}
51
+
52
+ beer_list.append(beer_dict)
53
+
54
+ keys = beer_list[0].keys()
55
+
56
+ with open('beers.csv', 'w', newline='') as output_file:
57
+ dict_writer = csv.DictWriter(output_file, keys)
58
+ dict_writer.writeheader()
59
+ dict_writer.writerows(beer_list)
60
+
61
+ file = 'beers.csv'
62
+ loader = CSVLoader(file_path=file)
63
+ data = loader.load()
64
+
65
+ embeddings = OpenAIEmbeddings()
66
+ db = FAISS.from_documents(data, embeddings)
67
+
68
+ # Save vectorstore
69
+
70
+ with open("db.pkl", "wb") as f:
71
+ pickle.dump(db, f)
72
+
73
+ if __name__ == "__main__":
74
+ ingest_data()
requirement.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ langchain
2
+ openai
3
+ python-dotenv
4
+ faiss-cpu
5
+ annoy
6
+ tiktoken
7
+ cohere
8
+ chromadb
9
+ beautifulsoup4
10
+ gradio