commit 5cda7bc309e20ab7b8ae67fe30c2c972518ce079 Author: ThePetrovich Date: Mon Aug 17 22:50:10 2026 +0800 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e70718 --- /dev/null +++ b/.gitignore @@ -0,0 +1,155 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/python +# Edit at https://www.toptal.com/developers/gitignore?templates=python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +pytestdebug.log + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ +doc/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +pythonenv* + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# profiling data +.prof + +# Db and static files +*.sqlite3 +/media +/static +/postgres +/EXAMPLE_* + +# Docker +docker-compose.override.yml +docker-compose.override + +# End of https://www.toptal.com/developers/gitignore/api/python diff --git a/README.md b/README.md new file mode 100644 index 0000000..e354536 --- /dev/null +++ b/README.md @@ -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 `.core` (table `