Skip to content

Commit 921651b

Browse files
committed
fix
1 parent 04dd40b commit 921651b

16 files changed

Lines changed: 157 additions & 241 deletions

samples/hello_world_agent.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from a2a.server.request_handlers.default_request_handler import (
1818
DefaultRequestHandler,
1919
)
20-
from a2a.server.routes import AgentCardRoutes, JsonRpcRoutes
20+
from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
2121
from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore
2222
from a2a.server.tasks.task_updater import TaskUpdater
2323
from a2a.types import (
@@ -198,17 +198,17 @@ async def serve(
198198
)
199199
rest_app = rest_app_builder.build()
200200

201-
jsonrpc_routes = JsonRpcRoutes(
201+
jsonrpc_routes = create_jsonrpc_routes(
202202
agent_card=agent_card,
203203
request_handler=request_handler,
204204
rpc_url='/a2a/jsonrpc/',
205205
)
206-
agent_card_routes = AgentCardRoutes(
206+
agent_card_routes = create_agent_card_routes(
207207
agent_card=agent_card,
208208
)
209209
app = FastAPI()
210-
app.routes.extend(jsonrpc_routes.routes)
211-
app.routes.extend(agent_card_routes.routes)
210+
app.routes.extend(jsonrpc_routes)
211+
app.routes.extend(agent_card_routes)
212212
app.mount('/a2a/rest', rest_app)
213213

214214
grpc_server = grpc.aio.server()

src/a2a/server/routes/__init__.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
"""A2A Routes."""
22

3-
from a2a.server.routes.agent_card_routes import AgentCardRoutes
3+
from a2a.server.routes.agent_card_routes import create_agent_card_routes
44
from a2a.server.routes.jsonrpc_dispatcher import (
55
CallContextBuilder,
66
DefaultCallContextBuilder,
7-
JsonRpcDispatcher,
8-
StarletteUserProxy,
97
)
10-
from a2a.server.routes.jsonrpc_routes import JsonRpcRoutes
8+
from a2a.server.routes.jsonrpc_routes import create_jsonrpc_routes
119

1210

1311
__all__ = [
14-
'AgentCardRoutes',
12+
'create_agent_card_routes',
1513
'CallContextBuilder',
1614
'DefaultCallContextBuilder',
17-
'JsonRpcDispatcher',
18-
'JsonRpcRoutes',
19-
'StarletteUserProxy',
15+
'create_jsonrpc_routes',
2016
]

src/a2a/server/routes/agent_card_routes.py

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -37,47 +37,29 @@
3737
logger = logging.getLogger(__name__)
3838

3939

40-
class AgentCardRoutes:
41-
"""Provides the Starlette Route for the A2A protocol agent card endpoint."""
42-
43-
def __init__(
44-
self,
45-
agent_card: AgentCard,
46-
card_modifier: Callable[[AgentCard], Awaitable[AgentCard] | AgentCard]
47-
| None = None,
48-
card_url: str = AGENT_CARD_WELL_KNOWN_PATH,
49-
middleware: Sequence['Middleware'] | None = None,
50-
) -> None:
51-
"""Initializes the AgentCardRoute.
52-
53-
Args:
54-
agent_card: The AgentCard describing the agent's capabilities.
55-
card_modifier: An optional callback to dynamically modify the public
56-
agent card before it is served.
57-
card_url: The URL for the agent card endpoint.
58-
middleware: An optional list of Starlette middleware to apply to the
59-
agent card endpoint.
60-
"""
61-
if not _package_starlette_installed:
62-
raise ImportError(
63-
'The `starlette` package is required to use `AgentCardRoutes`. '
64-
'It can be installed as part of `a2a-sdk` optional dependencies, `a2a-sdk[http-server]`.'
65-
)
66-
67-
self.agent_card = agent_card
68-
self.card_modifier = card_modifier
69-
70-
self.routes = [
71-
Route(
72-
path=card_url,
73-
endpoint=self._get_agent_card,
74-
methods=['GET'],
75-
middleware=middleware,
76-
)
77-
]
78-
79-
async def _get_agent_card(self, request: Request) -> Response:
80-
card_to_serve = self.agent_card
81-
if self.card_modifier:
82-
card_to_serve = await maybe_await(self.card_modifier(card_to_serve))
40+
def create_agent_card_routes(
41+
agent_card: AgentCard,
42+
card_modifier: Callable[[AgentCard], Awaitable[AgentCard] | AgentCard]
43+
| None = None,
44+
card_url: str = AGENT_CARD_WELL_KNOWN_PATH,
45+
) -> list['Route']:
46+
"""Creates the Starlette Route for the A2A protocol agent card endpoint."""
47+
if not _package_starlette_installed:
48+
raise ImportError(
49+
'The `starlette` package is required to use `create_agent_card_routes`. '
50+
'It can be installed as part of `a2a-sdk` optional dependencies, `a2a-sdk[http-server]`.'
51+
)
52+
53+
async def _get_agent_card(request: Request) -> Response:
54+
card_to_serve = agent_card
55+
if card_modifier:
56+
card_to_serve = await maybe_await(card_modifier(card_to_serve))
8357
return JSONResponse(agent_card_to_dict(card_to_serve))
58+
59+
return [
60+
Route(
61+
path=card_url,
62+
endpoint=_get_agent_card,
63+
methods=['GET'],
64+
)
65+
]

src/a2a/server/routes/jsonrpc_routes.py

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -36,72 +36,64 @@
3636
logger = logging.getLogger(__name__)
3737

3838

39-
class JsonRpcRoutes:
40-
"""Provides the Starlette Route for the A2A protocol JSON-RPC endpoint.
39+
def create_jsonrpc_routes( # noqa: PLR0913
40+
agent_card: AgentCard,
41+
request_handler: RequestHandler,
42+
extended_agent_card: AgentCard | None = None,
43+
context_builder: CallContextBuilder | None = None,
44+
card_modifier: Callable[[AgentCard], Awaitable[AgentCard] | AgentCard]
45+
| None = None,
46+
extended_card_modifier: Callable[
47+
[AgentCard, ServerCallContext], Awaitable[AgentCard] | AgentCard
48+
]
49+
| None = None,
50+
enable_v0_3_compat: bool = False,
51+
rpc_url: str = DEFAULT_RPC_URL,
52+
) -> list['Route']:
53+
"""Creates the Starlette Route for the A2A protocol JSON-RPC endpoint.
4154
4255
Handles incoming JSON-RPC requests, routes them to the appropriate
4356
handler methods, and manages response generation including Server-Sent Events
4457
(SSE).
45-
"""
4658
47-
def __init__( # noqa: PLR0913
48-
self,
49-
agent_card: AgentCard,
50-
request_handler: RequestHandler,
51-
extended_agent_card: AgentCard | None = None,
52-
context_builder: CallContextBuilder | None = None,
53-
card_modifier: Callable[[AgentCard], Awaitable[AgentCard] | AgentCard]
54-
| None = None,
55-
extended_card_modifier: Callable[
56-
[AgentCard, ServerCallContext], Awaitable[AgentCard] | AgentCard
57-
]
58-
| None = None,
59-
enable_v0_3_compat: bool = False,
60-
rpc_url: str = DEFAULT_RPC_URL,
61-
middleware: Sequence[Middleware] | None = None,
62-
) -> None:
63-
"""Initializes the JsonRpcRoute.
64-
65-
Args:
66-
agent_card: The AgentCard describing the agent's capabilities.
67-
request_handler: The handler instance responsible for processing A2A
68-
requests via http.
69-
extended_agent_card: An optional, distinct AgentCard to be served
70-
at the authenticated extended card endpoint.
71-
context_builder: The CallContextBuilder used to construct the
72-
ServerCallContext passed to the request_handler. If None, no
73-
ServerCallContext is passed.
74-
card_modifier: An optional callback to dynamically modify the public
75-
agent card before it is served.
76-
extended_card_modifier: An optional callback to dynamically modify
77-
the extended agent card before it is served. It receives the
78-
call context.
79-
enable_v0_3_compat: Whether to enable v0.3 backward compatibility on the same endpoint.
80-
rpc_url: The URL prefix for the RPC endpoints.
81-
middleware: An optional list of Starlette middleware to apply to the routes.
82-
"""
83-
if not _package_starlette_installed:
84-
raise ImportError(
85-
'The `starlette` package is required to use the `JsonRpcRoutes`.'
86-
' It can be added as a part of `a2a-sdk` optional dependencies,'
87-
' `a2a-sdk[http-server]`.'
88-
)
89-
90-
self.dispatcher = JsonRpcDispatcher(
91-
agent_card=agent_card,
92-
http_handler=request_handler,
93-
extended_agent_card=extended_agent_card,
94-
context_builder=context_builder,
95-
card_modifier=card_modifier,
96-
extended_card_modifier=extended_card_modifier,
97-
enable_v0_3_compat=enable_v0_3_compat,
59+
Args:
60+
agent_card: The AgentCard describing the agent's capabilities.
61+
request_handler: The handler instance responsible for processing A2A
62+
requests via http.
63+
extended_agent_card: An optional, distinct AgentCard to be served
64+
at the authenticated extended card endpoint.
65+
context_builder: The CallContextBuilder used to construct the
66+
ServerCallContext passed to the request_handler. If None, no
67+
ServerCallContext is passed.
68+
card_modifier: An optional callback to dynamically modify the public
69+
agent card before it is served.
70+
extended_card_modifier: An optional callback to dynamically modify
71+
the extended agent card before it is served. It receives the
72+
call context.
73+
enable_v0_3_compat: Whether to enable v0.3 backward compatibility on the same endpoint.
74+
rpc_url: The URL prefix for the RPC endpoints.
75+
"""
76+
if not _package_starlette_installed:
77+
raise ImportError(
78+
'The `starlette` package is required to use `create_jsonrpc_routes`.'
79+
' It can be added as a part of `a2a-sdk` optional dependencies,'
80+
' `a2a-sdk[http-server]`.'
9881
)
9982

100-
self.routes = [
101-
Route(
102-
path=rpc_url,
103-
endpoint=self.dispatcher.handle_requests,
104-
methods=['POST'],
105-
middleware=middleware,
106-
)
107-
]
83+
dispatcher = JsonRpcDispatcher(
84+
agent_card=agent_card,
85+
http_handler=request_handler,
86+
extended_agent_card=extended_agent_card,
87+
context_builder=context_builder,
88+
card_modifier=card_modifier,
89+
extended_card_modifier=extended_card_modifier,
90+
enable_v0_3_compat=enable_v0_3_compat,
91+
)
92+
93+
return [
94+
Route(
95+
path=rpc_url,
96+
endpoint=dispatcher.handle_requests,
97+
methods=['POST'],
98+
)
99+
]

tck/sut_agent.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
)
2626
from a2a.server.request_handlers.grpc_handler import GrpcHandler
2727
from a2a.server.routes import (
28-
AgentCardRoutes,
29-
JsonRpcRoutes,
28+
create_agent_card_routes,
29+
create_jsonrpc_routes,
3030
)
3131
from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore
3232
from a2a.server.tasks.task_store import TaskStore
@@ -200,18 +200,18 @@ def serve(task_store: TaskStore) -> None:
200200
)
201201

202202
# JSONRPC
203-
jsonrpc_routes = JsonRpcRoutes(
203+
jsonrpc_routes = create_jsonrpc_routes(
204204
agent_card=agent_card,
205205
request_handler=request_handler,
206206
rpc_url=JSONRPC_URL,
207207
)
208208
# Agent Card
209-
agent_card_routes = AgentCardRoutes(
209+
agent_card_routes = create_agent_card_routes(
210210
agent_card=agent_card,
211211
)
212212
routes = [
213-
*jsonrpc_routes.routes,
214-
*agent_card_routes.routes,
213+
*jsonrpc_routes,
214+
*agent_card_routes,
215215
]
216216

217217
main_app = Starlette(routes=routes)

tests/compat/v0_3/test_jsonrpc_app_compat.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from starlette.testclient import TestClient
88

99
from starlette.applications import Starlette
10-
from a2a.server.routes import JsonRpcRoutes
10+
from a2a.server.routes import create_jsonrpc_routes
1111
from a2a.server.request_handlers.request_handler import RequestHandler
1212
from a2a.types.a2a_pb2 import (
1313
AgentCard,
@@ -51,13 +51,13 @@ def test_app(mock_handler):
5151
mock_agent_card.capabilities.streaming = False
5252
mock_agent_card.capabilities.push_notifications = True
5353
mock_agent_card.capabilities.extended_agent_card = True
54-
jsonrpc_routes = JsonRpcRoutes(
54+
jsonrpc_routes = create_jsonrpc_routes(
5555
agent_card=mock_agent_card,
5656
request_handler=mock_handler,
5757
enable_v0_3_compat=True,
5858
rpc_url='/',
5959
)
60-
return Starlette(routes=jsonrpc_routes.routes)
60+
return Starlette(routes=jsonrpc_routes)
6161

6262

6363
@pytest.fixture

tests/integration/cross_version/client_server/server_1_0.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import grpc
66

77
from a2a.server.agent_execution import AgentExecutor, RequestContext
8-
from a2a.server.routes import AgentCardRoutes, JsonRpcRoutes
8+
from a2a.server.routes import AgentCardRoutes, create_jsonrpc_routes
99
from a2a.server.apps import A2ARESTFastAPIApplication
1010
from a2a.server.events import EventQueue
1111
from a2a.server.events.in_memory_queue_manager import InMemoryQueueManager
@@ -170,7 +170,7 @@ async def main_async(http_port: int, grpc_port: int):
170170
agent_card_routes = AgentCardRoutes(
171171
agent_card=agent_card, card_url='/.well-known/agent-card.json'
172172
)
173-
jsonrpc_routes = JsonRpcRoutes(
173+
jsonrpc_routes = create_jsonrpc_routes(
174174
agent_card=agent_card,
175175
request_handler=handler,
176176
extended_agent_card=agent_card,
@@ -179,7 +179,7 @@ async def main_async(http_port: int, grpc_port: int):
179179
)
180180
app.mount(
181181
'/jsonrpc',
182-
FastAPI(routes=jsonrpc_routes.routes + agent_card_routes.routes),
182+
FastAPI(routes=jsonrpc_routes + agent_card_routes.routes),
183183
)
184184

185185
app.mount(

tests/integration/test_agent_card.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from a2a.server.agent_execution import AgentExecutor, RequestContext
77
from starlette.applications import Starlette
88
from a2a.server.apps import A2ARESTFastAPIApplication
9-
from a2a.server.routes import AgentCardRoutes, JsonRpcRoutes
9+
from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
1010
from a2a.server.events import EventQueue
1111
from a2a.server.events.in_memory_queue_manager import InMemoryQueueManager
1212
from a2a.server.request_handlers import DefaultRequestHandler
@@ -73,12 +73,12 @@ async def test_agent_card_integration(header_val: str | None) -> None:
7373

7474
# Mount JSONRPC application
7575
jsonrpc_routes = [
76-
*AgentCardRoutes(
76+
*create_agent_card_routes(
7777
agent_card=agent_card, card_url='/.well-known/agent-card.json'
78-
).routes,
79-
*JsonRpcRoutes(
78+
),
79+
*create_jsonrpc_routes(
8080
agent_card=agent_card, request_handler=handler, rpc_url='/'
81-
).routes,
81+
),
8282
]
8383
jsonrpc_app = Starlette(routes=jsonrpc_routes)
8484
app.mount('/jsonrpc', jsonrpc_app)

0 commit comments

Comments
 (0)