SDS API wrapper/testing for coder
Find a file
2025-11-25 18:31:41 +00:00
examples refac: debugging checks and logs 2025-11-25 18:31:41 +00:00
sds_api_client refac: 2025-11-19 10:26:28 +00:00
.env.example refac: 2025-11-19 10:26:28 +00:00
.gitignore feat: config 2025-11-17 14:30:16 +00:00
pyproject.toml refac: 2025-11-19 10:26:28 +00:00
README.md refac: 2025-11-19 10:26:28 +00:00
uv.lock refac: debugging checks and logs 2025-11-25 18:31:41 +00:00

SDS Managed API - Python Client Wrapper

Lightweight Python wrapper around the SDS Managed API with:

  • SDSClient (Bearer auth)
  • Retries, timeouts, SSL verify toggle
  • OData helpers ($select, $expand, $orderby, $filter, $top, $skip, $count)
  • Auto-login on 401 Unauthorized (token cached and only fetched when needed) to prevent constant manual logins or logins on every single call

Prerequisites

Getting started (uv)

  • Sync deps (creates .venv from pyproject.toml):
    • uv sync
  • Run the example (provide credentials):
    • KEYCLOAK_MAIL="you@example.com" KEYCLOAK_PASSWORD="your-password"
      uv run examples/list_tenants.py

Quick usage

import os
from sds_api_client import SDSClient

# Option A: Let the client auto-login on first 401 using credentials
client = SDSClient(
    base_url=os.getenv("SDS_BASE_URL"),
    auth_user=os.getenv("KEYCLOAK_MAIL"),
    auth_password=os.getenv("KEYCLOAK_PASSWORD"),
)
rows = client.tenants.list(top=10)
print(rows)

# Option B: Explicit login (token applied to Authorization header)
client = SDSClient(base_url=os.getenv("SDS_BASE_URL"))
client.login_keycloak(
    user=os.getenv("KEYCLOAK_MAIL"),
    password=os.getenv("KEYCLOAK_PASSWORD"),
)
rows = client.tenants.list(top=10)
print(rows)

API error handling

from sds_api_client import APIError
try:
    client.tenants.list(top=1)
except APIError as e:
    print(e)
    print(e.to_dict())

Auth details

  • Auto-login on 401 Unauthorized: if a request returns 401 and auth_user/auth_password are configured, the client will call KeycloakAuth/token using form data user and password, cache the returned token, and retry the original request once. The token is reused for subsequent calls and not regenerated unless another 401 is received.
  • Explicit login option remains available via client.login_keycloak(user=..., password=..., path=..., extra=...). By default the client posts form data (Content-Type: application/x-www-form-urlencoded) to KeycloakAuth/token with fields user and password. It expects a JSON body containing a token (or common fallbacks like access_token).

Extending endpoints Use TenantsEndpoint as a template under sds_api_client/endpoints/ and expose via a property on SDSClient.

Notes

  • Default OData key paths like /Tenants(1); set key_style="slash" for /Tenants/1.