Promenade
A local development process manager with a web UI. Run all your services with one command and see their status, logs, and health in a unified dashboard.
Installation
pip install promenade
Quick Start
- Create a
promenade.yamlin your project root:
services:
api:
command: flask run --port 5001
directory: ./backend
port: 5001
ready_check:
type: http
path: /health
frontend:
command: npm run dev
directory: ./frontend
port: 3000
depends_on:
- api
- Start everything:
promenade start
- Open http://localhost:7766 to see the web UI.
Features
- Process supervision - Start, stop, and restart services with automatic dependency ordering
- Health checks - HTTP and TCP health checks with configurable timeouts
- Log aggregation - Unified log viewer with per-service filtering
- Web UI - Real-time dashboard showing service status, health, and logs
- Hot reload - Automatically detects config changes and restarts affected services
- Restart policies - Configure
never,once, oralwaysrestart behavior
CLI Commands
promenade start # Start all services (with web UI on port 7766)
promenade start --no-ui # Start services without the web UI
promenade start --daemon # Run in background
promenade stop # Stop all services
promenade status # Show service status
promenade restart [service] # Restart a service (or all if no name given)
promenade logs [service] # View logs
promenade logs -f # Follow logs in real-time
promenade reload # Reload config and restart changed services
promenade config check # Validate your config file
Configuration
Promenade looks for config in this order:
--configflag./promenade.yaml~/.config/promenade/promenade.yaml
Full Example
manager:
port: 7766
host: 127.0.0.1
log_buffer_lines: 1000
defaults:
restart_policy: once
env:
NODE_ENV: development
services:
api:
command: flask run --port 5001
directory: ./backend
port: 5001
env:
FLASK_DEBUG: "1"
ready_check:
type: http
path: /health
timeout: 30
interval: 2
frontend:
command: npm run dev
directory: ./frontend
port: 3000
depends_on:
- api
ready_check:
type: tcp
timeout: 30
worker:
command: python worker.py
directory: ./backend
restart_policy: always
Service Options
| Option | Description |
|---|---|
command |
Command to run (required) |
directory |
Working directory |
port |
Port the service listens on |
env |
Environment variables |
env_file |
Path to .env file |
depends_on |
Services that must start first |
restart_policy |
never, once, or always |
ready_check |
Health check configuration |
Health Checks
ready_check:
type: http # or "tcp"
path: /health # HTTP only
timeout: 30 # Seconds to wait for healthy
interval: 2 # Seconds between checks
Running as a Daemon
For services you always want running, you can set up promenade to start automatically on login.
macOS (launchd)
Create ~/Library/LaunchAgents/com.promenade.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.promenade</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/promenade</string>
<string>start</string>
<string>--no-ui</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/promenade.log</string>
<key>StandardErrorPath</key>
<string>/tmp/promenade.log</string>
</dict>
</plist>
Then load it:
launchctl load ~/Library/LaunchAgents/com.promenade.plist
Find the path to promenade with which promenade.
Linux (systemd)
Create ~/.config/systemd/user/promenade.service:
[Unit]
Description=Promenade Dev Services
[Service]
ExecStart=/path/to/promenade start --no-ui
Restart=always
[Install]
WantedBy=default.target
Then enable it:
systemctl --user enable --now promenade
REST API
The manager exposes a REST API at the same port as the web UI:
GET /api/status- All services statusGET /api/services/{name}- Single service statusPOST /api/services/{name}/start- Start a servicePOST /api/services/{name}/stop- Stop a servicePOST /api/services/{name}/restart- Restart a serviceGET /api/services/{name}/logs- Get service logsPOST /api/reload- Reload configurationWS /api/logs/stream- WebSocket for real-time logs
License
MIT
Metadata
Release files for promenade 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| promenade-0.1.1.tar.gz | 152.8 kB | Without provenance | Details for promenade-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| promenade-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for promenade-0.1.1-py3-none-any.whl |
Total release size: 227.6 kB
Release files / promenade-0.1.1.tar.gz
| Download URL | promenade-0.1.1.tar.gz |
|---|---|
| Size | 152.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bccd9056ec5702ce76fd9a4848096ae72492e147903ee54381724a98b5eb1ff6
|
|
BLAKE2b-256 checksum How to use checksums |
36e3e773f058444aa50fc8453ef8aa1a777136c2ad15c6fa3e5bb60310b6abbf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.3
|
Release files / promenade-0.1.1-py3-none-any.whl
| Download URL | promenade-0.1.1-py3-none-any.whl |
|---|---|
| Size | 74.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
491eebe70f75f11e2bcd0631276121687f8d298e50e5cbfcc0a6ed757f2f03c4
|
|
BLAKE2b-256 checksum How to use checksums |
a46a2a12a17f6c3f66b148ddaf03012fbc79157268fa0e7e5dd60c03a1125547
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.3
|
Security for promenade 0.1.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.