Skip to main content

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. With LocMemCache, every worker maintains its own cache and will fetch independently.

The HTTP client honours the standard HTTP_PROXY / HTTPS_PROXY environment 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

  1. The template tag / get_text(...) looks up the API key by text type in GETLAW["KEYS"].
  2. It checks the configured Django cache for a fresh entry (newer than TTL_SECONDS). If fresh, the cached HTML is returned.
  3. Otherwise the package calls GET https://www.getlaw.de/api/texts/{api_key} with the X-getLaw-API-Version: 1 header, parses the JSON response, and caches the content field.
  4. 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 so GetlawAdminBannerMiddleware can 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 in DEBUG).

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_getlaw-0.1.1.tar.gz (11.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_getlaw-0.1.1-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

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

Hashes for django_getlaw-0.1.1.tar.gz
Algorithm Hash digest
SHA256 250f36b38d666c89bcdefbd5af47dacfc91c848e882d010bc8d6a4056402ac88
MD5 a212d4792d432693495e1c3a779a43e1
BLAKE2b-256 1267db9f0a819b32d428bd9fc090537e749a462e1a5e81444df0949e7caad543

See more details on using hashes here.

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

Hashes for django_getlaw-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 46dfb3a52f9b70db26049770efb625649af60c49179737a5df300499d9043e89
MD5 960726b911df0397290dee635060e77d
BLAKE2b-256 326eceea6f1f93de5355dee0d3be0d95723102eb7d43baf0e26a02de522c6a9a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page