Skip to content

Commit 7b2471d

Browse files
committed
make extended_card_modifier async
1 parent ffe31e2 commit 7b2471d

3 files changed

Lines changed: 33 additions & 19 deletions

File tree

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import logging
2-
3-
from collections.abc import Callable
2+
from collections.abc import Awaitable, Callable
43
from typing import TYPE_CHECKING, Any
54

6-
75
if TYPE_CHECKING:
86
from fastapi import APIRouter, FastAPI, Request, Response
97
from fastapi.responses import JSONResponse
@@ -31,7 +29,6 @@
3129
from a2a.types import AgentCard
3230
from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
3331

34-
3532
logger = logging.getLogger(__name__)
3633

3734

@@ -51,7 +48,7 @@ def __init__( # noqa: PLR0913
5148
context_builder: CallContextBuilder | None = None,
5249
card_modifier: Callable[[AgentCard], AgentCard] | None = None,
5350
extended_card_modifier: Callable[
54-
[AgentCard, ServerCallContext], AgentCard
51+
[AgentCard, ServerCallContext], Awaitable[AgentCard]
5552
]
5653
| None = None,
5754
):
@@ -68,7 +65,7 @@ def __init__( # noqa: PLR0913
6865
ServerCallContext is passed.
6966
card_modifier: An optional callback to dynamically modify the public
7067
agent card before it is served.
71-
extended_card_modifier: An optional callback to dynamically modify
68+
extended_card_modifier: An optional async callback to dynamically modify
7269
the extended agent card before it is served. It receives the
7370
call context.
7471
"""

src/a2a/server/apps/rest/rest_adapter.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def __init__( # noqa: PLR0913
6060
context_builder: CallContextBuilder | None = None,
6161
card_modifier: Callable[[AgentCard], AgentCard] | None = None,
6262
extended_card_modifier: Callable[
63-
[AgentCard, ServerCallContext], AgentCard
63+
[AgentCard, ServerCallContext], Awaitable[AgentCard]
6464
]
6565
| None = None,
6666
):
@@ -77,9 +77,9 @@ def __init__( # noqa: PLR0913
7777
ServerCallContext is passed.
7878
card_modifier: An optional callback to dynamically modify the public
7979
agent card before it is served.
80-
extended_card_modifier: An optional callback to dynamically modify
81-
the extended agent card before it is served. It receives the
82-
call context.
80+
extended_card_modifier: An optional async callback to dynamically
81+
modify the extended agent card before it is served. It receives
82+
the call context.
8383
"""
8484
if not _package_starlette_installed:
8585
raise ImportError(
@@ -182,7 +182,9 @@ async def handle_authenticated_agent_card(
182182

183183
if self.extended_card_modifier:
184184
context = self._context_builder.build(request)
185-
card_to_serve = self.extended_card_modifier(card_to_serve, context)
185+
card_to_serve = await self.extended_card_modifier(
186+
card_to_serve, context
187+
)
186188
elif self.card_modifier:
187189
card_to_serve = self.card_modifier(card_to_serve)
188190

tests/server/apps/rest/test_rest_fastapi_app.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import logging
2-
2+
from collections.abc import Awaitable, Callable
33
from typing import Any
44
from unittest.mock import MagicMock
55

66
import pytest
7-
87
from fastapi import FastAPI
98
from google.protobuf import json_format
109
from httpx import ASGITransport, AsyncClient
@@ -13,6 +12,7 @@
1312
from a2a.server.apps.rest import fastapi_app, rest_adapter
1413
from a2a.server.apps.rest.fastapi_app import A2ARESTFastAPIApplication
1514
from a2a.server.apps.rest.rest_adapter import RESTAdapter
15+
from a2a.server.context import ServerCallContext
1616
from a2a.server.request_handlers.request_handler import RequestHandler
1717
from a2a.types import (
1818
AgentCard,
@@ -25,15 +25,14 @@
2525
TextPart,
2626
)
2727

28-
2928
logger = logging.getLogger(__name__)
3029

3130

3231
@pytest.fixture
3332
async def agent_card() -> AgentCard:
3433
mock_agent_card = MagicMock(spec=AgentCard)
3534
mock_agent_card.url = 'http://mockurl.com'
36-
mock_agent_card.supports_authenticated_extended_card = False
35+
mock_agent_card.supports_authenticated_extended_card = True
3736

3837
# Mock the capabilities object with streaming disabled
3938
mock_capabilities = MagicMock()
@@ -58,6 +57,15 @@ async def streaming_agent_card() -> AgentCard:
5857
return mock_agent_card
5958

6059

60+
@pytest.fixture
61+
async def extended_card_modifier() -> Callable[
62+
[AgentCard, ServerCallContext], Awaitable[AgentCard]
63+
]:
64+
return MagicMock(
65+
spec=Callable[[AgentCard, ServerCallContext], Awaitable[AgentCard]]
66+
)
67+
68+
6169
@pytest.fixture
6270
async def request_handler() -> RequestHandler:
6371
return MagicMock(spec=RequestHandler)
@@ -84,13 +92,20 @@ async def streaming_client(streaming_app: FastAPI) -> AsyncClient:
8492

8593
@pytest.fixture
8694
async def app(
87-
agent_card: AgentCard, request_handler: RequestHandler
95+
agent_card: AgentCard,
96+
request_handler: RequestHandler,
97+
extended_card_modifier: Callable[
98+
[AgentCard, ServerCallContext], Awaitable[AgentCard]
99+
],
88100
) -> FastAPI:
89101
"""Builds the FastAPI application for testing."""
90102

91-
return A2ARESTFastAPIApplication(agent_card, request_handler).build(
92-
agent_card_url='/well-known/agent.json', rpc_url=''
93-
)
103+
return A2ARESTFastAPIApplication(
104+
agent_card,
105+
request_handler,
106+
extended_agent_card=agent_card,
107+
extended_card_modifier=extended_card_modifier,
108+
).build(agent_card_url='/well-known/agent.json', rpc_url='')
94109

95110

96111
@pytest.fixture

0 commit comments

Comments
 (0)