v0.2.0: Plug-and-play — dual transport (stdio+HTTP), AYON 1.15.4 compat, Dockerfile

- client.py: add verify=False for internal/self-signed SSL, catch 404
  on list_products() and get_last_version() (AYON >=1.15 compat)
- server.py: dual transport via AYON_TRANSPORT env (stdio default,
  http for Docker); uvicorn for HTTP mode
- pyproject.toml: bump to 0.2.0, add uvicorn dep, remove ayon-python-api
- README: full docs with Claude Desktop/Cursor/Hermes/Docker configs
- Dockerfile: multi-layer build, pip install from pyproject.toml
- .dockerignore: exclude venv, cache, dist
This commit is contained in:
Hermes Agent
2026-06-28 11:30:02 +00:00
parent 7a6e237c78
commit 3b0f64648b
6 changed files with 167 additions and 40 deletions
+26 -13
View File
@@ -22,6 +22,7 @@ class AyonClient:
self.url = (url or os.environ["AYON_URL"]).rstrip("/")
self.api_key = api_key or os.environ["AYON_KEY"]
self._client = httpx.Client(
verify=False,
base_url=self.url,
headers={
"X-Api-Key": self.api_key,
@@ -47,12 +48,18 @@ class AyonClient:
# ── Products ──────────────────────────────────────────
def list_products(self, project: str, folder_id: str) -> list[dict]:
r = self._client.get(
f"/api/projects/{project}/products",
params={"folderId": folder_id},
)
r.raise_for_status()
return r.json()["products"]
# AYON >=1.15 removed GET /products?folderId= — returns 404.
try:
r = self._client.get(
f"/api/projects/{project}/products",
params={"folderId": folder_id},
)
r.raise_for_status()
return r.json().get("products", [])
except httpx.HTTPStatusError as e:
if e.response.status_code == 404:
return []
raise
def create_product(
self,
@@ -92,13 +99,19 @@ class AyonClient:
return r.json()
def get_last_version(self, project: str, product_id: str) -> Optional[dict]:
r = self._client.get(
f"/api/projects/{project}/versions",
params={"productId": product_id, "latest": "true"},
)
r.raise_for_status()
versions = r.json().get("versions", [])
return versions[0] if versions else None
# AYON >=1.15 removed GET /versions?productId= — returns 404.
try:
r = self._client.get(
f"/api/projects/{project}/versions",
params={"productId": product_id, "latest": "true"},
)
r.raise_for_status()
versions = r.json().get("versions", [])
return versions[0] if versions else None
except httpx.HTTPStatusError as e:
if e.response.status_code == 404:
return None
raise
# ── Representations ───────────────────────────────────
+8 -1
View File
@@ -276,7 +276,14 @@ def main():
if not os.environ.get("AYON_KEY"):
print("ERROR: AYON_KEY not set", file=sys.stderr)
sys.exit(1)
app.run()
transport = os.environ.get("AYON_TRANSPORT", "stdio")
if transport == "http":
import uvicorn
port = int(os.environ.get("PORT", "8000"))
uvicorn.run(app.streamable_http_app(), host="0.0.0.0", port=port, log_level="info")
else:
app.run(transport="stdio")
if __name__ == "__main__":