Skip to main content

A typed Python SDK wrapping the NextLabs CloudAz Console API and PDP REST API

Project description

nextlabs-sdk

PyPI version Python versions CI License: MIT

Typed Python SDK and CLI for the NextLabs CloudAz Console & PDP REST APIs.

[!WARNING] Alpha — the public surface may still change. Unofficial project, not affiliated with NextLabs.

CLI demo: auth login → policies search → pdp eval

Table of contents

Features

  • Two API clientsCloudAzClient for Console management and PdpClient for XACML-style authorization decisions.
  • Sync and async parity — every client ships in a sync (CloudAzClient, PdpClient) and an async (AsyncCloudAzClient, AsyncPdpClient) flavor, built on httpx.
  • Fully typed (PEP 561, py.typed) with Pydantic v2 request/response models — strong autocompletion under mypy and Pyright.
  • CloudAz coverage — tags, components, component types, policies (incl. retrieveAllPolicies export and named/scoped search), operators, entity audit logs, reporter audit logs (Policy Activity Reports, Monitors, Alerts), policy activity reports, activity logs, dashboard, and system config.
  • PDP coverageevaluate (single decision) and permissions (multi-action discovery), with JSON or XML payloads.
  • Resilient transport — OIDC token acquisition + refresh, configurable timeout, SSL verification, and retries with exponential backoff (clamped Retry-After honoured on 429/503).
  • Typed error hierarchy — HTTP status codes map to AuthenticationError, AuthorizationError, NotFoundError, ValidationError, ConflictError, RateLimitError, ServerError, RequestTimeoutError, TransportError, and ApiError — all subclasses of NextLabsError.
  • Pagination helpersSyncPaginator / AsyncPaginator iterate listed endpoints page-by-page or item-by-item.
  • Optional CLI — a nextlabs command (Typer + Rich) for scripting, admin tasks, and quick exploration. Persistent OIDC token cache, four output formats (table / wide / detail / json), per-call verbosity for HTTP tracing.

Installation

pip install nextlabs-sdk            # library only
pip install "nextlabs-sdk[cli]"     # + nextlabs CLI (Typer, Rich)

Requires Python 3.11+.


Using the SDK

Quick start — CloudAz (sync)

from nextlabs_sdk import CloudAzClient
from nextlabs_sdk.cloudaz import TagType

with CloudAzClient(
    base_url="https://cloudaz.example.com",
    username="admin",
    password="secret",
) as client:
    for tag in client.tags.list(TagType.COMPONENT):
        print(tag.id, tag.label)

    tag_id = client.tags.create(TagType.COMPONENT, key="env", label="Env")
    tag = client.tags.get(tag_id)
    client.tags.delete(tag.id)

Quick start — CloudAz (async)

import asyncio
from nextlabs_sdk import AsyncCloudAzClient
from nextlabs_sdk.cloudaz import TagType

async def main() -> None:
    async with AsyncCloudAzClient(
        base_url="https://cloudaz.example.com",
        username="admin",
        password="secret",
    ) as client:
        async for tag in client.tags.list(TagType.COMPONENT):
            print(tag.id, tag.label)

asyncio.run(main())

Quick start — PDP

from nextlabs_sdk import PdpClient
from nextlabs_sdk.pdp import (
    Action, Application, EvalRequest, Resource, Subject,
)

with PdpClient(
    base_url="https://pdp.example.com",
    client_id="my-client",
    client_secret="s3cret",
) as pdp:
    decision = pdp.evaluate(
        EvalRequest(
            subject=Subject(id="alice", attributes={"role": "engineer"}),
            resource=Resource(
                id="doc-42",
                type="document",
                attributes={"classification": "internal"},
            ),
            action=Action(id="read"),
            application=Application(id="wiki"),
            return_policy_ids=True,
        )
    )
    result = decision.first_result
    print(result.decision, [p.id for p in result.policy_refs])

Use content_type=ContentType.XML to exchange XACML XML payloads instead of JSON. pdp.permissions(...) returns the set of actions a subject may perform on a resource.

Pagination

SyncPaginator / AsyncPaginator are returned by every list method. Iterate page-by-page (.pages()) or item-by-item (default __iter__):

for tag in client.tags.list(TagType.COMPONENT):       # one item at a time
    ...

for page in client.tags.list(TagType.COMPONENT).pages():
    print(page.total, len(page.items))                # PageResult metadata

Error handling

from nextlabs_sdk import CloudAzClient
from nextlabs_sdk.exceptions import (
    AuthenticationError, NotFoundError, NextLabsError,
)

try:
    client.tags.get(123)
except AuthenticationError:
    ...  # re-login / rotate credentials
except NotFoundError:
    ...
except NextLabsError as exc:
    print(exc.status_code, exc.request_method, exc.request_url, exc.response_body)

Public API surface

All imports come from four public entry points:

  • nextlabs_sdk — clients (CloudAzClient, AsyncCloudAzClient, PdpClient, AsyncPdpClient), transport (HttpConfig, RetryConfig, create_http_client, create_async_http_client), pagination (SyncPaginator, AsyncPaginator, PageResult), auth (CloudAzAuth, PdpAuth, StaticTokenAuth), token cache (TokenCache, CachedToken, FileTokenCache, NullTokenCache), and __version__.
  • nextlabs_sdk.cloudaz — CloudAz domain models and enums (Tag, TagType, Operator, audit-log / report / dashboard / system-config / activity-log models).
  • nextlabs_sdk.pdp — PDP request/response models and enums (Subject, Resource, Action, Application, Environment, EvalRequest, EvalResponse, PermissionsRequest, PermissionsResponse, ContentType, Decision, ResourceDimension, …).
  • nextlabs_sdk.exceptions — the NextLabsError hierarchy.

Anything with a leading underscore (nextlabs_sdk._cloudaz, nextlabs_sdk._pdp, nextlabs_sdk._cli, nextlabs_sdk._auth, …) is an internal implementation detail and may change without notice.


Using the CLI

The optional CLI exposes most CloudAz operations plus PDP evaluation.

Quick start

pip install "nextlabs-sdk[cli]"

export NEXTLABS_BASE_URL="https://cloudaz.example.com"
export NEXTLABS_USERNAME="admin"

nextlabs auth login                # acquire & cache a token
nextlabs auth status               # is the cached token still valid?
nextlabs policies search --status APPROVED
nextlabs pdp eval --subject alice --resource doc-42 \
                  --resource-type document --action read --application wiki

Command groups

auth             login | logout | status | test | accounts | use
tags             list (positional <tag_type>) | get | create | delete
components       search | get | create | update | delete
component-types  list | get | create | update | delete
policies         search | get | export-all | tags
audit-logs       search (--start-date / --end-date in epoch-ms)
reports          ...
dashboard        ...
pdp              eval | permissions

Use nextlabs <group> --help for the exact flags of each subcommand.

Output formats

Every list/get command accepts -o / --output. Values are case-insensitive.

Format When to use
table Default. Compact columns; long values wrap (never truncated).
wide Table plus extra columns (owner, timestamps, version, …).
detail Sectioned per-item output, kubectl describe style.
json Raw JSON dump of the response model(s). Machine-readable.
nextlabs -o wide policies search
nextlabs -o detail policies get 17
nextlabs --output json components search    # machine-readable

Recipes

Real workflows assembled from the commands shipped today.

1. Daily admin — find an approved policy and read it.

nextlabs auth login
nextlabs policies search --status APPROVED --text "billing"
nextlabs policies get 17 -o detail

2. CI authorization smoke test — fail the build if alice cannot read the wiki.

nextlabs --token "$NEXTLABS_TOKEN" \
  pdp eval --subject alice --resource doc-42 --resource-type document \
           --action read --application wiki -o json \
  | jq -e '.eval_results[0].decision == "Permit"'

3. Export the policy catalogue to version control.

nextlabs -o json policies search --page-size 1000 > policies.json
git add policies.json && git commit -m "chore: snapshot policies"

4. Audit recent activity (last hour).

END=$(date +%s%3N)
START=$((END - 3600000))
nextlabs audit-logs search --start-date "$START" --end-date "$END"

5. Run in CI without an interactive login.

NEXTLABS_BASE_URL="https://cloudaz.example.com" \
NEXTLABS_TOKEN="$(vault kv get -field=token secret/nextlabs/ci)" \
  nextlabs policies search --page-size 50

NEXTLABS_TOKEN (or --token) bypasses the OIDC login flow and the token cache — nothing is read from or written to disk.

6. Templated extraction with jq.

nextlabs -o json components search | jq '.[].id'

For more day-to-day fixes (auth cache, SSL trust, missing PDP attributes, …) see docs/troubleshooting.md.


Configuration & authentication

Both the SDK and the CLI share the same transport, retry, and OIDC machinery.

HttpConfig and RetryConfig

from nextlabs_sdk import CloudAzClient, HttpConfig, RetryConfig

client = CloudAzClient(
    base_url="https://cloudaz.example.com",
    username="admin",
    password="secret",
    http_config=HttpConfig(
        timeout=15.0,
        verify_ssl=True,
        retry=RetryConfig(max_retries=5, base_delay=0.5, max_delay=10.0),
    ),
)

Retries use exponential backoff with jitter and apply to transient transport failures and 5xx / 429 responses. Retry-After is honoured and clamped to max_delay.

OIDC tokens, caching, and environment variables

The CLI persists OIDC tokens between invocations so users do not re-authenticate on every command. The SDK defaults to NullTokenCache (no silent filesystem writes); library consumers opt in explicitly:

from nextlabs_sdk import CloudAzClient, FileTokenCache

client = CloudAzClient(
    base_url="https://cloudaz.example.com",
    username="admin",
    password="secret",
    token_cache=FileTokenCache(),  # or any custom TokenCache
)

Token cache lookup precedence (CLI):

  1. --cache-dir <path> or NEXTLABS_CACHE_DIR<path>/tokens.json
  2. $XDG_CACHE_HOME/nextlabs-sdk/tokens.json
  3. ~/.cache/nextlabs-sdk/tokens.json

The file is written 0600 inside a 0700 directory; writes are atomic (temp file + os.replace). The cache key is "{token_url}|{username}|{client_id}" so multiple profiles coexist.

Refresh tokens are used transparently when available; on refresh failure the CLI falls back to the password grant (if --password / NEXTLABS_PASSWORD is set) and otherwise raises AuthenticationError with a "Run nextlabs auth login" hint.

Environment variables

Variable Purpose
NEXTLABS_BASE_URL CloudAz base URL
NEXTLABS_USERNAME CloudAz username
NEXTLABS_PASSWORD CloudAz password
NEXTLABS_CLIENT_ID OIDC client ID (default: ControlCenterOIDCClient)
NEXTLABS_CLIENT_SECRET PDP client secret
NEXTLABS_PDP_URL PDP base URL (defaults to --base-url)
NEXTLABS_TOKEN Pre-issued bearer token; bypasses the login flow and cache
NEXTLABS_CACHE_DIR Directory holding tokens.json (overrides XDG default)

Top-level CLI flags worth knowing: --no-verify (skip TLS verification — dev only), -v / -vv (verbose; -vv logs every HTTP request and response body), --token (one-shot bearer override).


Project layout

src/nextlabs_sdk/
├── cloudaz/        # Public: CloudAz models & enums (re-exports)
├── pdp/            # Public: PDP models & enums (re-exports)
├── exceptions.py   # Public: NextLabsError hierarchy
├── _auth/          # Internal: OIDC auth flows + token cache
├── _cloudaz/       # Internal: CloudAz service classes + models
├── _pdp/           # Internal: PDP client + JSON/XML serializers
├── _cli/           # Internal: Typer-based CLI (optional extra)
├── _config.py      # Internal (re-exported): HttpConfig, RetryConfig
├── _http_transport.py
└── _pagination.py  # Internal (re-exported): paginators

Development

See docs/development.md for the full development guide. Quick reference:

python ./tools/checks.py              # Black + Flake8 + MyPy + Pyright
python ./tools/tests.py --short       # unit tests
python ./tools/tests.py --short --e2e # E2E tests only (requires Docker)
python ./tools/tests.py --short --all # unit + E2E tests (requires Docker)

A .devcontainer is provided; pre-commit hooks (black, flake8, mypy, pyright) are preconfigured. The CLI demo above is regenerated with vhs docs/cast/demo.tape — see docs/cast/README.md.

License

MIT — see LICENSE.


Contributing · Security · Changelog · Troubleshooting

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nextlabs_sdk-0.2.0.tar.gz (184.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nextlabs_sdk-0.2.0-py3-none-any.whl (117.6 kB view details)

Uploaded Python 3

File details

Details for the file nextlabs_sdk-0.2.0.tar.gz.

File metadata

  • Download URL: nextlabs_sdk-0.2.0.tar.gz
  • Upload date:
  • Size: 184.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nextlabs_sdk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0bb300f5497bb6c4d25c35da018e1c72f9d9f14c376a8c989c83b59bf3e66c83
MD5 f8aee6c30a9288339ac778b5c76894d1
BLAKE2b-256 6a9f09e8cdf4c87c3915a5352d4dbc5f156d39d7a92b509ce0449a2445da4430

See more details on using hashes here.

Provenance

The following attestation bundles were made for nextlabs_sdk-0.2.0.tar.gz:

Publisher: release_publishing.yml on stevenengland/nextlabs_rest_api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nextlabs_sdk-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: nextlabs_sdk-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 117.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nextlabs_sdk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 690cfe2f251a85a1ed2f2ff6875e44d857af6cf0a914c318e1dcc74058334592
MD5 bf1b0ee5536e60d4a2df87b948e6251e
BLAKE2b-256 960d879668fe146dfde1edae65c0a22ff0468f090e507166e02b6cce6540ea94

See more details on using hashes here.

Provenance

The following attestation bundles were made for nextlabs_sdk-0.2.0-py3-none-any.whl:

Publisher: release_publishing.yml on stevenengland/nextlabs_rest_api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page