Skip to main content

PushMetrics CLI (pm)

pm is the command-line client for PushMetrics. It talks to the same REST API the web app uses, with the same permissions: you see the reports, databases and users you have access to, in one workspace, nothing more.

Use it to run and debug reports, keep report definitions in git, feed CI pipelines, or give an AI coding agent a scriptable handle on your workspace. Every command has a --json mode.

The complete user guide is on the website: PushMetrics CLI.

Install

PLACEHOLDER (D1). The install command depends on the distribution channel and is filled in at release time.

# PLACEHOLDER (D1): install command goes here
pm --version

Requires Python 3.9 or newer. Runs on macOS, Linux and Windows.

Quick start

  1. In the PushMetrics app, open Settings → Access Tokens (/a/tokens), click New token, and copy the pmpat_... value. It is shown once, and it is bound to the workspace that was active when you created it.

  2. Log in with the token. pm reads it from a hidden prompt, or from stdin when piped, and stores it in your OS credential store:

    pm login --token
    pm whoami
    
  3. Use it:

    pm report list
    pm report get <report-uid>
    pm report run <report-uid> --send-to-me
    pm run list --last-days 2 --status failed
    pm run logs <run-uid> --level ERROR
    pm report list --json
    

In CI, skip pm login and set PM_API_TOKEN instead.

PLACEHOLDER (D2). Browser login (pm login without --token, Auth0 device flow) is documented here only if it ships in the first release.

Commands

pm --help lists every command. pm <group> --help lists a group's actions, pm <group> <action> --help the options, and pm help <group> shows a compact page with examples.

Account:
  login   Log in with a personal access token.
  logout  Log out and forget the stored token or session.
  whoami  Show who you are logged in as, and the workspace.
  token   Personal access tokens for API / CLI authentication.
  config  Profiles: which PushMetrics server pm talks to.

Commands:
  block         Blocks of any type.
  chart         Charts (Plotly blocks).
  database      Databases, their schemas and tables.
  email         Email blocks.
  explore       Explore blocks (saved data views).
  favorite      Your favorite reports and other objects.
  folder        Folders that organize reports.
  help          Show compact help for a group, with examples.
  integration   Connected services (Slack, Tableau, Google Drive, ...).
  metrics-view  Metrics views (the semantic layer).
  organization  Your organization (the owner of workspaces).
  recipient     Recipients: who reports are delivered to.
  report        Reports and their runs.
  role          Roles and groups in the current workspace.
  run           Report runs: status, results and logs.
  saved-block   Saved blocks (reusable block templates).
  sftp          SFTP upload blocks.
  slack         Slack message blocks.
  slides        Google Slides blocks.
  sql           SQL query blocks.
  tableau       Tableau view blocks.
  user          Users in the current workspace.
  webhook       Webhooks that trigger report runs.
  workspace     Workspaces you belong to.

The ones most people need:

Command What it does
pm whoami Your user and the token's workspace.
pm report list Reports in the workspace. --name filters by name, --limit caps the rows.
pm report get <uid> One report. Full record with --json.
pm report yaml <uid> The report's full YAML configuration, to stdout.
pm report apply <file> --uid <uid> Write a YAML file back to a report. --dry-run shows the diff without saving.
pm report run <uid> Start a run and print its uid. --send-to-me sends the email blocks to you and skips every other destination; --email <address> previews as a saved recipient.
pm run list Recent runs, newest first. --report <uid>, --last-days N, --status failed, --limit N.
pm run get <run-uid> A run's status and timing.
pm run logs <run-uid> A run's log lines. --level ERROR keeps only errors.
pm run results <run-uid> What each block of the run produced.
pm token list / create <name> / revoke <id> Manage your personal access tokens.
pm config list Profiles and the environment overrides in effect.

--json works before or after the action (pm --json report list and pm report list --json). Data goes to stdout; messages and errors go to stderr. pm exits with 0 on success, 1 when a command fails and 2 when the command line is wrong.

Global options

Option Meaning
--json Print JSON instead of tables.
--quiet Suppress informational messages on stderr. Errors still print.
-v, --verbose Log each request, its status and timing to stderr; response bodies on errors only. Tokens are never logged.
--profile <name> Use a profile other than default.
--api-url <url> Talk to a different PushMetrics address for one command.
--version Print the version and exit.

Environment variables

Variable Purpose
PM_API_TOKEN A personal access token. Wins over a token stored by pm login --token. For CI and agents.
PM_PROFILE Profile to use when no --profile is given.
PM_API_URL Talk to this address instead of the profile's.
PM_CONFIG_HOME Where configuration and fallback credential files live. Default: ~/.pm.

Several workspaces

A token works in one workspace. To work in a second one, create a token there and give it its own profile:

pm config set acme api_url https://pushmetrics.io
pm --profile acme login --token
pm --profile acme report list

pm workspace switch is for browser login only; with a token, the token decides the workspace.

Where credentials live

pm login --token stores the token in the OS credential store (macOS Keychain, Windows Credential Manager, Linux Secret Service) under the service name pushmetrics-cli-pat, one entry per profile. Without a usable credential store it falls back to ~/.pm/tokens.json, mode 0600.

pm also caches the short-lived access token it exchanges from your personal access token, under the service name pushmetrics-cli-jwt or in ~/.pm/jwt_cache.json with mode 0600.

pm logout removes both for the active profile. It does not revoke the token on the server; use pm token revoke or the Access Tokens page for that.

pm never takes a token on the command line and never prints one, in -v output or in errors. It only sends tokens over https://, except to localhost.

Troubleshooting

Not logged in. Run pm login --token with a personal access token, or set PM_API_TOKEN. Nothing stored for the active profile and PM_API_TOKEN unset. Tokens are stored per profile: check pm config list.

That does not look like a personal access token… What was pasted, piped or set in PM_API_TOKEN is not a pmpat_... value. Copy it again exactly.

Personal access token rejected (invalid, expired, or revoked). Create a new token and log in again.

Could not reach https://... (ConnectionError)… Network, or the wrong address: pm config list shows it.

Unknown profile: 'acme'… or Profile 'acme' has no api_url… Each message ends with the pm config set command that fixes it; see also Several workspaces.

API ... failed: 403 / 404 with a Hint: line. The hint names the next step: permissions in the token's workspace, or an id that is not visible there.

Anything else. Re-run with pm -v ... and look at the response status and body.

The website guide lists every error with its fix.

Contributing

The CLI lives in the cli/ directory of the PushMetrics monorepo and must not import anything from the backend packages (superset/, prefect/); a test enforces this. To work on it:

cd cli
python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'          # contributors only; users install the released package
pytest tests/ -v
ruff check .

Tests mock HTTP with the responses library and never reach a real backend. tests/repo_only/ holds tests that read files outside cli/, such as test_docs_commands_exist.py, which checks every pm command written in this README and in the website guide against the real command tree; they run from a checkout and are not shipped in the sdist. CI runs the suite on every pull request that touches cli/.

When you run a real pm process during development, set PM_CONFIG_HOME to a scratch directory and PYTHON_KEYRING_BACKEND=keyring.backends.fail.Keyring. PM_CONFIG_HOME alone does not isolate credentials: the OS keyring is keyed by profile name, so a scratch run would read, and pm logout would delete, your real stored token.

Adding a resource. For anything with the standard CRUD shape (/<resource>/ list, /<resource>/<uid> single, plus POST/PUT/DELETE):

  1. Model in pm/models/<resource>.py: a Pydantic BaseModel with extra="allow"; re-export from pm/models/__init__.py.
  2. Client in pm/client/<resource>.py: subclass CrudClient[Model], set base_path and model. Register it on the PMClient facade in pm/client/__init__.py.
  3. Commands in pm/commands/<resource>.py: a click.group(cls=AliasedGroup, aliases={"ls": "list"}) with list/get/create/update/delete; use parse_data and merge_fields from pm/commands/_helpers.py for the --data '<json>' pattern. Skip verbs the backend does not support.
  4. Wire it in pm/cli.py with cli.add_command(...).
  5. Tests in tests/test_client_<resource>.py, asserting on model attributes.
  6. Docs: add the command to the website guide (website/content/posts/docs/admin/2026-10-12-cli.md); the docs test fails if a documented command does not exist.

Endpoint paths to mirror live in frontend/src/shared/services/*.ts; the frontend prefixes everything with /api/v1.

The PMClient facade is reusable from Python without the command layer:

from pm.client import PMClient
from pm.config import get_profile

client = PMClient.from_profile(get_profile("default"))
for report in client.reports.list():
    print(report.uid, report.name)

Authentication resolution order inside PMSession.from_profile: PM_API_JWT (a delegation JWT the PushMetrics AI agent sets, used as-is) > personal access token (PM_API_TOKEN or stored, exchanged at /api/v1/security/exchange for a short-lived workspace-scoped JWT) > Auth0 session cookies from a browser login. Bearer JWTs carry a workspace_id claim that the backend installs as the request's workspace, so a pure Bearer client has full workspace context; cookies are the interactive path only.

Metadata

Release files for pushmetrics-cli 0.1.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 pushmetrics-cli 0.1.0
File Size Uploaded
pushmetrics_cli-0.1.0.tar.gz 192.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pushmetrics-cli 0.1.0
File Interpreter ABI Platform
pushmetrics_cli-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 334.8 kB

Release files / pushmetrics_cli-0.1.0.tar.gz

Download URL pushmetrics_cli-0.1.0.tar.gz
Size 192.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a29824711097d55219fc28294bea01eb522f0038caccb4ca80396d18ed2b34c7
BLAKE2b-256 checksum
How to use checksums
cdcb987710cd018b34e06e0a6666527f69474184858a2ed83ced6830a882b3b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 16, 2026.

Transparency log

Release files / pushmetrics_cli-0.1.0-py3-none-any.whl

Download URL pushmetrics_cli-0.1.0-py3-none-any.whl
Size 142.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46bb6fff0890fbd5edf20961c881a0d0ea27a5b2662e8c1df3ac7dd14aeebb51
BLAKE2b-256 checksum
How to use checksums
d700fbb19717c00ea306382c1a14ec3e6c71b4b353c40e7916933816746f462e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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