Files
a2a/a2a_pack/cli/api_client.py
2026-05-08 21:59:51 -03:00

99 lines
2.9 KiB
Python

"""Thin HTTP client for the control plane API."""
from __future__ import annotations
from typing import Any
import httpx
class ApiError(RuntimeError):
def __init__(self, status: int, message: str) -> None:
self.status = status
super().__init__(f"API {status}: {message}")
class ControlPlaneClient:
def __init__(self, api_url: str, token: str | None = None) -> None:
self.api_url = api_url.rstrip("/")
self.token = token
def _headers(self) -> dict[str, str]:
h = {"content-type": "application/json"}
if self.token:
h["authorization"] = f"bearer {self.token}"
return h
def _request(self, method: str, path: str, **kw: Any) -> Any:
url = f"{self.api_url}{path}"
with httpx.Client(timeout=30.0) as c:
resp = c.request(method, url, headers=self._headers(), **kw)
if resp.status_code >= 400:
try:
detail = resp.json().get("detail", resp.text)
except Exception: # noqa: BLE001
detail = resp.text
raise ApiError(resp.status_code, str(detail))
if resp.status_code == 204 or not resp.content:
return None
return resp.json()
def signup(self, email: str, password: str) -> dict[str, Any]:
return self._request("POST", "/v1/auth/signup", json={"email": email, "password": password})
def login(self, email: str, password: str) -> dict[str, Any]:
return self._request("POST", "/v1/auth/login", json={"email": email, "password": password})
def me(self) -> dict[str, Any]:
return self._request("GET", "/v1/me")
def register_agent(
self,
*,
name: str,
description: str,
version: str,
image: str,
public: bool,
card: dict[str, Any],
) -> dict[str, Any]:
return self._request(
"POST",
"/v1/agents",
json={
"name": name,
"description": description,
"version": version,
"image": image,
"public": public,
"card": card,
},
)
def from_source(
self,
*,
name: str,
description: str,
version: str,
public: bool,
) -> dict[str, Any]:
return self._request(
"POST",
"/v1/agents/from-source",
json={
"name": name,
"description": description,
"version": version,
"public": public,
},
)
def list_agents(self) -> list[dict[str, Any]]:
return self._request("GET", "/v1/agents")
def get_agent(self, name: str) -> dict[str, Any]:
return self._request("GET", f"/v1/agents/{name}")
def delete_agent(self, name: str) -> None:
self._request("DELETE", f"/v1/agents/{name}")