Aegis Python SDK

Operator-grade Python integration for Axis + Aegis with rollout controls, telemetry readback, and deterministic E2E evidence receipts.

Executable TLS policy boundary: the released v0.5.5 native catalog requires exact versioned drafts, build capability checks, and reviewed plans. Older SDK rollout examples on this page do not express that contract. Use the authenticated Axis Crypto Policies workflow and build-specific support reference for proposed TLS changes; no SDK write compatibility is asserted.

Last updated
March 1, 2026
Source
VeliKey Docs Team
Owner
SDK Engineering

Prerequisites

  • Python 3.10+ for SDK audit/E2E closure (A4 baseline uses `python3.12` via `SDK_E2E_PYTHON_BIN`).
  • Axis tenant access with at least one live auth source: `AXIS_SESSION_COOKIE`, `AXIS_SESSION_TOKEN`, `AXIS_SESSION_COOKIE_FILE`, `AXIS_SESSION_COOKIE_COMMAND`, or credentials bootstrap (`AXIS_AUTH_EMAIL`/`AXIS_AUTH_PASSWORD`).
  • Aegis policy already present for rollout planning.
  • Optional: public Aegis ingest endpoint for payload integrity probe.
# manual-only example
python3 --version
python3 -m pip --version
echo "$AXIS_BASE_URL"
echo "${AXIS_SESSION_COOKIE:-$AXIS_SESSION_TOKEN}" | wc -c

Install

Use a virtual environment with Python 3.10+ and pin the package source for repeatable CI/dev parity.

# executable example
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install "git+https://github.com/sgreysond/velikey-python-sdk.git@v0.1.0#egg=velikey"

Minimal Working Example

Expected output: health status, policy count, and current usage snapshot.

import asyncio
import os
from velikey import AegisClient

async def main() -> None:
    client = AegisClient(
        api_key=None,
        session_cookie=os.environ["AXIS_SESSION_COOKIE"],
        base_url=os.environ.get("AXIS_BASE_URL", "https://axis.velikey.com"),
    )
    try:
        health = await client.get_health()
        policies = await client.policies.list(active_only=True)
        usage = await client.billing.get_usage(period="current")
        print("health:", health.get("status"))
        print("policies:", len(policies))
        print("telemetry_gb:", usage.get("usage", {}).get("telemetryDataGB"))
    finally:
        await client.close()

asyncio.run(main())

Production Pattern (Timeouts, Retries, Error Handling)

Use retry-capable client defaults and explicit exception handling before any rollout operation.

import asyncio
import os
from velikey import AegisClient
from velikey.exceptions import VeliKeyError

async def run() -> None:
    client = AegisClient(
        api_key=None,
        session_cookie=os.environ["AXIS_SESSION_COOKIE"],
        base_url=os.environ.get("AXIS_BASE_URL", "https://axis.velikey.com"),
        timeout=30.0,
        max_retries=3,
    )
    try:
        score = await client.monitoring.get_health_score()
        if score.overall_score < 70:
            raise RuntimeError("Health score below rollout threshold")
        print("overall_score:", score.overall_score)
    except VeliKeyError as err:
        print("sdk_error:", err)
        raise
    finally:
        await client.close()

asyncio.run(run())

Canary Rollout and Rollback (Dry-Run)

Start with plan/apply dry-run, then require human confirmation before non-dry-run execution.

import asyncio
import os
from velikey import AegisClient

POLICY_ID = os.environ["AEGIS_POLICY_ID"]

async def plan_apply() -> None:
    client = AegisClient(
        api_key=None,
        session_cookie=os.environ["AXIS_SESSION_COOKIE"],
        base_url=os.environ.get("AXIS_BASE_URL", "https://axis.velikey.com"),
    )
    try:
        plan = await client.rollouts.plan(
            POLICY_ID,
            canary_percent=5,
            stabilization_window_s=300,
            dry_run=True,
            explain=True,
        )
        plan_id = plan.get("data", {}).get("plan_id") or plan.get("data", {}).get("planId")
        if plan_id:
            apply_result = await client.rollouts.apply(plan_id, dry_run=True, explain=True)
            print("apply_dry_run:", apply_result.get("success"))
        rollback_token = os.environ.get("AEGIS_ROLLBACK_TOKEN")
        if rollback_token:
            rollback = await client.rollouts.rollback(rollback_token, confirm=True, explain=True)
            print("rollback_dry_run:", rollback.get("success"))
    finally:
        await client.close()

asyncio.run(plan_apply())

Telemetry and Metering Readback

Capture usage before/after operations and compute deltas for release evidence.

before = await client.billing.get_usage(period="current")
# ... perform rollout and traffic exercise ...
after = await client.billing.get_usage(period="current")

before_telemetry = float(before.get("usage", {}).get("telemetryDataGB", 0.0))
after_telemetry = float(after.get("usage", {}).get("telemetryDataGB", 0.0))
delta_telemetry = after_telemetry - before_telemetry
print("telemetry_delta_gb:", delta_telemetry)

Cloud E2E Runner

Expected output: deterministic `SUMMARY.json`/`SUMMARY.md`, reason codes, run manifest, and result receipt.

# manual-only example
git clone https://github.com/sgreysond/velikey_test-env.git
cd velikey_test-env
bash scripts/sdk-e2e/run_python_sdk_e2e.sh --dry-run

# manual-only example
export AXIS_BASE_URL="https://axis.velikey.com"
export AXIS_SESSION_COOKIE_FILE="$HOME/.velikey/secrets/axis.owner.velikey.storage.json"
# alternative: export AXIS_SESSION_COOKIE="next-auth.session-token=REDACTED"
# alternative: export AXIS_SESSION_TOKEN="REDACTED"
# alternative: export AXIS_SESSION_COOKIE_COMMAND='security find-generic-password ...'
# optional credentials bootstrap fallback:
# export AXIS_AUTH_EMAIL="owner@example.com"
# export AXIS_AUTH_PASSWORD="REDACTED"
export SDK_E2E_PYTHON_BIN="python3"
export SDK_E2E_PAYLOAD_URL="https://YOUR_AEGIS_PUBLIC_ENDPOINT/ingest"
bash scripts/sdk-e2e/run_python_sdk_e2e.sh --live

Expected output: `python-sdk-e2e-result.json` with `result=pass` once hosted auth/session context is valid and payload/policy inputs are set. If hosted callback/schema deployment is stale, live mode returns deterministic `manual-required` with reason code `axis_auth_schema_mismatch` plus `BLOCKER.json` guidance.

Troubleshooting + Security Notes

  • 401 Unauthorized: refresh session cookie, verify tenant scope, then retry.
  • Auth bootstrap mismatch: if reason code includes axis_auth_schema_mismatch, deployed Axis auth schema is out of sync and credentials bootstrap cannot mint session cookies until remediated.
  • No policy selected: set AEGIS_POLICY_ID or create an active policy first.
  • Payload integrity mismatch: validate endpoint path, TLS termination, and backend hash echo contract.
  • Live execution blocked: inspect `BLOCKER.json` in run output and satisfy listed missing inputs (session + Python runtime policy) before rerun with --live.
  • Security: do not commit cookies/tokens; keep secrets in env/secret manager only.
  • TLS: keep cert validation enabled in production; do not disable verification outside controlled diagnostics.