Skip to main content

Pure-Python client for PM2's daemon RPC socket

Project description

pm2-rpc

Pure-Python client for PM2's daemon RPC socket.

[!CAUTION] Experimental (v0.2.0) — Early-stage personal project. API may change without notice.

Talks directly to ~/.pm2/rpc.sock using PM2's pm2-axon / pm2-axon-rpc wire stack (AMP framing → amp-message arg packing → axon-rpc body). The runtime makes zero pm2 CLI subprocess calls — every operation is one round-trip on the Unix socket. Returned values are plain dicts in PM2's own shape, no extra abstraction.

Install

pip install pm2-rpc           # core (only stdlib)
pip install 'pm2-rpc[yaml]'   # add YAML ecosystem-config support

Requires Python ≥ 3.11 and a running PM2 daemon on the same host.

Quick start

import os
import pm2_rpc as pm2

# List
for p in pm2.list():
    env = p["pm2_env"]
    print(env["pm_id"], env["name"], env["status"])

# Describe (raises pm2.NotFound)
proc = pm2.describe("worker")
print(proc["pm2_env"]["restart_time"])

# Start a fresh process — no ecosystem file required
pm2.start("scripts/worker.py", name="worker", env={"DEBUG": "1"})

# Or from an ecosystem.config.{json,yaml}
pm2.start_ecosystem("ecosystem.config.json", only="worker")

# Flip an env var without re-reading the ecosystem file (avoids the
# `pm2 restart NAME --update-env` foot-gun where passing ecosystem.config.js
# silently overrides --update-env)
pm2.restart("worker", env={**os.environ, "APP_MODE": "suite"})

# Logs (tails the file PM2 writes on disk, no streaming)
print(pm2.logs("worker", lines=50))
print(pm2.error_logs("worker", lines=20))

# Teardown
pm2.stop("worker")    # keeps the entry, status='stopped'
pm2.delete("worker")  # removes it entirely

API

list() -> list[dict] All registered processes
exists(name) -> bool Cheap existence probe
describe(target) -> dict One process; raises NotFound
start(script, **opts) -> dict Launch (fork mode); see kwargs below
start_ecosystem(config, *, only=, cwd=) -> list[dict] .json/.yaml; .js raises UnsupportedConfigError
restart(target, *, env=None) -> dict env merges server-side via Object.assign
stop(target) -> dict Graceful stop, keeps entry
delete(target) -> None Unregister
env(target) -> dict[str, str] The runtime env the process sees
logs(target, lines=15) -> str Last N lines of stdout
error_logs(target, lines=15) -> str Last N lines of stderr

pm2_rpc.start() kwargs use PM2's vocabulary: name, interpreter, cwd, args, env, autorestart, out_file, error_file, merge_logs.

Low-level access if you need it:

from pm2_rpc import rpc_call, PM2Error
rpc_call("getMonitorData", {})   # raw axon-rpc round-trip

What's not supported (v0.2.0)

  • Cluster mode (exec_mode: "cluster", instances > 1) — fork-mode only.
  • .js/.cjs/.mjs ecosystem configs (require node to evaluate module.exports). Convert to .json/.yaml, use pm2_rpc.start() with app fields, or shell out to pm2 start ecosystem.config.js --only NAME.
  • NVM-pinned interpreters (exec_interpreter: "node@18.0.0").
  • filter_env, source-map auto-detection, watch mode.
  • $PATH lookup of script names — pass an absolute path (use shutil.which() yourself if you really want a PATH binary).

Development

uv sync --group dev
uv run pytest tests/        # 64 tests, ~6s, requires a live PM2 daemon
uv run ruff check           # lint
uv run ruff format          # format (omit --check to apply)
uv run mypy                 # typecheck pm2_rpc/

CI runs lint + format + typecheck + the full 64-test suite + build on every PR — PM2 is installed from npm on the runner.

Fixture processes are named pm2rpc-test-* so they're easy to identify if a test crashes and leaks one.

License

MIT — see LICENSE.

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

pm2_rpc-0.2.2.tar.gz (10.8 kB view details)

Uploaded Source

Built Distribution

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

pm2_rpc-0.2.2-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file pm2_rpc-0.2.2.tar.gz.

File metadata

  • Download URL: pm2_rpc-0.2.2.tar.gz
  • Upload date:
  • Size: 10.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pm2_rpc-0.2.2.tar.gz
Algorithm Hash digest
SHA256 209efe9038686e3c4aaf948fffbf9d76857736f51c098f35cd82bf586b62addf
MD5 c10ec7c4308c7102e6d9b7136460d07f
BLAKE2b-256 6eaf1c6a1ce6278bd621241c82bbcf1a52abb95e482ca9e24f5bf2ef74abf8d2

See more details on using hashes here.

File details

Details for the file pm2_rpc-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: pm2_rpc-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pm2_rpc-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4e718d91ff263b87cf31b2f7e978ca9ca902b58a602b5360cbf800e6bd59e4f5
MD5 c6937bb8e3ed1f61befd61d90266d29e
BLAKE2b-256 9052fbd83732f744f43f2a4ed6b35c9ab5ee151b25019413f6c349123a4d9eb7

See more details on using hashes here.

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