Press one key, ship your web app — detect FastAPI/Flask/Streamlit/Django and deploy to the cloud (stdlib-only engine).
Project description
publishkey — press one key, ship your web app
publishkey looks at your project, figures out what web framework it is
(FastAPI, Flask, Streamlit, or Django), works out the right production start
command, and deploys it to a cloud host — all from one command (and, soon,
one keystroke inside VS Code).
This package is the engine: a small, zero-dependency Python core. Two "faces" sit on top of it — a CLI (in this package) and a VS Code extension (separate) — so the deploy logic is written once and shared.
publishkey (Python engine) ← this package
detect framework · deploy
▲ ▲
CLI face VS Code extension ← the two UIs
Install
pip install publishkey # once published
# or, for local development:
cd publishkey && pip install -e .
You also need the CLI of whichever provider you deploy to — e.g. Railway:
npm i -g @railway/cli && railway login
Use it
publishkey detect # what framework is this folder?
publishkey init # write a .publishkey.json for the project
publishkey providers # which deploy targets are installed & logged in?
publishkey deploy # detect → pre-flight checks → confirm → ship
publishkey deploy --yes # skip the confirmation prompt (for scripts/hotkeys)
Typical first run:
$ publishkey deploy
Project: .
framework fastapi (high confidence)
entry file main.py
start command uvicorn main:app --host 0.0.0.0 --port $PORT
Deploy this fastapi to railway? [y/N] y
Deploying to railway ...
✓ Deploy started on Railway (wrote Procfile). Track it with `railway logs`.
What it detects
| Framework | Signal | Start command it generates |
|---|---|---|
| FastAPI | FastAPI( + import fastapi |
uvicorn <module>:<app> --host 0.0.0.0 --port $PORT |
| Flask | Flask( |
gunicorn <module>:<app> --bind 0.0.0.0:$PORT |
| Streamlit | import streamlit |
streamlit run <file> --server.port $PORT |
| Django | manage.py + wsgi.py |
gunicorn <project>.wsgi --bind 0.0.0.0:$PORT |
Detection is heuristic but deterministic — same folder in, same answer out.
Override anything in .publishkey.json.
Configuration (.publishkey.json)
{
"provider": "railway",
"hotkey": "cmd+shift+p",
"framework": "fastapi",
"start_command": "uvicorn main:app --host 0.0.0.0 --port $PORT",
"providers": { "railway": { "service": "web" } }
}
Everything is optional — with no config, publishkey auto-detects and uses
Railway.
Providers
Providers are pluggable adapters over a real deployment CLI:
| Provider | CLI | Notes |
|---|---|---|
| FastAPI Cloud | fastapi |
FastAPI-native: fastapi login then fastapi deploy. FastAPI apps only, no Procfile. |
| Railway | railway |
Any framework. Auto-creates the service; writes a Procfile for the start command. |
| Fly.io | flyctl / fly |
Needs a fly.toml first (fly launch once); then fly deploy. |
Adding another (Render, AWS App Runner, ...) is a small file — implement
is_installed, is_authenticated, and deploy against the injectable command
runner, then register it in providers/__init__.py. That runner is why the
whole engine is unit-testable without ever spawning a real deploy. Buildpack
hosts share the base class's ensure_procfile helper, so a new adapter is
often just the CLI-specific glue.
Set the provider (and per-provider options) in .publishkey.json:
{ "provider": "fly", "providers": { "fly": { "app": "my-app" } } }
Design principles
- Zero required dependencies — pure standard library, Python 3.8+.
- Deterministic & testable — every shell-out goes through an injectable
Runner; tests use aFakeRunnerthat scripts responses. - One engine, many faces — the CLI and the VS Code extension call the same functions; deploy logic lives in exactly one place.
Run the tests
python -m unittest discover -s tests
Publishing to PyPI
Releases go out via GitHub Actions using Trusted Publishing (OIDC) — no
tokens stored. Bump version in pyproject.toml, then run the
"Publish publishkey to PyPI" workflow from the Actions tab. One-time PyPI
setup is documented in
.github/workflows/publish-publishkey.yml.
Roadmap
- VS Code extension face (native keybinding → the "publish key" experience).
- More providers: Fly.io, Render, AWS App Runner.
- Deploy history + one-click rollback (premium tier).
- Env-var / secrets management UI (premium tier).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file publishkey-0.2.0.tar.gz.
File metadata
- Download URL: publishkey-0.2.0.tar.gz
- Upload date:
- Size: 19.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d442f5e5fb20c7b38bba0ba7a9b52c6b4d5052afd9e9f6fc4afb8cf033508f7
|
|
| MD5 |
eae2c803bec9d778e1ce825a140f58f6
|
|
| BLAKE2b-256 |
419ed13f6466c58ec3ad384c204ad74766ebb7e056f59479b23c4240ae7102f6
|
Provenance
The following attestation bundles were made for publishkey-0.2.0.tar.gz:
Publisher:
publish-publishkey.yml on Meet2147/pythonLibraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
publishkey-0.2.0.tar.gz -
Subject digest:
3d442f5e5fb20c7b38bba0ba7a9b52c6b4d5052afd9e9f6fc4afb8cf033508f7 - Sigstore transparency entry: 2271278473
- Sigstore integration time:
-
Permalink:
Meet2147/pythonLibraries@57176d25ade51cf9b45aa2cd34f0908278c3d862 -
Branch / Tag:
refs/heads/claude/python-cli-deploy-shortcuts-ny0v8r - Owner: https://github.com/Meet2147
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-publishkey.yml@57176d25ade51cf9b45aa2cd34f0908278c3d862 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file publishkey-0.2.0-py3-none-any.whl.
File metadata
- Download URL: publishkey-0.2.0-py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
622f4a00154eefd0dae0f48571c637878103fbfb7f47ae94e1b12402a3a5002a
|
|
| MD5 |
d37d1ba62e6b815ddaa43ed740c65672
|
|
| BLAKE2b-256 |
e0fdcdc89ff0e24f9d4778f5dca4053e5e3e5d6f11db9628459aa0d6e580da52
|
Provenance
The following attestation bundles were made for publishkey-0.2.0-py3-none-any.whl:
Publisher:
publish-publishkey.yml on Meet2147/pythonLibraries
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
publishkey-0.2.0-py3-none-any.whl -
Subject digest:
622f4a00154eefd0dae0f48571c637878103fbfb7f47ae94e1b12402a3a5002a - Sigstore transparency entry: 2271278558
- Sigstore integration time:
-
Permalink:
Meet2147/pythonLibraries@57176d25ade51cf9b45aa2cd34f0908278c3d862 -
Branch / Tag:
refs/heads/claude/python-cli-deploy-shortcuts-ny0v8r - Owner: https://github.com/Meet2147
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-publishkey.yml@57176d25ade51cf9b45aa2cd34f0908278c3d862 -
Trigger Event:
workflow_dispatch
-
Statement type: