duck.utils.cookie_consent¶
Utility functions for managing cookie consent in Duck framework apps.
This module helps you:
Parse and check cookie consent categories from incoming requests.
Set cookie consent on the response (server-driven).
Generate a cookie string for use in client-side (JavaScript) dynamic consent banners.
Consent is stored as a JSON-encoded cookie, e.g.:
{"analytics": true, "marketing": false}
Recommended usage:
Use the same cookie name (default: “cookie_consent”) on both backend and frontend.
Set cookie via backend
set_cookie_consent()after user accepts/rejects consent, orGenerate a cookie string with
generate_cookie_consent_str()for frontend use in dynamic modals.
Example:
# Check consent in a view
if has_cookie_consent(request, "analytics"):
# Run analytics logic
...
# Set consent on response (server-driven)
set_cookie_consent(response, {"analytics": True, "marketing": False})
# Generate cookie string for JS (dynamic modal)
cookie_str = generate_cookie_consent_str({"analytics": True}, max_age=31536000)
# In JS: document.cookie = "{{ cookie_str }}";
Functions:
get_cookie_consents(request, cookie_name)
has_cookie_consent(request, category, cookie_name)
set_cookie_consent(response, consents, cookie_name, **kwargs)
generate_cookie_consent_str(consents, cookie_name, **kwargs)
USAGE EXAMPLES
Server-Driven Approach (Recommended for backend-controlled consent):
from duck.utils.cookie_consent import set_cookie_consent, has_cookie_consent
def accept_cookies_view(request):
response = HttpResponse("Consent updated")
set_cookie_consent(response, {"analytics": True, "marketing": False})
return response
def view(request):
if has_cookie_consent(request, "analytics"):
# Analytics code here
pass
Dynamic JS Approach (Frontend-driven banners):
from duck.utils.cookie_consent import generate_cookie_consent_str
from duck.html.components.page import Page
from duck.html.components.button import Button
def consent_banner_js(request):
# Used to prefill consent state in JS, or as an example for your modal
page = Page(request)
accept_btn = Button(text="Accept All")
page.add_to_body(accept_btn)
async def on_accept(btn, event, value, ws):
cookie_str = generate_cookie_consent_str({"analytics": True, "marketing": True})
await ws.execute_js(f"document.cookie='{cookie_str}'';")
# Bind event on click
accept_btn.bind("click", on_accept, update_self=False, update_targets=[])
return page
Module Contents¶
Functions¶
Helper for JS-safe cookie decoding. |
|
Helper for JS-safe cookie encoding. |
|
Generates a cookie string suitable for setting document.cookie in JS (dynamic banner approach). |
|
Retrieves the user’s cookie consent preferences from the request cookies. |
|
Checks if a user has given consent for a specific category. |
|
Sets the consent cookie on the response object (server-driven approach). |
API¶
- duck.utils.cookie_consent.generate_cookie_consent_str(consents, cookie_name='cookie_consent', max_age=60 * 60 * 24 * 365, path='/', domain=None, secure=False, samesite='Lax', expires=None)[source]¶
Generates a cookie string suitable for setting document.cookie in JS (dynamic banner approach).
- Parameters:
consents – Consent dictionary (e.g., {“analytics”: True, “marketing”: False}).
cookie_name – Name of the cookie to set.
max_age – Cookie duration in seconds. Default: 1 year.
path – Path for cookie. Default: “/”.
domain – Domain for cookie. Default: None.
secure – Add “; Secure” if True. Defaults to False.
samesite – SameSite policy. Default: “Lax”.
expires – Optional absolute expiration.
- Returns:
Cookie string (e.g., ‘cookie_consent=%7B%22analytics%22%3Atrue%7D; path=/; max-age=31536000; samesite=Lax; Secure’)
- Return type:
str
- duck.utils.cookie_consent.get_cookie_consents(request, cookie_name='cookie_consent')[source]¶
Retrieves the user’s cookie consent preferences from the request cookies.
- Parameters:
request – The Duck request object, which provides a COOKIES dictionary.
cookie_name – The name of the consent cookie. Default is ‘cookie_consent’.
- Returns:
Mapping of category names to booleans (e.g., {“analytics”: True, “marketing”: False}). Returns {} if the cookie is missing or invalid.
- Return type:
dict
- duck.utils.cookie_consent.has_cookie_consent(request, category, cookie_name='cookie_consent')[source]¶
Checks if a user has given consent for a specific category.
- Parameters:
request – The Duck request object.
category – The category to check (e.g., “analytics”, “marketing”).
cookie_name – The name of the consent cookie. Default is ‘cookie_consent’.
- Returns:
True if consent is given for the category, False otherwise.
- Return type:
bool
- duck.utils.cookie_consent.set_cookie_consent(response, consents, cookie_name='cookie_consent', max_age=60 * 60 * 24 * 365, path='/', domain=None, secure=False, httponly=False, samesite='Lax', expires=None)[source]¶
Sets the consent cookie on the response object (server-driven approach).
- Parameters:
response – The Duck response object (must support set_cookie method).
consents – Consent dictionary (e.g., {“analytics”: True, “marketing”: False}).
cookie_name – Name of the cookie to set.
max_age – Cookie duration in seconds. Default: 1 year.
path – Path for cookie. Default: “/”.
domain – Domain for cookie. Default: None.
secure – Set True for HTTPS sites. Default: False.
httponly – Prevent JS access if True. Default: False.
samesite – SameSite policy. Default: “Lax”.
expires – Optional absolute expiration.
- Returns:
None