hop3-cli
Command-line interface for interacting with Hop3 servers.
Overview
hop3-cli is a thin client that communicates with hop3-server via JSON-RPC over HTTP or SSH tunneling. It provides a familiar Heroku-like CLI experience for deploying and managing applications.
Features
- Application management: Deploy, start, stop, restart, and scale applications
- Environment variables: Securely manage app configuration
- Log streaming: View real-time application logs
- Addon management: Provision and manage backing services (PostgreSQL, Redis, MySQL)
- SSH tunneling: Secure communication with remote servers
- Multiple output formats: Human-readable, JSON, or quiet mode
Installation
pip install hop3-cli
Quick Start
# Initialize connection to a Hop3 server
hop3 init user@hop3.example.com
# Or configure via environment
export HOP3_API_URL="ssh://user@hop3.example.com"
# List applications (no app target needed)
hop3 apps
# Bind a default app for this shell/context (sticky)
hop3 use myapp
# From here on, app-scoped commands resolve myapp automatically:
hop3 app logs
hop3 config set KEY=value
hop3 app restart
App Resolution
Commands that act on a single app (logs, restart, config set, run, …) no longer take the app name as a positional argument. Instead the CLI resolves it from a layered chain, walking sources until one supplies a value (ADR 042 §Resolution; supersedes ADR 036 §D7):
--app <name>/-a <name>— explicit flag, wins over everything.$HOP3_APP— environment variable for the current shell..hop3-app— one-line file in CWD or any ancestor up to$HOME. Drop it in a project repo andhop3from inside picks up the right app.hop3.toml [cli].app— same search path as.hop3-app, lower priority.hop3.toml [contexts.<resolved-context>].app— when a project context resolves (see below), itsappfield becomes the source. Lets one project map per-environment to different apps. Trusted only when the context was selected CWD-rooted (--contextor in-tree.hop3-local.toml); an ambiently-selected context still resolves but trips the project-mismatch guard.hop3.toml [metadata].id— the project's canonical name. The "I'm physically standing in this project" source, so being inside a project always wins over a sticky binding from elsewhere.
Use hop3 --why <command> to print the full trace and see which source won. --why is diagnostic-only: the command itself is not executed (so hop3 deploy --why is safe to run).
# Explicit (always works):
hop3 app logs --app myapp
hop3 config set --app myapp KEY=value
# Per-shell:
export HOP3_APP=myapp
# Per-directory (legacy pin file):
echo myapp > .hop3-app
# Per-project, declared in hop3.toml:
# [metadata]
# id = "myapp"
# [contexts.staging]
# app = "myapp-staging"
# Debug:
hop3 --why logs
The ADR 042 model has a single managed noun — the context — and a single selector, --context <name>, for every command (app-bound or not).
- Contexts — a named target at two scopes. A project context (dev / staging / prod) is declared as a
[contexts.<name>]block inside the committedhop3.toml: a non-secret bundle of server address + app + domains + env. A global context is a name bound to a server address in the per-developerconfig.toml([contexts.<name>].server), so project-less commands (hop3 apps --context prod) can target a server by name.--contextresolves project-first, then global; there is no--serverflag. Managed withhop3 context(add/use/list/show/remove/rename) — project scope inside a project tree, global scope outside one (or with--global). The per-checkout project selection is recorded in.hop3-local.toml(gitignored automatically). - Credentials are invisible plumbing — there is no "server" noun to manage.
hop3 loginstores a bearer token in the per-server credential store (~/.config/hop3-cli/credentials.toml, mode0600), keyed by the server's canonical address, and records that server as the default target;hop3 login --context <name>also names it as a global context and the default.config.tomlstays secret-free (local preferences, global contexts,[cli].default_context).
A hop3 deploy from a project tree resolves the context (which environment of this project, and therefore which server and app), and shows a preview-and-confirm prompt with the plan before invoking the deploy RPC. --dry-run exits after printing the plan; --force bypasses the project-mismatch safety guard.
See CLI Reference: App Resolution and ADR 042 for the full specification.
Configuration
Configuration can be set via environment variables or config file (~/.config/hop3-cli/config.toml).
| Variable | Description | Default |
|---|---|---|
HOP3_API_URL |
Server URL (HTTP or SSH) | - |
HOP3_API_TOKEN |
Authentication token | - |
HOP3_APP |
Default app for app-scoped commands | - |
HOP3_CONTEXT |
Active context name | - |
HOP3_DEV_MODE |
Enable development mode | false |
Architecture
hop3-cli/
├── src/hop3_cli/
│ ├── main.py # Entry point, argument parsing
│ ├── config.py # Configuration management
│ ├── core/
│ │ └── resolution.py # App resolution chain (ADR 036 D7)
│ ├── rpc/
│ │ └── client.py # JSON-RPC client with SSH tunnel
│ ├── commands/
│ │ ├── local/ # Local commands (init, login, settings, context)
│ │ ├── flags.py # CLI flag parsing (--app, --why, --json, -y, …)
│ │ └── destructive.py # Confirmation prompts
│ └── ui/
│ └── rich_printer.py # Output formatting
└── tests/
Development
# Run tests
uv run pytest tests/ -v
# Lint and format
uv run ruff check src/
uv run ruff format src/
Documentation
Related Packages
- hop3-server - The server that hop3-cli communicates with
- hop3-tui - Alternative terminal UI interface
License
Apache-2.0 - Copyright (c) 2024-2026, Abilian SAS
Metadata
Release files for hop3-cli 0.7.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hop3_cli-0.7.3.tar.gz | 146.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hop3_cli-0.7.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 326.0 kB
Release files / hop3_cli-0.7.3.tar.gz
| Download URL | hop3_cli-0.7.3.tar.gz |
|---|---|
| Size | 146.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cee6c9eaba6529e0dd2f0d47c9f84ec4a8cd80ca4b16afd8549c90eda0bbd3e4
|
|
BLAKE2b-256 checksum How to use checksums |
b09f9be9e556971b4a96074bb795d5f547c2f708fd47018cb64e4799dbbf453e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / hop3_cli-0.7.3-py3-none-any.whl
| Download URL | hop3_cli-0.7.3-py3-none-any.whl |
|---|---|
| Size | 179.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
538b959e27c8bbd52b7954e044ac37b8bfb4fe7596472d0648cff40e0b08f34a
|
|
BLAKE2b-256 checksum How to use checksums |
ecfe5b262fd4ade1424b233b3d0b3602ef24440ade66ce8155774193b404275d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|