Skip to main content

Pragmatiks

Pragma SDK

Ask DeepWiki PyPI version Python 3.13+ License: MIT Code style: ruff

Documentation | CLI | Providers

Build providers and interact with Pragmatiks programmatically.

Quick Start

Synchronous Client

from pragma_sdk import PragmaClient, Resource

with PragmaClient() as client:
    # Apply a resource
    client.apply_resource(
        Resource(
            provider="gcp", resource="storage", name="my-bucket", config={"location": "US", "storage_class": "STANDARD"}
        )
    )

    # Get resource status
    bucket = client.get_resource("gcp", "storage", "my-bucket")
    print(bucket.outputs)

Asynchronous Client

import asyncio
from pragma_sdk import AsyncPragmaClient, Resource


async def main():
    async with AsyncPragmaClient() as client:
        # Apply a resource
        await client.apply_resource(
            Resource(
                provider="gcp",
                resource="storage",
                name="my-bucket",
                config={"location": "US", "storage_class": "STANDARD"},
            )
        )

        # Get resource status
        bucket = await client.get_resource("gcp", "storage", "my-bucket")
        print(bucket.outputs)


asyncio.run(main())

Installation

pip install pragmatiks-sdk

Or with uv:

uv add pragmatiks-sdk

Features

  • HTTP Clients - Sync and async clients for the Pragmatiks API
  • Provider Authoring - Build custom providers with type-safe Config and Outputs
  • Provider Publishing and Installation - Publish provider versions, install, upgrade and downgrade them, and read an installation's history
  • Dead-Letter Queue - Inspect and retry failed events for debugging and recovery
  • Field References - Reference outputs from other resources dynamically
  • Testing Harness - Test provider lifecycle methods locally without deployment
  • Auto-discovery - Automatic credential resolution from environment or config files

Building Providers

Define resources with typed configuration and lifecycle methods:

from pragma_sdk import Provider, Resource, Config, Outputs, Field

gcp = Provider()


class BucketConfig(Config):
    location: Field[str]
    storage_class: Field[str] = "STANDARD"


class BucketOutputs(Outputs):
    url: str
    created_at: str


@gcp.resource("storage")
class Bucket(Resource[BucketConfig, BucketOutputs]):
    async def on_create(self) -> BucketOutputs:
        """Provision the bucket."""
        return BucketOutputs(url=f"gs://{self.name}", created_at="...")

    async def on_observe(self) -> BucketOutputs | None:
        """Look the bucket up by identity; None when it does not exist."""
        return BucketOutputs(url=f"gs://{self.name}", created_at="...")

    async def on_update(self, previous_config: BucketConfig | None) -> BucketOutputs:
        """Converge to self.config; previous_config is None when unknown."""
        return BucketOutputs(url=f"gs://{self.name}", created_at="...")

    async def on_delete(self) -> None:
        """Delete the bucket; succeeds when it is already gone."""

Declaring the provider

A provider wheel declares itself with one entry point in the pragma.provider group, named after the provider and pointing at its importable package:

[project.entry-points."pragma.provider"]
gcp = "gcp_provider"

The Pragmatiks platform finds the provider's resource types through this entry point. Only resource classes defined inside that package belong to the provider; resource classes it imports from another provider stay that provider's.

To check what the platform will read from an installed wheel, run introspection in its environment:

PRAGMA_PROVIDER_DISTRIBUTION=<distribution> python -m pragma_sdk.introspection --output report.json

<distribution> is the name in the wheel's [project] table. When you publish, the wheel is renamed to <organization>-<provider name you publish under> before it is uploaded, and the platform loads it under that name.

The report lists the resource types with their schemas, or why the provider failed to load.

Field References

Reference outputs from other resources:

from pragma_sdk import FieldReference

config = AppConfig(
    database_url=FieldReference(provider="postgres", resource="database", name="my-db", field="outputs.connection_url")
)

Testing Providers

Test lifecycle methods locally with ProviderHarness:

from pragma_sdk.provider import ProviderHarness


async def test_bucket_creation():
    harness = ProviderHarness()

    result = await harness.invoke_create(Bucket, name="test-bucket", config=BucketConfig(location="US"))

    assert result.success
    assert "gs://test-bucket" in result.outputs.url

Authentication

Credentials are discovered automatically in this order:

  1. Explicit auth_token parameter
  2. Context-specific environment variable: PRAGMA_AUTH_TOKEN_{CONTEXT} (e.g., PRAGMA_AUTH_TOKEN_PRODUCTION)
  3. Generic environment variable: PRAGMA_AUTH_TOKEN
  4. Credentials file: ~/.config/pragma/credentials

The context is determined by: explicit context parameter > PRAGMA_CONTEXT env var > CLI config > "default".

# Auto-discover credentials (uses default context)
client = PragmaClient()

# Explicit token
client = PragmaClient(auth_token="sk_...")

# Use a specific context (checks PRAGMA_AUTH_TOKEN_PRODUCTION first)
client = PragmaClient(context="production")

# Require authentication (fail if no token)
client = PragmaClient(require_auth=True)

API Reference

HTTP Client Methods

Both PragmaClient (sync) and AsyncPragmaClient (async) provide the same methods, except where noted below.

Resources

Resource operations live on a project handle: client.project("my-project").list_resources().

Method Description
list_resources(provider, resource, tags) List resources with optional filters
get_resource(provider, resource, name) Get a specific resource
apply_resource(resource) Create or update a resource
deactivate_resource(provider, resource, name, dry_run=False) Deactivate a resource; returns the teardown's impact list
delete_resource(provider, resource, name, dry_run=False) Delete a resource; returns the teardown's impact list
wait_ready(provider, resource, name, timeout=300) Poll until READY; timeout=0 or None waits forever
wait_deactivated(provider, resource, name, timeout=300) Poll until DRAFT; timeout=0 or None waits forever
wait_deleted(provider, resource, name, timeout=300) Poll until DELETED; an unknown resource raises instead of returning; timeout=0 or None waits forever

Lifecycle Events

On the client itself, AsyncPragmaClient only.

Method Description
stream_lifecycle_events(timeout=None) Yield lifecycle event frames from the API's SSE stream; timeout=0 or None streams forever

Providers

Method Description
list_providers(query, scope, tags, limit, offset) Browse and search the provider catalog
get_provider(provider_name) Get a provider from the catalog
list_provider_versions(provider_name) List a provider's versions
get_provider_version(provider_name, version) Get one version of a provider, in any status
publish_provider_version(wheel_path, changelog=None) Rename, declare and upload a provider wheel
delete_provider(provider_name) Delete a provider from the catalog

Installed Providers

Method Description
install_provider(provider_name, version=None, config=None) Install a provider; installing a failed installation again reuses its stored version and config
list_installations() List installed providers with their state, latest operation and its target version, and failure message
upgrade_provider(provider_name, target_version=None) Upgrade an installed provider (latest version if none)
downgrade_provider(provider_name, target_version) Downgrade an installed provider
uninstall_provider(provider_name, cascade=False) Uninstall a provider
list_provider_history(provider_name) List an installation's history, newest first; kept 30 days, also after an uninstall

Dead-Letter Queue

Method Description
list_dead_letter_events(provider) List dead letter events with optional provider filter
get_dead_letter_event(event_id) Get a dead letter event by ID
retry_dead_letter_event(event_id) Retry a single dead letter event
retry_all_dead_letter_events() Retry all dead letter events
delete_dead_letter_event(event_id) Delete a single dead letter event
delete_dead_letter_events(provider, all) Delete multiple dead letter events

User & Health

Method Description
is_healthy() Check API health
get_me() Get current authenticated user information

Provider Classes

Class Description
Provider() Resource grouping with @provider.resource() decorator
Resource[ConfigT, OutputsT] Base class with on_create, on_observe, on_update, on_delete
computed = True Class attribute for a resource with no external object; exempts it from on_observe
Config Base class for resource configuration (Pydantic model)
Outputs Base class for resource outputs (Pydantic model)
Field[T] Type alias for `T
ProviderHarness Local testing harness

Development

# Install the toolchain, dependencies and git hooks
mise run install

# Format code
mise run format

# Type check and lint
mise run check

License

MIT

Metadata

Release files for pragmatiks-sdk 19.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pragmatiks-sdk 19.0.0
File Size Uploaded Provenance Actions
pragmatiks_sdk-19.0.0.tar.gz 103.2 kB With provenance Details for pragmatiks_sdk-19.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pragmatiks-sdk 19.0.0
File Interpreter ABI Platform Actions
pragmatiks_sdk-19.0.0-py3-none-any.whl Python 3 none any Details for pragmatiks_sdk-19.0.0-py3-none-any.whl

Total release size: 232.2 kB

Release files / pragmatiks_sdk-19.0.0.tar.gz

Download URL pragmatiks_sdk-19.0.0.tar.gz
Size 103.2 kB
Tags Source
SHA-256 checksum
How to use checksums
938734bd6b6f5a02bd58a4f668ef153cd7824fd781f5e5f4cd43c341e415cf55
BLAKE2b-256 checksum
How to use checksums
6733736fb197dcb4890965fc8830e25345b89c87d7a5327d9ce017d819e888c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / pragmatiks_sdk-19.0.0-py3-none-any.whl

Download URL pragmatiks_sdk-19.0.0-py3-none-any.whl
Size 129.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0bfec2cf14897a53b20fa2e4a7522c782ceafdf4479f9bfd07f4d7163852bfb5
BLAKE2b-256 checksum
How to use checksums
dc709d79612d5ea70b157b11b89a79b1bc0d342587b2cea99c492d830545489b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Security for pragmatiks-sdk 19.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pragmatiks_sdk-19.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

19.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page