zenit 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. zenit-1.0.0/LICENSE +21 -0
  2. zenit-1.0.0/MANIFEST.in +2 -0
  3. zenit-1.0.0/PKG-INFO +419 -0
  4. zenit-1.0.0/README.md +372 -0
  5. zenit-1.0.0/pyproject.toml +75 -0
  6. zenit-1.0.0/setup.cfg +4 -0
  7. zenit-1.0.0/src/scaffolder/__init__.py +0 -0
  8. zenit-1.0.0/src/scaffolder/addons/__pycache__/_registry.cpython-314.pyc +0 -0
  9. zenit-1.0.0/src/scaffolder/addons/_registry.py +30 -0
  10. zenit-1.0.0/src/scaffolder/addons/celery/__pycache__/addon.cpython-314.pyc +0 -0
  11. zenit-1.0.0/src/scaffolder/addons/celery/addon.py +68 -0
  12. zenit-1.0.0/src/scaffolder/addons/celery/files/tasks/celery_app.py.j2 +37 -0
  13. zenit-1.0.0/src/scaffolder/addons/celery/files/tasks/example_tasks.py.j2 +15 -0
  14. zenit-1.0.0/src/scaffolder/addons/docker/__pycache__/addon.cpython-314.pyc +0 -0
  15. zenit-1.0.0/src/scaffolder/addons/docker/addon.py +31 -0
  16. zenit-1.0.0/src/scaffolder/addons/docker/files/.dockerignore +14 -0
  17. zenit-1.0.0/src/scaffolder/addons/docker/files/Dockerfile.j2 +34 -0
  18. zenit-1.0.0/src/scaffolder/addons/docker/files/compose.yml.j2 +26 -0
  19. zenit-1.0.0/src/scaffolder/addons/github-actions/__pycache__/addon.cpython-314.pyc +0 -0
  20. zenit-1.0.0/src/scaffolder/addons/github-actions/addon.py +18 -0
  21. zenit-1.0.0/src/scaffolder/addons/github-actions/files/ci.yml.j2 +83 -0
  22. zenit-1.0.0/src/scaffolder/addons/redis/__pycache__/addon.cpython-314.pyc +0 -0
  23. zenit-1.0.0/src/scaffolder/addons/redis/addon.py +61 -0
  24. zenit-1.0.0/src/scaffolder/addons/redis/files/compose.redis.yml.j2 +11 -0
  25. zenit-1.0.0/src/scaffolder/addons/redis/files/redis.py +48 -0
  26. zenit-1.0.0/src/scaffolder/addons/sentry/__pycache__/addon.cpython-314.pyc +0 -0
  27. zenit-1.0.0/src/scaffolder/addons/sentry/addon.py +41 -0
  28. zenit-1.0.0/src/scaffolder/addons/sentry/files/sentry.py.j2 +35 -0
  29. zenit-1.0.0/src/scaffolder/assembler.py +266 -0
  30. zenit-1.0.0/src/scaffolder/context.py +85 -0
  31. zenit-1.0.0/src/scaffolder/dryrun.py +159 -0
  32. zenit-1.0.0/src/scaffolder/exceptions.py +2 -0
  33. zenit-1.0.0/src/scaffolder/generate/justfile.j2 +30 -0
  34. zenit-1.0.0/src/scaffolder/generate/pyproject.toml.j2 +58 -0
  35. zenit-1.0.0/src/scaffolder/generate.py +86 -0
  36. zenit-1.0.0/src/scaffolder/git.py +25 -0
  37. zenit-1.0.0/src/scaffolder/main.py +209 -0
  38. zenit-1.0.0/src/scaffolder/prompt.py +384 -0
  39. zenit-1.0.0/src/scaffolder/render.py +47 -0
  40. zenit-1.0.0/src/scaffolder/rollback.py +35 -0
  41. zenit-1.0.0/src/scaffolder/schema.py +118 -0
  42. zenit-1.0.0/src/scaffolder/templates/__pycache__/_load_config.cpython-314.pyc +0 -0
  43. zenit-1.0.0/src/scaffolder/templates/_common/__pycache__/apply.cpython-314.pyc +0 -0
  44. zenit-1.0.0/src/scaffolder/templates/_common/apply.py +42 -0
  45. zenit-1.0.0/src/scaffolder/templates/_common/envrc +4 -0
  46. zenit-1.0.0/src/scaffolder/templates/_common/gitattributes +13 -0
  47. zenit-1.0.0/src/scaffolder/templates/_common/gitignore +26 -0
  48. zenit-1.0.0/src/scaffolder/templates/_common/pre-commit-config.yaml +22 -0
  49. zenit-1.0.0/src/scaffolder/templates/_common/shell.nix +7 -0
  50. zenit-1.0.0/src/scaffolder/templates/_load_config.py +22 -0
  51. zenit-1.0.0/src/scaffolder/templates/blank/__pycache__/template.cpython-314.pyc +0 -0
  52. zenit-1.0.0/src/scaffolder/templates/blank/files/__main__.py +3 -0
  53. zenit-1.0.0/src/scaffolder/templates/blank/files/main.py.j2 +7 -0
  54. zenit-1.0.0/src/scaffolder/templates/blank/files/tests/test_main.py.j2 +9 -0
  55. zenit-1.0.0/src/scaffolder/templates/blank/template.py +51 -0
  56. zenit-1.0.0/src/scaffolder/templates/fastapi/__pycache__/template.cpython-314.pyc +0 -0
  57. zenit-1.0.0/src/scaffolder/templates/fastapi/files/.env.example +4 -0
  58. zenit-1.0.0/src/scaffolder/templates/fastapi/files/.env.j2 +4 -0
  59. zenit-1.0.0/src/scaffolder/templates/fastapi/files/alembic/env.py.j2 +50 -0
  60. zenit-1.0.0/src/scaffolder/templates/fastapi/files/alembic/script.py.mako +24 -0
  61. zenit-1.0.0/src/scaffolder/templates/fastapi/files/alembic.ini.j2 +33 -0
  62. zenit-1.0.0/src/scaffolder/templates/fastapi/files/api/router.py +12 -0
  63. zenit-1.0.0/src/scaffolder/templates/fastapi/files/api/routes/health.py +8 -0
  64. zenit-1.0.0/src/scaffolder/templates/fastapi/files/core/security.py +44 -0
  65. zenit-1.0.0/src/scaffolder/templates/fastapi/files/db/base.py +5 -0
  66. zenit-1.0.0/src/scaffolder/templates/fastapi/files/db/session.py +13 -0
  67. zenit-1.0.0/src/scaffolder/templates/fastapi/files/exceptions.py +25 -0
  68. zenit-1.0.0/src/scaffolder/templates/fastapi/files/lifecycle.py +14 -0
  69. zenit-1.0.0/src/scaffolder/templates/fastapi/files/main.py.j2 +7 -0
  70. zenit-1.0.0/src/scaffolder/templates/fastapi/files/models/mixins.py +27 -0
  71. zenit-1.0.0/src/scaffolder/templates/fastapi/files/schemas/common.py +14 -0
  72. zenit-1.0.0/src/scaffolder/templates/fastapi/files/scripts/wait_db.py +29 -0
  73. zenit-1.0.0/src/scaffolder/templates/fastapi/files/settings.py.j2 +20 -0
  74. zenit-1.0.0/src/scaffolder/templates/fastapi/files/tests/conftest.py.j2 +64 -0
  75. zenit-1.0.0/src/scaffolder/templates/fastapi/files/tests/test_health.py +7 -0
  76. zenit-1.0.0/src/scaffolder/templates/fastapi/template.py +172 -0
  77. zenit-1.0.0/src/scaffolder/ui.py +166 -0
  78. zenit-1.0.0/src/scaffolder/validate.py +85 -0
  79. zenit-1.0.0/src/zenit.egg-info/PKG-INFO +419 -0
  80. zenit-1.0.0/src/zenit.egg-info/SOURCES.txt +91 -0
  81. zenit-1.0.0/src/zenit.egg-info/dependency_links.txt +1 -0
  82. zenit-1.0.0/src/zenit.egg-info/entry_points.txt +3 -0
  83. zenit-1.0.0/src/zenit.egg-info/requires.txt +3 -0
  84. zenit-1.0.0/src/zenit.egg-info/top_level.txt +1 -0
  85. zenit-1.0.0/tests/test_apply_contributions.py +598 -0
  86. zenit-1.0.0/tests/test_assembler.py +251 -0
  87. zenit-1.0.0/tests/test_dryrun.py +277 -0
  88. zenit-1.0.0/tests/test_functional.py +334 -0
  89. zenit-1.0.0/tests/test_generate.py +194 -0
  90. zenit-1.0.0/tests/test_integration.py +392 -0
  91. zenit-1.0.0/tests/test_prompt.py +230 -0
  92. zenit-1.0.0/tests/test_render.py +164 -0
  93. zenit-1.0.0/tests/test_validate.py +116 -0
zenit-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bojan Konjevic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ include LICENSE
2
+ include README.md
zenit-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,419 @@
1
+ Metadata-Version: 2.4
2
+ Name: zenit
3
+ Version: 1.0.0
4
+ Summary: Scaffold your next Python project with one command
5
+ Author-email: Bojan Konjevic <konjevicbojan1@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Bojan Konjevic
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/BojanKonjevic/zenit
29
+ Project-URL: Repository, https://github.com/BojanKonjevic/zenit
30
+ Project-URL: Issues, https://github.com/BojanKonjevic/zenit/issues
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: Programming Language :: Python :: 3.14
34
+ Classifier: Programming Language :: Python :: 3 :: Only
35
+ Classifier: Operating System :: OS Independent
36
+ Classifier: Development Status :: 4 - Beta
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: Topic :: Software Development :: Code Generators
39
+ Classifier: Topic :: Software Development :: Build Tools
40
+ Requires-Python: >=3.14
41
+ Description-Content-Type: text/markdown
42
+ License-File: LICENSE
43
+ Requires-Dist: jinja2
44
+ Requires-Dist: typer>=0.12
45
+ Requires-Dist: pyyaml
46
+ Dynamic: license-file
47
+
48
+ # zenit
49
+
50
+ A CLI that scaffolds a new Python project from a template with optional addons — sets up the package structure, dev tooling, config files, and an initial git commit, then tells you what to run next.
51
+
52
+ ```
53
+ zenit my-project
54
+ ```
55
+
56
+ ---
57
+
58
+ ## What it does
59
+
60
+ 1. Asks you to pick a **template** (blank or FastAPI)
61
+ 2. Asks you to pick **addons** (Docker, Redis, Celery, Sentry, GitHub Actions)
62
+ 3. Generates the project directory, all files, `pyproject.toml`, and `justfile`
63
+ 4. Runs `git init` and makes the first commit
64
+
65
+ It does not run `uv sync`, start servers, or do anything network-dependent. You get a directory you can immediately `cd` into and start working.
66
+
67
+ ---
68
+
69
+ ## Requirements
70
+
71
+ All platforms need:
72
+
73
+ - **Python 3.14+**
74
+ - **uv 0.4+** — [install](https://docs.astral.sh/uv/getting-started/installation/)
75
+ - **git**
76
+ - **just** — [install](https://github.com/casey/just#installation) (optional but the generated projects use it heavily)
77
+ - **direnv** — optional, auto-activates the virtualenv on `cd` (see per-platform notes below)
78
+
79
+ The `fastapi` template additionally needs **Docker** running locally.
80
+
81
+ ---
82
+
83
+ ## Installation
84
+
85
+ ### macOS
86
+
87
+ ```bash
88
+ # Install uv if you haven't
89
+ curl -LsSf https://astral.sh/uv/install.sh | sh
90
+
91
+ # Install zenit
92
+ uv tool install zenit
93
+
94
+ # Or run without installing
95
+ uvx zenit my-project
96
+ ```
97
+
98
+ **direnv** (recommended):
99
+ ```bash
100
+ brew install direnv
101
+ # Add to ~/.zshrc or ~/.bash_profile:
102
+ eval "$(direnv hook zsh)" # or bash
103
+ ```
104
+
105
+ ---
106
+
107
+ ### Linux (non-NixOS)
108
+
109
+ ```bash
110
+ curl -LsSf https://astral.sh/uv/install.sh | sh
111
+ uv tool install zenit
112
+ ```
113
+
114
+ **direnv**:
115
+ ```bash
116
+ # Ubuntu/Debian
117
+ sudo apt install direnv
118
+
119
+ # Arch
120
+ sudo pacman -S direnv
121
+
122
+ # Fedora
123
+ sudo dnf install direnv
124
+
125
+ # Add to ~/.bashrc or ~/.zshrc:
126
+ eval "$(direnv hook bash)" # or zsh
127
+ ```
128
+
129
+ ---
130
+
131
+ ### NixOS
132
+
133
+ NixOS does not allow uv to download or manage its own Python binaries — `UV_PYTHON_DOWNLOADS` must be set to `never` and uv must use the system Python. zenit handles this for you when run via the Nix flake, but you need Python 3.14+ available in your environment first.
134
+
135
+ **Option A — run directly from the flake (recommended):**
136
+
137
+ ```bash
138
+ nix run github:BojanKonjevic/zenit -- my-project
139
+ ```
140
+
141
+ This uses the bundled flake which sets `UV_PYTHON_DOWNLOADS=never` and points uv at the Nix-provided Python 3.14 automatically.
142
+
143
+ **Option B — install and run manually:**
144
+
145
+ ```bash
146
+ # Make sure python3.14 is in your PATH (via nix-shell, home-manager, etc.)
147
+ # Then:
148
+ UV_PYTHON_DOWNLOADS=never uv tool install zenit
149
+ UV_PYTHON_DOWNLOADS=never zenit my-project
150
+ ```
151
+
152
+ **Generated projects on NixOS:**
153
+
154
+ When zenit detects it's running on NixOS (by checking `/etc/NIXOS`), it generates a `.envrc` that uses `use nix shell.nix` instead of uv's own environment management, and writes a `shell.nix` that provides the correct `LD_LIBRARY_PATH` for compiled wheels like greenlet. So the generated project will also work correctly on NixOS.
155
+
156
+ **direnv on NixOS** — add to your `configuration.nix`:
157
+ ```nix
158
+ programs.direnv.enable = true;
159
+ ```
160
+ Or install it in your user environment:
161
+ ```bash
162
+ nix-env -iA nixpkgs.direnv
163
+ # Add to ~/.bashrc or ~/.zshrc:
164
+ eval "$(direnv hook bash)"
165
+ ```
166
+
167
+ ---
168
+
169
+ ### Windows
170
+
171
+ Windows is supported. The generated `justfile` uses `cmd` as the shell, and all `just` recipes work without WSL.
172
+
173
+ ```powershell
174
+ # Install uv
175
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
176
+
177
+ # Install zenit
178
+ uv tool install zenit
179
+ ```
180
+
181
+ **direnv on Windows** — direnv does not have an official Windows build. Your options:
182
+
183
+ 1. **Skip it** — instead of auto-activation, run `uv sync` once after scaffolding, then `uv run <command>` (or just use `just`, which routes through `uv run` already).
184
+ 2. **Use WSL2** — install direnv inside WSL2 as per the Linux instructions above.
185
+ 3. **Use `scoop`** — a community-maintained build exists: `scoop install direnv` (not officially supported).
186
+
187
+ zenit will copy `.envrc` regardless, but will warn you if direnv is not found rather than failing.
188
+
189
+ ---
190
+
191
+ ## Usage
192
+
193
+ ```
194
+ zenit <project-name> scaffold a new project
195
+ zenit <project-name> --dry-run preview what would be created (nothing is written)
196
+ zenit list-templates show available templates
197
+ zenit list-addons show available addons
198
+ zenit --version
199
+ ```
200
+
201
+ The interactive prompt uses arrow keys and space to select. If stdin is not a tty (e.g. piped input or CI), it falls back to numbered selection.
202
+
203
+ ---
204
+
205
+ ## Templates
206
+
207
+ ### `blank`
208
+
209
+ A minimal Python package with dev tooling. Good for CLIs, scripts, and libraries.
210
+
211
+ ```
212
+ my-project/
213
+ src/my_project/
214
+ __init__.py
215
+ main.py
216
+ __main__.py
217
+ tests/
218
+ test_main.py
219
+ pyproject.toml
220
+ justfile
221
+ .gitignore
222
+ .envrc
223
+ ```
224
+
225
+ Includes: pytest, ruff, mypy, pytest-cov, ipython.
226
+
227
+ ### `fastapi`
228
+
229
+ A production-oriented FastAPI setup. **Requires the `docker` addon** (selected automatically).
230
+
231
+ ```
232
+ my-project/
233
+ src/my_project/
234
+ main.py FastAPI app + lifespan
235
+ lifecycle.py startup/shutdown logic
236
+ settings.py pydantic-settings (reads from .env)
237
+ exceptions.py HTTP exception helpers
238
+ api/
239
+ router.py
240
+ routes/
241
+ health.py GET /health → {"status": "ok"}
242
+ core/
243
+ security.py JWT encode/decode, bcrypt hashing
244
+ db/
245
+ base.py SQLAlchemy DeclarativeBase
246
+ session.py async engine, session factory, get_session dep
247
+ models/
248
+ mixins.py TimestampMixin (created_at, updated_at)
249
+ schemas/
250
+ common.py PaginationParams, PaginatedResponse
251
+ alembic/
252
+ env.py async-compatible Alembic env
253
+ versions/
254
+ tests/
255
+ conftest.py session + anon_client + client fixtures
256
+ integration/
257
+ test_health.py
258
+ unit/
259
+ fixtures/
260
+ scripts/
261
+ wait_db.py waits for postgres container to be ready
262
+ .env auto-generated with a random SECRET_KEY
263
+ .env.example
264
+ alembic.ini
265
+ ```
266
+
267
+ ---
268
+
269
+ ## Addons
270
+
271
+ Addons are selected interactively and can be mixed freely with either template, with a few constraints noted below.
272
+
273
+ ### `docker`
274
+
275
+ Generates a multi-stage `Dockerfile` (uv-based, minimal final image), `compose.yml`, and `.dockerignore`.
276
+
277
+ - For `blank`: compose starts just the app container.
278
+ - For `fastapi`: compose also starts a `db` (postgres:16) service.
279
+ - Required by `fastapi` (auto-selected).
280
+
281
+ ### `redis`
282
+
283
+ Adds `src/<pkg>/integrations/redis.py` — an async connection pool with a `get_redis` FastAPI dependency and a `close_redis` shutdown helper.
284
+
285
+ - If `docker` is also selected: appends a `redis:7-alpine` service to `compose.yml`.
286
+ - If `docker` is not selected: writes a standalone `compose.redis.yml`.
287
+ - For `fastapi`: also patches `settings.py` to add a `redis_url` field.
288
+ - Required by `celery`.
289
+
290
+ ### `celery`
291
+
292
+ Adds `src/<pkg>/tasks/celery_app.py` (Celery app configured against Redis) and `tasks/example_tasks.py` with a trivial `add` task.
293
+
294
+ - Requires `redis`.
295
+ - If `docker` is selected: appends `celery-worker` and `celery-beat` services to `compose.yml`.
296
+
297
+ ### `sentry`
298
+
299
+ Adds `src/<pkg>/integrations/sentry.py` with an `init_sentry()` function that no-ops when `SENTRY_DSN` is unset — safe to commit and run locally without a DSN.
300
+
301
+ - For `fastapi`: patches `lifecycle.py` to call `init_sentry()` on startup, and patches `settings.py` and `.env` to add `SENTRY_DSN` / `SENTRY_ENVIRONMENT`.
302
+ - For `blank`: patches `main.py` to call `init_sentry()` at startup.
303
+
304
+ ### `github-actions`
305
+
306
+ Writes `.github/workflows/ci.yml` that runs lint (`ruff check`), format check (`ruff format --check`), type check (`mypy`), and tests (`pytest`) on push and pull requests.
307
+
308
+ - Spins up a `postgres:16` service automatically when the `fastapi` template is used.
309
+ - Spins up a `redis:7-alpine` service automatically when `redis` is selected.
310
+ - Runs migrations before tests when postgres is present.
311
+
312
+ ---
313
+
314
+ ## Generated commands (`just`)
315
+
316
+ All generated projects come with a `justfile`. Run `just` with no arguments to list what's available.
317
+
318
+ | Command | What it does |
319
+ |---|---|
320
+ | `just test` | run pytest |
321
+ | `just cov` | pytest with coverage report |
322
+ | `just lint` | ruff check |
323
+ | `just fmt` | ruff format |
324
+ | `just fix` | ruff check --fix + ruff format |
325
+ | `just check` | mypy |
326
+ | `just run` | start the app (uvicorn --reload for fastapi, python -m for blank) |
327
+
328
+ **FastAPI only:**
329
+
330
+ | Command | What it does |
331
+ |---|---|
332
+ | `just migrate "message"` | generate an Alembic migration |
333
+ | `just upgrade` | apply all pending migrations |
334
+ | `just downgrade` | roll back one step |
335
+ | `just db-create` | start db container, create app + test databases, migrate |
336
+ | `just db-reset` | drop and recreate both databases |
337
+ | `just wait-db` | wait until postgres is accepting connections |
338
+
339
+ **Docker addon:**
340
+
341
+ | Command | What it does |
342
+ |---|---|
343
+ | `just docker-up` | docker compose up --build |
344
+ | `just docker-down` | docker compose down |
345
+
346
+ **Redis addon:**
347
+
348
+ | Command | What it does |
349
+ |---|---|
350
+ | `just redis-up` | start redis |
351
+ | `just redis-down` | stop redis |
352
+ | `just redis-cli` | open redis-cli |
353
+
354
+ **Celery addon:**
355
+
356
+ | Command | What it does |
357
+ |---|---|
358
+ | `just celery-up` | start worker + beat via compose |
359
+ | `just celery-down` | stop worker + beat |
360
+ | `just celery-flower` | open Flower monitoring UI on port 5555 |
361
+ | `just celery-logs` | tail worker logs |
362
+
363
+ **Sentry addon:**
364
+
365
+ | Command | What it does |
366
+ |---|---|
367
+ | `just sentry-check` | print sentry-sdk version |
368
+ | `just sentry-test` | print whether SENTRY_DSN is set |
369
+
370
+ ---
371
+
372
+ ## Dry run
373
+
374
+ Pass `--dry-run` to preview everything that would happen without touching disk:
375
+
376
+ ```
377
+ zenit my-project --dry-run
378
+ ```
379
+
380
+ Output shows every file that would be created or modified, every dependency that would be added to `pyproject.toml`, every `just` recipe, and every git command — then exits without writing anything.
381
+
382
+ ---
383
+
384
+ ## Adding auth to a FastAPI project
385
+
386
+ The `fastapi` template lays out the security plumbing but stops short of generating auth routes (everyone's auth is different). When you're ready:
387
+
388
+ 1. Define `User` and `RefreshToken` models in `models/` — import them in `models/__init__.py` so Alembic discovers them.
389
+ 2. Add `core/dependencies.py` with a `get_current_user` dependency using `decode_access_token` from `core/security.py`.
390
+ 3. Add `api/routes/auth.py` with register, login, and refresh endpoints.
391
+ 4. Register it in `api/router.py`.
392
+ 5. Uncomment the auth block in `tests/conftest.py` to enable the authenticated `client` fixture.
393
+ 6. Run `just db-create && just migrate "add users" && just upgrade`.
394
+
395
+ ---
396
+
397
+ ## Running from source
398
+
399
+ If you want to hack on zenit itself:
400
+
401
+ ```bash
402
+ git clone https://github.com/BojanKonjevic/zenit.git
403
+ cd zenit
404
+ uv sync
405
+ uv run python main.py my-project
406
+ ```
407
+
408
+ On NixOS, enter the dev shell first:
409
+ ```bash
410
+ nix develop
411
+ python main.py my-project
412
+ ```
413
+
414
+ ---
415
+
416
+ ## License
417
+
418
+ MIT — see [LICENSE](LICENSE).
419
+