Setup
First we need to set up our FastAPI app:
from fastapi import FastAPI
app = FastAPI()
Secret
Now we declare a secret key. We define our key as a global value for simplicity, normally one would store the secret key in some sort of environment variable.
from fastapi import FastAPI
app = FastAPI()
SECRET = "super-secret-key"
Warning
To obtain a suitable key run the following command in your shell.
python -c "import os; print(os.urandom(24).hex())"
Warning
Most of the time it's better not to store the secret key in a file like this, but rather in an environment variable, in order to avoid committing it to source control.
LoginManager
Now we start setting up fastapi-login
by importing LoginManager
.
from fastapi import FastAPI
from fastapi_login import LoginManager
app = FastAPI()
SECRET = "super-secret-key"
The LoginManager
expects two arguments on initialization, a secret used to
encrypt and decrypt the tokens, and the url where one can obtain the token in
your application. The url is needed in order to display correctly inside the api docs.
from fastapi import FastAPI
from fastapi_login import LoginManager
app = FastAPI()
SECRET = "super-secret-key"
manager = LoginManager(SECRET, '/login')
Thats all you need to setup the LoginManager
object.
Note
The provided url should be the same your users call to obtain a token.
Database
Now that we have created a new instance of LoginManager
, we need to setup
our database.
First we need a way to query a user from the db. For this example we will use a dictionary in order to model a database.
DB = {
'users': {
'johndoe@mail.com': {
'name': 'John Doe',
'password': 'hunter2'
}
}
}
def query_user(user_id: str):
"""
Get a user from the db
:param user_id: E-Mail of the user
:return: None or the user object
"""
return DB['users'].get(user_id)
Now that we have our "database" setup, and a way to retrieve a user
we need to pass this function to our manager object, this way LoginManager
automatically can return the user object.
It's as simple as it gets, you just have to add this decorator to the query function.
@manager.user_loader()
def query_user(user_id: str):
...
Note
manager
in this context is an instance of LoginManager
Callable as extra argument
Before version 1.7.0 the empty parentheses were not needed after the decorator. To provide backwards compatibility it's still possible to omit them as of v1.7.1. Because of this it's however not possible to pass a callable object as the first extra argument.
This will not work:
def some_callable_object(...):
...
@manager.user_loader(some_callable_object)
def load_user(email, some_callable):
...
@manager.user_loader(some_callable=some_callable_object)
def load_user(email, some_callable)
To see how to use fastapi-login
as a dependency continue with usage.