1+ import contextlib
12import json
23import logging
34import traceback
5+
46from abc import ABC , abstractmethod
57from collections .abc import AsyncGenerator
68from typing import Any
79
810from pydantic import ValidationError
911from sse_starlette .sse import EventSourceResponse
1012from starlette .applications import Starlette
13+ from starlette .authentication import BaseUser
1114from starlette .requests import Request
1215from starlette .responses import JSONResponse , Response
1316from starlette .routing import Route
1417
18+ from a2a .auth .user import UnauthenticatedUser
19+ from a2a .auth .user import User as A2AUser
1520from a2a .server .context import ServerCallContext
1621from a2a .server .request_handlers .jsonrpc_handler import JSONRPCHandler
1722from a2a .server .request_handlers .request_handler import RequestHandler
18- from a2a .types import (A2AError , A2ARequest , AgentCard , CancelTaskRequest ,
19- GetTaskPushNotificationConfigRequest , GetTaskRequest ,
20- InternalError , InvalidRequestError , JSONParseError ,
21- JSONRPCError , JSONRPCErrorResponse , JSONRPCResponse ,
22- SendMessageRequest , SendStreamingMessageRequest ,
23- SendStreamingMessageResponse ,
24- SetTaskPushNotificationConfigRequest ,
25- TaskResubscriptionRequest , UnsupportedOperationError )
23+ from a2a .types import (
24+ A2AError ,
25+ A2ARequest ,
26+ AgentCard ,
27+ CancelTaskRequest ,
28+ GetTaskPushNotificationConfigRequest ,
29+ GetTaskRequest ,
30+ InternalError ,
31+ InvalidRequestError ,
32+ JSONParseError ,
33+ JSONRPCError ,
34+ JSONRPCErrorResponse ,
35+ JSONRPCResponse ,
36+ SendMessageRequest ,
37+ SendStreamingMessageRequest ,
38+ SendStreamingMessageResponse ,
39+ SetTaskPushNotificationConfigRequest ,
40+ TaskResubscriptionRequest ,
41+ UnsupportedOperationError ,
42+ )
2643from a2a .utils .errors import MethodNotImplementedError
2744
45+
2846logger = logging .getLogger (__name__ )
2947
48+ # Register Starlette User as an implementation of a2a.auth.user.User
49+ A2AUser .register (BaseUser )
50+
3051
3152class CallContextBuilder (ABC ):
3253 """A class for building ServerCallContexts using the Starlette Request."""
@@ -36,6 +57,18 @@ def build(self, request: Request) -> ServerCallContext:
3657 """Builds a ServerCallContext from a Starlette Request."""
3758
3859
60+ class DefaultCallContextBuilder (CallContextBuilder ):
61+ """A default implementation of CallContextBuilder."""
62+
63+ def build (self , request : Request ) -> ServerCallContext :
64+ user = UnauthenticatedUser ()
65+ state = {}
66+ with contextlib .suppress (Exception ):
67+ user = request .user
68+ state ['auth' ] = request .auth
69+ return ServerCallContext (user = user , state = state )
70+
71+
3972class A2AStarletteApplication :
4073 """A Starlette application implementing the A2A protocol server endpoints.
4174
@@ -75,7 +108,7 @@ def __init__(
75108 logger .error (
76109 'AgentCard.supportsAuthenticatedExtendedCard is True, but no extended_agent_card was provided. The /agent/authenticatedExtendedCard endpoint will return 404.'
77110 )
78- self ._context_builder = context_builder
111+ self ._context_builder = context_builder or DefaultCallContextBuilder ()
79112
80113 def _generate_error_response (
81114 self , request_id : str | int | None , error : JSONRPCError | A2AError
@@ -137,11 +170,7 @@ async def _handle_requests(self, request: Request) -> Response:
137170 try :
138171 body = await request .json ()
139172 a2a_request = A2ARequest .model_validate (body )
140- call_context = (
141- self ._context_builder .build (request )
142- if self ._context_builder
143- else None
144- )
173+ call_context = self ._context_builder .build (request )
145174
146175 request_id = a2a_request .root .id
147176 request_obj = a2a_request .root
@@ -344,7 +373,9 @@ async def _handle_get_authenticated_extended_agent_card(
344373 # extended_agent_card was provided during server initialization,
345374 # return a 404
346375 return JSONResponse (
347- {'error' : 'Authenticated extended agent card is supported but not configured on the server.' },
376+ {
377+ 'error' : 'Authenticated extended agent card is supported but not configured on the server.'
378+ },
348379 status_code = 404 ,
349380 )
350381
0 commit comments