Skip to main content

A TM1py-inspired Python wrapper for the IBM Planning Analytics Workspace (PAW) REST API.

Project description

PAWpy — Planning Analytics Workspace REST API Wrapper

PyPI version Python versions License: MIT

A TM1py-inspired Python wrapper for the PAW REST API.

Install

uv sync --extra dev         # installs PAWpy + pytest
uv run python -m pytest     # 21 offline tests (no live server needed)

Requires Python ≥3.11 and requests. The URL-builder calls (paw.ui.*, *.get_embed_url) make no network request and work without a live PAW server.

Releasing

Publishing is automated by .github/workflows/publish.yml via PyPI Trusted Publishing (OIDC — no API token stored). To cut a release:

  1. Bump version in pyproject.toml and add a CHANGELOG.md entry.
  2. One-time on PyPI: add a Trusted Publisher for project PAWpybluestarleo/PAWpy, workflow publish.yml, environment pypi.
  3. Tag and push:
    git tag v0.1.0 && git push origin v0.1.0
    

The workflow runs the tests (3.11–3.13), builds, checks the tag matches the package version, and publishes the sdist + wheel to PyPI.

Architecture

PAWService                  ← top-level entry point (mirrors TM1py's TM1Service)
├── RestService             ← session + auth + GET/POST/PATCH/PUT/DELETE core
├── ContentService          ← /pacontent/v1/Assets  (legacy OData folders / books / assets)
├── ContentV1Service        ← /api/v1/content  (OAuth-era assets, permissions,
│                             bulk ops, asset types — PAW 2.1.21+/3.1.8+)
├── UserGroupService        ← /api/v1/content/users|groups  (PAW 2.1.21+/3.1.8+)
├── BookService             ← books (type=book/dashboard) over ContentService
├── ViewService             ← views over ContentService
├── AdminService            ← /api/v1/admin  (servers, users, groups)
├── UIService               ← URL builder for /ui?type=… embed endpoints
└── TM1ProxyService         ← /api/v0/tm1/<db>/api/v1/…  (TM1 REST via PAW auth;
                              pass tm1_proxy_base="/api/v1/tm1" on PAW 2.1.21+/3.1.8+)

All base paths (content_base, admin_base) are constructor-overridable, since they vary across PAW builds (/pacontent/v1 vs /api/v1/content).

Auth Modes

Mode How it works
oauth Client-credentials grant against token_urlAuthorization: Bearer
cam CAM namespace login via POST /loginx-csrf-token
native TM1 native username/password login via POST /loginx-csrf-token
passport Cognos CAM passport (camid) via POST /login
session Inject an existing csrf_token / session_cookie (dev/test)

Usage

OAuth (Recommended)

from PAWpy import PAWService

with PAWService(
    host="paw.mycompany.com",
    auth_mode="oauth",
    client_id="my-client-id",
    client_secret="my-client-secret",
    token_url="https://idp.mycompany.com/oauth2/token",  # required for oauth
    scope="paw",                    # optional
    database="Global FPA",          # optional default TM1 database
) as paw:

    # List books in a folder (returns Asset objects)
    books = paw.books.get_all("/shared/FP&A")

    # Get embed URL for an iframe (no HTTP call)
    url = paw.books.get_embed_url("/shared/FP&A/Monthly Report")

    # List registered TM1 servers
    servers = paw.admin.get_tm1_servers()

    # OAuth-era content API (PAW 2.1.21+/3.1.8+): permissions, bulk ops, users
    assets = paw.content_v1.list_children("shared")
    perms  = paw.content_v1.get_effective_permissions(assets[0].id)
    users  = paw.user_groups.get_users()

    # TM1 proxy call (MDX via PAW auth) — returns the raw cellset JSON
    tm1 = paw.tm1("Global FPA")
    data = tm1.execute_mdx("SELECT {[Account].[Revenue]} ON 0 FROM [Revenue Cube]")

    # Embed URL generation (no HTTP call)
    embed = paw.ui.cube_viewer_url("Global FPA", "Revenue Cube", view="Monthly View")

Legacy CAM

with PAWService(
    host="paw.mycompany.com",
    auth_mode="cam",
    namespace="LDAP",
    username="my-username",
    password="secret",
) as paw:
    ...

Multi-tenant (PAW Cloud)

with PAWService(
    host="planning-analytics.cloud.ibm.com",
    tenant_id="my-tenant-id",
    auth_mode="oauth",
    client_id="...",
    client_secret="...",
) as paw:
    ...

Mapping to TM1py

TM1py PAWpy
TM1Service PAWService
CubeService TM1ProxyService (via PAW)
DimensionService TM1ProxyService (via PAW)
ProcessService TM1ProxyService (via PAW)
(no equivalent) BookService
(no equivalent) ContentService
(no equivalent) AdminService
(no equivalent) UIService

Versioning against PAW builds

The PAW REST API is still incomplete and grows with each IBM release, so PAWpy is versioned against two axes: its own semver (PAWpy.__version__) and the minimum PAW build each API group requires. Each service declares its API_GROUP; the per-group minimums live in PAWpy/version_requirements.py (MIN_PAW_VERSION).

paw = PAWService(host="paw.acme.com", auth_mode="oauth", ..., paw_version="2.1.21")

paw.requires("content")          # -> "2.1.21"  (min PAW build for Content Services)
paw.supports("content")          # -> True / False against the known paw_version
paw.assert_supported("content")  # raises PAWVersionError if the build is too old
paw.detect_paw_version()         # best-effort probe (overridable path/field)

When paw_version is unknown, gating is a no-op — PAWpy never blocks a call solely because it couldn't determine the version; the server still rejects genuinely-unsupported requests. The version pins are reconciled on each PAW release as part of a maintainer-local workflow.

Coverage & release tracking

PAWpy's endpoint coverage is tracked in a maintainer-local coverage matrix (not part of this repo). Because the PAW REST API is still growing, it is reconciled on each PAW release: IBM's endpoint inventory (the IBM-linked Postman collection or the published API references) is re-pulled and diffed against the matrix to flag endpoints PAW now exposes that PAWpy doesn't yet wrap, so the wrapper tracks IBM's cadence instead of drifting. New coverage lands here as Added entries in CHANGELOG.md and Roadmap items below.

Roadmap (aligned with IBM's "future releases" promise)

  • Content API v1 (/api/v1/content, PAW 2.1.21+/3.1.8+) — ContentV1Service: assets incl. content retrieval, permissions (get/set/effective), bulk copy/move/delete/permissions, asset types
  • UserGroupService — PAW users/groups reads (/api/v1/content/users|groups); write endpoints not yet documented by IBM
  • ViewService — PAW view CRUD
  • EmbedTokenService — generate scoped embed tokens
  • MCPService — PAW MCP endpoint integration
  • Token refresh / OAuth expiry handling
  • Async support (aiohttp)
  • Pydantic models for Books, Assets, Servers

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

pawpy-0.4.0.tar.gz (28.5 kB view details)

Uploaded Source

Built Distribution

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

pawpy-0.4.0-py3-none-any.whl (31.7 kB view details)

Uploaded Python 3

File details

Details for the file pawpy-0.4.0.tar.gz.

File metadata

  • Download URL: pawpy-0.4.0.tar.gz
  • Upload date:
  • Size: 28.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for pawpy-0.4.0.tar.gz
Algorithm Hash digest
SHA256 1321f29910e61c360d2341df9832f31daa5809d797c8bd81be284ea94bfc03a8
MD5 909b611befeaee9f68412c69d4997a07
BLAKE2b-256 0081ca33fff4b142dc58e1484c5b1e41c4dc7e2ffbfc39b5cd6d3cb7357051c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pawpy-0.4.0.tar.gz:

Publisher: publish.yml on bluestarleo/PAWpy

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

File details

Details for the file pawpy-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: pawpy-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 31.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for pawpy-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3c2fb5f38edc1192bacc8f226819f2a071cc186400c5efc510976d37c4ac06f1
MD5 4ca5ad4c33a3df3f4c7fb8117fb53b6a
BLAKE2b-256 d34d67ce132a76dba51d6cef13f7de1425598a9913824e7b0cb018bae41d1502

See more details on using hashes here.

Provenance

The following attestation bundles were made for pawpy-0.4.0-py3-none-any.whl:

Publisher: publish.yml on bluestarleo/PAWpy

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