@@ -88,114 +88,6 @@ def __init__(
8888 self ._registry : dict [str , TransportProducer ] = {}
8989 self ._register_defaults (config .supported_protocol_bindings )
9090
91- def register (self , label : str , generator : TransportProducer ) -> None :
92- """Register a new transport producer for a given transport label."""
93- self ._registry [label ] = generator
94-
95- def create (
96- self ,
97- card : AgentCard ,
98- interceptors : list [ClientCallInterceptor ] | None = None ,
99- ) -> Client :
100- """Create a new `Client` for the provided `AgentCard`.
101-
102- Args:
103- card: An `AgentCard` defining the characteristics of the agent.
104- interceptors: A list of interceptors to use for each request. These
105- are used for things like attaching credentials or http headers
106- to all outbound requests.
107-
108- Returns:
109- A `Client` object.
110-
111- Raises:
112- If there is no valid matching of the client configuration with the
113- server configuration, a `ValueError` is raised.
114- """
115- client_set = self ._config .supported_protocol_bindings or [
116- TransportProtocol .JSONRPC
117- ]
118- transport_protocol = None
119- selected_interface = None
120- if self ._config .use_client_preference :
121- for protocol_binding in client_set :
122- selected_interface = ClientFactory ._find_best_interface (
123- list (card .supported_interfaces ),
124- protocol_bindings = [protocol_binding ],
125- )
126- if selected_interface :
127- transport_protocol = protocol_binding
128- break
129- else :
130- for supported_interface in card .supported_interfaces :
131- if supported_interface .protocol_binding in client_set :
132- transport_protocol = supported_interface .protocol_binding
133- selected_interface = ClientFactory ._find_best_interface (
134- list (card .supported_interfaces ),
135- protocol_bindings = [transport_protocol ],
136- )
137- break
138- if not transport_protocol or not selected_interface :
139- raise ValueError ('no compatible transports found.' )
140- if transport_protocol not in self ._registry :
141- raise ValueError (f'no client available for { transport_protocol } ' )
142-
143- transport = self ._registry [transport_protocol ](
144- card , selected_interface .url , self ._config
145- )
146-
147- if selected_interface .tenant :
148- transport = TenantTransportDecorator (
149- transport , selected_interface .tenant
150- )
151-
152- return BaseClient (
153- card ,
154- self ._config ,
155- transport ,
156- interceptors or [],
157- )
158-
159- async def create_from_url (
160- self ,
161- url : str ,
162- interceptors : list [ClientCallInterceptor ] | None = None ,
163- relative_card_path : str | None = None ,
164- resolver_http_kwargs : dict [str , Any ] | None = None ,
165- signature_verifier : Callable [[AgentCard ], None ] | None = None ,
166- ) -> Client :
167- """Create a `Client` by resolving an `AgentCard` from a URL.
168-
169- Resolves the agent card from the given URL using the factory's
170- configured httpx client, then creates a client via `create`.
171-
172- If the agent card is already available, use `create` directly
173- instead.
174-
175- Args:
176- url: The base URL of the agent. The agent card will be fetched
177- from `<url>/.well-known/agent-card.json` by default.
178- interceptors: A list of interceptors to use for each request.
179- These are used for things like attaching credentials or http
180- headers to all outbound requests.
181- relative_card_path: The relative path when resolving the agent
182- card. See `A2ACardResolver.get_agent_card` for details.
183- resolver_http_kwargs: Dictionary of arguments to provide to the
184- httpx client when resolving the agent card.
185- signature_verifier: A callable used to verify the agent card's
186- signatures.
187-
188- Returns:
189- A `Client` object.
190- """
191- resolver = A2ACardResolver (self ._httpx_client , url )
192- card = await resolver .get_agent_card (
193- relative_card_path = relative_card_path ,
194- http_kwargs = resolver_http_kwargs ,
195- signature_verifier = signature_verifier ,
196- )
197- return self .create (card , interceptors )
198-
19991 def _register_defaults (self , supported : list [str ]) -> None :
20092 # Empty support list implies JSON-RPC only.
20193
@@ -363,6 +255,114 @@ def _find_best_interface(
363255
364256 return best_gt_1_0 or best_ge_0_3 or best_no_version
365257
258+ async def create_from_url (
259+ self ,
260+ url : str ,
261+ interceptors : list [ClientCallInterceptor ] | None = None ,
262+ relative_card_path : str | None = None ,
263+ resolver_http_kwargs : dict [str , Any ] | None = None ,
264+ signature_verifier : Callable [[AgentCard ], None ] | None = None ,
265+ ) -> Client :
266+ """Create a `Client` by resolving an `AgentCard` from a URL.
267+
268+ Resolves the agent card from the given URL using the factory's
269+ configured httpx client, then creates a client via `create`.
270+
271+ If the agent card is already available, use `create` directly
272+ instead.
273+
274+ Args:
275+ url: The base URL of the agent. The agent card will be fetched
276+ from `<url>/.well-known/agent-card.json` by default.
277+ interceptors: A list of interceptors to use for each request.
278+ These are used for things like attaching credentials or http
279+ headers to all outbound requests.
280+ relative_card_path: The relative path when resolving the agent
281+ card. See `A2ACardResolver.get_agent_card` for details.
282+ resolver_http_kwargs: Dictionary of arguments to provide to the
283+ httpx client when resolving the agent card.
284+ signature_verifier: A callable used to verify the agent card's
285+ signatures.
286+
287+ Returns:
288+ A `Client` object.
289+ """
290+ resolver = A2ACardResolver (self ._httpx_client , url )
291+ card = await resolver .get_agent_card (
292+ relative_card_path = relative_card_path ,
293+ http_kwargs = resolver_http_kwargs ,
294+ signature_verifier = signature_verifier ,
295+ )
296+ return self .create (card , interceptors )
297+
298+ def register (self , label : str , generator : TransportProducer ) -> None :
299+ """Register a new transport producer for a given transport label."""
300+ self ._registry [label ] = generator
301+
302+ def create (
303+ self ,
304+ card : AgentCard ,
305+ interceptors : list [ClientCallInterceptor ] | None = None ,
306+ ) -> Client :
307+ """Create a new `Client` for the provided `AgentCard`.
308+
309+ Args:
310+ card: An `AgentCard` defining the characteristics of the agent.
311+ interceptors: A list of interceptors to use for each request. These
312+ are used for things like attaching credentials or http headers
313+ to all outbound requests.
314+
315+ Returns:
316+ A `Client` object.
317+
318+ Raises:
319+ If there is no valid matching of the client configuration with the
320+ server configuration, a `ValueError` is raised.
321+ """
322+ client_set = self ._config .supported_protocol_bindings or [
323+ TransportProtocol .JSONRPC
324+ ]
325+ transport_protocol = None
326+ selected_interface = None
327+ if self ._config .use_client_preference :
328+ for protocol_binding in client_set :
329+ selected_interface = ClientFactory ._find_best_interface (
330+ list (card .supported_interfaces ),
331+ protocol_bindings = [protocol_binding ],
332+ )
333+ if selected_interface :
334+ transport_protocol = protocol_binding
335+ break
336+ else :
337+ for supported_interface in card .supported_interfaces :
338+ if supported_interface .protocol_binding in client_set :
339+ transport_protocol = supported_interface .protocol_binding
340+ selected_interface = ClientFactory ._find_best_interface (
341+ list (card .supported_interfaces ),
342+ protocol_bindings = [transport_protocol ],
343+ )
344+ break
345+ if not transport_protocol or not selected_interface :
346+ raise ValueError ('no compatible transports found.' )
347+ if transport_protocol not in self ._registry :
348+ raise ValueError (f'no client available for { transport_protocol } ' )
349+
350+ transport = self ._registry [transport_protocol ](
351+ card , selected_interface .url , self ._config
352+ )
353+
354+ if selected_interface .tenant :
355+ transport = TenantTransportDecorator (
356+ transport , selected_interface .tenant
357+ )
358+
359+ return BaseClient (
360+ card ,
361+ self ._config ,
362+ transport ,
363+ interceptors or [],
364+ )
365+
366366
367367async def create_client ( # noqa: PLR0913
368368 agent : str | AgentCard ,
0 commit comments