Metadata-Version: 2.5
Name: djangocloud-cli
Version: 0.1.6
Summary: Deploy a Django app from the command line: djangocloud login, djangocloud deploy, djangocloud logs.
Project-URL: Homepage, https://djangocloud.dev
Project-URL: Source, https://github.com/two-trick-pony-NL/djangocloud-cli
Project-URL: Issues, https://github.com/two-trick-pony-NL/djangocloud-cli/issues
Author-email: Peter van Doorn <peter@petervandoorn.com>
License-Expression: MIT
License-File: LICENSE
Keywords: aws,cli,deploy,django,lightsail
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Framework :: Django :: 5.2
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development
Requires-Python: >=3.10
Requires-Dist: questionary>=2.0
Requires-Dist: rich>=13
Description-Content-Type: text/markdown

<img width="800" alt="og-image" src="https://github.com/user-attachments/assets/061d5725-dfba-49b9-906e-79a3e938dfb7" />


**Deploying a Django app shouldn't be a hassle.**

No Dockerfiles. No load balancers. No server to babysit. You add one package to your project, sign in, and
[DjangoCloud](https://djangocloud.dev) takes care of the rest, running your app on AWS.

```
pip install djangocloud-cli
python manage.py djangocloud login
python manage.py djangocloud deploy
```

That's the whole idea: a few commands, from the project you already have.

> **Early release.** Sign-in, linking, packaging and uploading work, and the deploy streams its progress back to
> your terminal. Image builds on DjangoCloud's side are still being finished, so a deploy may stop at that step.
> Follow along at [djangocloud.dev](https://djangocloud.dev).

You need a [DjangoCloud](https://djangocloud.dev) account with a card on file to create projects.

## What it looks like

```
$ python manage.py djangocloud deploy
You're not signed in yet.
Open https://djangocloud.dev/dashboard/cli/?code=ABCD-EFGH and check that the code is ABCD-EFGH.
✓ Signed in as you@example.com
? Which project is this?  Create a new project
? Server size  Nano  0.25 vCPU, 0.5 GB RAM  ~$7/month on AWS
? AWS bills you about $7/month for this server, directly in your own AWS account. Continue? Yes
✓ Linked to my-shop (.djangocloud/config.json)
Deploying my-shop
✓ Wrote build settings to .djangocloud/config.json
  found wsgi_module = config.wsgi:application
✓ Packed 148 files (212 KB). .env and .git are never uploaded.
✓ Uploaded. Release v1 started.
  Building v1
  v1 is live
✓ v1 is live.
```

## Features

### Everything runs through `manage.py`

All commands live under `python manage.py djangocloud`. Run it with no arguments, or use `help`, to see them all.

| Command | What it does |
|---|---|
| `login` | Sign in by approving a code in your browser |
| `logout` | Forget the stored token |
| `whoami` | Show who you're signed in as, and which project this folder deploys to |
| `link` | Pick or create the project this folder deploys to |
| `unlink` | Detach this folder from its project |
| `deploy` | Link the folder if needed, pack it, upload it and stream the release until it is live (`--github` deploys the linked repo's latest commit instead) |
| `logs` | Show a project's logs *(coming)* |
| `status` | Show the current release and its state *(coming)* |
| `help [command]` | Help for everything, or for one command |

A standalone `djangocloud` command is installed as well, with the same commands and no `manage.py`. It's handy when
your project's settings won't load.

### Smooth, guided setup

Arrow-key menus, clear prices up front and no surprises. Nothing is created until you confirm.

### Your folder remembers its project

`.djangocloud/config.json` records which project a folder deploys to. It holds no secrets, and a `.gitignore` inside
the folder keeps it out of your repository. After the first run there are no prompts.

### What gets uploaded

The folder is packed into a `.tar.gz` that is the same every time for the same files. In a git repository that is
what git sees (your `.gitignore` is respected); otherwise junk is skipped. Whatever `.gitignore` says, these never go
up: `.env` and `.env.*` (except `.env.example`), `.git`, virtualenvs, `node_modules`, `*.sqlite3`, `*.pem`, `*.key` and
caches. Set your environment variables in the dashboard, not in the upload.

### Build settings

The first deploy detects your setup and writes it to the `"build"` block of `.djangocloud/config.json`. That file is
then the source of truth, so edit it to change how your app is built:

```json
{
  "build": {
    "wsgi_module": "config.wsgi:application",
    "django_settings_module": "config.settings",
    "python_version": "3.13",
    "package_manager": "pip",
    "requirements_file": "requirements.txt",
    "system_packages": ["libpq-dev"],
    "collectstatic": true,
    "release_command": "python manage.py migrate --noinput",
    "port": 8000,
    "workers": 2,
    "healthcheck_path": "/"
  }
}
```

The server checks every setting and lists all problems at once. The full list with defaults is at
`/api/v1/build-config`. If your WSGI app can't be detected in CI, pass `--wsgi-module config.wsgi:application`.

### Safe sign-in

Login uses a short code you approve in the browser, so no password or key is ever typed into the terminal. The token
is stored in `~/.config/djangocloud/credentials.json`, readable only by you. You can see and revoke tokens any time
under **Command line** in your dashboard.

### Works in CI, no questions asked

For GitHub Actions and similar, create a token under **Command line → Token for CI** and save it as the repository
secret `DJANGOCLOUD_TOKEN`. `--no-input` makes the CLI never prompt and never open a browser, and fail with a clear
message if something is missing.

```yaml
- run: pip install djangocloud-cli
- run: python manage.py djangocloud deploy --no-input --project my-shop
  env:
    DJANGOCLOUD_TOKEN: ${{ secrets.DJANGOCLOUD_TOKEN }}
```

To create a project from CI, give it everything up front: `--name "My Shop" --size nano`.

### Configuration

| Variable | Purpose |
|---|---|
| `DJANGOCLOUD_TOKEN` | API token for CI. Takes precedence over the stored login |
| `DJANGOCLOUD_NO_INPUT` | Same as `--no-input` (set it to `1`) |
| `DJANGOCLOUD_API` | API base URL (default `https://djangocloud.dev/api/v1`) |

## Requirements

Python 3.10 or newer and Django 4.2 or newer.

## Development

```
uv sync
uv run pytest
uv run ruff check          # includes security (bandit), pytest-style, pathlib and simplification rules
uv run ruff format --check
```

Every push to `main` is released automatically: the tests run, the patch version goes up by one (0.1.1 becomes
0.1.2), the package is published to PyPI and a GitHub Release is created. There are no version numbers to edit.

For a bigger bump, tag it yourself before the next push (`git tag v0.2.0 && git push --tags`) and releases continue
from there. Put `[skip release]` in a commit message to skip releasing that commit.

## License

MIT. See [LICENSE](LICENSE).
