Skip to content

Session

Introduction

Since HTTP-driven applications are stateless, sessions provide a way to store information about the user across multiple requests. Arvel stores that information server-side and ships a signed session-id cookie to the browser.

Note

Unlike Laravel, the Session facade is intentionally thin — it exposes only Session.manager(). The day-to-day read/write API lives on the per-request SessionData object, which you reach through request.state.session.

Configuration

Sessions read config/session.py when present; the SESSION_* environment variables are the fallback for any key the file doesn't set (see the cascade):

SESSION_DRIVER=cookie
SESSION_LIFETIME=7200
SESSION_COOKIE_NAME=arvel_session
SESSION_FILES_PATH=storage/framework/sessions

Drivers

Driver Backing store Notes
cookie The cookie itself Default; stateless, size-limited
file Files on disk Server-side, good for local dev
redis Redis Requires arvel[redis]
database A sessions table Ship the bundled migration

Enabling Sessions

Sessions are opt-in. Register SessionServiceProvider (it binds the Session facade), then add StartSession to the ASGI middleware stack. StartSession is pure ASGI middleware — it loads the session at the start of the request, attaches it to request.state.session, and writes it back when the response finishes. It takes a store (from Session.manager().store()) plus lifetime and cookie_name:

from starlette.middleware import Middleware
from arvel.facades.session import Session
from arvel.session.middleware import StartSession

store = Session.manager().store()
middleware = [Middleware(StartSession, store=store, lifetime=7200)]

Note

StartSession is not a route-level middleware alias — there's no "session" group registered by the provider. Wire it as ASGI middleware on the app.

Note

The session id cookie is set with HttpOnly, Path=/, and SameSite=Lax. It is not marked Secure, so serve session-bearing routes over HTTPS in production and terminate TLS in front of the app.

Interacting With the Session

Reach the session through the request:

async def show(request: Request) -> dict[str, Any]:
    session = request.state.session   # SessionData
    ...

Retrieving Data

value = session.get("key")
value = session.get("key", "default")
exists = session.has("key")
everything = session.all()

Storing Data

session.put("key", "value")

Deleting Data

session.forget("key")    # remove a single key
session.flush()          # remove everything (keeps the session id)

Flash Data

Flash data lives for exactly one subsequent request — ideal for status messages after a redirect. flash stores a value readable on the next request; now stores one readable only on the current request:

session.flash("status", "Profile updated!")   # available next request
session.now("alert", "Heads up")               # available this request only
session.reflash()                              # keep current flash one more request

The StartSession middleware ages flash data automatically: new flash from one request becomes readable flash on the next, then expires.

Regenerating the Session ID

Regenerate the session id after authentication to prevent session fixation:

session.regenerate()