6. Interacting with the Server¶
With the Helloworld A2A server running, let's send some requests to it.
The Helloworld Test Client¶
The test_client.py script demonstrates how to:
- Fetch the Agent Card from the server.
- Create a client using
create_client. - Send both
Send MessageandSend Streaming Messagerequests.
Open a new terminal window, activate your virtual environment, and navigate to the a2a-samples directory.
Activate the virtual environment (be sure to do this in the same directory where you created it):
Run the test client:
Understanding the Client Code¶
Let's look at key parts of test_client.py:
-
Fetching the Agent Card:
import httpx # noqa: PLC0415 from a2a.client import A2ACardResolver # noqa: PLC0415 # Initializes the A2ACardResolver instance with an HTTP client, base URL, # and uses the default path for the agent card. async with httpx.AsyncClient() as httpx_client: resolver = A2ACardResolver( httpx_client=httpx_client, base_url='http://127.0.0.1:9999', # Provide agent_card_path, if your agent uses a different path # agent_card_path='' # noqa: ERA001 ) public_agent_card = await resolver.get_agent_card()The
A2ACardResolverclass is a convenience. Whenget_agent_card()is called, it fetches theAgentCardfrom the server's/.well-known/agent-card.jsonendpoint (based on the provided base URL), which is then used to initialize the client. -
Initializing the Client & Sending a Non-Streaming Message:
from a2a.client import ClientConfig, create_client # noqa: PLC0415 from a2a.helpers import new_text_message # noqa: PLC0415 from a2a.types.a2a_pb2 import Role, SendMessageRequest # noqa: PLC0415 print('\nInitializing a non-streaming client.') config = ClientConfig(streaming=False) client = await create_client(agent=public_agent_card, client_config=config) # Creates a new text message to be sent to the A2A Server. # Ex: text_query = 'Why is the sky blue?' # noqa: ERA001 message = new_text_message(text_query, role=Role.ROLE_USER) request = SendMessageRequest(message=message) print('Response:') async for chunk in client.send_message(request): print(chunk)- The
create_clientfunction creates aClientbased on the information provided by theAgentCardand aClientConfig. - We construct a
Messageusing thenew_text_messagehelper (passingrole=Role.ROLE_USER), then wrap it in aSendMessageRequest. - The client's
send_messagemethod returns an async iterator that yields a single finalTaskorMessageresponse from the agent. In this example, it is aTask.
- The
-
Initializing the Client & Sending a Streaming Message:
print('\nInitializing a streaming client.') client_config = ClientConfig(streaming=True) # Streaming client = await create_client(agent=public_agent_card, client_config=client_config) print('Response:') async for chunk in client.send_message(request): print(chunk)- A separate streaming client is created via
create_clientwithstreaming=Truein itsClientConfig. - We again call
send_message, which now streams events: each iteration of the loop prints a discrete chunk as it arrives over the network. - Call
await streaming_client.close()after the loop to release the underlying HTTP connection.
- A separate streaming client is created via
Expected Output¶
When you run test_client.py, you'll see output for:
- The public agent card, displayed in a formatted summary.
- The non-streaming response: a single
taskin protobuf text format containing the completed status, the generated artifact with "Hello, World!", and the agent's intermediate status message in history. - The streaming response: four chunks — the initial
task, astatus_updatefor WORKING, anartifact_updatewith the result, and a finalstatus_updatefor COMPLETED. - The extended agent card, displayed in a formatted summary (with an additional
super_hello_worldskill).
The id fields in the output will vary with each run.
AgentCard
--- General ---
Name : Hello World Agent
Description : Just a hello world agent
Version : 0.0.1
--- Interfaces ---
[0] http://127.0.0.1:9999 (JSONRPC)
--- Capabilities ---
Streaming : True
Push notifications : False
Extended agent card : True
--- I/O Modes ---
Input : text/plain
Output : text/plain
--- Skills ---
----------------------------------------------------
ID : hello_world
Name : Returns hello world
Description : just returns hello world
Tags : hello world
Example : hi
Example : hello world
--- Non-Streaming Call ---
Non-streaming Client initialized.
Response:
// Non-streaming response
task {
id: "xxxxxxxx"
context_id: "yyyyyyyy"
status {
state: TASK_STATE_COMPLETED
}
artifacts {
artifact_id: "zzzzzzzz"
name: "result"
parts {
text: "Hello, World!"
}
}
history {
message_id: "vvvvvvvv"
context_id: "yyyyyyyy"
task_id: "xxxxxxxx"
role: ROLE_USER
parts {
text: "Say hello."
}
}
history {
message_id: "wwwwwwww"
role: ROLE_AGENT
parts {
text: "Processing request..."
}
}
}
// Streaming response
task {
id: "xxxxxxxx-s"
context_id: "yyyyyyyy-s"
status {
state: TASK_STATE_SUBMITTED
}
history {
message_id: "vvvvvvvv"
context_id: "yyyyyyyy-s"
task_id: "xxxxxxxx-s"
role: ROLE_USER
parts {
text: "Say hello."
}
}
}
Response chunk:
status_update {
task_id: "xxxxxxxx-s"
context_id: "yyyyyyyy-s"
status {
state: TASK_STATE_WORKING
message {
message_id: "zzzzzzzz-s"
role: ROLE_AGENT
parts {
text: "Processing request..."
}
}
}
}
Response chunk:
artifact_update {
task_id: "xxxxxxxx-s"
context_id: "yyyyyyyy-s"
artifact {
artifact_id: "wwwwwwww-s"
name: "result"
parts {
text: "Hello, World!"
}
}
}
Response chunk:
status_update {
task_id: "xxxxxxxx-s"
context_id: "yyyyyyyy-s"
status {
state: TASK_STATE_COMPLETED
}
}
AgentCard
--- General ---
Name : Hello World Agent - Extended Edition
Description : The full-featured hello world agent for authenticated users.
Version : 0.0.2
--- Interfaces ---
[0] http://127.0.0.1:9999 (JSONRPC)
--- Capabilities ---
Streaming : True
Push notifications : False
Extended agent card : True
--- I/O Modes ---
Input : text/plain
Output : text/plain
--- Skills ---
----------------------------------------------------
ID : hello_world
Name : Returns hello world
Description : just returns hello world
Tags : hello world
Example : hi
Example : hello world
----------------------------------------------------
ID : super_hello_world
Name : Returns a SUPER Hello World
Description : A more enthusiastic greeting, only for authenticated users.
Tags : hello world, super, extended
Example : super hi
Example : give me a super hello
(Actual IDs like xxxxxxxx, yyyyyyyy, zzzzzzzz, wwwwwwww, and vvvvvvvv will be different UUIDs in each run.)
This confirms your server is correctly handling basic A2A interactions with the updated SDK structure.
You can now shut down the server by pressing Ctrl+C in the terminal window where __main__.py is running.