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)

If you install the library without the [cli] extra, the nextlabs command is still registered but will print a friendly error pointing at pip install 'nextlabs-sdk[cli]' and exit with status 1.

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.3.0.tar.gz (190.3 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.3.0-py3-none-any.whl (121.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nextlabs_sdk-0.3.0.tar.gz
  • Upload date:
  • Size: 190.3 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.3.0.tar.gz
Algorithm Hash digest
SHA256 0e04e35e6c11ecf137750858854dea056851a5f9c65419d337ff4c2549862a7b
MD5 2588a37e49b7aba2acde1dd1ec6e0176
BLAKE2b-256 eba6a74929926019696a6c0d7368e1c123304d2e86d380998cb97d6c91cc4d7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for nextlabs_sdk-0.3.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.3.0-py3-none-any.whl.

File metadata

  • Download URL: nextlabs_sdk-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 121.2 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 411e07f425d5de14a78f7e5b6c3619477d21ba0a07ffaaa54263839132e0aebb
MD5 0953bdffc04d059a6b1c4cb043b0e121
BLAKE2b-256 0b083fc905c35379aa57d26a8e06bbf4a3f65ac7e8918330ed8fdb96e254667d

See more details on using hashes here.

Provenance

The following attestation bundles were made for nextlabs_sdk-0.3.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