jeremierostan commited on
Commit
cc3fb29
·
verified ·
1 Parent(s): a13be24

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -0
app.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ os.environ["AIRTABLE_API_KEY"] = os.getenv["AIRTABLE_API_KEY"]
16
+ os.environ["OPENAI_API_KEY"] = os.getenv["OPENAI_API_KEY"]
17
+
18
+ base_id = os.getenv["base_id"]
19
+ table_id = os.getenv["table_id"]
20
+ view = os.getenv["view"]
21
+
22
+ def load_airtable_data() -> List[Dict]:
23
+ """Load data from Airtable and return as a list of dictionaries."""
24
+ loader = AirtableLoader(os.environ["AIRTABLE_API_KEY"], table_id, base_id, view=view)
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
+ airtable_data = load_airtable_data()
41
+ print(f"Successfully loaded {len(airtable_data)} records from Airtable.")
42
+ except Exception as e:
43
+ print(f"Error loading Airtable data: {str(e)}")
44
+ airtable_data = []
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
+ You are a school assistant with strong database Q&A capabilities.
64
+ Your role is to help educators keep track of students' assignments in different classes.
65
+ 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
66
+ in other classes. Solving this requires carefully analyzing a database.
67
+ You have acces to a database with the following format:
68
+ -List of classes
69
+ -List of DUE dates, when students turn in work done at home
70
+ -List of DO dates, when students take assessments in class
71
+ -List of DUE assignments
72
+ -List of DO assessments
73
+ The policy is that students cannot have to DO more than 2 in-class assignments on a given day.
74
+ HOWEVER, they might have 2 or more assignments DUE on the same day.
75
+ Be concise and factual in your answers unless asked for more details.
76
+ Base all of your answers on the data provided.
77
+ Double-check your answers, and if you don't know the answer, say that you don't know.
78
+ """
79
+
80
+ # Create the QA chain
81
+ qa_chain = RetrievalQA.from_chain_type(
82
+ llm=chat_model,
83
+ chain_type="stuff",
84
+ retriever=retriever,
85
+ return_source_documents=True
86
+ )
87
+
88
+ def ask_question(question: str) -> str:
89
+ """Ask a question about the Airtable data."""
90
+ # Combine the system message and user question
91
+ full_query = f"{system_message_content}\n\nHuman: {question}\n\nAssistant:"
92
+
93
+ # Get the response from the QA chain
94
+ response = qa_chain({"query": full_query})
95
+
96
+ # Return the response content
97
+ return response['result']
98
+
99
+ # Define the Gradio interface
100
+ def gradio_interface(question: str) -> str:
101
+ return ask_question(question)
102
+
103
+ # Set up Gradio interface
104
+ iface = gr.Interface(
105
+ fn=gradio_interface,
106
+ inputs="text",
107
+ outputs="text",
108
+ title="Summative Assessment Tracker",
109
+ description="I am here to help you schedule summative assessments for your students"
110
+ )
111
+
112
+ # Launch the Gradio app
113
+ iface.launch(debug=True)