API Examples¶
This page provides practical examples of using the A2A Registry API with different protocols and programming languages.
REST API Examples¶
Python with requests¶
import requests
import json
# Base URL for the registry
BASE_URL = "http://localhost:8000"
# 1. Register an agent
agent_card = {
"agent_card": {
"name": "weather-service",
"description": "Provides weather information and forecasts",
"url": "http://weather-agent.example.com:3000",
"version": "0.420.0",
"protocol_version": "0.3.0",
"skills": [
{
"id": "get_current_weather",
"description": "Get current weather conditions for a location"
},
{
"id": "get_forecast",
"description": "Get weather forecast for upcoming days"
}
]
}
}
response = requests.post(f"{BASE_URL}/agents", json=agent_card)
print(f"Registration: {response.json()}")
# 2. List all agents
response = requests.get(f"{BASE_URL}/agents")
agents = response.json()
print(f"Found {agents['count']} agents")
# 3. Search for weather-related agents
search_request = {"query": "weather"}
response = requests.post(f"{BASE_URL}/agents/search", json=search_request)
results = response.json()
print(f"Weather agents: {len(results['agents'])}")
# 4. Get specific agent
agent_id = "weather-service"
response = requests.get(f"{BASE_URL}/agents/{agent_id}")
if response.status_code == 200:
agent = response.json()
print(f"Agent URL: {agent['agent_card']['url']}")
# 5. Unregister agent
response = requests.delete(f"{BASE_URL}/agents/{agent_id}")
print(f"Unregistration: {response.json()}")
JavaScript/Node.js with fetch¶
// 1. Register an agent
const agentCard = {
agent_card: {
name: "translation-service",
description: "Multi-language translation agent",
url: "http://translator.example.com:4000",
version: "0.420.0",
protocol_version: "0.3.0",
skills: [
{
id: "translate_text",
description: "Translate text between languages"
},
{
id: "detect_language",
description: "Detect the language of input text"
}
]
}
};
const response = await fetch('http://localhost:8000/agents', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(agentCard)
});
const result = await response.json();
console.log('Registration result:', result);
// 2. Search for translation agents
const searchResponse = await fetch('http://localhost:8000/agents/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: 'translate' })
});
const searchResults = await searchResponse.json();
console.log(`Found ${searchResults.count} translation agents`);
cURL Examples¶
# 1. Health check
curl http://localhost:8000/health
# 2. Register an agent
curl -X POST http://localhost:8000/agents \
-H "Content-Type: application/json" \
-d '{
"agent_card": {
"name": "math-solver",
"description": "Mathematical problem solving agent",
"url": "http://math.example.com:5000",
"version": "3.0.1",
"protocol_version": "0.3.0",
"skills": [
{
"id": "solve_equation",
"description": "Solve mathematical equations"
},
{
"id": "plot_function",
"description": "Generate plots for mathematical functions"
}
]
}
}'
# 3. List all agents
curl http://localhost:8000/agents
# 4. Search for math agents
curl -X POST http://localhost:8000/agents/search \
-H "Content-Type: application/json" \
-d '{"query": "math"}'
# 5. Get specific agent
curl http://localhost:8000/agents/math-solver
# 6. Unregister agent
curl -X DELETE http://localhost:8000/agents/math-solver
gRPC Examples¶
Python with grpcio¶
import grpc
from google.protobuf.timestamp_pb2 import Timestamp
from a2a_registry.proto.generated import (
registry_pb2,
registry_pb2_grpc,
a2a_pb2
)
# Create gRPC channel
channel = grpc.insecure_channel('localhost:50051')
stub = registry_pb2_grpc.A2ARegistryServiceStub(channel)
# 1. Create an agent card
agent_card = a2a_pb2.AgentCard(
name="data-analyzer",
description="Advanced data analysis and visualization agent",
url="http://analyzer.example.com:6000",
version="1.2.0",
protocol_version="0.3.0"
)
# Add skills
skill1 = agent_card.skills.add()
skill1.id = "analyze_dataset"
skill1.description = "Perform statistical analysis on datasets"
skill2 = agent_card.skills.add()
skill2.id = "create_visualization"
skill2.description = "Generate charts and graphs from data"
# Create registry agent card
registry_card = registry_pb2.RegistryAgentCard(
agent_card=agent_card
)
# 2. Store the agent card
store_request = registry_pb2.StoreAgentCardRequest(
registry_agent_card=registry_card,
upsert=True
)
try:
store_response = stub.StoreAgentCard(store_request)
print(f"Stored agent: {store_response.success}")
print(f"Message: {store_response.message}")
except grpc.RpcError as e:
print(f"gRPC error: {e.code()} - {e.details()}")
# 3. Search for agents
search_criteria = registry_pb2.AgentSearchCriteria(
required_skills=["analyze_dataset", "visualization"],
min_health_score=80,
page_size=10
)
search_request = registry_pb2.SearchAgentsRequest(criteria=search_criteria)
search_response = stub.SearchAgents(search_request)
print(f"Found {len(search_response.agents)} matching agents")
for agent in search_response.agents:
print(f"- {agent.agent_card.name}: {agent.agent_card.description}")
# 4. Get specific agent
get_request = registry_pb2.GetAgentCardRequest(
agent_id="data-analyzer",
include_registry_metadata=True
)
get_response = stub.GetAgentCard(get_request)
if get_response.found:
agent = get_response.registry_agent_card.agent_card
print(f"Found agent: {agent.name} v{agent.version}")
if get_response.registry_agent_card.registry_metadata:
metadata = get_response.registry_agent_card.registry_metadata
print(f"Health score: {metadata.health_score}")
print(f"Status: {metadata.status}")
# 5. Ping agent for health check
ping_request = registry_pb2.PingAgentRequest(
agent_id="data-analyzer",
timestamp=Timestamp()
)
ping_response = stub.PingAgent(ping_request)
print(f"Agent responsive: {ping_response.responsive}")
print(f"Response time: {ping_response.response_time_ms}ms")
# 6. List all agents with pagination
list_request = registry_pb2.ListAllAgentsRequest(
include_inactive=False,
page_size=5
)
list_response = stub.ListAllAgents(list_request)
print(f"Total agents: {list_response.total_count}")
for agent in list_response.agents:
print(f"- {agent.agent_card.name}")
# Close the channel
channel.close()
Go with grpc¶
package main
import (
"context"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "dev.allenday/a2a-registry/v1"
)
func main() {
// Connect to the server
conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewA2ARegistryServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
// Create and store an agent card
agentCard := &pb.AgentCard{
Name: "document-processor",
Description: "Document analysis and processing agent",
Url: "http://docs.example.com:7000",
Version: "2.3.1",
ProtocolVersion: "0.3.0",
Skills: []*pb.Skill{
{
Id: "extract_text",
Description: "Extract text from various document formats",
},
{
Id: "summarize_document",
Description: "Generate summaries of long documents",
},
},
}
registryCard := &pb.RegistryAgentCard{
AgentCard: agentCard,
}
storeReq := &pb.StoreAgentCardRequest{
RegistryAgentCard: registryCard,
Upsert: true,
}
storeResp, err := client.StoreAgentCard(ctx, storeReq)
if err != nil {
log.Fatalf("Failed to store agent: %v", err)
}
log.Printf("Agent stored: %v", storeResp.Success)
// Search for document-related agents
searchCriteria := &pb.AgentSearchCriteria{
RequiredSkills: []string{"extract_text"},
PageSize: 10,
}
searchReq := &pb.SearchAgentsRequest{
Criteria: searchCriteria,
}
searchResp, err := client.SearchAgents(ctx, searchReq)
if err != nil {
log.Fatalf("Failed to search: %v", err)
}
log.Printf("Found %d agents", len(searchResp.Agents))
for _, agent := range searchResp.Agents {
log.Printf("- %s: %s", agent.AgentCard.Name, agent.AgentCard.Description)
}
}
Error Handling Examples¶
Python REST Error Handling¶
import requests
from requests.exceptions import RequestException
def register_agent_safely(agent_card):
try:
response = requests.post(
"http://localhost:8000/agents",
json={"agent_card": agent_card},
timeout=10
)
response.raise_for_status() # Raises HTTPError for bad responses
return response.json()
except requests.exceptions.ConnectionError:
print("Failed to connect to registry service")
except requests.exceptions.Timeout:
print("Request timed out")
except requests.exceptions.HTTPError as e:
if e.response.status_code == 400:
print(f"Invalid agent card: {e.response.json().get('detail')}")
elif e.response.status_code == 409:
print("Agent already exists")
else:
print(f"HTTP error {e.response.status_code}: {e.response.text}")
except RequestException as e:
print(f"Request failed: {e}")
return None
Python gRPC Error Handling¶
import grpc
from grpc import StatusCode
def search_agents_safely(stub, criteria):
try:
request = registry_pb2.SearchAgentsRequest(criteria=criteria)
response = stub.SearchAgents(request)
return response.agents
except grpc.RpcError as e:
if e.code() == StatusCode.INVALID_ARGUMENT:
print(f"Invalid search criteria: {e.details()}")
elif e.code() == StatusCode.NOT_FOUND:
print("No agents found matching criteria")
elif e.code() == StatusCode.UNAVAILABLE:
print("Registry service unavailable")
else:
print(f"gRPC error {e.code()}: {e.details()}")
return []
Integration Patterns¶
Agent Auto-Registration¶
import time
import threading
from contextlib import contextmanager
class AgentRegistrar:
def __init__(self, registry_url, agent_card):
self.registry_url = registry_url
self.agent_card = agent_card
self.registered = False
self._stop_event = threading.Event()
def register(self):
"""Register agent with the registry."""
try:
response = requests.post(
f"{self.registry_url}/agents",
json={"agent_card": self.agent_card}
)
response.raise_for_status()
self.registered = True
print(f"Agent {self.agent_card['name']} registered successfully")
except Exception as e:
print(f"Registration failed: {e}")
def unregister(self):
"""Unregister agent from the registry."""
if self.registered:
try:
response = requests.delete(
f"{self.registry_url}/agents/{self.agent_card['name']}"
)
response.raise_for_status()
print(f"Agent {self.agent_card['name']} unregistered")
except Exception as e:
print(f"Unregistration failed: {e}")
finally:
self.registered = False
def start_heartbeat(self, interval=30):
"""Start sending periodic heartbeats to maintain registration."""
def heartbeat():
while not self._stop_event.is_set():
if self.registered:
try:
# Re-register to update last_seen timestamp
self.register()
except Exception as e:
print(f"Heartbeat failed: {e}")
time.sleep(interval)
thread = threading.Thread(target=heartbeat, daemon=True)
thread.start()
return thread
def stop_heartbeat(self):
"""Stop the heartbeat thread."""
self._stop_event.set()
@contextmanager
def managed_registration(self):
"""Context manager for automatic registration/unregistration."""
try:
self.register()
heartbeat_thread = self.start_heartbeat()
yield self
finally:
self.stop_heartbeat()
self.unregister()
# Usage example
agent_card = {
"name": "my-agent",
"description": "My autonomous agent",
"url": "http://localhost:3000",
"version": "0.420.0",
"protocol_version": "0.3.0",
"skills": []
}
registrar = AgentRegistrar("http://localhost:8000", agent_card)
# Use with context manager for automatic cleanup
with registrar.managed_registration():
# Agent is now registered and sending heartbeats
# Run your agent's main loop here
time.sleep(60) # Simulate agent work
# Agent automatically unregistered when exiting context
This comprehensive API documentation provides examples for both REST and gRPC interfaces, showing how to handle errors properly and implement common integration patterns.