Sessions

Keywords: session store, session cookie, cookie expiration, file session, memory session, session lifespan, session lifetime

Server-side sessions with signed cookie IDs.

Usage

from asok import Request

def render(request: Request):
    # Read
    username = request.session.get("username")

    # Write
    request.session["username"] = "alice"
    request.session["cart"] = [1, 2, 3]

    return request.html("page.html")

Sessions are lazy-loaded on first access. Modified sessions are automatically saved when the response is sent.

SESSION_MAX_AGE controls the browser cookie lifetime, while SESSION_TTL controls how long the server keeps session data before expiring it.

Configuration

Key

Default

Description

SESSION_BACKEND

"memory"

"memory", "file", or "redis"

SESSION_PATH

".sessions"

Directory for file backend

SESSION_MAX_AGE

2592000

Browser cookie lifetime in seconds

SESSION_TTL

86400

Session lifetime in seconds

REDIS_URL

None

Redis connection URL (e.g. redis://localhost:6379/0)

How it works

  1. A signed cookie (asok_sid) identifies the session

  2. Session data is stored server-side (memory or file)

  3. On first request.session access, data is loaded from the store

  4. If session.modified is True at response time, data is saved back

Session API

request.session behaves like a regular dict:

request.session["key"] = "value"
request.session.get("key", "default")
del request.session["key"]
request.session.pop("key")
request.session.clear()

All mutating operations automatically set session.modified = True.

Production Persistence

In production environments using multi-worker servers like Gunicorn, you must use either the file or the redis backend.

The default memory backend stores sessions in the RAM of the specific worker process. Since requests are distributed across multiple workers, a user will “lose” their session as soon as their request is handled by a different worker.

Option B: File backend

To ensure persistence across workers using files, configure the file backend in your .env or wsgi.py:

# .env
SESSION_BACKEND=file
SESSION_PATH=/run/asok/sessions

Note: If you are using SystemD RuntimeDirectory=asok, the path /run/asok is automatically managed and has the correct permissions for the web server user.

Adjust SESSION_MAX_AGE and SESSION_TTL separately if you want the cookie lifetime and server-side lifetime to differ.

For RHEL/AlmaLinux servers, see the Deployment guide for handling SELinux permissions.