HTTP Session
HTTP sessions are a convenient way to store user data between requests. In most cases they are backed by a persistent store where their data is stored and can be accessed across requests.
Expanse provides by default a few session stores that can be used out of the box, like databases, files or in-memory stores. They are all exposed through a common interface, so you can easily switch between them when needed.
Configuration
The settings related to the session are stored in the config/session.py
application configuration file. By default,
it's configured to use the database
store.
The store
setting defines which store the session will be used to store its data. The available stores are:
file
: store the session data in files.database
: store the session data in a relational database table.dict
: store the session data in memory.null
: do not store the session data. This can be used to disable the session feature.
The dict
store is only recommended for testing purposes, as it will store the session data in memory and will be
lost when the application is restarted.
Database
When using the database
store, you must have a dedicated table to store the session data. This will typically be
the sessions
table that will be created automatically when you first set up your Expanse application. However, if
you do not have the table already you can add a database migration to create it using the make session-table
command.
./beam make session-table
./beam db migrate
You can configure the database connection used by the session store by using the SESSION_STORES__DATABASE__CONNECTION
environment variable.
SESSION_STORES__DATABASE__CONNECTION=my-connection
The connection used must match one of the configured database connections.
The database
store requires configuring the database
to be compatible with both synchronous and asynchronous implementations of the backend used by the configured connection.
This mostly means that you will need to install the necessary asynchronous DBAPI packages:
for instance if you use an SQLite database, you will need to install the aiosqlite
package.
Using the session
The session can be retrieved from the current Request
instance.
from expanse.http.request import Request
from expanse.http.response import Response
class MyController:
async def index(self, request: Request) -> Response:
session = request.session
value = session["key"]
...
Retrieving data from the session
The session behaves like a dictionary, so retrieving data can be done through standard key access.
from expanse.http.request import Request
from expanse.http.response import Response
class MyController:
async def index(self, request: Request) -> Response:
session = request.session
value = session["key"]
...
Like the application configuration, the session support dot notation to access nested data stored in it.
You may also use the get()
method to retrieve a value from the session, providing a default value to return if the key
does not exist.
from expanse.http.request import Request
from expanse.http.response import Response
class MyController:
async def index(self, request: Request) -> Response:
session = request.session
value = session.get("key", "default")
...
If you need to retrieve all the data stored in the session, you can use the all()
method.
data = request.session.all()
You may also check if a key exists in the session using the has()
method or by using a more standard key in session
statement.
if "key" in request.session:
...
if request.session.has("key"):
...
The pop()
method may be used to retrieve a value from the session and remove it at the same time.
value = request.session.pop("key", "default")
Storing data in the session
You may store data in the session by using the set()
method or by using a dict-like approach.
request.session["key"] = "value"
request.session.set("key", "value")
If you wish to append values to an existing key that holds a list, you may use the append()
method.
request.session.append("article.tags", "value")
Flashing data to the session
Flashing data is a way to store data in the session that will only be available for the next request. This is achieved
by using the flash()
method. This will make the data available immediately as well as in the next request. After that
the data will automatically be discarded. This is useful for displaying messages to the user after a form submission for
instance.
request.session.flash("status", "Successfully saved the article.")
If you need to keep the data for an additional request, you may use the reflash()
method. If only some of the data
should be kept, you can specify it via the only
keyword argument.
request.session.reflash()
request.session.reflash(only=["status"])
Removing data from the session
You may remove data from the session by using the remove()
method or by using the del
statement.
del request.session["key"]
request.session.remove("key")
Regenerating the session
Regenerating the session will create a new session ID and keep the existing data. This would typically be done when a user authenticates to prevent session fixation attacks.
request.session.regenerate()
If, instead, you want to regenerate the session ID and clear all the data, you may use the invalidate()
method.
request.session.invalidate()