|
3 | 3 | import logging |
4 | 4 |
|
5 | 5 | from collections.abc import Callable |
| 6 | +from typing import Any |
6 | 7 |
|
7 | 8 | import httpx |
8 | 9 |
|
9 | 10 | from a2a.client.base_client import BaseClient |
| 11 | +from a2a.client.card_resolver import A2ACardResolver |
10 | 12 | from a2a.client.client import Client, ClientConfig, Consumer |
11 | 13 | from a2a.client.middleware import ClientCallInterceptor |
12 | 14 | from a2a.client.transports.base import ClientTransport |
@@ -101,6 +103,61 @@ def _register_defaults( |
101 | 103 | GrpcTransport.create, |
102 | 104 | ) |
103 | 105 |
|
| 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 | + |
104 | 161 | def register(self, label: str, generator: TransportProducer) -> None: |
105 | 162 | """Register a new transport producer for a given transport label.""" |
106 | 163 | self._registry[label] = generator |
|
0 commit comments