jzou19950715's picture
Update app.py
47e9852 verified
raw
history blame
8.25 kB
"""
Gradio Interactive Chat App for Educational Information Collection.
"""
# Imports
import gradio as gr
import openai
import json
from datetime import datetime
from typing import List, Optional, Dict
from pydantic import BaseModel, Field
# Constants
SYSTEM_PROMPT = """You are an educational information collection assistant. Your task is to systematically collect the following information in a conversational manner:
Required Information (collect in this order):
1. Institution Details:
- Name
- Type (e.g., university, college, etc.)
- Location
2. Degree Information:
- Type (e.g., Bachelor's, Master's, etc.)
- Field of Study
- Status (e.g., completed, ongoing)
3. Attendance Dates (start and end)
4. Academic Performance:
- GPA (if provided)
- Honors or awards
5. Activities:
- Extracurricular activities, roles, and durations
Always maintain a friendly, professional tone while systematically collecting this information."""
# Data Models
class Institution(BaseModel):
name: str
type: str
location: str
class Degree(BaseModel):
type: str
field: str
status: str
class Dates(BaseModel):
start: str
end: str
class Activity(BaseModel):
name: str
description: str
duration: str
class Academic(BaseModel):
gpa: Optional[float] = None
honors: List[str] = Field(default_factory=list)
achievements: List[str] = Field(default_factory=list)
class Education(BaseModel):
institution: Institution
degree: Degree
dates: Dates
academic: Academic
activities: List[Activity] = Field(default_factory=list)
class EducationRecord(BaseModel):
education: List[Education] = Field(default_factory=list)
metadata: Dict[str, str]
# Assistant Logic
class EducationAssistant:
"""
Handles conversation state, chat interactions, and JSON generation.
"""
def __init__(self):
self.conversation_history = []
self.client = None
self.system_prompt = SYSTEM_PROMPT
def initialize_chat(self, api_key: str) -> str:
"""Initializes OpenAI client and provides the first prompt."""
try:
openai.api_key = api_key
return "Hello! Let's record your educational history. What is the name of your most recent educational institution?"
except Exception as e:
return f"Error initializing chat: {str(e)}"
def chat(self, message: str, api_key: str) -> Dict[str, str]:
"""Processes user messages and generates responses."""
if not self.client:
first_message = self.initialize_chat(api_key)
self.conversation_history.append({"role": "assistant", "content": first_message})
return {"role": "assistant", "content": first_message}
try:
# Append user message to history
self.conversation_history.append({"role": "user", "content": message})
# Generate response
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": self.system_prompt}] + self.conversation_history,
temperature=0.7,
max_tokens=300
)
# Parse and store assistant response
assistant_message = {"role": "assistant", "content": response.choices[0].message.content}
self.conversation_history.append(assistant_message)
return assistant_message
except Exception as e:
return {"role": "assistant", "content": f"Error: {str(e)}"}
def generate_json(self) -> Optional[str]:
"""Generates structured JSON from the conversation history."""
try:
json_prompt = """Based on our conversation, generate a structured JSON containing the educational information shared. Format it as follows:
{
"education": [
{
"institution": {
"name": string,
"type": string,
"location": string
},
"degree": {
"type": string,
"field": string,
"status": string
},
"dates": {
"start": string,
"end": string
},
"academic": {
"gpa": float (if provided),
"honors": [string],
"achievements": [string]
},
"activities": [
{
"name": string,
"description": string,
"duration": string
}
]
}
],
"metadata": {
"timestamp": string,
"source": "Education Information Assistant"
}
}
Respond ONLY with the JSON."""
# Generate JSON based on the conversation history
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": self.system_prompt}] + self.conversation_history +
[{"role": "user", "content": json_prompt}],
temperature=0.1,
max_tokens=1500
)
# Parse response and write JSON file
json_data = json.loads(response.choices[0].message.content)
filename = f"education_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
with open(filename, "w") as f:
json.dump(json_data, f, indent=2)
return filename
except Exception as e:
print(f"Error generating JSON: {str(e)}")
return None
# Gradio Interface
def create_interface():
assistant = EducationAssistant()
with gr.Blocks() as demo:
gr.Markdown("# 📘 Educational Information Collection Assistant")
with gr.Row():
api_key = gr.Textbox(
label="OpenAI API Key",
type="password",
placeholder="Enter your OpenAI API Key",
info="Required for using OpenAI's GPT model."
)
chatbot = gr.Chatbot(label="Assistant", height=400)
with gr.Row():
user_input = gr.Textbox(
label="Your Message",
placeholder="Type your message here...",
lines=2
)
send_button = gr.Button("Send", variant="primary")
generate_button = gr.Button("Generate JSON")
download_file = gr.File(label="Generated JSON")
# Event Handlers
def handle_send(message, history, api_key):
if not api_key.strip():
return history + [{"role": "assistant", "content": "Please provide your OpenAI API key to continue."}]
if not message.strip():
return history
response = assistant.chat(message, api_key)
return history + [{"role": "user", "content": message}, response]
def handle_generate():
filename = assistant.generate_json()
if filename:
return filename
return "Error generating JSON. Please ensure all required information is collected."
# Button Actions
send_button.click(
handle_send,
inputs=[user_input, chatbot, api_key],
outputs=[chatbot]
)
user_input.submit(
handle_send,
inputs=[user_input, chatbot, api_key],
outputs=[chatbot]
)
generate_button.click(
handle_generate,
outputs=[download_file]
)
return demo
# Main Execution
if __name__ == "__main__":
demo = create_interface()
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=True
)