diff --git a/docs/configuration/databases/ormar.md b/docs/configuration/databases/ormar.md
index 533a6026..47f55213 100644
--- a/docs/configuration/databases/ormar.md
+++ b/docs/configuration/databases/ormar.md
@@ -24,7 +24,7 @@ For the sake of this tutorial from now on, we'll use a simple SQLite databse.
Let's declare our User ORM model.
-```py hl_lines="11-15"
+```py hl_lines="12-16"
{!./src/db_ormar.py!}
```
@@ -37,11 +37,11 @@ there to fit to your needs!
The database adapter of **FastAPI Users** makes the link between your
database configuration and the users logic. It should be generated by a FastAPI dependency.
-```py hl_lines="22-23"
+```py hl_lines="23-24"
{!./src/db_ormar.py!}
```
-Notice that we pass a reference to your [`UserDB` model](../models.md).
+Notice that we pass a reference to your [`UserDB` model](../model.md).
!!! warning
In production, it's strongly recommended to setup a migration system to
diff --git a/docs/configuration/oauth.md b/docs/configuration/oauth.md
index 5a2f64ce..7c5132fc 100644
--- a/docs/configuration/oauth.md
+++ b/docs/configuration/oauth.md
@@ -70,26 +70,14 @@ Notice that we inherit from the `BaseOAuthAccountMixin`, which adds a `List` of
You'll need to define the table for storing the OAuth account model. We provide a base one for this:
-```py
-from fastapi_users.db import SQLAlchemyBaseOAuthAccountTable
-
-class OAuthAccount(SQLAlchemyBaseOAuthAccountTable, Base):
- pass
+```py hl_lines="21 22"
+{!./src/db_sqlalchemy_oauth.py!}
```
-Similarly, define the table for storing the User model:
+When instantiating the database adapter, you should pass this table in argument::
-```py
-from fastapi_users.db import SQLAlchemyBaseUserTable
-
-class UserTable(Base, SQLAlchemyBaseUserTable):
- pass
-```
-
-Then, you should declare them on the database adapter:
-
-```py
-user_db = SQLAlchemyUserDatabase(UserDB, database, UserTable.__table__, OAuthAccount.__table__)
+```py hl_lines="31 34 35"
+{!./src/db_sqlalchemy_oauth.py!}
```
#### MongoDB
@@ -100,12 +88,8 @@ Nothing to do, the [basic configuration](./databases/mongodb.md) is enough.
You'll need to define the Tortoise model for storing the OAuth account model. We provide a base one for this:
-```py
-from fastapi_users.db.tortoise import TortoiseBaseOAuthAccountModel
-
-
-class OAuthAccount(TortoiseBaseOAuthAccountModel):
- user = fields.ForeignKeyField("models.User", related_name="oauth_accounts")
+```py hl_lines="29 30"
+{!./src/db_tortoise_oauth_model.py!}
```
!!! warning
@@ -113,8 +97,8 @@ class OAuthAccount(TortoiseBaseOAuthAccountModel):
Then, you should declare it on the database adapter:
-```py
-user_db = TortoiseUserDatabase(UserDB, User, OAuthAccount)
+```py hl_lines="8 9"
+{!./src/db_tortoise_oauth_adapter.py!}
```
### Generate a router
@@ -122,51 +106,11 @@ user_db = TortoiseUserDatabase(UserDB, User, OAuthAccount)
Once you have a `FastAPIUsers` instance, you can make it generate a single OAuth router for the given client.
```py
-from fastapi import FastAPI
-from fastapi_users import FastAPIUsers
-from httpx_oauth.clients.google import GoogleOAuth2
-
-google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
-
-app = FastAPI()
-fastapi_users = FastAPIUsers(
- user_db, auth_backends, User, UserCreate, UserUpdate, UserDB
+app.include_router(
+ fastapi_users.get_oauth_router(google_oauth_client, "SECRET"),
+ prefix="/auth/google",
+ tags=["auth"],
)
-
-google_oauth_router = fastapi_users.get_oauth_router(google_oauth_client, SECRET)
-
-app.include_router(google_oauth_router, prefix="/auth/google", tags=["auth"])
-```
-
-### After register
-
-You can provide a custom function to be called after a successful registration. It is called with **two argument**: the **user** that has just registered, and the original **`Request` object**.
-
-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:
-
-```py
-from fastapi import FastAPI
-from fastapi_users import FastAPIUsers
-from httpx_oauth.clients.google import GoogleOAuth2
-
-
-def on_after_register(user: UserDB, request: Request):
- print(f"User {user.id} has registered.")
-
-google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
-
-app = FastAPI()
-fastapi_users = FastAPIUsers(
- user_db, auth_backends, User, UserCreate, UserUpdate, UserDB
-)
-
-google_oauth_router = fastapi_users.get_oauth_router(google_oauth_client, SECRET, after_register=on_after_register)
-
-app.include_router(google_oauth_router, prefix="/auth/google", tags=["auth"])
```
### Full example
@@ -177,18 +121,12 @@ app.include_router(google_oauth_router, prefix="/auth/google", tags=["auth"])
#### SQLAlchemy
-``` py
-{!./src/oauth_full_sqlalchemy.py!}
-```
+
#### MongoDB
-```py
-{!./src/oauth_full_mongodb.py!}
-```
+
#### Tortoise ORM
-```py
-{!./src/oauth_full_tortoise.py!}
-```
+
diff --git a/docs/configuration/overview.md b/docs/configuration/overview.md
index 3c174347..c3af46ab 100644
--- a/docs/configuration/overview.md
+++ b/docs/configuration/overview.md
@@ -4,9 +4,10 @@ The schema below shows you how the library is structured and how each part fit t
```mermaid
-flowchart TB
+flowchart LR
FASTAPI_USERS{FastAPIUsers}
USER_MANAGER{UserManager}
+ DATABASE_DEPENDENCY[[get_user_db]]
USER_MANAGER_DEPENDENCY[[get_user_manager]]
CURRENT_USER[[current_user]]
subgraph MODELS[Models]
@@ -37,7 +38,8 @@ flowchart TB
COOKIE[CookieAuthentication]
JWT[JWTAuthentication]
end
- DATABASE --> USER_MANAGER
+ DATABASE --> DATABASE_DEPENDENCY
+ DATABASE_DEPENDENCY --> USER_MANAGER
MODELS --> USER_MANAGER
MODELS --> FASTAPI_USERS
diff --git a/docs/configuration/user-manager.md b/docs/configuration/user-manager.md
index cd06ea35..cc87fa62 100644
--- a/docs/configuration/user-manager.md
+++ b/docs/configuration/user-manager.md
@@ -8,7 +8,7 @@ It's designed to be easily extensible and customizable so that you can integrate
You should define your own version of the `UserManager` class to set various parameters.
-```py hl_lines="13-29"
+```py hl_lines="12-28"
{!./src/user_manager.py!}
```
diff --git a/docs/src/db_ormar.py b/docs/src/db_ormar.py
index bb699938..d9e577b2 100644
--- a/docs/src/db_ormar.py
+++ b/docs/src/db_ormar.py
@@ -2,6 +2,7 @@ import databases
import sqlalchemy
from fastapi_users.db import OrmarBaseUserModel, OrmarUserDatabase
+from .models import UserDB
DATABASE_URL = "sqlite:///test.db"
metadata = sqlalchemy.MetaData()
diff --git a/docs/src/db_sqlalchemy_oauth.py b/docs/src/db_sqlalchemy_oauth.py
new file mode 100644
index 00000000..6822d4ee
--- /dev/null
+++ b/docs/src/db_sqlalchemy_oauth.py
@@ -0,0 +1,35 @@
+import databases
+import sqlalchemy
+from fastapi_users.db import (
+ SQLAlchemyBaseOAuthAccountTable,
+ SQLAlchemyBaseUserTable,
+ SQLAlchemyUserDatabase,
+)
+from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base
+
+from .models import UserDB
+
+DATABASE_URL = "sqlite:///./test.db"
+database = databases.Database(DATABASE_URL)
+Base: DeclarativeMeta = declarative_base()
+
+
+class UserTable(Base, SQLAlchemyBaseUserTable):
+ pass
+
+
+class OAuthAccount(SQLAlchemyBaseOAuthAccountTable, Base):
+ pass
+
+
+engine = sqlalchemy.create_engine(
+ DATABASE_URL, connect_args={"check_same_thread": False}
+)
+Base.metadata.create_all(engine)
+
+users = UserTable.__table__
+oauth_accounts = OAuthAccount.__table__
+
+
+def get_user_db():
+ yield SQLAlchemyUserDatabase(UserDB, database, users, oauth_accounts)
diff --git a/docs/src/db_tortoise_oauth_adapter.py b/docs/src/db_tortoise_oauth_adapter.py
new file mode 100644
index 00000000..c864687d
--- /dev/null
+++ b/docs/src/db_tortoise_oauth_adapter.py
@@ -0,0 +1,9 @@
+from fastapi_users.db import TortoiseUserDatabase
+
+from .models import OAuthAccount, UserDB, UserModel
+
+DATABASE_URL = "sqlite://./test.db"
+
+
+def get_user_db():
+ yield TortoiseUserDatabase(UserDB, UserModel, OAuthAccount)
diff --git a/docs/src/db_tortoise_oauth_model.py b/docs/src/db_tortoise_oauth_model.py
new file mode 100644
index 00000000..9d470192
--- /dev/null
+++ b/docs/src/db_tortoise_oauth_model.py
@@ -0,0 +1,30 @@
+from fastapi_users import models
+from fastapi_users.db import TortoiseBaseOAuthAccountModel, TortoiseBaseUserModel
+from tortoise import fields
+from tortoise.contrib.pydantic import PydanticModel
+
+
+class User(models.BaseUser, models.BaseOAuthAccountMixin):
+ pass
+
+
+class UserCreate(models.BaseUserCreate):
+ pass
+
+
+class UserUpdate(models.BaseUserUpdate):
+ pass
+
+
+class UserModel(TortoiseBaseUserModel):
+ pass
+
+
+class UserDB(User, models.BaseUserDB, PydanticModel):
+ class Config:
+ orm_mode = True
+ orig_model = UserModel
+
+
+class OAuthAccount(TortoiseBaseOAuthAccountModel):
+ user = fields.ForeignKeyField("models.UserModel", related_name="oauth_accounts")
diff --git a/docs/src/oauth_full_mongodb.py b/docs/src/oauth_full_mongodb.py
deleted file mode 100644
index b0fd9037..00000000
--- a/docs/src/oauth_full_mongodb.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import motor.motor_asyncio
-from fastapi import FastAPI, Request
-from fastapi_users import FastAPIUsers, models
-from fastapi_users.authentication import JWTAuthentication
-from fastapi_users.db import MongoDBUserDatabase
-from httpx_oauth.clients.google import GoogleOAuth2
-
-DATABASE_URL = "mongodb://localhost:27017"
-SECRET = "SECRET"
-
-
-google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
-
-
-class User(models.BaseUser, models.BaseOAuthAccountMixin):
- pass
-
-
-class UserCreate(models.BaseUserCreate):
- pass
-
-
-class UserUpdate(User, models.BaseUserUpdate):
- pass
-
-
-class UserDB(User, models.BaseUserDB):
- pass
-
-
-client = motor.motor_asyncio.AsyncIOMotorClient(
- DATABASE_URL, uuidRepresentation="standard"
-)
-db = client["database_name"]
-collection = db["users"]
-user_db = MongoDBUserDatabase(UserDB, collection)
-
-
-def on_after_register(user: UserDB, request: Request):
- print(f"User {user.id} has registered.")
-
-
-def on_after_forgot_password(user: UserDB, token: str, request: Request):
- print(f"User {user.id} has forgot their password. Reset token: {token}")
-
-
-def after_verification_request(user: UserDB, token: str, request: Request):
- print(f"Verification requested for user {user.id}. Verification token: {token}")
-
-
-jwt_authentication = JWTAuthentication(
- secret=SECRET, lifetime_seconds=3600, tokenUrl="auth/jwt/login"
-)
-
-app = FastAPI()
-fastapi_users = FastAPIUsers(
- user_db,
- [jwt_authentication],
- User,
- UserCreate,
- UserUpdate,
- UserDB,
-)
-app.include_router(
- fastapi_users.get_auth_router(jwt_authentication), prefix="/auth/jwt", tags=["auth"]
-)
-app.include_router(
- fastapi_users.get_register_router(on_after_register), prefix="/auth", tags=["auth"]
-)
-app.include_router(
- fastapi_users.get_reset_password_router(
- SECRET, after_forgot_password=on_after_forgot_password
- ),
- prefix="/auth",
- tags=["auth"],
-)
-app.include_router(
- fastapi_users.get_verify_router(
- SECRET, after_verification_request=after_verification_request
- ),
- prefix="/auth",
- tags=["auth"],
-)
-app.include_router(fastapi_users.get_users_router(), prefix="/users", tags=["users"])
-
-google_oauth_router = fastapi_users.get_oauth_router(
- google_oauth_client, SECRET, after_register=on_after_register
-)
-app.include_router(google_oauth_router, prefix="/auth/google", tags=["auth"])
diff --git a/docs/src/oauth_full_sqlalchemy.py b/docs/src/oauth_full_sqlalchemy.py
deleted file mode 100644
index 83510898..00000000
--- a/docs/src/oauth_full_sqlalchemy.py
+++ /dev/null
@@ -1,119 +0,0 @@
-import databases
-import sqlalchemy
-from fastapi import FastAPI, Request
-from fastapi_users import FastAPIUsers, models
-from fastapi_users.authentication import JWTAuthentication
-from fastapi_users.db import (
- SQLAlchemyBaseOAuthAccountTable,
- SQLAlchemyBaseUserTable,
- SQLAlchemyUserDatabase,
-)
-from httpx_oauth.clients.google import GoogleOAuth2
-from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base
-
-DATABASE_URL = "sqlite:///./test.db"
-SECRET = "SECRET"
-
-
-google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
-
-
-class User(models.BaseUser, models.BaseOAuthAccountMixin):
- pass
-
-
-class UserCreate(models.BaseUserCreate):
- pass
-
-
-class UserUpdate(User, models.BaseUserUpdate):
- pass
-
-
-class UserDB(User, models.BaseUserDB):
- pass
-
-
-database = databases.Database(DATABASE_URL)
-Base: DeclarativeMeta = declarative_base()
-
-
-class UserTable(Base, SQLAlchemyBaseUserTable):
- pass
-
-
-class OAuthAccount(SQLAlchemyBaseOAuthAccountTable, Base):
- pass
-
-
-engine = sqlalchemy.create_engine(
- DATABASE_URL, connect_args={"check_same_thread": False}
-)
-Base.metadata.create_all(engine)
-
-users = UserTable.__table__
-oauth_accounts = OAuthAccount.__table__
-user_db = SQLAlchemyUserDatabase(UserDB, database, users, oauth_accounts)
-
-
-def on_after_register(user: UserDB, request: Request):
- print(f"User {user.id} has registered.")
-
-
-def on_after_forgot_password(user: UserDB, token: str, request: Request):
- print(f"User {user.id} has forgot their password. Reset token: {token}")
-
-
-def after_verification_request(user: UserDB, token: str, request: Request):
- print(f"Verification requested for user {user.id}. Verification token: {token}")
-
-
-jwt_authentication = JWTAuthentication(
- secret=SECRET, lifetime_seconds=3600, tokenUrl="auth/jwt/login"
-)
-
-app = FastAPI()
-fastapi_users = FastAPIUsers(
- user_db,
- [jwt_authentication],
- User,
- UserCreate,
- UserUpdate,
- UserDB,
-)
-app.include_router(
- fastapi_users.get_auth_router(jwt_authentication), prefix="/auth/jwt", tags=["auth"]
-)
-app.include_router(
- fastapi_users.get_register_router(on_after_register), prefix="/auth", tags=["auth"]
-)
-app.include_router(
- fastapi_users.get_reset_password_router(
- SECRET, after_forgot_password=on_after_forgot_password
- ),
- prefix="/auth",
- tags=["auth"],
-)
-app.include_router(
- fastapi_users.get_verify_router(
- SECRET, after_verification_request=after_verification_request
- ),
- prefix="/auth",
- tags=["auth"],
-)
-app.include_router(fastapi_users.get_users_router(), prefix="/users", tags=["users"])
-
-google_oauth_router = fastapi_users.get_oauth_router(
- google_oauth_client, SECRET, after_register=on_after_register
-)
-app.include_router(google_oauth_router, prefix="/auth/google", tags=["auth"])
-
-
-@app.on_event("startup")
-async def startup():
- await database.connect()
-
-
-@app.on_event("shutdown")
-async def shutdown():
- await database.disconnect()
diff --git a/docs/src/oauth_full_tortoise.py b/docs/src/oauth_full_tortoise.py
deleted file mode 100644
index 651b9b67..00000000
--- a/docs/src/oauth_full_tortoise.py
+++ /dev/null
@@ -1,106 +0,0 @@
-from fastapi import FastAPI, Request
-from fastapi_users import FastAPIUsers, models
-from fastapi_users.authentication import JWTAuthentication
-from fastapi_users.db import (
- TortoiseBaseOAuthAccountModel,
- TortoiseBaseUserModel,
- TortoiseUserDatabase,
-)
-from httpx_oauth.clients.google import GoogleOAuth2
-from tortoise import fields
-from tortoise.contrib.fastapi import register_tortoise
-from tortoise.contrib.pydantic import PydanticModel
-
-DATABASE_URL = "sqlite://./test.db"
-SECRET = "SECRET"
-
-
-google_oauth_client = GoogleOAuth2("CLIENT_ID", "CLIENT_SECRET")
-
-
-class UserModel(TortoiseBaseUserModel):
- pass
-
-
-class OAuthAccountModel(TortoiseBaseOAuthAccountModel):
- user = fields.ForeignKeyField("models.UserModel", related_name="oauth_accounts")
-
-
-class User(models.BaseUser, models.BaseOAuthAccountMixin):
- pass
-
-
-class UserCreate(models.BaseUserCreate):
- pass
-
-
-class UserUpdate(User, models.BaseUserUpdate):
- pass
-
-
-class UserDB(User, models.BaseUserDB, PydanticModel):
- class Config:
- orm_mode = True
- orig_model = UserModel
-
-
-user_db = TortoiseUserDatabase(UserDB, UserModel, OAuthAccountModel)
-app = FastAPI()
-register_tortoise(
- app,
- db_url=DATABASE_URL,
- modules={"models": ["oauth_full_tortoise"]},
- generate_schemas=True,
-)
-
-
-def on_after_register(user: UserDB, request: Request):
- print(f"User {user.id} has registered.")
-
-
-def on_after_forgot_password(user: UserDB, token: str, request: Request):
- print(f"User {user.id} has forgot their password. Reset token: {token}")
-
-
-def after_verification_request(user: UserDB, token: str, request: Request):
- print(f"Verification requested for user {user.id}. Verification token: {token}")
-
-
-jwt_authentication = JWTAuthentication(
- secret=SECRET, lifetime_seconds=3600, tokenUrl="auth/jwt/login"
-)
-
-fastapi_users = FastAPIUsers(
- user_db,
- [jwt_authentication],
- User,
- UserCreate,
- UserUpdate,
- UserDB,
-)
-app.include_router(
- fastapi_users.get_auth_router(jwt_authentication), prefix="/auth/jwt", tags=["auth"]
-)
-app.include_router(
- fastapi_users.get_register_router(on_after_register), prefix="/auth", tags=["auth"]
-)
-app.include_router(
- fastapi_users.get_reset_password_router(
- SECRET, after_forgot_password=on_after_forgot_password
- ),
- prefix="/auth",
- tags=["auth"],
-)
-app.include_router(
- fastapi_users.get_verify_router(
- SECRET, after_verification_request=after_verification_request
- ),
- prefix="/auth",
- tags=["auth"],
-)
-app.include_router(fastapi_users.get_users_router(), prefix="/users", tags=["users"])
-
-google_oauth_router = fastapi_users.get_oauth_router(
- google_oauth_client, SECRET, after_register=on_after_register
-)
-app.include_router(google_oauth_router, prefix="/auth/google", tags=["auth"])