| from datetime import datetime
|
| import streamlit as st
|
| from pymongo import MongoClient
|
| from openai import OpenAI
|
| from bson import ObjectId
|
| import json
|
| from dotenv import load_dotenv
|
| import os
|
| import google.generativeai as genai
|
|
|
| load_dotenv()
|
| MONGO_URI = os.getenv('MONGO_URI')
|
| OPENAI_API_KEY = os.getenv('OPENAI_KEY')
|
| GEMINI_API_KEY = os.getenv('GEMINI_KEY')
|
| genai.configure(api_key=GEMINI_API_KEY)
|
| model = genai.GenerativeModel("gemini-1.5-flash")
|
|
|
| client = MongoClient(MONGO_URI)
|
| db = client['novascholar_db']
|
|
|
| rubrics_collection = db['rubrics']
|
| resources_collection = db['resources']
|
| courses_collection = db['courses']
|
|
|
| def generate_rubrics(session_title, outcomes, pre_class_material):
|
|
|
| outcomes_text = "\n".join([
|
| f"Outcome {i+1}:\n- Description: {outcome.get('outcome_description')}\n- Taxonomy Level: {outcome.get('bloom_taxanomy_level')}"
|
| for i, outcome in enumerate(outcomes)
|
| ])
|
|
|
| prompt = f"""
|
| You are an expert educational AI assistant specializing in instructional design. Generate a detailed rubric for the session titled "{session_title}". The rubric should cover multiple learning outcomes and use numerical scoring levels (4,3,2,1). Use the following context:
|
|
|
| Session Outcomes Description:
|
| {outcomes_text}
|
|
|
| Pre-class Material:
|
| {pre_class_material}
|
|
|
| Please generate the rubric in JSON format with these specifications:
|
| 1. Use numerical levels (4=Highest, 1=Lowest) instead of descriptive levels
|
| 2. Include 4-5 relevant criteria based on the session outcome
|
| 3. Each criterion should have clear descriptors for each numerical level
|
| 4. Focus on objectively measurable aspects for evaluation
|
| 5. Structure should be suitable for evaluating assignments and test answers
|
|
|
| ***IMPORTANT: DO NOT INCLUDE THE WORD JSON IN THE OUTPUT STRING, DO NOT INCLUDE BACKTICKS (```) IN THE OUTPUT, AND DO NOT INCLUDE ANY OTHER TEXT, OTHER THAN THE ACTUAL JSON RESPONSE. START THE RESPONSE STRING WITH AN OPEN CURLY BRACE {{ AND END WITH A CLOSING CURLY BRACE }}.***
|
| """
|
|
|
| messages = [
|
| {
|
| "role": "system",
|
| "content": "You are an expert educational AI assistant specializing in instructional design.",
|
| },
|
| {
|
| "role": "user",
|
| "content": prompt
|
| },
|
| ]
|
|
|
| try:
|
| response = model.generate_content(
|
| prompt,
|
| generation_config=genai.GenerationConfig(
|
| response_mime_type="application/json"
|
| )
|
| )
|
| return response.text
|
| except Exception as e:
|
| st.error(f"Failed to generate rubrics: {e}")
|
| return None
|
|
|
| def display_rubrics_tab(session, course_id):
|
| st.subheader("Generated Rubrics")
|
|
|
|
|
| course_data = courses_collection.find_one(
|
| {"course_id": course_id, "sessions.session_id": session['session_id']},
|
| {"sessions.$": 1}
|
| )
|
|
|
| if course_data and 'sessions' in course_data and len(course_data['sessions']) > 0:
|
| session_data = course_data['sessions'][0]
|
|
|
|
|
| if 'session_learning_outcomes' in session_data and len(session_data['session_learning_outcomes']) > 0:
|
| outcomes = session_data['session_learning_outcomes']
|
|
|
|
|
|
|
|
|
| st.markdown("### Session Information")
|
| st.markdown(f"**Session Title:** {session['title']}")
|
|
|
|
|
|
|
|
|
| st.markdown("### Learning Outcomes:")
|
| for i, outcome in enumerate(outcomes, 1):
|
| st.markdown(f"""
|
| **Outcome {i}:**
|
| - Description: {outcome.get('outcome_description')}
|
| - Taxonomy Level: {outcome.get('bloom_taxanomy_level')}
|
| """)
|
|
|
|
|
| pre_class_material_docs = resources_collection.find({"session_id": session['session_id']})
|
| pre_class_material = "\n".join([f"{doc.get('title', 'No Title')}: {doc.get('url', 'No URL')}" for doc in pre_class_material_docs])
|
|
|
| if st.button("Generate Rubric"):
|
| rubric = generate_rubrics(
|
| session['title'],
|
| outcomes,
|
| pre_class_material
|
| )
|
|
|
| if rubric:
|
| st.json(rubric)
|
|
|
| rubric_data = {
|
| "course_id": course_id,
|
| "session_id": session['session_id'],
|
| "rubric": json.loads(rubric),
|
| "outcomes": outcomes,
|
| "created_at": datetime.now()
|
| }
|
|
|
|
|
|
|
| existing_rubric = rubrics_collection.find_one({
|
| "session_id": session['session_id']
|
| })
|
|
|
| if existing_rubric:
|
| rubrics_collection.update_one(
|
| {"_id": existing_rubric["_id"]},
|
| {"$set": rubric_data}
|
| )
|
| st.success("Rubric updated successfully!")
|
| else:
|
| rubrics_collection.insert_one(rubric_data)
|
| st.success("Rubric saved successfully!")
|
|
|
|
|
| existing_rubric = rubrics_collection.find_one({
|
| "session_id": session['session_id']
|
| })
|
|
|
| if existing_rubric:
|
| with st.expander("View Existing Rubric"):
|
| st.json(existing_rubric['rubric'])
|
| st.caption(f"Last updated: {existing_rubric['created_at'].strftime('%Y-%m-%d %H:%M:%S')}")
|
|
|
| if st.button("Generate New Rubric", key="new_rubric"):
|
| st.rerun()
|
| else:
|
| st.error("No learning outcomes found for this session")
|
| else:
|
| st.error("Session data not found") |