Metadata-Version: 2.2
Name: publishkey
Version: 0.1.0
Summary: Press one key, ship your web app — detect FastAPI/Flask/Streamlit/Django and deploy to the cloud (stdlib-only engine).
Author-email: Meet2147 <meetjethwa3@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/Meet2147/pythonLibraries/tree/main/publishkey
Project-URL: Repository, https://github.com/Meet2147/pythonLibraries
Project-URL: Issues, https://github.com/Meet2147/pythonLibraries/issues
Keywords: deploy,cli,fastapi,flask,streamlit,django,railway,devtools
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE

# 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

```bash
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:

```bash
npm i -g @railway/cli && railway login
```

## Use it

```bash
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`)

```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 |
|----------|-----|-------|
| **Railway** | `railway` | 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`:

```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 a `FakeRunner` that 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

```bash
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`](../.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).
