Skip to content

Commit 12634ba

Browse files
committed
refactor: Reduce Duplication in server/apps/jsonrpc
1 parent aa63b98 commit 12634ba

File tree

3 files changed

+49
-102
lines changed

3 files changed

+49
-102
lines changed

src/a2a/server/apps/jsonrpc/fastapi_app.py

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@
22

33
from typing import Any
44

5-
from fastapi import FastAPI, Request, Response
5+
from fastapi import FastAPI
66

77
from a2a.server.apps.jsonrpc.jsonrpc_app import (
8-
CallContextBuilder,
98
JSONRPCApplication,
109
)
11-
from a2a.server.request_handlers.jsonrpc_handler import RequestHandler
12-
from a2a.types import AgentCard
1310

1411

1512
logger = logging.getLogger(__name__)
@@ -23,32 +20,6 @@ class A2AFastAPIApplication(JSONRPCApplication):
2320
(SSE).
2421
"""
2522

26-
def __init__(
27-
self,
28-
agent_card: AgentCard,
29-
http_handler: RequestHandler,
30-
extended_agent_card: AgentCard | None = None,
31-
context_builder: CallContextBuilder | None = None,
32-
):
33-
"""Initializes the A2AStarletteApplication.
34-
35-
Args:
36-
agent_card: The AgentCard describing the agent's capabilities.
37-
http_handler: The handler instance responsible for processing A2A
38-
requests via http.
39-
extended_agent_card: An optional, distinct AgentCard to be served
40-
at the authenticated extended card endpoint.
41-
context_builder: The CallContextBuilder used to construct the
42-
ServerCallContext passed to the http_handler. If None, no
43-
ServerCallContext is passed.
44-
"""
45-
super().__init__(
46-
agent_card=agent_card,
47-
http_handler=http_handler,
48-
extended_agent_card=extended_agent_card,
49-
context_builder=context_builder,
50-
)
51-
5223
def add_routes_to_app(
5324
self,
5425
app: FastAPI,
@@ -64,22 +35,12 @@ def add_routes_to_app(
6435
rpc_url: The URL for the A2A JSON-RPC endpoint.
6536
extended_agent_card_url: The URL for the authenticated extended agent card endpoint.
6637
"""
38+
route_definitions = self._get_route_definitions(
39+
agent_card_url, rpc_url, extended_agent_card_url
40+
)
6741

68-
@app.post(rpc_url)
69-
async def handle_a2a_request(request: Request) -> Response:
70-
return await self._handle_requests(request)
71-
72-
@app.get(agent_card_url)
73-
async def get_agent_card(request: Request) -> Response:
74-
return await self._handle_get_agent_card(request)
75-
76-
if self.agent_card.supportsAuthenticatedExtendedCard:
77-
78-
@app.get(extended_agent_card_url)
79-
async def get_extended_agent_card(request: Request) -> Response:
80-
return await self._handle_get_authenticated_extended_agent_card(
81-
request
82-
)
42+
for route_def in route_definitions:
43+
app.add_api_route(**route_def)
8344

8445
def build(
8546
self,

src/a2a/server/apps/jsonrpc/jsonrpc_app.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,18 +409,54 @@ async def _handle_get_authenticated_extended_agent_card(
409409
status_code=404,
410410
)
411411

412+
def _get_route_definitions(
413+
self,
414+
agent_card_url: str,
415+
rpc_url: str,
416+
extended_agent_card_url: str,
417+
) -> list[dict[str, Any]]:
418+
"""Generates a list of route definitions for the application."""
419+
routes = [
420+
{
421+
'path': rpc_url,
422+
'endpoint': self._handle_requests,
423+
'methods': ['POST'],
424+
'name': 'a2a_handler',
425+
},
426+
{
427+
'path': agent_card_url,
428+
'endpoint': self._handle_get_agent_card,
429+
'methods': ['GET'],
430+
'name': 'agent_card',
431+
},
432+
]
433+
434+
if self.agent_card.supportsAuthenticatedExtendedCard:
435+
routes.append(
436+
{
437+
'path': extended_agent_card_url,
438+
'endpoint': self._handle_get_authenticated_extended_agent_card,
439+
'methods': ['GET'],
440+
'name': 'authenticated_extended_agent_card',
441+
}
442+
)
443+
return routes
444+
412445
@abstractmethod
413446
def build(
414447
self,
415448
agent_card_url: str = '/.well-known/agent.json',
416449
rpc_url: str = '/',
450+
extended_agent_card_url: str = '/agent/authenticatedExtendedCard',
417451
**kwargs: Any,
418452
) -> FastAPI | Starlette:
419453
"""Builds and returns the JSONRPC application instance.
420454
421455
Args:
422456
agent_card_url: The URL for the agent card endpoint.
423-
rpc_url: The URL for the A2A JSON-RPC endpoint
457+
rpc_url: The URL for the A2A JSON-RPC endpoint.
458+
extended_agent_card_url: The URL for the authenticated extended
459+
agent card endpoint.
424460
**kwargs: Additional keyword arguments to pass to the FastAPI constructor.
425461
426462
Returns:

src/a2a/server/apps/jsonrpc/starlette_app.py

Lines changed: 6 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@
66
from starlette.routing import Route
77

88
from a2a.server.apps.jsonrpc.jsonrpc_app import (
9-
CallContextBuilder,
109
JSONRPCApplication,
1110
)
12-
from a2a.server.request_handlers.jsonrpc_handler import RequestHandler
13-
from a2a.types import AgentCard
1411

1512

1613
logger = logging.getLogger(__name__)
@@ -24,32 +21,6 @@ class A2AStarletteApplication(JSONRPCApplication):
2421
(SSE).
2522
"""
2623

27-
def __init__(
28-
self,
29-
agent_card: AgentCard,
30-
http_handler: RequestHandler,
31-
extended_agent_card: AgentCard | None = None,
32-
context_builder: CallContextBuilder | None = None,
33-
):
34-
"""Initializes the A2AStarletteApplication.
35-
36-
Args:
37-
agent_card: The AgentCard describing the agent's capabilities.
38-
http_handler: The handler instance responsible for processing A2A
39-
requests via http.
40-
extended_agent_card: An optional, distinct AgentCard to be served
41-
at the authenticated extended card endpoint.
42-
context_builder: The CallContextBuilder used to construct the
43-
ServerCallContext passed to the http_handler. If None, no
44-
ServerCallContext is passed.
45-
"""
46-
super().__init__(
47-
agent_card=agent_card,
48-
http_handler=http_handler,
49-
extended_agent_card=extended_agent_card,
50-
context_builder=context_builder,
51-
)
52-
5324
def routes(
5425
self,
5526
agent_card_url: str = '/.well-known/agent.json',
@@ -66,31 +37,10 @@ def routes(
6637
Returns:
6738
A list of Starlette Route objects.
6839
"""
69-
app_routes = [
70-
Route(
71-
rpc_url,
72-
self._handle_requests,
73-
methods=['POST'],
74-
name='a2a_handler',
75-
),
76-
Route(
77-
agent_card_url,
78-
self._handle_get_agent_card,
79-
methods=['GET'],
80-
name='agent_card',
81-
),
82-
]
83-
84-
if self.agent_card.supportsAuthenticatedExtendedCard:
85-
app_routes.append(
86-
Route(
87-
extended_agent_card_url,
88-
self._handle_get_authenticated_extended_agent_card,
89-
methods=['GET'],
90-
name='authenticated_extended_agent_card',
91-
)
92-
)
93-
return app_routes
40+
route_definitions = self._get_route_definitions(
41+
agent_card_url, rpc_url, extended_agent_card_url
42+
)
43+
return [Route(**route_def) for route_def in route_definitions]
9444

9545
def add_routes_to_app(
9646
self,
@@ -107,12 +57,12 @@ def add_routes_to_app(
10757
rpc_url: The URL path for the A2A JSON-RPC endpoint (POST requests).
10858
extended_agent_card_url: The URL for the authenticated extended agent card endpoint.
10959
"""
110-
routes = self.routes(
60+
app_routes = self.routes(
11161
agent_card_url=agent_card_url,
11262
rpc_url=rpc_url,
11363
extended_agent_card_url=extended_agent_card_url,
11464
)
115-
app.routes.extend(routes)
65+
app.routes.extend(app_routes)
11666

11767
def build(
11868
self,

0 commit comments

Comments
 (0)