CoolFace
Apppublic

Metaviz-Pro/Website_content_generation

sourceHugging Faceupdated 2y agoView on Hugging Face
4likes
main.py158 linesDownload Raw Back to root
1from langgraph.graph import END
2from fastapi import FastAPI, HTTPException
3from fastapi.responses import JSONResponse
4from fastapi.middleware.cors import CORSMiddleware
5from pydantic import BaseModel
6from typing import Dict, List, Any
7from langgraph.graph import StateGraph
8from service import research_task, seo_optimization_task, content_writing_task, refine_content, evaluate_content_quality, feedback_improvement, meeting_insights, upload_file
9from langchain_google_genai import ChatGoogleGenerativeAI
10from service import system_prompt
11app = FastAPI()
12app.add_middleware(
13    CORSMiddleware,
14    allow_origins=["*"],  # Change this to specific origins if needed
15    allow_credentials=True,
16    allow_methods=["*"],  # Allow all methods (GET, POST, PUT, DELETE, etc.)
17    allow_headers=["*"],  # Allow all headers
18)
19
20llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash")
21class ContentState(Dict):
22    idea: str
23    company_name: str
24    services: Dict[str, List[str]]  # Main services with their sub-services
25    service_area: Dict[str, Dict[str, str]]  # Each area has multiple sub-service pages
26    research_data: str
27    seo_optimization: str
28    home_page: str
29    about_us_page: str
30    service_page: str
31    individual_service_page: Dict[str, str]  # Single service pages
32    service_area_page: Dict[str, Dict[str, str]]  # Each area with its sub-services
33    quality_score: int
34    feedback: str
35    content: str
36    data: str
37    text:str
38    meeting_point:str
39    file_path:str
40workflow = StateGraph(ContentState)
41
42# ✅ Define Workflow Steps
43workflow.add_node("research_step", research_task)
44workflow.add_node("seo_step", seo_optimization_task)
45workflow.add_node("writing_step", content_writing_task)
46workflow.add_node("refine_content", refine_content)
47workflow.add_node("evaluate_content_quality", evaluate_content_quality)
48workflow.add_node("feedback_improvement", feedback_improvement)  # Node for quality rework
49workflow.add_node("human_review", lambda state: state)  # Human-in-the-loop review
50workflow.add_node("meeting_insights",meeting_insights)
51workflow.add_node("upload_file",upload_file)
52# ✅ Define Transitions
53workflow.set_entry_point("research_step")
54workflow.set_entry_point("upload_file")
55workflow.add_edge("upload_file", "meeting_insights")
56workflow.add_edge("research_step", "seo_step")
57workflow.add_edge("seo_step", "writing_step")
58workflow.add_edge("meeting_insights", "writing_step")
59workflow.add_edge("writing_step", "refine_content")
60workflow.add_edge("refine_content", "evaluate_content_quality")
61
62# Conditional Flow for Quality Check & Human Review
63workflow.add_conditional_edges(
64    "evaluate_content_quality",
65    lambda state: "feedback_improvement" if state["quality_score"] <= 7 else "human_review",
66    {
67        "feedback_improvement": "feedback_improvement",
68        "human_review": "human_review"
69    }
70)
71
72# ✅ Add Loopback from feedback_improvement to refine_content
73workflow.add_edge("feedback_improvement", "evaluate_content_quality")
74
75# ✅ Add Human-in-the-loop approval before finalization
76workflow.add_edge("human_review", END)
77
78# ✅ Compile the Graph
79content_graph = workflow.compile()
80class RequestModel(BaseModel):
81    idea: str
82    company_name: str
83    services: Dict[str, List[str]]
84    service_area: List[str]
85class UpdateRequest(BaseModel):
86    page_key: List[str]
87    user_query: str  
88
89def generate_content(data):  # Remove @app.post to make it an importable function
90    state = content_graph.invoke({
91        "idea": data["idea"],
92        "company_name": data["company_name"],
93        "services": data["services"],
94        "service_area": data["service_area"],
95        "quality_score": 0,
96        "file_path": data["file_path"]
97    })
98
99    response = {
100        "home_page": state.get("home_page", ""),
101        "about_us_page": state.get("about_us_page", ""),
102        "service_page": state.get("service_page", ""),
103        "individual_service_page": state.get("individual_service_page", {}),
104        "service_area_page": state.get("service_area_page", {})
105    }
106    
107    return response  # Return dictionary instead of JSONResponse
108@app.post("/generate-content/")
109def generate_content_endpoint(request: RequestModel):
110    """
111    API endpoint to generate website content based on user input.
112    """
113    data = request.dict()
114
115    response = generate_content(data)
116
117    return JSONResponse(content=response)
118
119
120@app.put("/update-page/")
121def update_page(state: dict, user_query: str):
122    """
123    Updates the selected page content based on user feedback.
124    """
125    current_content = state.get("page_content", "")
126
127    # Define the prompt for updating the content
128    prompt = f"""
129    You are a professional content editor. Modify the content strictly according to the user request below.
130    
131    ### **Rules for Modification**  
132    - Apply the requested changes **EXACTLY as specified** in the user request.  
133    - **Return the entire content** with only the requested modifications applied.  
134    - **DO NOT return only the changed section**—always return the full content with modifications integrated.  
135    - **DO NOT rephrase or modify anything that is not explicitly requested to change.**  
136    - Ensure the modified content reads naturally and maintains professional quality.  
137    - **DO NOT include explanations, formatting hints, or extra commentary—only return the final updated content.**  
138
139    ### **User Request:**  
140    {user_query}
141
142    ### **Original Content:**  
143    {current_content}
144
145    ### **Updated Content (Return Full Updated Version Below):**
146    """
147
148    # Call Gemini to process the update
149    updated_content = llm.invoke([
150        {"role": "system", "content": system_prompt},
151        {"role": "user", "content": prompt}
152    ]).content.strip()
153
154    # Ensure the modified content is updated correctly
155    return {"page_content": updated_content}
156
157  
158