from fastapi import FastAPI , UploadFile , File , Form from fastapi.responses import JSONResponse from pydantic import BaseModel from brainstroming_agent.agent import brainstroming_graph import pandas as pd from typing import Optional , List from context_analysis_agent.agent import IntroductionChatbot from business_interaction_agent.agent import BusinessInteractionChatbot from context_analysis_agent.utils.utils import save_to_db import ast from brainstroming_agent.utils.utils import encode_image_to_base64 , generate_final_story, generate_image from idea_to_budget_agent.agent import budget_calculator from ideation_agent.agent import ideation_graph from langgraph.errors import GraphRecursionError import json # Store brainstorming results per thread_id app = FastAPI() context_analysis_graph = IntroductionChatbot() business_interaction_graph = BusinessInteractionChatbot() idea_graph = ideation_graph() brainstrom_graph = brainstroming_graph() stored_data={} # stored_data['business_details']={"business_type": "fitness and gym", "platform": "instagram, tiktok", "target_audience": "every software needed clients", "business_goals": "to expand in every cities of nepal", "offerings": "nepali cloths and products", "Challenges_faced": "finding new customers, attracting large customers"} stored_data['business_details'] = { "business_type": "fitness and gym", "platform": "Instagram, TikTok", "target_audience": "young Nepali adults (ages 18–40) who are health-conscious and active on social media", "business_goals": "to expand gym branches across all major cities of Nepal and build a strong fitness community", "offerings": "personal training, group fitness classes, modern workout equipment, nutrition guidance, and wellness programs", "Challenges_faced": "attracting loyal members, standing out in a competitive market, and promoting consistent engagement" } stored_data['final_ideation']= ['''A street magician performs tricks, leaving a crowd awestruck. One trick falters, inspiring him to hit the gym. Months later, he fuses fitness with magic, showcasing strength through performance, proving that transformation can captivate and inspire a community''', '''A group of strangers attends a quirky food festival, each trying bizarre dishes. One adventurer finds a fitness coach among them. They bond over health, sparking a weekly workout group that brings the community together, blending fun and fitness effortlessly.''', '''A lost hiker discovers a hidden waterfall, but slips on the rocks, nearly falling. A passing fitness enthusiast helps him up, encouraging regular exercise for safety and strength. Together, they start a hiking club, uniting fitness and nature lovers in their city''', '''A lost hiker discovers a hidden waterfall, but slips on the rocks, nearly falling. A passing fitness enthusiast helps him up, encouraging regular exercise for safety and strength. Together, they start a hiking club, uniting fitness and nature lovers in their city.'''] class UserMessage(BaseModel): message: str @app.post("/context-analysis") def context_analysis(msg: UserMessage): response = context_analysis_graph.chat(msg.message) if context_analysis_graph.is_complete(response): details = context_analysis_graph.extract_details() if type(details) != dict: details = details.model_dump() print('Business_details:',details) if isinstance(details, str): details= ast.literal_eval(details) print('Details Type:',type(details)) save_to_db(details) stored_data['business_details'] = details return {"response": response, "business_details": details, "complete": True} return {"response": response, "complete": False} @app.post("/business-interaction") def business_interaction(interaction: str): response,business_details = business_interaction_graph.chat(interaction , stored_data['business_details']) stored_data['business_details']=business_details return {'response': response} class IdeationRequest(BaseModel): topic : List[str] @app.post("/ideation") def ideation_endpoint(request:IdeationRequest): config={"recursion_limit":15, "configurable": {"thread_id": "ideation_thread123"}} try: result = idea_graph.invoke( { 'topic': request.topic, 'business_details': [stored_data['business_details']] }, config=config, ) stored_data['final_ideation'] = result['improver_response'][-1] stored_data['final_ideation']=ast.literal_eval(stored_data['final_ideation']) return {'response':result} except GraphRecursionError: result = idea_graph.get_state({"configurable": {"thread_id": "ideation_thread123"}}) return {'response': result[0]} class BudgetMappingRequest(BaseModel): pass @app.post("/budget-mapping") def budget_mapping_endpoint(): result = budget_calculator(stored_data["business_details"],stored_data['final_ideation']) return {'response':result} class BrainstormRequest(BaseModel): preferred_topics: Optional[list] = [] image_base64_list: Optional[list] = [] thread_id: Optional[str]="default-session" @app.post("/brainstrom") def brainstroming_endpoint( request: BrainstormRequest, # 🔥 Full JSON body here ): result = brainstrom_graph.invoke({ 'topic': [stored_data['final_ideation'][0]], 'images': request.image_base64_list, 'latest_preferred_topics': request.preferred_topics, 'business_details': (lambda d: d['business_details'] if 'business_details' in d else {})(stored_data) }, config={"configurable": {"thread_id": request.thread_id}}) stored_data['brainstroming_response'] = result return {'response': result} @app.post("/generate-final-story") def generate_final_story_endpoint(): final_story = generate_final_story(stored_data["brainstroming_response"]) stored_data['final_story']=final_story return { 'response': final_story } stored_data['final_story']= '''A cinematic journey follows a street magician\'s metamorphosis from a mere trickster to a powerful performer, as he transforms his act with newfound physical strength, effortlessly executing death-defying stunts, and inspiring a captivated crowd to take action, all set against a backdrop of urban grandeur and pulsing energy.''' @app.post("/generate-image") def generate_image_endpoint(): image = generate_image(str(stored_data['final_story'])) stored_data['generated_image']=image return { 'response':image }