Pasindu599 commited on
Commit
948e715
·
1 Parent(s): 58c189d

Add CORS middleware to FastAPI app and update summarize endpoint to accept multiple input fields (urls, codes, notes). Enhance graph logic to process new input structure and return detailed summary response.

Browse files
Files changed (2) hide show
  1. app.py +15 -2
  2. langgraph/agents/summarize_agent/graph.py +80 -9
app.py CHANGED
@@ -1,11 +1,22 @@
1
  from fastapi import FastAPI
2
  from langgraph.agents.summarize_agent.graph import graph
3
  from fastapi import Request
 
 
4
 
5
 
6
 
7
  app = FastAPI()
8
 
 
 
 
 
 
 
 
 
 
9
  @app.get("/")
10
  def greet_json():
11
  return {"Hello": "World!"}
@@ -15,8 +26,10 @@ def greet_json():
15
  @app.post("/summarize")
16
  async def summarize(request: Request):
17
  data = await request.json()
18
- user_input = data.get("user_input")
19
- return graph.invoke({"user_input": user_input})
 
 
20
 
21
 
22
 
 
1
  from fastapi import FastAPI
2
  from langgraph.agents.summarize_agent.graph import graph
3
  from fastapi import Request
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+
6
 
7
 
8
 
9
  app = FastAPI()
10
 
11
+ # cors
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
  @app.get("/")
21
  def greet_json():
22
  return {"Hello": "World!"}
 
26
  @app.post("/summarize")
27
  async def summarize(request: Request):
28
  data = await request.json()
29
+ urls = data.get("urls")
30
+ codes = data.get("codes")
31
+ notes = data.get("notes")
32
+ return graph.invoke({"urls": urls, "codes": codes, "notes": notes})
33
 
34
 
35
 
langgraph/agents/summarize_agent/graph.py CHANGED
@@ -1,31 +1,99 @@
1
- from typing import TypedDict
2
  import os
3
  from dotenv import load_dotenv
4
  from google import genai
5
  from langgraph.graph import StateGraph
6
- from google.genai import types
7
- load_dotenv()
8
 
 
 
 
9
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
10
 
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
 
14
 
15
 
16
  class State(TypedDict):
17
- user_input: str
18
- summary: str
 
 
 
 
 
 
 
 
19
 
20
 
21
  def summarize_user_input(state: State) -> State:
22
  client = genai.Client(api_key=GOOGLE_API_KEY)
23
  response = client.models.generate_content(
24
- model="gemini-2.0-flash", contents=state["user_input"], config=types.GenerateContentConfig(
25
- system_instruction="You are a helpful assistant that summarizes user input.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  )
27
 
28
- state["summary"] = response.text
 
 
 
 
 
29
  return state
30
 
31
 
@@ -33,9 +101,12 @@ def summarize_user_input(state: State) -> State:
33
  builder = StateGraph(State)
34
 
35
  builder.add_node("summarize", summarize_user_input)
 
36
 
37
  builder.add_edge("__start__", "summarize")
38
- builder.add_edge("summarize", "__end__")
 
 
39
 
40
  graph = builder.compile()
41
  graph.name = "summarize_agent"
 
1
+ from typing import TypedDict, Optional
2
  import os
3
  from dotenv import load_dotenv
4
  from google import genai
5
  from langgraph.graph import StateGraph
 
 
6
 
7
+ from pydantic import Field , BaseModel
8
+ load_dotenv()
9
+ from google.genai.types import Tool, GenerateContentConfig, GoogleSearch, UrlContext
10
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
11
 
12
 
13
+ class SummaryResponse(BaseModel):
14
+ title: Optional[str] = Field(default=None , description="The title of the content")
15
+ category: Optional[str] = Field(default=None , description="The category of the content")
16
+ tags: Optional[list[str]] = Field(default=[] , description="The tags of the content")
17
+ references: Optional[list[str]] = Field(default=[] , description="The references of the content")
18
+ summary: Optional[str] = Field(default="" , description="The summary of the content")
19
+
20
+
21
+
22
+ tools = []
23
+ tools.append(Tool(url_context=UrlContext))
24
+ tools.append(Tool(google_search=GoogleSearch))
25
+
26
 
27
 
28
 
29
 
30
  class State(TypedDict):
31
+ urls: Optional[list[str]] = Field(default=[])
32
+ codes: Optional[str] = Field(default="")
33
+ notes: Optional[str] = Field(default="")
34
+ summary_content: Optional[str] = Field(default="" , description="The summary of all urls, codes, and notes")
35
+ title: Optional[str] = Field(default="" , description="The title of the content")
36
+ category: Optional[str] = Field(default="" , description="The category of the content")
37
+ tags: Optional[list[str]] = Field(default=[] , description="The tags of the content")
38
+ references: Optional[list[str]] = Field(default=[] , description="The references of the content")
39
+ summary_response: Optional[SummaryResponse] = Field(default=None , description="The summary of the content")
40
+
41
 
42
 
43
  def summarize_user_input(state: State) -> State:
44
  client = genai.Client(api_key=GOOGLE_API_KEY)
45
  response = client.models.generate_content(
46
+ model="gemini-2.5-flash-preview-05-20",
47
+ config=GenerateContentConfig(
48
+ tools=tools,
49
+ system_instruction="You are a helpful assistant that summarizes from urls, codes, and notes",
50
+
51
+ ),
52
+
53
+ contents=f"""
54
+ Summarize the following urls, codes, and notes:
55
+ Urls: {
56
+ state["urls"]
57
+
58
+ }
59
+ Codes: {state["codes"]}
60
+ Notes: {state["notes"]}
61
+
62
+ And Give the complete summary to as blog to post on medium.com
63
+
64
+ Give the title of the blog.
65
+ Give the category of the blog.
66
+ Give the tags of the blog.
67
+
68
+ Search and always give five references from the internet to support the summary.
69
+
70
+ """
71
+
72
+ )
73
+
74
+ summary_response = response.text
75
+ state["summary_response"] = summary_response
76
+
77
+
78
+ return state
79
+
80
+ def get_summary_response(state: State) -> State:
81
+ client = genai.Client(api_key=GOOGLE_API_KEY)
82
+ response = client.models.generate_content(
83
+ model="gemini-2.5-flash-preview-05-20",
84
+ contents="Structured the summary of the content . The summary is: " + state["summary_response"] + " and give the title, category, tags, and references",
85
+ config={
86
+ "response_mime_type": "application/json",
87
+ "response_schema": SummaryResponse,
88
+ },
89
  )
90
 
91
+ summary : SummaryResponse = response.parsed
92
+ state["title"] = summary.title
93
+ state["category"] = summary.category
94
+ state["tags"] = summary.tags
95
+ state["references"] = summary.references
96
+ state["summary_content"] = summary.summary
97
  return state
98
 
99
 
 
101
  builder = StateGraph(State)
102
 
103
  builder.add_node("summarize", summarize_user_input)
104
+ builder.add_node("get_summary_response", get_summary_response)
105
 
106
  builder.add_edge("__start__", "summarize")
107
+
108
+ builder.add_edge("summarize", "get_summary_response")
109
+ builder.add_edge("get_summary_response", "__end__")
110
 
111
  graph = builder.compile()
112
  graph.name = "summarize_agent"