diff --git a/configuration/databases/mongodb/index.html b/configuration/databases/mongodb/index.html index 61b96b08..01e1989d 100644 --- a/configuration/databases/mongodb/index.html +++ b/configuration/databases/mongodb/index.html @@ -340,6 +340,20 @@
Coming soon. Track the progress of this feature in ticket #4.
+FastAPI Users provides the necessary tools to work with MongoDB databases thanks to mongodb/motor package for full async support.
+Let's create a MongoDB connection and instantiate a collection.
+import motor.motor_asyncio +from fastapi import FastAPI +from fastapi_users.db import MongoDBUserDatabase + +DATABASE_URL = "mongodb://localhost:27017" +client = motor.motor_asyncio.AsyncIOMotorClient(DATABASE_URL) +db = client["database_name"] +collection = db["users"] + + +app = FastAPI() + + +user_db = MongoDBUserDatabase(collection) +
You can choose any name for the database and the collection.
+The database adapter of FastAPI Users makes the link between your database configuration and the users logic. Create it like this.
+import motor.motor_asyncio +from fastapi import FastAPI +from fastapi_users.db import MongoDBUserDatabase + +DATABASE_URL = "mongodb://localhost:27017" +client = motor.motor_asyncio.AsyncIOMotorClient(DATABASE_URL) +db = client["database_name"] +collection = db["users"] + + +app = FastAPI() + + +user_db = MongoDBUserDatabase(collection) +
Info
+The database adapter will automatically create a unique index on id
and email
.
Warning
+FastAPI Users will use its defined id
UUID-string as unique identifier for the user, rather than the builtin MongoDB _id
.
We will now configure an authentication method.
diff --git a/configuration/full_example/index.html b/configuration/full_example/index.html index aa65c81b..1b84201d 100644 --- a/configuration/full_example/index.html +++ b/configuration/full_example/index.html @@ -598,7 +598,43 @@ -# Coming soon +import motor.motor_asyncio +from fastapi import FastAPI +from fastapi_users import BaseUser, FastAPIUsers +from fastapi_users.authentication import JWTAuthentication +from fastapi_users.db import MongoDBUserDatabase + +DATABASE_URL = "mongodb://localhost:27017" +SECRET = "SECRET" + + +client = motor.motor_asyncio.AsyncIOMotorClient(DATABASE_URL) +db = client["database_name"] +collection = db["users"] + + +user_db = MongoDBUserDatabase(collection) + + +class User(BaseUser): + pass + + +auth = JWTAuthentication(secret=SECRET, lifetime_seconds=3600) + +app = FastAPI() +fastapi_users = FastAPIUsers(user_db, auth, User, SECRET) +app.include_router(fastapi_users.router, prefix="/users", tags=["users"]) + + +@fastapi_users.on_after_register() +def on_after_register(user: User): + print(f"User {user.id} has registered.") + + +@fastapi_users.on_after_forgot_password() +def on_after_forgot_password(user: User, token: str): + print(f"User {user.id} has forgot their password. Reset token: {token}")
You can add FastAPI Users to your FastAPI project in a few easy steps. First of all, install the dependency:
-pip install fastapi-users +With SQLAlchemy support¶
+-pip install fastapi-users[sqlalchemy]...or if you're already in the future:
-pipenv install fastapi-users +With MongoDB support¶
+pip install fastapi-users[mongodb]
diff --git a/search/search_index.json b/search/search_index.json index c80728c1..f14804be 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"FastAPI Users \u00b6 Ready-to-use and customizable users management for FastAPI Documentation : https://frankie567.github.io/fastapi-users/ Source Code : https://github.com/frankie567/fastapi-users Add quickly a registration and authentication system to your FastAPI project. FastAPI Users is designed to be as customizable and adaptable as possible. Features \u00b6 Extensible base user model Ready-to-use register, login, forgot and reset password routes. Customizable database backend SQLAlchemy backend included MongoDB backend included ( #4 ) Customizable authentication backend JWT authentication backend included License \u00b6 This project is licensed under the terms of the MIT license.","title":"About"},{"location":"#fastapi-users","text":"Ready-to-use and customizable users management for FastAPI Documentation : https://frankie567.github.io/fastapi-users/ Source Code : https://github.com/frankie567/fastapi-users Add quickly a registration and authentication system to your FastAPI project. FastAPI Users is designed to be as customizable and adaptable as possible.","title":"FastAPI Users"},{"location":"#features","text":"Extensible base user model Ready-to-use register, login, forgot and reset password routes. Customizable database backend SQLAlchemy backend included MongoDB backend included ( #4 ) Customizable authentication backend JWT authentication backend included","title":"Features"},{"location":"#license","text":"This project is licensed under the terms of the MIT license.","title":"License"},{"location":"installation/","text":"Installation \u00b6 You can add FastAPI Users to your FastAPI project in a few easy steps. First of all, install the dependency: pip install fastapi-users ...or if you're already in the future: pipenv install fastapi-users That's it! Now, let's have a look at our User model .","title":"Installation"},{"location":"installation/#installation","text":"You can add FastAPI Users to your FastAPI project in a few easy steps. First of all, install the dependency: pip install fastapi-users ...or if you're already in the future: pipenv install fastapi-users That's it! Now, let's have a look at our User model .","title":"Installation"},{"location":"configuration/full_example/","text":"Full example \u00b6 Here is a full working example with JWT authentication to help get you started. SQLAlchemy import databases import sqlalchemy from fastapi import FastAPI from fastapi_users import BaseUser , FastAPIUsers from fastapi_users.authentication import JWTAuthentication from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" SECRET = \"SECRET\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) class User ( BaseUser ): pass auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) app = FastAPI () fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET ) app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" ) @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () MongoDB # Coming soon What now? \u00b6 You're ready to go! Be sure to check the Usage section to understand how yo work with FastAPI Users .","title":"Full example"},{"location":"configuration/full_example/#full-example","text":"Here is a full working example with JWT authentication to help get you started. SQLAlchemy import databases import sqlalchemy from fastapi import FastAPI from fastapi_users import BaseUser , FastAPIUsers from fastapi_users.authentication import JWTAuthentication from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" SECRET = \"SECRET\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) class User ( BaseUser ): pass auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) app = FastAPI () fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET ) app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" ) @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () MongoDB # Coming soon","title":"Full example"},{"location":"configuration/full_example/#what-now","text":"You're ready to go! Be sure to check the Usage section to understand how yo work with FastAPI Users .","title":"What now?"},{"location":"configuration/model/","text":"User model \u00b6 FastAPI Users defines a minimal User model for authentication purposes. It is structured like this: id ( str ) \u2013 Unique identifier of the user. Default to a UUID4 . email ( str ) \u2013 Email of the user. Validated by email-validator . is_active ( bool ) \u2013 Whether or not the user is active. If not, login and forgot password requests will be denied. Default to True . is_active ( bool ) \u2013 Whether or not the user is a superuser. Useful to implement administration logic. Default to False . Use the model \u00b6 The model is exposed as a Pydantic model mixin. from fastapi_users import BaseUser class User ( BaseUser ): pass You can of course add you own properties there to fit to your needs! Next steps \u00b6 Depending on your database backend, database configuration will differ a bit. I'm using SQLAlchemy I'm using MongoDB","title":"User model"},{"location":"configuration/model/#user-model","text":"FastAPI Users defines a minimal User model for authentication purposes. It is structured like this: id ( str ) \u2013 Unique identifier of the user. Default to a UUID4 . email ( str ) \u2013 Email of the user. Validated by email-validator . is_active ( bool ) \u2013 Whether or not the user is active. If not, login and forgot password requests will be denied. Default to True . is_active ( bool ) \u2013 Whether or not the user is a superuser. Useful to implement administration logic. Default to False .","title":"User model"},{"location":"configuration/model/#use-the-model","text":"The model is exposed as a Pydantic model mixin. from fastapi_users import BaseUser class User ( BaseUser ): pass You can of course add you own properties there to fit to your needs!","title":"Use the model"},{"location":"configuration/model/#next-steps","text":"Depending on your database backend, database configuration will differ a bit. I'm using SQLAlchemy I'm using MongoDB","title":"Next steps"},{"location":"configuration/router/","text":"Router \u00b6 We're almost there! The last step is to configure the FastAPIUsers object that will wire the database adapter, the authentication class and the user model to expose the FastAPI router. Configure FastAPIUsers \u00b6 Configure FastAPIUsers object with all the elements we defined before. More precisely: db : Database adapter instance. auth : Authentication logic instance. user_model : Pydantic model of a user. reset_password_token_secret : Secret to encode reset password token. reset_password_token_lifetime_seconds : Lifetime of reset password token in seconds. Default to one hour. from fastapi_users import FastAPIUsers fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET , ) And then, include the router in the FastAPI app: app = FastAPI () app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) Event handlers \u00b6 In order to be as unopinionated as possible, we expose decorators that allow you to plug your own logic after some actions. You can have several handlers per event. After register \u00b6 This event handler is called after a successful registration. It is called with one argument : the user that has just registered. Typically, you'll want to send a welcome e-mail or add it to your marketing analytics pipeline. You can define it as an async or standard method. Example: @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) After forgot password \u00b6 This event handler is called after a successful forgot password request. It is called with two arguments : the user which has requested to reset their password and a ready-to-use JWT token that will be accepted by the reset password route. Typically, you'll want to send an e-mail with the link (and the token) that allows the user to reset their password. You can define it as an async or standard method. Example: @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" ) Next steps \u00b6 Check out a full example that will show you the big picture.","title":"Router"},{"location":"configuration/router/#router","text":"We're almost there! The last step is to configure the FastAPIUsers object that will wire the database adapter, the authentication class and the user model to expose the FastAPI router.","title":"Router"},{"location":"configuration/router/#configure-fastapiusers","text":"Configure FastAPIUsers object with all the elements we defined before. More precisely: db : Database adapter instance. auth : Authentication logic instance. user_model : Pydantic model of a user. reset_password_token_secret : Secret to encode reset password token. reset_password_token_lifetime_seconds : Lifetime of reset password token in seconds. Default to one hour. from fastapi_users import FastAPIUsers fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET , ) And then, include the router in the FastAPI app: app = FastAPI () app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ])","title":"Configure FastAPIUsers"},{"location":"configuration/router/#event-handlers","text":"In order to be as unopinionated as possible, we expose decorators that allow you to plug your own logic after some actions. You can have several handlers per event.","title":"Event handlers"},{"location":"configuration/router/#after-register","text":"This event handler is called after a successful registration. It is called with one argument : the user that has just registered. Typically, you'll want to send a welcome e-mail or add it to your marketing analytics pipeline. You can define it as an async or standard method. Example: @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" )","title":"After register"},{"location":"configuration/router/#after-forgot-password","text":"This event handler is called after a successful forgot password request. It is called with two arguments : the user which has requested to reset their password and a ready-to-use JWT token that will be accepted by the reset password route. Typically, you'll want to send an e-mail with the link (and the token) that allows the user to reset their password. You can define it as an async or standard method. Example: @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" )","title":"After forgot password"},{"location":"configuration/router/#next-steps","text":"Check out a full example that will show you the big picture.","title":"Next steps"},{"location":"configuration/authentication/","text":"Authentication \u00b6 FastAPI Users allows you to plug in several authentication methods. Provided methods \u00b6 JWT authentication","title":"Authentication"},{"location":"configuration/authentication/#authentication","text":"FastAPI Users allows you to plug in several authentication methods.","title":"Authentication"},{"location":"configuration/authentication/#provided-methods","text":"JWT authentication","title":"Provided methods"},{"location":"configuration/authentication/jwt/","text":"JWT \u00b6 JSON Web Token (JWT) is an internet standard for creating access tokens based on JSON. Configuration \u00b6 from fastapi_users.authentication import JWTAuthentication SECRET = \"SECRET\" auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) As you can see, instantiation is quite simple. You just have to define a constant SECRET which is used to encode the token and the lifetime of token (in seconds). Authentication \u00b6 This method expects that you provide a Bearer authentication with a valid JWT. curl http://localhost:9000/protected-route -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI' Next steps \u00b6 We will now configure the main FastAPI Users object that will expose the API router .","title":"JWT"},{"location":"configuration/authentication/jwt/#jwt","text":"JSON Web Token (JWT) is an internet standard for creating access tokens based on JSON.","title":"JWT"},{"location":"configuration/authentication/jwt/#configuration","text":"from fastapi_users.authentication import JWTAuthentication SECRET = \"SECRET\" auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) As you can see, instantiation is quite simple. You just have to define a constant SECRET which is used to encode the token and the lifetime of token (in seconds).","title":"Configuration"},{"location":"configuration/authentication/jwt/#authentication","text":"This method expects that you provide a Bearer authentication with a valid JWT. curl http://localhost:9000/protected-route -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI'","title":"Authentication"},{"location":"configuration/authentication/jwt/#next-steps","text":"We will now configure the main FastAPI Users object that will expose the API router .","title":"Next steps"},{"location":"configuration/databases/mongodb/","text":"MongoDB \u00b6 Coming soon . Track the progress of this feature in ticket #4 . Next steps \u00b6 We will now configure an authentication method .","title":"MongoDB"},{"location":"configuration/databases/mongodb/#mongodb","text":"Coming soon . Track the progress of this feature in ticket #4 .","title":"MongoDB"},{"location":"configuration/databases/mongodb/#next-steps","text":"We will now configure an authentication method .","title":"Next steps"},{"location":"configuration/databases/sqlalchemy/","text":"SQLAlchemy \u00b6 FastAPI Users provides the necessary tools to work with SQL databases thanks to SQLAlchemy Core and encode/databases package for full async support. Installation \u00b6 Install the database driver that corresponds to your DBMS: pip install databases [ postgresql ] pip install databases [ mysql ] pip install databases [ sqlite ] For the sake of this tutorial from now on, we'll use a simple SQLite databse. Setup User table \u00b6 Let's create a metadata object and declare our User table. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () As you can see, FastAPI Users provides a mixin that will include base fields for our User table. You can of course add you own fields there to fit to your needs! Create the tables \u00b6 We'll now create an SQLAlchemy enigne and ask it to create all the defined tables. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Tip In production, you would probably want to create the tables with Alembic, integrated with migrations, etc. Create the database adapter \u00b6 The database adapter of FastAPI Users makes the link between your database configuration and the users logic. Create it like this. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Notice that we declare the users variable, which is the actual SQLAlchemy table behind the table class. We also use our database instance, which allows us to do asynchronous request to the database. Next steps \u00b6 We will now configure an authentication method . What about SQLAlchemy ORM? \u00b6 The primary objective was to use pure async approach as much as possible. However, we understand that ORM is convenient and useful for many developers. If this feature becomes very demanded, we will add a database adapter for SQLAlchemy ORM.","title":"SQLAlchemy"},{"location":"configuration/databases/sqlalchemy/#sqlalchemy","text":"FastAPI Users provides the necessary tools to work with SQL databases thanks to SQLAlchemy Core and encode/databases package for full async support.","title":"SQLAlchemy"},{"location":"configuration/databases/sqlalchemy/#installation","text":"Install the database driver that corresponds to your DBMS: pip install databases [ postgresql ] pip install databases [ mysql ] pip install databases [ sqlite ] For the sake of this tutorial from now on, we'll use a simple SQLite databse.","title":"Installation"},{"location":"configuration/databases/sqlalchemy/#setup-user-table","text":"Let's create a metadata object and declare our User table. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () As you can see, FastAPI Users provides a mixin that will include base fields for our User table. You can of course add you own fields there to fit to your needs!","title":"Setup User table"},{"location":"configuration/databases/sqlalchemy/#create-the-tables","text":"We'll now create an SQLAlchemy enigne and ask it to create all the defined tables. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Tip In production, you would probably want to create the tables with Alembic, integrated with migrations, etc.","title":"Create the tables"},{"location":"configuration/databases/sqlalchemy/#create-the-database-adapter","text":"The database adapter of FastAPI Users makes the link between your database configuration and the users logic. Create it like this. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Notice that we declare the users variable, which is the actual SQLAlchemy table behind the table class. We also use our database instance, which allows us to do asynchronous request to the database.","title":"Create the database adapter"},{"location":"configuration/databases/sqlalchemy/#next-steps","text":"We will now configure an authentication method .","title":"Next steps"},{"location":"configuration/databases/sqlalchemy/#what-about-sqlalchemy-orm","text":"The primary objective was to use pure async approach as much as possible. However, we understand that ORM is convenient and useful for many developers. If this feature becomes very demanded, we will add a database adapter for SQLAlchemy ORM.","title":"What about SQLAlchemy ORM?"},{"location":"usage/dependency-callables/","text":"Dependency callables \u00b6 FastAPI Users provides dependency callables to easily inject users in your routes. They are available from your FastAPIUsers instance. Tip For more information about how to make an authenticated request to your API, check the documentation of your Authentication method . get_current_user \u00b6 Get the current user ( active or not ). Will throw a 401 Unauthorized if missing or wrong credentials. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_user )): return f 'Hello, {user.email}' get_current_active_user \u00b6 Get the current active user. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_active_user )): return f 'Hello, {user.email}' get_current_superuser \u00b6 Get the current superuser. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. Will throw a 403 Forbidden if the user is not a superuser. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_superuser )): return f 'Hello, {user.email}'","title":"Dependency callables"},{"location":"usage/dependency-callables/#dependency-callables","text":"FastAPI Users provides dependency callables to easily inject users in your routes. They are available from your FastAPIUsers instance. Tip For more information about how to make an authenticated request to your API, check the documentation of your Authentication method .","title":"Dependency callables"},{"location":"usage/dependency-callables/#get_current_user","text":"Get the current user ( active or not ). Will throw a 401 Unauthorized if missing or wrong credentials. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_user )): return f 'Hello, {user.email}'","title":"get_current_user"},{"location":"usage/dependency-callables/#get_current_active_user","text":"Get the current active user. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_active_user )): return f 'Hello, {user.email}'","title":"get_current_active_user"},{"location":"usage/dependency-callables/#get_current_superuser","text":"Get the current superuser. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. Will throw a 403 Forbidden if the user is not a superuser. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_superuser )): return f 'Hello, {user.email}'","title":"get_current_superuser"},{"location":"usage/routes/","text":"Routes \u00b6 You'll find here the routes exposed by FastAPI Users . Note that you can also review them through the interactive API docs . Unauthenticated \u00b6 POST /register \u00b6 Register a new user. Will call the on_after_register event handlers on successful registration. Payload { \"email\" : \"king.arthur@camelot.bt\" , \"password\" : \"guinevere\" } 201 Created { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 422 Validation Error 400 Bad Request A user already exists with this email. POST /login \u00b6 Login a user. Payload ( application/x-www-form-urlencoded ) username = king . arthur @camelot . bt & password = guinevere 200 OK { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" } 422 Validation Error 400 Bad Request Bad credentials or the user is inactive. POST /forgot-password \u00b6 Request a reset password procedure. Will generate a temporary token and call the on_after_forgot_password event handlers if the user exists. To prevent malicious users from guessing existing users in your databse, the route will always return a 202 Accepted response, even if the user requested does not exist. Payload { \"email\" : \"king.arthur@camelot.bt\" } 202 Accepted POST /reset-password \u00b6 Reset a password. Requires the token generated by the /forgot-password route. Payload { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" , \"password\" : \"merlin\" } 200 OK 422 Validation Error 400 Bad Request Bad or expired token. Authenticated \u00b6 GET /me \u00b6 Return the current authenticated active user. 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user. PATCH /me \u00b6 Update the current authenticated active user. Payload { \"email\" : \"king.arthur@tintagel.bt\" , \"password\" : \"merlin\" } 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@tintagel.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user.","title":"Routes"},{"location":"usage/routes/#routes","text":"You'll find here the routes exposed by FastAPI Users . Note that you can also review them through the interactive API docs .","title":"Routes"},{"location":"usage/routes/#unauthenticated","text":"","title":"Unauthenticated"},{"location":"usage/routes/#post-register","text":"Register a new user. Will call the on_after_register event handlers on successful registration. Payload { \"email\" : \"king.arthur@camelot.bt\" , \"password\" : \"guinevere\" } 201 Created { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 422 Validation Error 400 Bad Request A user already exists with this email.","title":"POST /register"},{"location":"usage/routes/#post-login","text":"Login a user. Payload ( application/x-www-form-urlencoded ) username = king . arthur @camelot . bt & password = guinevere 200 OK { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" } 422 Validation Error 400 Bad Request Bad credentials or the user is inactive.","title":"POST /login"},{"location":"usage/routes/#post-forgot-password","text":"Request a reset password procedure. Will generate a temporary token and call the on_after_forgot_password event handlers if the user exists. To prevent malicious users from guessing existing users in your databse, the route will always return a 202 Accepted response, even if the user requested does not exist. Payload { \"email\" : \"king.arthur@camelot.bt\" } 202 Accepted","title":"POST /forgot-password"},{"location":"usage/routes/#post-reset-password","text":"Reset a password. Requires the token generated by the /forgot-password route. Payload { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" , \"password\" : \"merlin\" } 200 OK 422 Validation Error 400 Bad Request Bad or expired token.","title":"POST /reset-password"},{"location":"usage/routes/#authenticated","text":"","title":"Authenticated"},{"location":"usage/routes/#get-me","text":"Return the current authenticated active user. 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user.","title":"GET /me"},{"location":"usage/routes/#patch-me","text":"Update the current authenticated active user. Payload { \"email\" : \"king.arthur@tintagel.bt\" , \"password\" : \"merlin\" } 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@tintagel.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user.","title":"PATCH /me"}]} \ No newline at end of file +{"config":{"lang":["en"],"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"FastAPI Users \u00b6 Ready-to-use and customizable users management for FastAPI Documentation : https://frankie567.github.io/fastapi-users/ Source Code : https://github.com/frankie567/fastapi-users Add quickly a registration and authentication system to your FastAPI project. FastAPI Users is designed to be as customizable and adaptable as possible. Features \u00b6 Extensible base user model Ready-to-use register, login, forgot and reset password routes. Dependency callables to inject current user in route. Customizable database backend SQLAlchemy async backend included thanks to encode/databases MongoDB async backend included thanks to mongodb/motor Customizable authentication backend JWT authentication backend included License \u00b6 This project is licensed under the terms of the MIT license.","title":"About"},{"location":"#fastapi-users","text":"Ready-to-use and customizable users management for FastAPI Documentation : https://frankie567.github.io/fastapi-users/ Source Code : https://github.com/frankie567/fastapi-users Add quickly a registration and authentication system to your FastAPI project. FastAPI Users is designed to be as customizable and adaptable as possible.","title":"FastAPI Users"},{"location":"#features","text":"Extensible base user model Ready-to-use register, login, forgot and reset password routes. Dependency callables to inject current user in route. Customizable database backend SQLAlchemy async backend included thanks to encode/databases MongoDB async backend included thanks to mongodb/motor Customizable authentication backend JWT authentication backend included","title":"Features"},{"location":"#license","text":"This project is licensed under the terms of the MIT license.","title":"License"},{"location":"installation/","text":"Installation \u00b6 You can add FastAPI Users to your FastAPI project in a few easy steps. First of all, install the dependency: With SQLAlchemy support \u00b6 pip install fastapi-users [ sqlalchemy ] With MongoDB support \u00b6 pip install fastapi-users [ mongodb ] That's it! Now, let's have a look at our User model .","title":"Installation"},{"location":"installation/#installation","text":"You can add FastAPI Users to your FastAPI project in a few easy steps. First of all, install the dependency:","title":"Installation"},{"location":"installation/#with-sqlalchemy-support","text":"pip install fastapi-users [ sqlalchemy ]","title":"With SQLAlchemy support"},{"location":"installation/#with-mongodb-support","text":"pip install fastapi-users [ mongodb ] That's it! Now, let's have a look at our User model .","title":"With MongoDB support"},{"location":"configuration/full_example/","text":"Full example \u00b6 Here is a full working example with JWT authentication to help get you started. SQLAlchemy import databases import sqlalchemy from fastapi import FastAPI from fastapi_users import BaseUser , FastAPIUsers from fastapi_users.authentication import JWTAuthentication from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" SECRET = \"SECRET\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) class User ( BaseUser ): pass auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) app = FastAPI () fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET ) app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" ) @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () MongoDB import motor.motor_asyncio from fastapi import FastAPI from fastapi_users import BaseUser , FastAPIUsers from fastapi_users.authentication import JWTAuthentication from fastapi_users.db import MongoDBUserDatabase DATABASE_URL = \"mongodb://localhost:27017\" SECRET = \"SECRET\" client = motor . motor_asyncio . AsyncIOMotorClient ( DATABASE_URL ) db = client [ \"database_name\" ] collection = db [ \"users\" ] user_db = MongoDBUserDatabase ( collection ) class User ( BaseUser ): pass auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) app = FastAPI () fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET ) app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" ) What now? \u00b6 You're ready to go! Be sure to check the Usage section to understand how yo work with FastAPI Users .","title":"Full example"},{"location":"configuration/full_example/#full-example","text":"Here is a full working example with JWT authentication to help get you started. SQLAlchemy import databases import sqlalchemy from fastapi import FastAPI from fastapi_users import BaseUser , FastAPIUsers from fastapi_users.authentication import JWTAuthentication from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" SECRET = \"SECRET\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) class User ( BaseUser ): pass auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) app = FastAPI () fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET ) app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" ) @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () MongoDB import motor.motor_asyncio from fastapi import FastAPI from fastapi_users import BaseUser , FastAPIUsers from fastapi_users.authentication import JWTAuthentication from fastapi_users.db import MongoDBUserDatabase DATABASE_URL = \"mongodb://localhost:27017\" SECRET = \"SECRET\" client = motor . motor_asyncio . AsyncIOMotorClient ( DATABASE_URL ) db = client [ \"database_name\" ] collection = db [ \"users\" ] user_db = MongoDBUserDatabase ( collection ) class User ( BaseUser ): pass auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) app = FastAPI () fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET ) app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" )","title":"Full example"},{"location":"configuration/full_example/#what-now","text":"You're ready to go! Be sure to check the Usage section to understand how yo work with FastAPI Users .","title":"What now?"},{"location":"configuration/model/","text":"User model \u00b6 FastAPI Users defines a minimal User model for authentication purposes. It is structured like this: id ( str ) \u2013 Unique identifier of the user. Default to a UUID4 . email ( str ) \u2013 Email of the user. Validated by email-validator . is_active ( bool ) \u2013 Whether or not the user is active. If not, login and forgot password requests will be denied. Default to True . is_active ( bool ) \u2013 Whether or not the user is a superuser. Useful to implement administration logic. Default to False . Use the model \u00b6 The model is exposed as a Pydantic model mixin. from fastapi_users import BaseUser class User ( BaseUser ): pass You can of course add you own properties there to fit to your needs! Next steps \u00b6 Depending on your database backend, database configuration will differ a bit. I'm using SQLAlchemy I'm using MongoDB","title":"User model"},{"location":"configuration/model/#user-model","text":"FastAPI Users defines a minimal User model for authentication purposes. It is structured like this: id ( str ) \u2013 Unique identifier of the user. Default to a UUID4 . email ( str ) \u2013 Email of the user. Validated by email-validator . is_active ( bool ) \u2013 Whether or not the user is active. If not, login and forgot password requests will be denied. Default to True . is_active ( bool ) \u2013 Whether or not the user is a superuser. Useful to implement administration logic. Default to False .","title":"User model"},{"location":"configuration/model/#use-the-model","text":"The model is exposed as a Pydantic model mixin. from fastapi_users import BaseUser class User ( BaseUser ): pass You can of course add you own properties there to fit to your needs!","title":"Use the model"},{"location":"configuration/model/#next-steps","text":"Depending on your database backend, database configuration will differ a bit. I'm using SQLAlchemy I'm using MongoDB","title":"Next steps"},{"location":"configuration/router/","text":"Router \u00b6 We're almost there! The last step is to configure the FastAPIUsers object that will wire the database adapter, the authentication class and the user model to expose the FastAPI router. Configure FastAPIUsers \u00b6 Configure FastAPIUsers object with all the elements we defined before. More precisely: db : Database adapter instance. auth : Authentication logic instance. user_model : Pydantic model of a user. reset_password_token_secret : Secret to encode reset password token. reset_password_token_lifetime_seconds : Lifetime of reset password token in seconds. Default to one hour. from fastapi_users import FastAPIUsers fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET , ) And then, include the router in the FastAPI app: app = FastAPI () app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ]) Event handlers \u00b6 In order to be as unopinionated as possible, we expose decorators that allow you to plug your own logic after some actions. You can have several handlers per event. After register \u00b6 This event handler is called after a successful registration. It is called with one argument : the user that has just registered. Typically, you'll want to send a welcome e-mail or add it to your marketing analytics pipeline. You can define it as an async or standard method. Example: @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" ) After forgot password \u00b6 This event handler is called after a successful forgot password request. It is called with two arguments : the user which has requested to reset their password and a ready-to-use JWT token that will be accepted by the reset password route. Typically, you'll want to send an e-mail with the link (and the token) that allows the user to reset their password. You can define it as an async or standard method. Example: @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" ) Next steps \u00b6 Check out a full example that will show you the big picture.","title":"Router"},{"location":"configuration/router/#router","text":"We're almost there! The last step is to configure the FastAPIUsers object that will wire the database adapter, the authentication class and the user model to expose the FastAPI router.","title":"Router"},{"location":"configuration/router/#configure-fastapiusers","text":"Configure FastAPIUsers object with all the elements we defined before. More precisely: db : Database adapter instance. auth : Authentication logic instance. user_model : Pydantic model of a user. reset_password_token_secret : Secret to encode reset password token. reset_password_token_lifetime_seconds : Lifetime of reset password token in seconds. Default to one hour. from fastapi_users import FastAPIUsers fastapi_users = FastAPIUsers ( user_db , auth , User , SECRET , ) And then, include the router in the FastAPI app: app = FastAPI () app . include_router ( fastapi_users . router , prefix = \"/users\" , tags = [ \"users\" ])","title":"Configure FastAPIUsers"},{"location":"configuration/router/#event-handlers","text":"In order to be as unopinionated as possible, we expose decorators that allow you to plug your own logic after some actions. You can have several handlers per event.","title":"Event handlers"},{"location":"configuration/router/#after-register","text":"This event handler is called after a successful registration. It is called with one argument : the user that has just registered. Typically, you'll want to send a welcome e-mail or add it to your marketing analytics pipeline. You can define it as an async or standard method. Example: @fastapi_users.on_after_register () def on_after_register ( user : User ): print ( f \"User {user.id} has registered.\" )","title":"After register"},{"location":"configuration/router/#after-forgot-password","text":"This event handler is called after a successful forgot password request. It is called with two arguments : the user which has requested to reset their password and a ready-to-use JWT token that will be accepted by the reset password route. Typically, you'll want to send an e-mail with the link (and the token) that allows the user to reset their password. You can define it as an async or standard method. Example: @fastapi_users.on_after_forgot_password () def on_after_forgot_password ( user : User , token : str ): print ( f \"User {user.id} has forgot their password. Reset token: {token}\" )","title":"After forgot password"},{"location":"configuration/router/#next-steps","text":"Check out a full example that will show you the big picture.","title":"Next steps"},{"location":"configuration/authentication/","text":"Authentication \u00b6 FastAPI Users allows you to plug in several authentication methods. Provided methods \u00b6 JWT authentication","title":"Authentication"},{"location":"configuration/authentication/#authentication","text":"FastAPI Users allows you to plug in several authentication methods.","title":"Authentication"},{"location":"configuration/authentication/#provided-methods","text":"JWT authentication","title":"Provided methods"},{"location":"configuration/authentication/jwt/","text":"JWT \u00b6 JSON Web Token (JWT) is an internet standard for creating access tokens based on JSON. Configuration \u00b6 from fastapi_users.authentication import JWTAuthentication SECRET = \"SECRET\" auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) As you can see, instantiation is quite simple. You just have to define a constant SECRET which is used to encode the token and the lifetime of token (in seconds). Authentication \u00b6 This method expects that you provide a Bearer authentication with a valid JWT. curl http://localhost:9000/protected-route -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI' Next steps \u00b6 We will now configure the main FastAPI Users object that will expose the API router .","title":"JWT"},{"location":"configuration/authentication/jwt/#jwt","text":"JSON Web Token (JWT) is an internet standard for creating access tokens based on JSON.","title":"JWT"},{"location":"configuration/authentication/jwt/#configuration","text":"from fastapi_users.authentication import JWTAuthentication SECRET = \"SECRET\" auth = JWTAuthentication ( secret = SECRET , lifetime_seconds = 3600 ) As you can see, instantiation is quite simple. You just have to define a constant SECRET which is used to encode the token and the lifetime of token (in seconds).","title":"Configuration"},{"location":"configuration/authentication/jwt/#authentication","text":"This method expects that you provide a Bearer authentication with a valid JWT. curl http://localhost:9000/protected-route -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI'","title":"Authentication"},{"location":"configuration/authentication/jwt/#next-steps","text":"We will now configure the main FastAPI Users object that will expose the API router .","title":"Next steps"},{"location":"configuration/databases/mongodb/","text":"MongoDB \u00b6 FastAPI Users provides the necessary tools to work with MongoDB databases thanks to mongodb/motor package for full async support. Setup database connection and collection \u00b6 Let's create a MongoDB connection and instantiate a collection. import motor.motor_asyncio from fastapi import FastAPI from fastapi_users.db import MongoDBUserDatabase DATABASE_URL = \"mongodb://localhost:27017\" client = motor . motor_asyncio . AsyncIOMotorClient ( DATABASE_URL ) db = client [ \"database_name\" ] collection = db [ \"users\" ] app = FastAPI () user_db = MongoDBUserDatabase ( collection ) You can choose any name for the database and the collection. Create the database adapter \u00b6 The database adapter of FastAPI Users makes the link between your database configuration and the users logic. Create it like this. import motor.motor_asyncio from fastapi import FastAPI from fastapi_users.db import MongoDBUserDatabase DATABASE_URL = \"mongodb://localhost:27017\" client = motor . motor_asyncio . AsyncIOMotorClient ( DATABASE_URL ) db = client [ \"database_name\" ] collection = db [ \"users\" ] app = FastAPI () user_db = MongoDBUserDatabase ( collection ) Info The database adapter will automatically create a unique index on id and email . Warning FastAPI Users will use its defined id UUID-string as unique identifier for the user, rather than the builtin MongoDB _id . Next steps \u00b6 We will now configure an authentication method .","title":"MongoDB"},{"location":"configuration/databases/mongodb/#mongodb","text":"FastAPI Users provides the necessary tools to work with MongoDB databases thanks to mongodb/motor package for full async support.","title":"MongoDB"},{"location":"configuration/databases/mongodb/#setup-database-connection-and-collection","text":"Let's create a MongoDB connection and instantiate a collection. import motor.motor_asyncio from fastapi import FastAPI from fastapi_users.db import MongoDBUserDatabase DATABASE_URL = \"mongodb://localhost:27017\" client = motor . motor_asyncio . AsyncIOMotorClient ( DATABASE_URL ) db = client [ \"database_name\" ] collection = db [ \"users\" ] app = FastAPI () user_db = MongoDBUserDatabase ( collection ) You can choose any name for the database and the collection.","title":"Setup database connection and collection"},{"location":"configuration/databases/mongodb/#create-the-database-adapter","text":"The database adapter of FastAPI Users makes the link between your database configuration and the users logic. Create it like this. import motor.motor_asyncio from fastapi import FastAPI from fastapi_users.db import MongoDBUserDatabase DATABASE_URL = \"mongodb://localhost:27017\" client = motor . motor_asyncio . AsyncIOMotorClient ( DATABASE_URL ) db = client [ \"database_name\" ] collection = db [ \"users\" ] app = FastAPI () user_db = MongoDBUserDatabase ( collection ) Info The database adapter will automatically create a unique index on id and email . Warning FastAPI Users will use its defined id UUID-string as unique identifier for the user, rather than the builtin MongoDB _id .","title":"Create the database adapter"},{"location":"configuration/databases/mongodb/#next-steps","text":"We will now configure an authentication method .","title":"Next steps"},{"location":"configuration/databases/sqlalchemy/","text":"SQLAlchemy \u00b6 FastAPI Users provides the necessary tools to work with SQL databases thanks to SQLAlchemy Core and encode/databases package for full async support. Installation \u00b6 Install the database driver that corresponds to your DBMS: pip install databases [ postgresql ] pip install databases [ mysql ] pip install databases [ sqlite ] For the sake of this tutorial from now on, we'll use a simple SQLite databse. Setup User table \u00b6 Let's create a metadata object and declare our User table. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () As you can see, FastAPI Users provides a mixin that will include base fields for our User table. You can of course add you own fields there to fit to your needs! Create the tables \u00b6 We'll now create an SQLAlchemy enigne and ask it to create all the defined tables. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Tip In production, you would probably want to create the tables with Alembic, integrated with migrations, etc. Create the database adapter \u00b6 The database adapter of FastAPI Users makes the link between your database configuration and the users logic. Create it like this. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Notice that we declare the users variable, which is the actual SQLAlchemy table behind the table class. We also use our database instance, which allows us to do asynchronous request to the database. Next steps \u00b6 We will now configure an authentication method . What about SQLAlchemy ORM? \u00b6 The primary objective was to use pure async approach as much as possible. However, we understand that ORM is convenient and useful for many developers. If this feature becomes very demanded, we will add a database adapter for SQLAlchemy ORM.","title":"SQLAlchemy"},{"location":"configuration/databases/sqlalchemy/#sqlalchemy","text":"FastAPI Users provides the necessary tools to work with SQL databases thanks to SQLAlchemy Core and encode/databases package for full async support.","title":"SQLAlchemy"},{"location":"configuration/databases/sqlalchemy/#installation","text":"Install the database driver that corresponds to your DBMS: pip install databases [ postgresql ] pip install databases [ mysql ] pip install databases [ sqlite ] For the sake of this tutorial from now on, we'll use a simple SQLite databse.","title":"Installation"},{"location":"configuration/databases/sqlalchemy/#setup-user-table","text":"Let's create a metadata object and declare our User table. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () As you can see, FastAPI Users provides a mixin that will include base fields for our User table. You can of course add you own fields there to fit to your needs!","title":"Setup User table"},{"location":"configuration/databases/sqlalchemy/#create-the-tables","text":"We'll now create an SQLAlchemy enigne and ask it to create all the defined tables. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Tip In production, you would probably want to create the tables with Alembic, integrated with migrations, etc.","title":"Create the tables"},{"location":"configuration/databases/sqlalchemy/#create-the-database-adapter","text":"The database adapter of FastAPI Users makes the link between your database configuration and the users logic. Create it like this. import databases import sqlalchemy from fastapi import FastAPI from fastapi_users.db import SQLAlchemyBaseUserTable , SQLAlchemyUserDatabase from sqlalchemy.ext.declarative import DeclarativeMeta , declarative_base DATABASE_URL = \"sqlite:///./test.db\" database = databases . Database ( DATABASE_URL ) Base : DeclarativeMeta = declarative_base () class UserTable ( Base , SQLAlchemyBaseUserTable ): pass engine = sqlalchemy . create_engine ( DATABASE_URL , connect_args = { \"check_same_thread\" : False } ) Base . metadata . create_all ( engine ) users = UserTable . __table__ user_db = SQLAlchemyUserDatabase ( database , users ) app = FastAPI () @app.on_event ( \"startup\" ) async def startup (): await database . connect () @app.on_event ( \"shutdown\" ) async def shutdown (): await database . disconnect () Notice that we declare the users variable, which is the actual SQLAlchemy table behind the table class. We also use our database instance, which allows us to do asynchronous request to the database.","title":"Create the database adapter"},{"location":"configuration/databases/sqlalchemy/#next-steps","text":"We will now configure an authentication method .","title":"Next steps"},{"location":"configuration/databases/sqlalchemy/#what-about-sqlalchemy-orm","text":"The primary objective was to use pure async approach as much as possible. However, we understand that ORM is convenient and useful for many developers. If this feature becomes very demanded, we will add a database adapter for SQLAlchemy ORM.","title":"What about SQLAlchemy ORM?"},{"location":"usage/dependency-callables/","text":"Dependency callables \u00b6 FastAPI Users provides dependency callables to easily inject users in your routes. They are available from your FastAPIUsers instance. Tip For more information about how to make an authenticated request to your API, check the documentation of your Authentication method . get_current_user \u00b6 Get the current user ( active or not ). Will throw a 401 Unauthorized if missing or wrong credentials. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_user )): return f 'Hello, {user.email}' get_current_active_user \u00b6 Get the current active user. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_active_user )): return f 'Hello, {user.email}' get_current_superuser \u00b6 Get the current superuser. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. Will throw a 403 Forbidden if the user is not a superuser. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_superuser )): return f 'Hello, {user.email}'","title":"Dependency callables"},{"location":"usage/dependency-callables/#dependency-callables","text":"FastAPI Users provides dependency callables to easily inject users in your routes. They are available from your FastAPIUsers instance. Tip For more information about how to make an authenticated request to your API, check the documentation of your Authentication method .","title":"Dependency callables"},{"location":"usage/dependency-callables/#get_current_user","text":"Get the current user ( active or not ). Will throw a 401 Unauthorized if missing or wrong credentials. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_user )): return f 'Hello, {user.email}'","title":"get_current_user"},{"location":"usage/dependency-callables/#get_current_active_user","text":"Get the current active user. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_active_user )): return f 'Hello, {user.email}'","title":"get_current_active_user"},{"location":"usage/dependency-callables/#get_current_superuser","text":"Get the current superuser. Will throw a 401 Unauthorized if missing or wrong credentials or if the user is not active. Will throw a 403 Forbidden if the user is not a superuser. @app.get ( '/protected-route' ) def protected_route ( user : User = Depends ( fastapi_users . get_current_superuser )): return f 'Hello, {user.email}'","title":"get_current_superuser"},{"location":"usage/routes/","text":"Routes \u00b6 You'll find here the routes exposed by FastAPI Users . Note that you can also review them through the interactive API docs . Unauthenticated \u00b6 POST /register \u00b6 Register a new user. Will call the on_after_register event handlers on successful registration. Payload { \"email\" : \"king.arthur@camelot.bt\" , \"password\" : \"guinevere\" } 201 Created { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 422 Validation Error 400 Bad Request A user already exists with this email. POST /login \u00b6 Login a user. Payload ( application/x-www-form-urlencoded ) username = king . arthur @camelot . bt & password = guinevere 200 OK { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" } 422 Validation Error 400 Bad Request Bad credentials or the user is inactive. POST /forgot-password \u00b6 Request a reset password procedure. Will generate a temporary token and call the on_after_forgot_password event handlers if the user exists. To prevent malicious users from guessing existing users in your databse, the route will always return a 202 Accepted response, even if the user requested does not exist. Payload { \"email\" : \"king.arthur@camelot.bt\" } 202 Accepted POST /reset-password \u00b6 Reset a password. Requires the token generated by the /forgot-password route. Payload { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" , \"password\" : \"merlin\" } 200 OK 422 Validation Error 400 Bad Request Bad or expired token. Authenticated \u00b6 GET /me \u00b6 Return the current authenticated active user. 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user. PATCH /me \u00b6 Update the current authenticated active user. Payload { \"email\" : \"king.arthur@tintagel.bt\" , \"password\" : \"merlin\" } 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@tintagel.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user.","title":"Routes"},{"location":"usage/routes/#routes","text":"You'll find here the routes exposed by FastAPI Users . Note that you can also review them through the interactive API docs .","title":"Routes"},{"location":"usage/routes/#unauthenticated","text":"","title":"Unauthenticated"},{"location":"usage/routes/#post-register","text":"Register a new user. Will call the on_after_register event handlers on successful registration. Payload { \"email\" : \"king.arthur@camelot.bt\" , \"password\" : \"guinevere\" } 201 Created { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 422 Validation Error 400 Bad Request A user already exists with this email.","title":"POST /register"},{"location":"usage/routes/#post-login","text":"Login a user. Payload ( application/x-www-form-urlencoded ) username = king . arthur @camelot . bt & password = guinevere 200 OK { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" } 422 Validation Error 400 Bad Request Bad credentials or the user is inactive.","title":"POST /login"},{"location":"usage/routes/#post-forgot-password","text":"Request a reset password procedure. Will generate a temporary token and call the on_after_forgot_password event handlers if the user exists. To prevent malicious users from guessing existing users in your databse, the route will always return a 202 Accepted response, even if the user requested does not exist. Payload { \"email\" : \"king.arthur@camelot.bt\" } 202 Accepted","title":"POST /forgot-password"},{"location":"usage/routes/#post-reset-password","text":"Reset a password. Requires the token generated by the /forgot-password route. Payload { \"token\" : \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI\" , \"password\" : \"merlin\" } 200 OK 422 Validation Error 400 Bad Request Bad or expired token.","title":"POST /reset-password"},{"location":"usage/routes/#authenticated","text":"","title":"Authenticated"},{"location":"usage/routes/#get-me","text":"Return the current authenticated active user. 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@camelot.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user.","title":"GET /me"},{"location":"usage/routes/#patch-me","text":"Update the current authenticated active user. Payload { \"email\" : \"king.arthur@tintagel.bt\" , \"password\" : \"merlin\" } 200 OK { \"id\" : \"57cbb51a-ab71-4009-8802-3f54b4f2e23\" , \"email\" : \"king.arthur@tintagel.bt\" , \"is_active\" : true , \"is_superuser\" : false } 401 Unauthorized Missing token or inactive user.","title":"PATCH /me"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index c70fa5ea..150ad520 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,57 +2,57 @@\ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index bd3af3c8..5f8dad41 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ diff --git a/src/db_mongodb.py b/src/db_mongodb.py new file mode 100644 index 00000000..6ee9eb90 --- /dev/null +++ b/src/db_mongodb.py @@ -0,0 +1,14 @@ +import motor.motor_asyncio +from fastapi import FastAPI +from fastapi_users.db import MongoDBUserDatabase + +DATABASE_URL = "mongodb://localhost:27017" +client = motor.motor_asyncio.AsyncIOMotorClient(DATABASE_URL) +db = client["database_name"] +collection = db["users"] + + +app = FastAPI() + + +user_db = MongoDBUserDatabase(collection) diff --git a/src/full_mongodb.py b/src/full_mongodb.py new file mode 100644 index 00000000..ca46e4bf --- /dev/null +++ b/src/full_mongodb.py @@ -0,0 +1,37 @@ +import motor.motor_asyncio +from fastapi import FastAPI +from fastapi_users import BaseUser, FastAPIUsers +from fastapi_users.authentication import JWTAuthentication +from fastapi_users.db import MongoDBUserDatabase + +DATABASE_URL = "mongodb://localhost:27017" +SECRET = "SECRET" + + +client = motor.motor_asyncio.AsyncIOMotorClient(DATABASE_URL) +db = client["database_name"] +collection = db["users"] + + +user_db = MongoDBUserDatabase(collection) + + +class User(BaseUser): + pass + + +auth = JWTAuthentication(secret=SECRET, lifetime_seconds=3600) + +app = FastAPI() +fastapi_users = FastAPIUsers(user_db, auth, User, SECRET) +app.include_router(fastapi_users.router, prefix="/users", tags=["users"]) + + +@fastapi_users.on_after_register() +def on_after_register(user: User): + print(f"User {user.id} has registered.") + + +@fastapi_users.on_after_forgot_password() +def on_after_forgot_password(user: User, token: str): + print(f"User {user.id} has forgot their password. Reset token: {token}") None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily None -2019-10-25 +2019-10-27 daily