Update app.py
Browse files
app.py
CHANGED
@@ -1,130 +1,97 @@
|
|
1 |
import os
|
2 |
import json
|
|
|
3 |
import gradio as gr
|
|
|
|
|
4 |
from typing import List, Dict
|
5 |
from langchain.document_loaders import AirtableLoader
|
6 |
-
from langchain.vectorstores import FAISS
|
7 |
-
from langchain.embeddings import OpenAIEmbeddings
|
8 |
-
from langchain.chains import RetrievalQA
|
9 |
-
from langchain.chat_models import ChatOpenAI
|
10 |
-
from langchain.schema import SystemMessage, HumanMessage
|
11 |
-
from langchain.text_splitter import CharacterTextSplitter
|
12 |
-
from langchain.docstore.document import Document
|
13 |
|
14 |
# Set up API keys
|
15 |
AIRTABLE_API_KEY = os.getenv("AIRTABLE_API_KEY")
|
16 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
documents = loader.load()
|
26 |
data = []
|
27 |
for doc in documents:
|
28 |
try:
|
29 |
-
# Try to parse the JSON content
|
30 |
record = json.loads(doc.page_content)
|
31 |
data.append(record)
|
32 |
except json.JSONDecodeError:
|
33 |
-
# If JSON parsing fails, use the raw content
|
34 |
print(f"Warning: Could not parse JSON for document: {doc.page_content[:100]}...")
|
35 |
data.append({"raw_content": doc.page_content})
|
36 |
-
return data
|
37 |
|
38 |
-
# Load Airtable data
|
39 |
try:
|
40 |
-
|
41 |
-
print(f"Successfully loaded
|
42 |
except Exception as e:
|
43 |
print(f"Error loading Airtable data: {str(e)}")
|
44 |
-
|
45 |
-
|
46 |
-
# Prepare documents for embedding
|
47 |
-
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
|
48 |
-
documents = [Document(page_content=json.dumps(record)) for record in airtable_data]
|
49 |
-
split_documents = text_splitter.split_documents(documents)
|
50 |
-
|
51 |
-
# Initialize the embedding model and FAISS index
|
52 |
-
embedding_model = OpenAIEmbeddings()
|
53 |
-
vectorstore = FAISS.from_documents(split_documents, embedding_model)
|
54 |
-
|
55 |
-
# Define the retrieval model
|
56 |
-
retriever = vectorstore.as_retriever()
|
57 |
-
|
58 |
-
# Define the chat model
|
59 |
-
chat_model = ChatOpenAI(model="gpt-4o")
|
60 |
-
|
61 |
-
# Define a custom prompt for context
|
62 |
-
system_message_content = """
|
63 |
-
#Context
|
64 |
-
You are a school assistant with strong database Q&A capabilities.
|
65 |
-
Your role is to help educators keep track of students' assignments in different classes.
|
66 |
-
This is a complex problem, because each student has their own menu of classes (they choose their classes), so that it can be hard for a teacher to know what assignments their students might have
|
67 |
-
in other classes. Solving this requires carefully analyzing a database.
|
68 |
-
You have acces to a list of records with the following format:
|
69 |
-
-Class
|
70 |
-
-List of students enrolled in the class (student codes)
|
71 |
-
-List of DUE dates, when students turn in work done at home
|
72 |
-
-List of DO dates, when students take assessments in class
|
73 |
-
-List of DUE assignments
|
74 |
-
-List of DO assessments
|
75 |
-
The policy is that students cannot have 0, 1, or 2 DO assessments the same day, but not 3 or more.
|
76 |
-
HOWEVER, DUE assignments do not count towards this total.
|
77 |
-
|
78 |
-
#Instructions
|
79 |
-
When asked a question about a class and a date, follow this thought process internally without sharing it with the user. Only share the conclusion.
|
80 |
-
[Thought process (hidden internal state):
|
81 |
-
-Store a dictionary of all students enrolled in this class
|
82 |
-
-Look up all other classes one by one, and check if it has a DO date the same day, and if some of the same students are enrolled. Make sure to double-check the student codes and rosters
|
83 |
-
-Deduce whether any student in the first class already has 2 or more "DO" assessments on that day in the other classes
|
84 |
-
-Double check by running the same steps again and testing your conclusion. Pay careful attention to student codes and dates.
|
85 |
-
|
86 |
-
Keep this procedure in mind when answering other questions as well.
|
87 |
-
]
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
-
|
110 |
-
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
-
|
113 |
-
return response['result']
|
114 |
|
115 |
# Define the Gradio interface
|
116 |
def gradio_interface(question: str) -> str:
|
117 |
-
return
|
118 |
|
119 |
# Set up Gradio interface
|
120 |
iface = gr.Interface(
|
121 |
fn=gradio_interface,
|
122 |
inputs="text",
|
123 |
-
#outputs="text",
|
124 |
outputs=gr.Markdown(),
|
125 |
title="📅 Summative Assessment Tracker",
|
126 |
description="I am here to help you schedule summative assessments for your students"
|
127 |
)
|
128 |
|
129 |
# Launch the Gradio app
|
130 |
-
iface.launch(debug=True)
|
|
|
1 |
import os
|
2 |
import json
|
3 |
+
import pandas as pd
|
4 |
import gradio as gr
|
5 |
+
import openai
|
6 |
+
import time
|
7 |
from typing import List, Dict
|
8 |
from langchain.document_loaders import AirtableLoader
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
# Set up API keys
|
11 |
AIRTABLE_API_KEY = os.getenv("AIRTABLE_API_KEY")
|
12 |
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
13 |
+
BASE_ID = os.getenv("base_id")
|
14 |
+
TABLE_ID = os.getenv("table_id")
|
15 |
+
VIEW = os.getenv("view")
|
16 |
+
|
17 |
+
# Set up OpenAI client
|
18 |
+
openai.api_key = OPENAI_API_KEY
|
19 |
+
client = openai.Client(api_key=OPENAI_API_KEY)
|
20 |
+
|
21 |
+
# Set up assistant
|
22 |
+
ASSISTANT_ID = os.getenv('assistant_id')
|
23 |
+
assistant = client.beta.assistants.retrieve(ASSISTANT_ID)
|
24 |
+
thread = client.beta.threads.create()
|
25 |
+
|
26 |
+
# Function to load data from Airtable and return as a DataFrame
|
27 |
+
def load_airtable_data() -> pd.DataFrame:
|
28 |
+
loader = AirtableLoader(AIRTABLE_API_KEY, TABLE_ID, BASE_ID, view=VIEW)
|
29 |
documents = loader.load()
|
30 |
data = []
|
31 |
for doc in documents:
|
32 |
try:
|
|
|
33 |
record = json.loads(doc.page_content)
|
34 |
data.append(record)
|
35 |
except json.JSONDecodeError:
|
|
|
36 |
print(f"Warning: Could not parse JSON for document: {doc.page_content[:100]}...")
|
37 |
data.append({"raw_content": doc.page_content})
|
38 |
+
return pd.DataFrame(data)
|
39 |
|
40 |
+
# Load Airtable data into DataFrame
|
41 |
try:
|
42 |
+
airtable_data_df = load_airtable_data()
|
43 |
+
print(f"Successfully loaded data from Airtable.")
|
44 |
except Exception as e:
|
45 |
print(f"Error loading Airtable data: {str(e)}")
|
46 |
+
airtable_data_df = pd.DataFrame()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
+
# Function to chat with the assistant
|
49 |
+
def chat_with_assistant(message: str, dataframe: pd.DataFrame) -> str:
|
50 |
+
dataframe_csv = dataframe.to_csv(index=False)
|
51 |
+
|
52 |
+
full_message = f"""
|
53 |
+
You are an assistant with code interpreter capabilities.
|
54 |
+
I have a DataFrame with the following content:
|
55 |
+
{dataframe_csv}
|
56 |
+
|
57 |
+
Here is my question: {message}
|
58 |
+
|
59 |
+
Please use the DataFrame and code to provide an answer.
|
60 |
+
"""
|
61 |
+
|
62 |
+
client.beta.threads.messages.create(
|
63 |
+
thread_id=thread.id,
|
64 |
+
role="user",
|
65 |
+
content=full_message
|
66 |
+
)
|
67 |
+
|
68 |
+
run = client.beta.threads.runs.create(
|
69 |
+
thread_id=thread.id,
|
70 |
+
assistant_id=ASSISTANT_ID
|
71 |
+
)
|
72 |
|
73 |
+
while True:
|
74 |
+
run_status = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
|
75 |
+
if run_status.status == 'completed':
|
76 |
+
messages = client.beta.threads.messages.list(thread_id=thread.id)
|
77 |
+
assistant_response = messages.data[0].content[0].text.value
|
78 |
+
break
|
79 |
+
time.sleep(1)
|
80 |
|
81 |
+
return assistant_response
|
|
|
82 |
|
83 |
# Define the Gradio interface
|
84 |
def gradio_interface(question: str) -> str:
|
85 |
+
return chat_with_assistant(question, airtable_data_df)
|
86 |
|
87 |
# Set up Gradio interface
|
88 |
iface = gr.Interface(
|
89 |
fn=gradio_interface,
|
90 |
inputs="text",
|
|
|
91 |
outputs=gr.Markdown(),
|
92 |
title="📅 Summative Assessment Tracker",
|
93 |
description="I am here to help you schedule summative assessments for your students"
|
94 |
)
|
95 |
|
96 |
# Launch the Gradio app
|
97 |
+
iface.launch(debug=True)
|