Owen Wang commited on
Commit
471307c
·
1 Parent(s): 9bc85e2

working app

Browse files
Files changed (3) hide show
  1. README.md +15 -0
  2. app.py +98 -28
  3. requirements.txt +2 -1
README.md CHANGED
@@ -10,3 +10,18 @@ pinned: false
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
+
14
+ ## Setup
15
+
16
+ ```
17
+ pip install virtualenv
18
+ python -m venv myenv
19
+ source myenv/bin/activate
20
+ pip install -r requirements.txt
21
+ ```
22
+
23
+ ## Run
24
+
25
+ ```
26
+ streamlit run app.py
27
+ ```
app.py CHANGED
@@ -1,45 +1,115 @@
 
1
  import streamlit as st
 
2
  import openai
3
- import os
 
 
4
 
5
- # Set OpenAI API key from Streamlit Secrets
6
  OPENAI_API_KEY = st.secrets["OPENAI_API_KEY"]
 
 
 
 
 
 
 
 
7
  openai.api_key = OPENAI_API_KEY
8
 
9
- # Set maximum token length
10
- MAX_TOKENS = 1024
 
 
 
 
 
 
 
11
 
12
- # Set OpenAI model
13
- MODEL = "openai-davinci-003"
 
 
 
14
 
15
- # Set Streamlit page configuration
16
- st.set_page_config(layout="centered")
17
 
18
- # Set Streamlit title and description
19
- st.title("Email Response Generator")
20
- st.markdown("Generate a response to an email.")
21
 
22
- # Define the email input form
23
- st.subheader("Input Email")
24
- email_text = st.text_area("Enter your email here", height=200)
25
 
26
- # Define the response generation function
27
- @st.cache(show_spinner=False)
28
- def generate_response(email_text):
29
- prompt = "You are sharing an email. You have very little time in your schedule but want to be polite in your response. You are expecting a response.\n\nEmail:\n" + email_text
 
 
 
 
 
 
 
 
 
 
30
  response = openai.Completion.create(
31
- engine=MODEL,
32
  prompt=prompt,
33
- max_tokens=MAX_TOKENS
 
 
 
34
  )
35
  return response.choices[0].text.strip()
36
 
37
- # Define the submit button
38
- if st.button("Generate Response"):
39
- if email_text.strip() == "":
40
- st.warning("Please enter your email.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  else:
42
- with st.spinner("Generating response..."):
43
- response_text = generate_response(email_text)
44
- st.subheader("Generated Response")
45
- st.markdown(response_text)
 
1
+ from typing import List, Optional, TypedDict
2
  import streamlit as st
3
+ import requests
4
  import openai
5
+ import pinecone
6
+ import json
7
+ import re
8
 
9
+ PINECONE_API_KEY = st.secrets["PINECONE_API_KEY"]
10
  OPENAI_API_KEY = st.secrets["OPENAI_API_KEY"]
11
+
12
+ class Metadata(TypedDict):
13
+ title: str
14
+ description
15
+ slides: str
16
+
17
+ # Initialize Pinecone and OpenAI
18
+ pinecone.init(api_key=PINECONE_API_KEY, environment="asia-southeast1-gcp")
19
  openai.api_key = OPENAI_API_KEY
20
 
21
+ def get_embeddings(texts: List[str]) -> List[List[float]]:
22
+ """
23
+ Embed texts using OpenAI's ada model.
24
+
25
+ Args:
26
+ texts: The list of texts to embed.
27
+
28
+ Returns:
29
+ A list of embeddings, each of which is a list of floats.
30
 
31
+ Raises:
32
+ Exception: If the OpenAI API call fails.
33
+ """
34
+ # Call the OpenAI API to get the embeddings
35
+ response = openai.Embedding.create(input=texts, model="text-embedding-ada-002")
36
 
37
+ # Extract the embedding data from the response
38
+ data = response["data"] # type: ignore
39
 
40
+ # Return the embeddings as a list of lists of floats
41
+ return [result["embedding"] for result in data]
 
42
 
43
+ # Pinecone fetch function
44
+ def fetch_lesson(query: str):
45
+ vector = get_embeddings([query])[0]
46
 
47
+ index_name = "prequelworkshops"
48
+ index = pinecone.Index(index_name)
49
+ return index.query(
50
+ vector=vector,
51
+ # filter={
52
+ # "genre": {"$eq": "documentary"},
53
+ # "year": 2019
54
+ # },
55
+ top_k=1,
56
+ include_metadata=True
57
+ )
58
+
59
+ # OpenAI prompt generation function
60
+ def query_openai(prompt) -> str:
61
  response = openai.Completion.create(
62
+ engine="text-davinci-003",
63
  prompt=prompt,
64
+ max_tokens=1024,
65
+ n=1,
66
+ stop=None,
67
+ temperature=0.7,
68
  )
69
  return response.choices[0].text.strip()
70
 
71
+ def extract_arrays(s: str) -> Optional[List[str]]:
72
+ s = s.replace("'", '"')
73
+
74
+ try:
75
+ arrays = json.loads(s) # try to parse the string as JSON
76
+ except json.JSONDecodeError as e:
77
+ print(e)
78
+ return None # if parsing fails, return None
79
+
80
+ if isinstance(arrays, list): # if parsing succeeds and the result is a list
81
+ return arrays # return the list
82
+ else:
83
+ return None
84
+
85
+ def generate_curriculum(user_input) -> Optional[List[str]]:
86
+ # st.write("Generating curriculum...")
87
+ prompt = f"You are a world class high school teacher. Create a curriculum for a course based on the student's interest below. Output the curriculum as a javascript array of strings, where each string is a description of the lesson. The output should just be the array and nothing else. Student's interest: {user_input}"
88
+ response = query_openai(prompt)
89
+ return extract_arrays(response)
90
+
91
+ def get_metadata(lesson) -> Metadata:
92
+ return lesson.matches[0].metadata
93
+
94
+ def format_metadata(metadata) -> List[str]:
95
+ return f"Title: {metadata['title']}\n\nDescription: {metadata['description']}"
96
+
97
+ # Streamlit UI
98
+ st.title("Personalized Learning Curriculum Generator")
99
+ user_input = st.text_input("Enter what you want to learn:")
100
+ submit_button = st.button("Generate response")
101
+ status = st.empty()
102
+
103
+ if submit_button:
104
+ status.text("Generating curriculum...")
105
+ curriculum = generate_curriculum(user_input)
106
+
107
+ if curriculum is not None:
108
+ status.text("Fetching relevant courses...")
109
+ lessons = [fetch_lesson(lesson) for lesson in curriculum]
110
+ lesson_text = "\n\n".join([format_metadata(get_metadata(lesson)) for lesson in lessons])
111
+ status.empty()
112
+ st.markdown(f"**Generated Curriculum:**\n\n{lesson_text}")
113
  else:
114
+ status.text("Error generating curriculum. Please try again")
115
+
 
 
requirements.txt CHANGED
@@ -1,2 +1,3 @@
 
1
  openai
2
- streamlit
 
1
+ streamlit
2
  openai
3
+ pinecone-client