import json from fastapi import FastAPI, HTTPException from pydantic import BaseModel import openai from typing import List, Dict, Any import os app = FastAPI() # Pydantic models for request body class StudyInput(BaseModel): overall_study_pattern: str memorization_study_pattern: str problem_solving_study_pattern: str visualization_study_pattern: str obstacle_study_pattern: str new_topic_approach: str old_topic_approach: str topic_ratio: str hours_of_study: str hours_of_study_weekends: str revision_days: str test_days: str physicsStartIndex: int chemistryStartIndex: int mathematicsStartIndex: int completed_phy_chapters: List[str] completed_chem_chapters: List[str] completed_maths_chapters: List[str] # Function to remove completed chapters def remove_completed_chapters(subject_data, completed_chapters): subject_data["chapters"] = [chapter for chapter in subject_data["chapters"] if chapter["chapter"] not in completed_chapters] return subject_data # Function to get data at index def get_data_at_index(json_data, index): if 0 <= index < len(json_data['chapters']): return json_data['chapters'][index] else: return {} @app.post("/generate_roadmap") async def generate_roadmap(study_input: StudyInput): # Load JSON data for each subject # Note: You'll need to adjust the file paths or include these JSON files in your Docker image with open('Physics.json', 'r', encoding='utf-8') as file: phy = json.load(file) with open('Chemistry.json', 'r', encoding='utf-8') as file: chem = json.load(file) with open('Maths.json', 'r', encoding='utf-8') as file: maths = json.load(file) # Remove completed chapters phy = remove_completed_chapters(phy, study_input.completed_phy_chapters) chem = remove_completed_chapters(chem, study_input.completed_chem_chapters) maths = remove_completed_chapters(maths, study_input.completed_maths_chapters) # Get data at specified indices phy = get_data_at_index(phy, study_input.physicsStartIndex) chem = get_data_at_index(chem, study_input.chemistryStartIndex) maths = get_data_at_index(maths, study_input.mathematicsStartIndex) # Prepare user persona user_persona = f""" You are required to generate a highly personalized roadmap for a student studying Physics, Chemistry, and Mathematics for the JEE Main exam. The roadmap should be tailored based on the following student-specific details: 1. *Study Preferences:* - Study Pattern: {study_input.overall_study_pattern} - Memorization Approach: {study_input.memorization_study_pattern} - Problem-Solving Approach: {study_input.problem_solving_study_pattern} - Visualization Approach: {study_input.visualization_study_pattern} 2. *Handling Challenges:* - If unable to understand a topic: {study_input.obstacle_study_pattern} - Approach to New Topics: {study_input.new_topic_approach} - Approach to Previously Encountered Topics: {study_input.old_topic_approach} 3. *Study Hours:* - Weekdays: {study_input.hours_of_study} hours/day - Weekends: {study_input.hours_of_study_weekends} hours/day - Time Allocation Ratio (Physics:Chemistry:Mathematics): {study_input.topic_ratio} - By weekdays I mean day 1, day 2 , day 3 , day 4 , day 5 - By weekends I mean day 6 , day 7 4. *Revision and Test Strategy:* - The days of the week when you do revision : {study_input.revision_days} - The days of the week when you give tests : {study_input.test_days} """ output_structure = """{ "schedule": [ { "dayNumber": int, "subjects": [ { "name": "string", "tasks": [ { "type": "string", "topic": "string", "time": "string" } ] } ] } ] } """ # Prepare system prompt sys_prompt = f""" You are required to generate a highly personalized roadmap for a student studying Physics, Chemistry, and Mathematics for the JEE Main exam. The roadmap should be tailored based on the following student-specific details: The roadmap must be provided in the following format: {output_structure} Do not include anything other than the roadmap, and ensure the focus remains strictly on the subjects {phy}, {chem}, and {maths} and associated chapters. MAKE SURE THAT YOU MAKE THE ROADMAP FOR ALL THE THREE CHAPTERS EACH OF PHYSICS , CHEMISTRY AND MATHS TO COMPLETE THOSE CHAPTERS WITH 4 ASPECTS i.e "CONCEPT UNDERSTANDING","QUESTION PRACTICE","REVISION","TEST". ALSO INCLUDE TIME FOR EACH TASK THAT YOU GENERATE MAKE SURE THAT WE FIRST COMPLETE 1) CONCEPT UNDERSTANDING , 2) QUESTION PRACTICE FOR EVERY SUBTOPIC AND THEN REVISION AND TEST FOR WHOLE CHAPTER TOGETHER. MAKE SURE THAT WE INCULDE EACH SUBTOPIC OF EACH CHAPTER FROM {phy},{chem} and {maths} IS FINISHED YOU ARE NOT CONSTRAINED TO CREATE A ROADMAP FOR ONLY 'X' NUMBER OF DAYS , YOU CAN EXTEND TILL THE TOPICS ARE FINISHED BUT ONLY STICK TO THE TIMEFRAME ALLOTED FOR EACH SUBJECT AND DO NOT GO ABOVE OR BELOW THAT TIME FRAME. Make sure you make the roadmap for 7-10 days only. """ # Make OpenAI API call openai.api_key = os.getenv("KEY") # Replace with your actual API key or use environment variables try: response = openai.ChatCompletion.create( model="gpt-4o-mini", messages=[ { "role": "system", "content": sys_prompt + "MAKE SURE YOU VERY VERY STRUCTLY FOLLOW THE JSON STRUCTURE BECAUSE I WILL PARSE YOUR OUTPUT TO JSON" }, { "role": "user", "content": user_persona } ] ) answer = response['choices'][0]['message']['content'].strip() # Second OpenAI API call response = openai.ChatCompletion.create( model="gpt-4o-mini", messages=[ { "role": "system", "content": f''' you created a very good roadmap {answer} but you make sure that you dont forget any subtopics from Physics : {phy}, Chemistry : {chem} and Maths : {maths}. ensure that the style is same as the previous roadmap. MAKE SURE YOU VERY VERY STRUCTLY FOLLOW THE JSON STRUCTURE BECAUSE I WILL PARSE YOUR OUTPUT TO JSON. DO not include json at the top of the answer ''' }, { "role": "user", "content": "Generate" } ] ) final_answer = response['choices'][0]['message']['content'].strip() parsed_json = json.loads(final_answer) return parsed_json except Exception as e: raise HTTPException(status_code=500, detail=str(e)) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)