Skip to content

Commit 0e50e7e

Browse files
committed
Implement a convenience method for constructing clients
1 parent 051ab20 commit 0e50e7e

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

src/a2a/client/client_factory.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import logging
44

55
from collections.abc import Callable
6+
from typing import Any
67

78
import httpx
89

910
from a2a.client.base_client import BaseClient
11+
from a2a.client.card_resolver import A2ACardResolver
1012
from a2a.client.client import Client, ClientConfig, Consumer
1113
from a2a.client.middleware import ClientCallInterceptor
1214
from a2a.client.transports.base import ClientTransport
@@ -101,6 +103,61 @@ def _register_defaults(
101103
GrpcTransport.create,
102104
)
103105

106+
@classmethod
107+
async def connect( # noqa: PLR0913
108+
cls,
109+
agent: str | AgentCard,
110+
client_config: ClientConfig | None = None,
111+
consumers: list[Consumer] | None = None,
112+
interceptors: list[ClientCallInterceptor] | None = None,
113+
relative_card_path: str | None = None,
114+
resolver_http_kwargs: dict[str, Any] | None = None,
115+
extra_transports: dict[str, TransportProducer] | None = None,
116+
) -> Client:
117+
"""Convenience method for constructing a client.
118+
119+
Constructs a client that connects to the specified agent. Note that
120+
creating multiple clients via this method is less efficient than
121+
constructing an instance of ClientFactory and reusing that.
122+
123+
Args:
124+
agent: The base URL of the agent, or the AgentCard to connect to.
125+
client_config: The ClientConfig to use when connecting to the agent.
126+
consumers: A list of `Consumer` methods to pass responses to.
127+
interceptors: A list of interceptors to use for each request. These
128+
are used for things like attaching credentials or http headers
129+
to all outbound requests.
130+
relative_card_path: If the agent field is a URL, this value is used as
131+
the relative path when resolving the agent card. See
132+
A2AAgentCardResolver.get_agent_card for more details.
133+
resolver_http_kwargs: Dictionary of arguments to provide to the httpx
134+
client when resolving the agent card. This value is provided to
135+
A2AAgentCardResolver.get_agent_card as the http_kwargs parameter.
136+
extra_transports: Additional transport protocols to enable when
137+
constructing the client.
138+
139+
Returns:
140+
A `Client` object.
141+
"""
142+
client_config = client_config or ClientConfig()
143+
if isinstance(agent, str):
144+
if not client_config.httpx_client:
145+
async with httpx.AsyncClient() as client:
146+
resolver = A2ACardResolver(client, agent)
147+
card = await resolver.get_agent_card()
148+
else:
149+
resolver = A2ACardResolver(client_config.httpx_client, agent)
150+
card = await resolver.get_agent_card(
151+
relative_card_path=relative_card_path,
152+
http_kwargs=resolver_http_kwargs,
153+
)
154+
else:
155+
card = agent
156+
factory = cls(client_config)
157+
for label, generator in (extra_transports or {}).items():
158+
factory.register(label, generator)
159+
return factory.create(card, consumers, interceptors)
160+
104161
def register(self, label: str, generator: TransportProducer) -> None:
105162
"""Register a new transport producer for a given transport label."""
106163
self._registry[label] = generator

0 commit comments

Comments
 (0)