Initial commit

This commit is contained in:
ThePetrovich 2026-08-17 22:50:10 +08:00
commit 5cda7bc309
28 changed files with 1173 additions and 0 deletions

71
README.md Normal file
View file

@ -0,0 +1,71 @@
# yksa-django-kit
Common Django modules for use across various YKSA services.
## Install
```
yksa-django-kit @ git+https://git.intra.yksa.space/web/yksa-django-kit.git@v0.1.0
```
## Wire up
```python
# settings/base.py
from yksa_kit.settings import read_secret, env_bool
YKSA_SERVICE = "tdas" # required
YKSA_USER_AGENT = "yksa-tdas/0.1 (+https://tdas.tmtc.yksa.space)"
INSTALLED_APPS = [..., "yksa_kit", ...]
MIDDLEWARE = [..., "yksa_kit.middleware.UserTimezoneMiddleware", ...]
TEMPLATES[0]["OPTIONS"]["context_processors"] += [
"yksa_kit.context_processors.ui_preferences",
]
```
```python
# urls.py
urlpatterns = [
path("", include("yksa_kit.urls")),
...
]
```
`YKSA_SERVICE` is used as the Redis cache key, don't leave it unset.
The templates the timezone and policy views render (`timezone_preferences.html`,
`privacy_policy.html`, `cookie_policy.html`) come from
[yksa-web-kit](../yksa-web-kit).
## What is in it
| Module | |
|---|---|
| `models.ApiToken` | static bearer token, `read` or `ingest` |
| `auth` | header / query / session carriers, `request_has_valid_token`, `request_can_ingest` |
| `admin` | `ApiToken` admin |
| `choices.RunStatus` | running / success / failed / skipped |
| `http.get` | retries 429 and 5xx, honours `Retry-After`, sends the service User-Agent |
| `host_rate_limit` | Redis fixed-window buckets, per-minute and per-hour |
| `middleware.UserTimezoneMiddleware` | activates the session timezone |
| `context_processors.ui_preferences` | timezone name, quick-pick zones, cookie consent |
| `views` + `urls` | health, timezone preferences, privacy, cookies |
| `settings` | `read_secret`, `env_bool`, `env_list` |
## Migrating a service
`ApiToken` moves from `<project>.core` (table `<label>_apitoken`) to `yksa_kit`
(table `yksa_kit_apitoken`). None of the tmtc services is deployed, so the cheap
path is taken: reset the migrations and re-issue the tokens (where needed) manually.
## Tests
```sh
pip install -e ".[test]"
python -m pytest
```
They run against `tests/settings.py`, a Django project with nothing in it but
this package -- which is the point: if a test needs a service, the code belongs in
the service.