fastapi-fullauth 0.5.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastapi_fullauth-0.7.0/.github/ISSUE_TEMPLATE/bug_report.yml +60 -0
- fastapi_fullauth-0.7.0/.github/ISSUE_TEMPLATE/feature_request.yml +30 -0
- fastapi_fullauth-0.7.0/.github/pull_request_template.md +17 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/CHANGELOG.md +92 -0
- fastapi_fullauth-0.7.0/CONTRIBUTING.md +83 -0
- fastapi_fullauth-0.7.0/Makefile +64 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/PKG-INFO +106 -39
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/README.md +104 -37
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/adapters/index.md +18 -8
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/adapters/sqlalchemy.md +24 -10
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/adapters/sqlmodel.md +15 -8
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/api-reference.md +22 -21
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/auth/custom-claims.md +4 -1
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/auth/dependencies.md +77 -1
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/auth/hooks.md +1 -1
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/auth/passwords.md +8 -4
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/configuration.md +13 -18
- fastapi_fullauth-0.7.0/docs/contributing.md +72 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/getting-started.md +31 -5
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/index.md +60 -25
- fastapi_fullauth-0.7.0/docs/llms-full.txt +2141 -0
- fastapi_fullauth-0.7.0/docs/llms.txt +30 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/oauth.md +27 -17
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/security/middleware.md +7 -3
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/security/rate-limiting.md +26 -14
- fastapi_fullauth-0.7.0/docs/stylesheets/home.css +5 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlalchemy_app/auth.py +5 -3
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlmodel_app/auth.py +5 -3
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/__init__.py +11 -3
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/adapters/__init__.py +1 -2
- fastapi_fullauth-0.7.0/fastapi_fullauth/adapters/base.py +117 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/adapters/sqlalchemy/__init__.py +4 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/adapters/sqlalchemy/adapter.py +100 -60
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/adapters/sqlalchemy/models.py +19 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/adapters/sqlmodel/__init__.py +4 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/adapters/sqlmodel/adapter.py +100 -43
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/adapters/sqlmodel/models.py +15 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/config.py +4 -2
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/core/crypto.py +6 -17
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/core/tokens.py +14 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/dependencies/__init__.py +6 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/dependencies/current_user.py +153 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/dependencies/require_role.py +22 -4
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/exceptions.py +34 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/flows/__init__.py +4 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/flows/change_password.py +31 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/flows/email_verify.py +6 -5
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/flows/login.py +10 -9
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/flows/oauth.py +11 -8
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/flows/password_reset.py +11 -4
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/flows/register.py +7 -1
- fastapi_fullauth-0.7.0/fastapi_fullauth/flows/update_profile.py +27 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/fullauth.py +204 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/hooks.py +2 -2
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/middleware/csrf.py +1 -1
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/oauth/base.py +4 -15
- fastapi_fullauth-0.7.0/fastapi_fullauth/protection/__init__.py +15 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/protection/lockout.py +129 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/protection/ratelimit.py +19 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/router/__init__.py +11 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/router/_models.py +61 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/router/admin.py +108 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/router/auth.py +244 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/router/oauth.py +25 -21
- fastapi_fullauth-0.7.0/fastapi_fullauth/router/profile.py +108 -0
- fastapi_fullauth-0.7.0/fastapi_fullauth/router/verify.py +117 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/types.py +24 -19
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/utils.py +4 -2
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/mkdocs.yml +2 -2
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/pyproject.toml +13 -1
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/tests/conftest.py +33 -4
- fastapi_fullauth-0.7.0/tests/test_auth.py +809 -0
- fastapi_fullauth-0.7.0/tests/test_config.py +604 -0
- fastapi_fullauth-0.7.0/tests/test_hooks.py +185 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/tests/test_oauth.py +39 -16
- fastapi_fullauth-0.5.0/tests/test_new_endpoints.py → fastapi_fullauth-0.7.0/tests/test_profile.py +66 -118
- fastapi_fullauth-0.7.0/tests/test_rbac.py +446 -0
- fastapi_fullauth-0.5.0/tests/test_middleware.py → fastapi_fullauth-0.7.0/tests/test_security.py +112 -32
- fastapi_fullauth-0.7.0/tests/test_sqlalchemy_adapter.py +338 -0
- fastapi_fullauth-0.7.0/tests/test_sqlmodel_adapter.py +380 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/uv.lock +1 -1
- fastapi_fullauth-0.5.0/docs/adapters/memory.md +0 -32
- fastapi_fullauth-0.5.0/docs/stylesheets/home.css +0 -90
- fastapi_fullauth-0.5.0/examples/memory_app/auth.py +0 -8
- fastapi_fullauth-0.5.0/examples/memory_app/main.py +0 -13
- fastapi_fullauth-0.5.0/examples/sqlmodel_app/routes.py +0 -15
- fastapi_fullauth-0.5.0/fastapi_fullauth/adapters/base.py +0 -87
- fastapi_fullauth-0.5.0/fastapi_fullauth/adapters/memory.py +0 -133
- fastapi_fullauth-0.5.0/fastapi_fullauth/dependencies/current_user.py +0 -87
- fastapi_fullauth-0.5.0/fastapi_fullauth/fullauth.py +0 -289
- fastapi_fullauth-0.5.0/fastapi_fullauth/migrations/__init__.py +0 -3
- fastapi_fullauth-0.5.0/fastapi_fullauth/protection/__init__.py +0 -4
- fastapi_fullauth-0.5.0/fastapi_fullauth/protection/lockout.py +0 -41
- fastapi_fullauth-0.5.0/fastapi_fullauth/rbac/__init__.py +0 -0
- fastapi_fullauth-0.5.0/fastapi_fullauth/router/__init__.py +0 -0
- fastapi_fullauth-0.5.0/fastapi_fullauth/router/auth.py +0 -544
- fastapi_fullauth-0.5.0/tests/__init__.py +0 -0
- fastapi_fullauth-0.5.0/tests/test_auth_flows.py +0 -177
- fastapi_fullauth-0.5.0/tests/test_customization.py +0 -369
- fastapi_fullauth-0.5.0/tests/test_dx_improvements.py +0 -317
- fastapi_fullauth-0.5.0/tests/test_email_verify.py +0 -116
- fastapi_fullauth-0.5.0/tests/test_lockout.py +0 -52
- fastapi_fullauth-0.5.0/tests/test_refresh_tokens.py +0 -379
- fastapi_fullauth-0.5.0/tests/test_roles.py +0 -161
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/.github/workflows/ci.yml +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/.github/workflows/docs.yml +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/.github/workflows/publish.yml +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/.gitignore +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/.python-version +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/LICENSE +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/docs/migrations.md +0 -0
- {fastapi_fullauth-0.5.0/examples/memory_app → fastapi_fullauth-0.7.0/examples/sqlalchemy_app}/__init__.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlalchemy_app/config.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlalchemy_app/main.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlalchemy_app/models.py +0 -0
- {fastapi_fullauth-0.5.0/examples/memory_app → fastapi_fullauth-0.7.0/examples/sqlalchemy_app}/routes.py +0 -0
- {fastapi_fullauth-0.5.0/examples/sqlalchemy_app → fastapi_fullauth-0.7.0/examples/sqlmodel_app}/__init__.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlmodel_app/config.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlmodel_app/main.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/examples/sqlmodel_app/models.py +0 -0
- {fastapi_fullauth-0.5.0/examples/sqlalchemy_app → fastapi_fullauth-0.7.0/examples/sqlmodel_app}/routes.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/backends/__init__.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/backends/base.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/backends/bearer.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/backends/cookie.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/core/__init__.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/core/redis_blacklist.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/flows/logout.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/middleware/__init__.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/middleware/ratelimit.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/middleware/security_headers.py +0 -0
- /fastapi_fullauth-0.5.0/fastapi_fullauth/migrations/helpers.py → /fastapi_fullauth-0.7.0/fastapi_fullauth/migrations.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/oauth/__init__.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/oauth/github.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/oauth/google.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/fastapi_fullauth/validators.py +0 -0
- {fastapi_fullauth-0.5.0/examples/sqlmodel_app → fastapi_fullauth-0.7.0/tests}/__init__.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/tests/test_crypto.py +0 -0
- {fastapi_fullauth-0.5.0 → fastapi_fullauth-0.7.0}/tests/test_tokens.py +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug in fastapi-fullauth
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for reporting a bug! Please fill out the details below.
|
|
9
|
+
|
|
10
|
+
- type: input
|
|
11
|
+
id: version
|
|
12
|
+
attributes:
|
|
13
|
+
label: fastapi-fullauth version
|
|
14
|
+
placeholder: "0.5.0"
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
|
|
18
|
+
- type: input
|
|
19
|
+
id: python-version
|
|
20
|
+
attributes:
|
|
21
|
+
label: Python version
|
|
22
|
+
placeholder: "3.12"
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
|
|
26
|
+
- type: dropdown
|
|
27
|
+
id: adapter
|
|
28
|
+
attributes:
|
|
29
|
+
label: Adapter
|
|
30
|
+
options:
|
|
31
|
+
- SQLModel
|
|
32
|
+
- SQLAlchemy
|
|
33
|
+
- InMemory
|
|
34
|
+
- Custom
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: textarea
|
|
39
|
+
id: description
|
|
40
|
+
attributes:
|
|
41
|
+
label: Description
|
|
42
|
+
description: What happened? What did you expect to happen?
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
45
|
+
|
|
46
|
+
- type: textarea
|
|
47
|
+
id: reproduction
|
|
48
|
+
attributes:
|
|
49
|
+
label: Steps to reproduce
|
|
50
|
+
description: Minimal code or steps to reproduce the bug.
|
|
51
|
+
render: python
|
|
52
|
+
validations:
|
|
53
|
+
required: true
|
|
54
|
+
|
|
55
|
+
- type: textarea
|
|
56
|
+
id: logs
|
|
57
|
+
attributes:
|
|
58
|
+
label: Error output / traceback
|
|
59
|
+
description: Paste any relevant error messages or tracebacks.
|
|
60
|
+
render: shell
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature for fastapi-fullauth
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for suggesting a feature! Please describe what you'd like.
|
|
9
|
+
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: problem
|
|
12
|
+
attributes:
|
|
13
|
+
label: Problem
|
|
14
|
+
description: What problem does this feature solve? What's the use case?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: solution
|
|
20
|
+
attributes:
|
|
21
|
+
label: Proposed solution
|
|
22
|
+
description: How would you like this to work? Code examples are welcome.
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
|
|
26
|
+
- type: textarea
|
|
27
|
+
id: alternatives
|
|
28
|
+
attributes:
|
|
29
|
+
label: Alternatives considered
|
|
30
|
+
description: Any workarounds or alternative approaches you've considered?
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this PR do? Keep it brief. -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- Bullet list of what changed. -->
|
|
8
|
+
|
|
9
|
+
-
|
|
10
|
+
|
|
11
|
+
## Test plan
|
|
12
|
+
|
|
13
|
+
<!-- How was this tested? -->
|
|
14
|
+
|
|
15
|
+
- [ ] All existing tests pass
|
|
16
|
+
- [ ] New tests added for new functionality
|
|
17
|
+
- [ ] Lint and format clean (`ruff check .` + `ruff format --check .`)
|
|
@@ -1,5 +1,97 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Breaking changes
|
|
6
|
+
|
|
7
|
+
- **InMemory adapter removed** — use SQLModel + SQLite for prototyping instead.
|
|
8
|
+
- **`UserID` is now `UUID`** (was `str | int | UUID`) — all adapter methods, `RefreshToken.user_id`, `OAuthAccount.user_id`, and `RoleAssignment.user_id` are now `UUID`.
|
|
9
|
+
- **OAuth providers passed as objects** — `FullAuth(providers=[GoogleOAuthProvider(...)])` replaces `OAUTH_PROVIDERS` dict in config. `OAuthProviderConfig` removed.
|
|
10
|
+
- **`OAuthProvider` simplified** — only `redirect_uris: list[str]` (removed singular `redirect_uri`). `get_redirect_uri()` removed.
|
|
11
|
+
- **`redirect_uri` required in authorize URL** — clients must pass `?redirect_uri=` in the OAuth authorize request.
|
|
12
|
+
|
|
13
|
+
### Breaking changes (audit cleanup)
|
|
14
|
+
|
|
15
|
+
- **`include_user_in_login` moved to config** — use `FullAuthConfig(INCLUDE_USER_IN_LOGIN=True)` or `FULLAUTH_INCLUDE_USER_IN_LOGIN=true` env var instead of `FullAuth(include_user_in_login=True)`.
|
|
16
|
+
- **Login response always includes `user` field** — when `INCLUDE_USER_IN_LOGIN=False`, `user` is `null` (previously the key was absent). When `True`, `user` contains the full user schema object.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Redis lockout backend** — `LOCKOUT_BACKEND="redis"` for multi-worker deployments
|
|
21
|
+
- `LOCKOUT_ENABLED` config — disable account lockout entirely (`False`)
|
|
22
|
+
- `INCLUDE_USER_IN_LOGIN` config — include user object in login/OAuth callback response
|
|
23
|
+
- `LoginResponse` dynamic model — login and OAuth callback routes now have proper `response_model` with typed `user` field matching the configured user schema
|
|
24
|
+
- `validate_profile_updates` flow — profile field filtering extracted from router to `flows/update_profile.py`
|
|
25
|
+
- `NoValidFieldsError`, `UnknownFieldsError` exceptions for profile update validation
|
|
26
|
+
- `change_password` flow — business logic extracted from profile router
|
|
27
|
+
- `PROTECTED_FIELDS` ClassVar on `UserSchema` — users can extend in subclasses
|
|
28
|
+
- Password validation moved to flows (`register`, `reset_password`, `change_password`)
|
|
29
|
+
- `Makefile` with `make check`, `make test`, `make lint`, `make format`, `make docs`, etc.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- `LockoutManager` is now an abstract base class with async methods
|
|
34
|
+
- `InMemoryLockoutManager` replaces the old sync `LockoutManager`
|
|
35
|
+
- `migrations/` package flattened to single `migrations.py` module (import paths unchanged)
|
|
36
|
+
- 4 `type: ignore` comments fixed (replaced with `getattr`, assertions, `model_validate`)
|
|
37
|
+
- Misplaced `type: ignore` comments moved inline
|
|
38
|
+
- 204 routes (`delete_me`, `unlink_oauth_account`) no longer return unnecessary `Response` objects
|
|
39
|
+
- Logout route return type corrected to `Response` (needs it for cookie deletion)
|
|
40
|
+
- All tests migrated from InMemory to SQLModel + SQLite
|
|
41
|
+
- Tests regrouped: `test_auth`, `test_profile`, `test_config`, `test_hooks`, `test_security`, `test_rbac`
|
|
42
|
+
- `UUID(payload.sub)` conversion at token boundaries (dependencies, router, flows)
|
|
43
|
+
- Removed `isinstance` str-to-UUID guards from adapters
|
|
44
|
+
- Removed `str(user.id)` / `str(row.user_id)` conversions — UUID used directly
|
|
45
|
+
|
|
46
|
+
### Removed
|
|
47
|
+
|
|
48
|
+
- `InMemoryAdapter` and `examples/memory_app/`
|
|
49
|
+
- `OAuthProviderConfig` from config
|
|
50
|
+
- `OAUTH_PROVIDERS` from `FullAuthConfig`
|
|
51
|
+
- `FullAuth._build_oauth_providers()` and `_OAUTH_PROVIDER_REGISTRY`
|
|
52
|
+
- `OAuthProvider.get_redirect_uri()` method
|
|
53
|
+
- `rbac/` package (was empty, just re-exported from `dependencies`)
|
|
54
|
+
|
|
55
|
+
## 0.6.0
|
|
56
|
+
|
|
57
|
+
### Breaking changes
|
|
58
|
+
|
|
59
|
+
- **Config-only API** — `FullAuth` no longer accepts `secret_key=`, `**config_kwargs`, or positional `config`. Pass `config=FullAuthConfig(SECRET_KEY="...")` or set `FULLAUTH_SECRET_KEY` env var. All params are keyword-only.
|
|
60
|
+
- **`enabled_routes` removed** — replaced by composable routers. Include only the routers you need instead of filtering route names.
|
|
61
|
+
- **`RouteName` type removed** — no longer needed with composable routers.
|
|
62
|
+
- **`configure_hasher()` removed** — hash algorithm is now passed explicitly from config through flows. No more global mutable state.
|
|
63
|
+
- **Schema auto-derivation removed** — `_derive_user_schema()` and `_resolve_create_schema()` deleted from all adapters and FullAuth. Define your own schemas extending `UserSchema` / `CreateUserSchema` and pass them to the adapter.
|
|
64
|
+
- **`create_user_schema` moved to adapter** — pass it to the adapter, not FullAuth: `InMemoryAdapter(user_schema=MyUser, create_user_schema=MyCreate)`.
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- **Generic type parameters** — `AbstractUserAdapter[UserSchemaType, CreateUserSchemaType]`, `FullAuth[UserSchemaType, CreateUserSchemaType]` with PEP 696 defaults for full type safety
|
|
69
|
+
- **Composable routers** — `fullauth.auth_router`, `fullauth.profile_router`, `fullauth.verify_router`, `fullauth.admin_router`, `fullauth.oauth_router`. Each lazily created, include only what you need
|
|
70
|
+
- **Typed dependency factories** — `get_current_user_dependency(MyUser)`, `get_verified_user_dependency(MyUser)`, `get_superuser_dependency(MyUser)` for custom schema type safety
|
|
71
|
+
- `create_blacklist(config)` — extracted from FullAuth to `core/tokens.py`
|
|
72
|
+
- `create_rate_limiter(config, max, window)` — extracted from FullAuth to `protection/ratelimit.py`
|
|
73
|
+
- `UserSchemaType`, `CreateUserSchemaType` TypeVars exported from top-level package
|
|
74
|
+
- `UserSchema`, `CreateUserSchema` base classes exported from top-level package
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
- **Router split** — 613-line monolithic `create_auth_router()` split into `create_auth_router()` (login/register/logout/refresh), `create_profile_router()` (me/update/delete/change-password), `create_verify_router()` (email verify/password reset), `create_admin_router()` (roles/permissions)
|
|
79
|
+
- **FullAuth slimmed** — factory methods extracted, composable router properties added, `_OAUTH_PROVIDER_REGISTRY` stays on class for now
|
|
80
|
+
- `fullauth.router` still works as before (composes all sub-routers), `fullauth.init_app(app)` unchanged
|
|
81
|
+
- `hash_password()` and `password_needs_rehash()` now accept explicit `algorithm` parameter (default `argon2id`)
|
|
82
|
+
- Shared request/response models extracted to `router/_models.py`
|
|
83
|
+
- RBAC permissions (`require_role`, `require_permission`) available via `fastapi_fullauth.dependencies`
|
|
84
|
+
|
|
85
|
+
### Removed
|
|
86
|
+
|
|
87
|
+
- `FullAuth._resolve_create_schema()` — auto-derivation of create schema from ORM model
|
|
88
|
+
- `SQLModelAdapter._derive_user_schema()` — auto-derivation of user schema
|
|
89
|
+
- `SQLAlchemyAdapter._derive_user_schema()` — auto-derivation of user schema
|
|
90
|
+
- `_SA_TYPE_MAP` and `_get_sa_type_map()` — SQLAlchemy type mapping for auto-derivation
|
|
91
|
+
- `FullAuth._create_blacklist()` — moved to `core/tokens.create_blacklist()`
|
|
92
|
+
- `FullAuth._create_rate_limiter()` — moved to `protection.ratelimit.create_rate_limiter()`
|
|
93
|
+
- `configure_hasher()` and `_algorithm` global from `core/crypto.py`
|
|
94
|
+
|
|
3
95
|
## 0.5.0
|
|
4
96
|
|
|
5
97
|
### Added
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Contributing to FastAPI FullAuth
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing! Here's how to get started.
|
|
4
|
+
|
|
5
|
+
## Development setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/mdfarhankc/fastapi-fullauth.git
|
|
9
|
+
cd fastapi-fullauth
|
|
10
|
+
uv sync --dev --extra sqlalchemy --extra sqlmodel --extra redis --extra oauth
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running tests
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv run pytest tests/ -v
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Linting and formatting
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv run ruff check .
|
|
23
|
+
uv run ruff format .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Both must pass before submitting a PR. CI enforces this.
|
|
27
|
+
|
|
28
|
+
## Making changes
|
|
29
|
+
|
|
30
|
+
1. Fork the repo and create a branch from `main`
|
|
31
|
+
2. Make your changes
|
|
32
|
+
3. Add tests for new functionality
|
|
33
|
+
4. Ensure all tests pass and lint is clean
|
|
34
|
+
5. Submit a pull request
|
|
35
|
+
|
|
36
|
+
## Branch naming
|
|
37
|
+
|
|
38
|
+
- `feat/description` — new features
|
|
39
|
+
- `fix/description` — bug fixes
|
|
40
|
+
- `refactor/description` — code improvements
|
|
41
|
+
- `docs/description` — documentation changes
|
|
42
|
+
|
|
43
|
+
## Commit messages
|
|
44
|
+
|
|
45
|
+
Keep them short and descriptive. Use imperative mood:
|
|
46
|
+
|
|
47
|
+
- `add permission-based RBAC`
|
|
48
|
+
- `fix OAuth state token TTL`
|
|
49
|
+
- `update README with docs link`
|
|
50
|
+
|
|
51
|
+
## What to contribute
|
|
52
|
+
|
|
53
|
+
- Bug fixes
|
|
54
|
+
- New OAuth providers (Apple, Discord, Microsoft, etc.)
|
|
55
|
+
- Adapter implementations (MongoDB, Tortoise ORM, etc.)
|
|
56
|
+
- Documentation improvements
|
|
57
|
+
- Test coverage improvements
|
|
58
|
+
- Performance improvements
|
|
59
|
+
|
|
60
|
+
## Reporting bugs
|
|
61
|
+
|
|
62
|
+
Use the [bug report template](https://github.com/mdfarhankc/fastapi-fullauth/issues/new?template=bug_report.yml) on GitHub Issues. Include:
|
|
63
|
+
|
|
64
|
+
- Python version
|
|
65
|
+
- fastapi-fullauth version
|
|
66
|
+
- Minimal reproduction steps
|
|
67
|
+
- Expected vs actual behavior
|
|
68
|
+
|
|
69
|
+
## Requesting features
|
|
70
|
+
|
|
71
|
+
Use the [feature request template](https://github.com/mdfarhankc/fastapi-fullauth/issues/new?template=feature_request.yml) on GitHub Issues.
|
|
72
|
+
|
|
73
|
+
## Code style
|
|
74
|
+
|
|
75
|
+
- Follow existing patterns in the codebase
|
|
76
|
+
- Use type annotations
|
|
77
|
+
- Keep functions focused and small
|
|
78
|
+
- Log security-sensitive events via `logging.getLogger("fastapi_fullauth.*")`
|
|
79
|
+
- Don't add docstrings/comments unless the logic isn't self-evident
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
.PHONY: install test lint format check fix clean build docs
|
|
2
|
+
|
|
3
|
+
# Install dependencies
|
|
4
|
+
install:
|
|
5
|
+
uv sync --dev --extra sqlalchemy --extra sqlmodel --extra oauth --extra redis
|
|
6
|
+
|
|
7
|
+
# Run tests
|
|
8
|
+
test:
|
|
9
|
+
uv run pytest tests/ -x --tb=short
|
|
10
|
+
|
|
11
|
+
# Run tests with verbose output
|
|
12
|
+
test-v:
|
|
13
|
+
uv run pytest tests/ -v
|
|
14
|
+
|
|
15
|
+
# Run a specific test file
|
|
16
|
+
# Usage: make test-file FILE=test_auth
|
|
17
|
+
test-file:
|
|
18
|
+
uv run pytest tests/$(FILE).py -x --tb=short -v
|
|
19
|
+
|
|
20
|
+
# Lint check (no changes)
|
|
21
|
+
lint:
|
|
22
|
+
uv run ruff check .
|
|
23
|
+
|
|
24
|
+
# Format check (no changes)
|
|
25
|
+
format-check:
|
|
26
|
+
uv run ruff format --check .
|
|
27
|
+
|
|
28
|
+
# Fix lint issues
|
|
29
|
+
fix:
|
|
30
|
+
uv run ruff check --fix .
|
|
31
|
+
|
|
32
|
+
# Format code
|
|
33
|
+
format:
|
|
34
|
+
uv run ruff format .
|
|
35
|
+
|
|
36
|
+
# Run all checks (format + lint + tests) — run before committing
|
|
37
|
+
check: format-check lint test
|
|
38
|
+
|
|
39
|
+
# Fix all issues then verify
|
|
40
|
+
fix-all: format fix test
|
|
41
|
+
|
|
42
|
+
# Build package
|
|
43
|
+
build:
|
|
44
|
+
uv build
|
|
45
|
+
|
|
46
|
+
# Serve docs locally
|
|
47
|
+
docs:
|
|
48
|
+
uv run mkdocs serve
|
|
49
|
+
|
|
50
|
+
# Build docs
|
|
51
|
+
docs-build:
|
|
52
|
+
uv run mkdocs build
|
|
53
|
+
|
|
54
|
+
# Run example apps
|
|
55
|
+
run-sqlmodel:
|
|
56
|
+
uv run uvicorn examples.sqlmodel_app.main:app --reload
|
|
57
|
+
|
|
58
|
+
run-sqlalchemy:
|
|
59
|
+
uv run uvicorn examples.sqlalchemy_app.main:app --reload
|
|
60
|
+
|
|
61
|
+
# Clean build artifacts
|
|
62
|
+
clean:
|
|
63
|
+
rm -rf dist/ build/ *.egg-info .pytest_cache .ruff_cache
|
|
64
|
+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-fullauth
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Production-grade, async-native authentication and authorization library for FastAPI
|
|
5
5
|
Project-URL: Homepage, https://github.com/mdfarhankc/fastapi-fullauth
|
|
6
6
|
Project-URL: Documentation, https://mdfarhankc.github.io/fastapi-fullauth
|
|
7
7
|
Project-URL: Repository, https://github.com/mdfarhankc/fastapi-fullauth
|
|
8
8
|
License-Expression: MIT
|
|
9
9
|
License-File: LICENSE
|
|
10
|
-
Keywords: argon2,authentication,authorization,fastapi,jwt,security
|
|
10
|
+
Keywords: argon2,async,authentication,authorization,bcrypt,csrf,fastapi,jwt,oauth2,password-hashing,pydantic,rbac,redis,refresh-token,role-based-access-control,security,sqlalchemy,sqlmodel
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
12
12
|
Classifier: Framework :: FastAPI
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
@@ -82,8 +82,9 @@ Add a complete authentication and authorization system to your **FastAPI** proje
|
|
|
82
82
|
- **Role-based access control** — `CurrentUser`, `VerifiedUser`, `SuperUser`, `require_role()`
|
|
83
83
|
- **Rate limiting** — per-route auth limits + global middleware (memory or Redis)
|
|
84
84
|
- **CSRF protection** and **security headers** middleware, auto-wired
|
|
85
|
-
- **Pluggable adapters** — SQLModel
|
|
86
|
-
- **
|
|
85
|
+
- **Pluggable adapters** — SQLModel or SQLAlchemy
|
|
86
|
+
- **Generic type parameters** — define your own schemas with full IDE support and type safety
|
|
87
|
+
- **Composable routers** — include only the route groups you need
|
|
87
88
|
- **Event hooks** — `after_register`, `after_login`, `send_verification_email`, etc.
|
|
88
89
|
- **Custom JWT claims** — embed app-specific data in tokens
|
|
89
90
|
- **Structured logging** — all auth events, security violations, and failures logged
|
|
@@ -113,21 +114,45 @@ pip install fastapi-fullauth[all]
|
|
|
113
114
|
|
|
114
115
|
```python
|
|
115
116
|
from fastapi import FastAPI
|
|
116
|
-
from fastapi_fullauth import FullAuth
|
|
117
|
-
from fastapi_fullauth.adapters.
|
|
117
|
+
from fastapi_fullauth import FullAuth, FullAuthConfig
|
|
118
|
+
from fastapi_fullauth.adapters.sqlmodel import SQLModelAdapter
|
|
118
119
|
|
|
119
120
|
app = FastAPI()
|
|
120
121
|
|
|
121
122
|
fullauth = FullAuth(
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
adapter=SQLModelAdapter(session_maker=session_maker, user_model=User),
|
|
124
|
+
config=FullAuthConfig(SECRET_KEY="your-secret-key"),
|
|
124
125
|
)
|
|
125
126
|
fullauth.init_app(app)
|
|
126
127
|
```
|
|
127
128
|
|
|
128
|
-
That's it —
|
|
129
|
+
That's it — all auth routes are registered under `/api/v1/auth/` automatically.
|
|
129
130
|
|
|
130
|
-
Omit `
|
|
131
|
+
Omit `config` in dev and a random secret key is generated (tokens won't survive restarts).
|
|
132
|
+
|
|
133
|
+
### Composable routers
|
|
134
|
+
|
|
135
|
+
Include only the route groups you need:
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
app = FastAPI()
|
|
139
|
+
app.state.fullauth = fullauth
|
|
140
|
+
|
|
141
|
+
# pick what you want
|
|
142
|
+
app.include_router(fullauth.auth_router, prefix="/api/v1/auth")
|
|
143
|
+
app.include_router(fullauth.profile_router, prefix="/api/v1/auth")
|
|
144
|
+
# skip verify, admin, oauth
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
| Router | Routes |
|
|
148
|
+
|--------|--------|
|
|
149
|
+
| `auth_router` | register, login, logout, refresh |
|
|
150
|
+
| `profile_router` | me, verified-me, update profile, delete account, change password |
|
|
151
|
+
| `verify_router` | email verification, password reset |
|
|
152
|
+
| `admin_router` | assign/remove roles and permissions (superuser) |
|
|
153
|
+
| `oauth_router` | OAuth provider routes (only if configured) |
|
|
154
|
+
|
|
155
|
+
`fullauth.init_app(app)` includes all of them. Use individual routers for granular control.
|
|
131
156
|
|
|
132
157
|
## Routes
|
|
133
158
|
|
|
@@ -148,15 +173,19 @@ Omit `secret_key` in dev and a random one is generated (tokens won't survive res
|
|
|
148
173
|
| `POST` | `/auth/password-reset/confirm` | Reset password |
|
|
149
174
|
| `POST` | `/auth/admin/assign-role` | Assign role (superuser) |
|
|
150
175
|
| `POST` | `/auth/admin/remove-role` | Remove role (superuser) |
|
|
176
|
+
| `POST` | `/auth/admin/assign-permission` | Assign permission to role (superuser) |
|
|
177
|
+
| `POST` | `/auth/admin/remove-permission` | Remove permission from role (superuser) |
|
|
178
|
+
| `GET` | `/auth/admin/role-permissions/{role}` | List role's permissions (superuser) |
|
|
151
179
|
|
|
152
180
|
With OAuth enabled, additional routes are registered under `/auth/oauth/`. All routes are prefixed with `/api/v1` by default.
|
|
153
181
|
|
|
154
|
-
## Custom user
|
|
182
|
+
## Custom user schemas
|
|
155
183
|
|
|
156
|
-
Define your model
|
|
184
|
+
Define your model and schemas — pass them explicitly to the adapter:
|
|
157
185
|
|
|
158
186
|
```python
|
|
159
187
|
from sqlmodel import Field, Relationship
|
|
188
|
+
from fastapi_fullauth import FullAuth, FullAuthConfig, UserSchema, CreateUserSchema
|
|
160
189
|
from fastapi_fullauth.adapters.sqlmodel import (
|
|
161
190
|
UserBase, Role, UserRoleLink, RefreshTokenRecord, SQLModelAdapter,
|
|
162
191
|
)
|
|
@@ -170,13 +199,37 @@ class User(UserBase, table=True):
|
|
|
170
199
|
roles: list[Role] = Relationship(link_model=UserRoleLink)
|
|
171
200
|
refresh_tokens: list[RefreshTokenRecord] = Relationship()
|
|
172
201
|
|
|
202
|
+
class MyUserSchema(UserSchema):
|
|
203
|
+
display_name: str = ""
|
|
204
|
+
phone: str = ""
|
|
205
|
+
|
|
206
|
+
class MyCreateSchema(CreateUserSchema):
|
|
207
|
+
display_name: str = ""
|
|
208
|
+
|
|
173
209
|
fullauth = FullAuth(
|
|
174
|
-
|
|
175
|
-
|
|
210
|
+
adapter=SQLModelAdapter(
|
|
211
|
+
session_maker,
|
|
212
|
+
user_model=User,
|
|
213
|
+
user_schema=MyUserSchema,
|
|
214
|
+
create_user_schema=MyCreateSchema,
|
|
215
|
+
),
|
|
216
|
+
config=FullAuthConfig(SECRET_KEY="..."),
|
|
176
217
|
)
|
|
177
218
|
```
|
|
178
219
|
|
|
179
|
-
|
|
220
|
+
Full IDE autocompletion and type checking on custom fields. Use `get_current_user_dependency()` for typed dependencies:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
from typing import Annotated
|
|
224
|
+
from fastapi import Depends
|
|
225
|
+
from fastapi_fullauth.dependencies import get_current_user_dependency
|
|
226
|
+
|
|
227
|
+
MyCurrentUser = Annotated[MyUserSchema, Depends(get_current_user_dependency(MyUserSchema))]
|
|
228
|
+
|
|
229
|
+
@app.get("/profile")
|
|
230
|
+
async def profile(user: MyCurrentUser):
|
|
231
|
+
return {"name": user.display_name} # IDE knows this field exists
|
|
232
|
+
```
|
|
180
233
|
|
|
181
234
|
## Protected routes
|
|
182
235
|
|
|
@@ -204,24 +257,28 @@ async def editor_panel(user=Depends(require_role("editor"))):
|
|
|
204
257
|
## OAuth2 social login
|
|
205
258
|
|
|
206
259
|
```python
|
|
260
|
+
from fastapi_fullauth import FullAuth, FullAuthConfig
|
|
261
|
+
from fastapi_fullauth.oauth.google import GoogleOAuthProvider
|
|
262
|
+
from fastapi_fullauth.oauth.github import GitHubOAuthProvider
|
|
263
|
+
|
|
207
264
|
fullauth = FullAuth(
|
|
208
|
-
secret_key="...",
|
|
209
265
|
adapter=adapter,
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
"
|
|
214
|
-
"
|
|
266
|
+
config=FullAuthConfig(SECRET_KEY="..."),
|
|
267
|
+
providers=[
|
|
268
|
+
GoogleOAuthProvider(
|
|
269
|
+
client_id="your-google-client-id",
|
|
270
|
+
client_secret="your-google-secret",
|
|
271
|
+
redirect_uris=[
|
|
215
272
|
"http://localhost:3000/auth/callback",
|
|
216
273
|
"https://myapp.com/auth/callback",
|
|
217
274
|
],
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
"
|
|
223
|
-
|
|
224
|
-
|
|
275
|
+
),
|
|
276
|
+
GitHubOAuthProvider(
|
|
277
|
+
client_id="your-github-client-id",
|
|
278
|
+
client_secret="your-github-secret",
|
|
279
|
+
redirect_uris=["http://localhost:3000/auth/callback"],
|
|
280
|
+
),
|
|
281
|
+
],
|
|
225
282
|
)
|
|
226
283
|
```
|
|
227
284
|
|
|
@@ -244,25 +301,36 @@ Events: `after_register`, `after_login`, `after_logout`, `after_password_change`
|
|
|
244
301
|
|
|
245
302
|
## Configuration
|
|
246
303
|
|
|
247
|
-
Pass
|
|
304
|
+
Pass a `FullAuthConfig` object or set env vars with `FULLAUTH_` prefix.
|
|
248
305
|
|
|
249
306
|
```python
|
|
250
307
|
fullauth = FullAuth(
|
|
251
|
-
secret_key="...",
|
|
252
308
|
adapter=adapter,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
309
|
+
config=FullAuthConfig(
|
|
310
|
+
SECRET_KEY="...",
|
|
311
|
+
ACCESS_TOKEN_EXPIRE_MINUTES=60,
|
|
312
|
+
API_PREFIX="/api/v2",
|
|
313
|
+
LOGIN_FIELD="username",
|
|
314
|
+
PASSWORD_HASH_ALGORITHM="bcrypt",
|
|
315
|
+
BLACKLIST_BACKEND="redis",
|
|
316
|
+
REDIS_URL="redis://localhost:6379/0",
|
|
317
|
+
AUTH_RATE_LIMIT_ENABLED=True,
|
|
318
|
+
TRUSTED_PROXY_HEADERS=["X-Forwarded-For"],
|
|
319
|
+
),
|
|
261
320
|
)
|
|
262
321
|
```
|
|
263
322
|
|
|
264
323
|
See [Configuration docs](https://mdfarhankc.github.io/fastapi-fullauth/configuration/) for all options.
|
|
265
324
|
|
|
325
|
+
## AI-friendly docs
|
|
326
|
+
|
|
327
|
+
Using an AI coding assistant? Point it at our LLM-optimized docs:
|
|
328
|
+
|
|
329
|
+
- **[llms.txt](https://mdfarhankc.github.io/fastapi-fullauth/llms.txt)** — concise overview with links to all doc pages
|
|
330
|
+
- **[llms-full.txt](https://mdfarhankc.github.io/fastapi-fullauth/llms-full.txt)** — full documentation in a single file
|
|
331
|
+
|
|
332
|
+
Works with Claude, Cursor, Copilot, and any tool that accepts a docs URL.
|
|
333
|
+
|
|
266
334
|
## Development
|
|
267
335
|
|
|
268
336
|
```bash
|
|
@@ -272,7 +340,6 @@ uv sync --dev --extra sqlalchemy --extra sqlmodel
|
|
|
272
340
|
uv run pytest tests/ -v
|
|
273
341
|
|
|
274
342
|
# run examples
|
|
275
|
-
uv run uvicorn examples.memory_app.main:app --reload
|
|
276
343
|
uv run uvicorn examples.sqlmodel_app.main:app --reload
|
|
277
344
|
```
|
|
278
345
|
|