Skip to content

Commit 4799b02

Browse files
committed
quick checkin to maintain progress
1 parent 4d64887 commit 4799b02

33 files changed

+5709
-6158
lines changed

AGENTS.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# AGENTS.md
2+
3+
## Project Overview
4+
5+
`fastops` is an nbdev-based Python library providing fluent builders for Docker, Compose, Caddy, Cloudflare DNS/tunnels, and Hetzner VPS provisioning — all composable from Python with no YAML/config files by hand.
6+
7+
## Critical Rule: nbdev Workflow
8+
9+
**Never edit `.py` files in `fastops/` directly.** They are autogenerated. Only edit notebooks in `nbs/` and run `uv run nbdev-prepare` to regenerate `fastops/*.py`, `_modidx.py`, and docs.
10+
11+
Use hyphenated nbdev CLI commands (`nbdev-prepare`, `nbdev-export`, etc.), not underscore variants.
12+
13+
Mapping:
14+
15+
| Notebook | Module |
16+
|---|---|
17+
| `nbs/00_core.ipynb` | `fastops/core.py` — Dockerfile, Cli, Docker, Compose, app presets, env/secret helpers |
18+
| `nbs/01_cloudflare.ipynb` | `fastops/cloudflare.py` — CF wrapper, DNS records, tunnels |
19+
| `nbs/02_proxy.ipynb` | `fastops/proxy.py` — Caddyfile builder, caddy_svc, cloudflared_svc, crowdsec |
20+
| `nbs/05_vps.ipynb` | `fastops/vps.py` — cloud-init, Hetzner hcloud, SSH/rsync deploy |
21+
| `nbs/06_ship.ipynb` | `fastops/ship.py` — end-to-end: provision → build_stack → ship |
22+
23+
## Build System
24+
25+
- **Hatchling** (not setuptools). Build config lives in `pyproject.toml` under `[tool.hatch.build]`. Do NOT edit `MANIFEST.in` for build includes.
26+
- Package management: `uv add <pkg>` (never `pip install`). Run tools with `uv run`.
27+
28+
## Architecture & Patterns
29+
30+
### Immutable fluent builders (core pattern)
31+
`Dockerfile`, `Compose`, and `Caddyfile` all extend `fastcore.L` (an immutable list). Every method returns a **new instance** via `_add()` / `_new()` — never mutates. Example:
32+
```python
33+
df = Dockerfile().from_('python','3.12-slim').workdir('/app').cmd(['python','app.py'])
34+
```
35+
36+
### `Cli` base + `__getattr__` dispatch
37+
`Cli` turns unknown attribute access into CLI subcommands: `Docker().image('prune', f=True)``docker image prune -f`. The `_mk_flags()` helper converts kwargs to CLI flags (single-char → `-k v`, multi-char → `--key=v`).
38+
39+
### `@patch` from fastcore
40+
Methods added after class definition use `@patch` (e.g., `Dockerfile.build`, `Dockerfile.inst_uv`). Check for patched methods in the same notebook — they won't be in the class body.
41+
42+
### Service composition
43+
`caddy_svc()`, `cloudflared_svc()`, `crowdsec()` return `dict` kwargs meant to be splatted into `Compose().svc('name', **result)`. The `ship._build_stack()` function orchestrates the full topology.
44+
45+
## Code Style
46+
47+
- **fastcore idioms**: `store_attr`, `patch`, `L`, `listify`, `joins`, `bind`, `filter_values`, `Path` (fastcore's, not pathlib's).
48+
- **Succinct variable names**, dense functions, fast.ai style. No verbose docstrings — one-line descriptions only.
49+
- Trailing-underscore convention for Python-keyword collisions: `from_()`, `as_=`, `exec_()`.
50+
51+
## Key External Dependencies
52+
53+
- `fastcore` — foundational utilities (`L`, `patch`, `bind`, `run`, `Path`)
54+
- `cloudflare` — official Cloudflare Python SDK (not requests-based)
55+
- `hcloud` — Hetzner Cloud Python client
56+
- `fastcloudinit` — cloud-init YAML generation
57+
- `pyyaml`, `python-dotenv`, `keyring` — config/secrets
58+
59+
## Environment Variables
60+
61+
| Variable | Used by |
62+
|---|---|
63+
| `CLOUDFLARE_API_TOKEN` | `cloudflare.py` — CF class |
64+
| `HCLOUD_TOKEN` | `vps.py` — Hetzner client |
65+
| `DOCKR_RUNTIME` | `core.py` — set to `podman` for podman support |
66+
| `FASTOPS_VPS_HOST` / `FASTOPS_VPS_NAME` | `ship.py` — stored by `provision()` |
67+
68+
Config persists to `~/.config/fastops/.env` via `env_set()`/`env_get()`. Secrets use OS keychain via `keyring` with `secret_set()`/`secret_get()`.
69+
70+
## Testing
71+
72+
Tests live inline in the notebooks as cells. Run: `uv run nbdev-prepare` (exports + tests + docs). For pytest: `uv run pytest`. Include test cells when adding features to notebooks.

0 commit comments

Comments
 (0)