User state and form flash data
Use sessions for small preferences or temporary browser state. Data outlives one request object, but sessions are not permanent domain storage. Avoid passwords, secrets and complete ORM objects.
Accessing state from a handler
Section titled “Accessing state from a handler”from orionis.http import responsefrom orionis.session.contracts.session import ISession
async def choose_theme(session: ISession): session.put("theme", "dark") return response.redirect("/settings", 303).withFlash("notice", "Theme saved")Place the handler in routes/web.py and add a read endpoint and registrations:
from orionis.support.facades import Route
async def settings(session: ISession): return response.json({ "theme": session.get("theme", "system"), "notice": session.get("notice"), })
Route.post("/settings/theme", choose_theme)Route.get("/settings", settings)After a valid CSRF-protected POST to /settings/theme, the browser follows HTTP 303 to /settings; the response contains theme: "dark" and notice: "Theme saved". A later request keeps the theme but the flash notice expires. Use the same browser session cookie for the whole flow. For the form token, see CSRF.
Injection requires an active web scope. Alternatively, from orionis.support.facades import Session resolves the same contract. get, put, has, forget, clear and all are synchronous: do not add await. Store and manager operations are asynchronous.
from orionis.session.session import Session
session = Session()assert session.id is None and not session.startedassert session.get("theme", "system") == "system"session.put("theme", "dark")assert session.started and session.dirtyassert session.get("theme") == "dark"Writing an equal value does not dirty the session. However, mutating a retrieved collection may change data without put; renewal conservatively treats mutable payloads. Do not expose all() as a public response: it includes internal bags.
POST, redirect, GET
Section titled “POST, redirect, GET”flash(key, value) makes data readable in the current request and the next. At the next start, the manager removes the old bag and promotes the new one. This is neither a message queue nor indefinite persistence.
from orionis.session.session import Session
session = Session()session.flashInput({"email": "ada@example.test", "password": "secret", "_csrf": "secret"})session.flashErrors({"email": "Already registered"})assert session.getOldInput("email") == "ada@example.test"assert session.getOldInput("password") is Noneassert session.getErrors() == {"email": ["Already registered"]}flashInput filters known credential and CSRF field names. Exclude application-specific secrets yourself. flashErrors accepts mappings or validation exceptions and normalizes values into message lists. Repeated writes to reserved bags merge.
Response withInput, withErrors and withFlash queue the same data for middleware to apply; do not write it twice. Sessions expose setPreviousUrl/getPreviousUrl; the web layer updates navigation only for eligible requests/responses. Redirect-back flows must check safe destinations through HTTP helpers rather than trust arbitrary Referer input.
Lifetime and testing
Section titled “Lifetime and testing”An isolated Session() can test value manipulation but does not demonstrate persistence between requests: that depends on the manager, cookies and store. Do not share the instance between concurrent requests. Read stores and security.