Embed legal texts (Impressum, Datenschutz, AGB, Widerruf, Barrierefreiheit) from getLaw.de in Django projects.
Project description
django-getlaw
Embed legal texts (Impressum, Datenschutzerklärung, AGB, Widerrufsbelehrung, Barrierefreiheitserklärung) from getLaw.de in your Django project.
This is the Django counterpart to the official getLaw plugins for
WordPress and
Contao. It calls the same
getLaw client API (/api/texts/{api_key} with the
X-getLaw-API-Version: 1 header), caches the response in your Django cache
backend, and refreshes it lazily every 24 hours (configurable). A management
command is provided for cron- or django-q-driven warming.
The package depends on Django only (no third-party HTTP client) and uses
the standard library urllib so it works wherever Django works.
Installation
uv add django-getlaw # or: pip install django-getlaw
Add the app to INSTALLED_APPS:
# settings.py
INSTALLED_APPS = [
# ...
"django_getlaw",
]
Configuration
All settings live under a single GETLAW dict. Only KEYS is required; every
text type you want to render must have an API key here. Get the keys from your
getLaw.de account (one key per text).
# settings.py
GETLAW = {
"KEYS": {
"impressum": os.environ["GETLAW_KEY_IMPRESSUM"],
"datenschutz": os.environ["GETLAW_KEY_DATENSCHUTZ"],
# "agb": "...",
# "widerruf": "...",
# "barrierefreiheit": "...",
},
# Optional, shown with their defaults:
"TTL_SECONDS": 86400, # 24 hours
"API_BASE_URL": "https://www.getlaw.de/api/texts/",
"API_VERSION": "1",
"TIMEOUT_SECONDS": 10,
"CACHE_ALIAS": "default", # any django CACHES alias
"CACHE_KEY_PREFIX": "getlaw:",
"USER_AGENT": "django-getlaw/<version>", # auto-filled with package version
}
Use a shared cache backend (Redis, Memcached, or Django's
DatabaseCache) in multi-worker deployments. WithLocMemCache, every worker maintains its own cache and will fetch independently.
The HTTP client honours the standard
HTTP_PROXY/HTTPS_PROXYenvironment variables automatically.
Usage
Template tag
{% load getlaw %}
<section>
{% getlaw "impressum" %}
</section>
The tag returns safe HTML. On GETLAW misconfiguration or fetch failure it
returns an empty string in production (DEBUG=False) and a visible HTML
comment when DEBUG=True, so problems are obvious in development without
breaking pages in production.
Programmatic API
from django_getlaw import get_text, refresh_text
html = get_text("impressum") # cached, lazy refresh after TTL
html = get_text("impressum", force=True) # bypass TTL, fetch now
html = refresh_text("impressum") # alias for force-fetch
Management command
# Refresh every configured text:
uv run python manage.py getlaw_refresh
# Refresh specific texts only:
uv run python manage.py getlaw_refresh impressum datenschutz
The command exits with a non-zero status if any refresh fails — wire it into cron or your scheduler so failures alert you.
Admin banner on fetch failures
django-getlaw always falls back to the last known content when an API
fetch fails — there is no upper bound on staleness, because a slightly
outdated Impressum is virtually always better than a blank page. To make
sure the failure doesn't go unnoticed, add the bundled middleware after
Django's messages middleware:
# settings.py
MIDDLEWARE = [
# ...
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django_getlaw.middleware.GetlawAdminBannerMiddleware",
]
Any staff user (request.user.is_staff) visiting a Django admin page will
see a warning banner listing the affected text types and the most recent
error. The banner re-renders on every admin request and disappears as soon
as a successful fetch (template tag, refresh_text(...), or
getlaw_refresh) clears the failure marker.
If you need the failure list programmatically (e.g. for a status endpoint
or your own dashboard), call django_getlaw.fetch_failures().
Scheduling with django-q
from django_q.tasks import schedule
from django_q.models import Schedule
schedule(
"django.core.management.call_command",
"getlaw_refresh",
name="getlaw-refresh-daily",
schedule_type=Schedule.DAILY,
)
Supported text types
impressum, datenschutz, agb, widerruf, barrierefreiheit — but the
package does not hard-code that list. Any text type for which you put a
key in GETLAW["KEYS"] is fetchable; the API decides what's valid. This
means you don't have to wait for a package release if getLaw adds a new text
type in the future.
How it works
- The template tag /
get_text(...)looks up the API key by text type inGETLAW["KEYS"]. - It checks the configured Django cache for a fresh entry (newer than
TTL_SECONDS). If fresh, the cached HTML is returned. - Otherwise the package calls
GET https://www.getlaw.de/api/texts/{api_key}with theX-getLaw-API-Version: 1header, parses the JSON response, and caches thecontentfield. - On HTTP redirects (the way the getLaw API signals "invalid key"), HTTP
errors, timeouts, or unparseable responses, the call raises a
GetlawAPIError. If any cached content exists, it is returned as a fallback (regardless of age), a warning is logged, and a per-text-type failure marker is recorded soGetlawAdminBannerMiddlewarecan warn staff on the next admin page. The marker clears the next time a fetch succeeds. If nothing has ever been fetched successfully, the error propagates and the template tag renders empty (or an HTML comment inDEBUG).
The cache key includes a hash of the API key, so rotating a key in your settings transparently invalidates the corresponding entry.
Development
uv sync
uv run pytest
uv run ruff check
Licence
MIT — see LICENSE. The upstream WordPress and Contao plugins by getLaw.de are GPL-3.0; this package contains no code from them — it simply calls the same client HTTP API (endpoint and headers) as those plugins. The getLaw API page is only a short overview.
Acknowledgements
Thanks to getLaw.de for providing a clean API for clients (paid subscription; requires an API key).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_getlaw-0.1.1.tar.gz.
File metadata
- Download URL: django_getlaw-0.1.1.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
250f36b38d666c89bcdefbd5af47dacfc91c848e882d010bc8d6a4056402ac88
|
|
| MD5 |
a212d4792d432693495e1c3a779a43e1
|
|
| BLAKE2b-256 |
1267db9f0a819b32d428bd9fc090537e749a462e1a5e81444df0949e7caad543
|
File details
Details for the file django_getlaw-0.1.1-py3-none-any.whl.
File metadata
- Download URL: django_getlaw-0.1.1-py3-none-any.whl
- Upload date:
- Size: 13.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46dfb3a52f9b70db26049770efb625649af60c49179737a5df300499d9043e89
|
|
| MD5 |
960726b911df0397290dee635060e77d
|
|
| BLAKE2b-256 |
326eceea6f1f93de5355dee0d3be0d95723102eb7d43baf0e26a02de522c6a9a
|