fastapi-apikey-auth is a FastAPI package developed by Lazarus that provides robust API key authentication and management for FastAPI applications.
Designed for simplicity and flexibility, it enables developers to secure API endpoints with API keys, enforce rate limiting, and manage key expiration. The package integrates seamlessly with FastAPI's dependency injection system and SQLAlchemy's async ORM, while offering optional caching for performance optimization.
Key features include a customizable header-based authentication mechanism, user-associated API keys, and a modern route for displaying keys in a sleek, animated template.
Whether you're building a public API or an internal service, fastapi-apikey-auth offers a lightweight yet powerful solution for API security and access control.
It is a direct port of dj-apikey-auth, so projects moving from Django to FastAPI keep the same settings, the same endpoints and the same response shapes.
- Language: Python >= 3.9
- Framework: FastAPI >= 0.110
- SQLAlchemy: >= 2.0 (async)
- Pydantic: >= 2.5
The documentation is organized into the following sections:
- Quick Start: Get up and running quickly with basic setup instructions.
- Authentication and Permissions: Learn how to secure your API using API key authentication and manage access control with the
APIKeyAuthenticationdependency and theHasAPIKeypermission (optional use case). - API Guide: Detailed information on available APIs and endpoints.
- Usage: How to effectively use the package in your projects.
- Settings: Configuration options and settings you can customize.
- Coming from dj-apikey-auth: A mapping between the Django package and this one.
This section provides a fast and easy guide to getting the fastapi-apikey-auth package up and running in your FastAPI
project.
Follow the steps below to quickly set up the package and start using the package.
Option 1: Using pip (Recommended)
Install the package via pip:
$ pip install fastapi-apikey-authOption 2: Using Poetry
If you're using Poetry, add the package with:
$ poetry add fastapi-apikey-authOption 3: Using pipenv
If you're using pipenv, install the package with:
$ pipenv install fastapi-apikey-authThe package talks to your database through SQLAlchemy's async engine, so you need a driver that supports it. For PostgreSQL:
$ pip install asyncpgFor SQLite:
$ pip install aiosqliteThe package ships a declarative Base carrying the apikey_auth_api_key table. Create it either through your migration
tool of choice (Alembic) or directly at startup:
from fastapi_apikey_auth import Base
async with engine.begin() as connection:
await connection.run_sync(Base.metadata.create_all)If you use Alembic, point your target_metadata at fastapi_apikey_auth.Base.metadata (alongside your own metadata) and
autogenerate a migration.
Note:
APIKey.user_idis a plain nullable integer column rather than a foreign key. FastAPI projects own their user table, so the package stays agnostic about it. Add a foreign key in your own migration if you want referential integrity.
setup() registers your session dependency, applies your settings, installs the rate limit middleware and mounts every
router in one call:
from fastapi import FastAPI
from fastapi_apikey_auth import setup
app = FastAPI()
async def get_db():
async with SessionLocal() as session:
yield session
setup(app, get_db)That mounts:
POST|GET|PATCH|PUT|DELETE /apikey_auth/apikey/— the admin APIGET /apikey_auth/my-apikey/— the user APIGET /apikey_auth/api_keys/— the HTML dashboard
Pass prefix= to mount them somewhere else.
An API key can be linked to a user through its user_id. To let the package resolve that id into a real user — for the
user object in responses, for the IsAdminUser permission and for the staff throttle rate — register a user
loader:
from fastapi_apikey_auth import setup
async def load_user(session, user_id):
return await session.get(User, user_id)
setup(app, get_db, user_loader=load_user)The loader may be sync or async, and may return:
- a
Principalinstance, - a mapping such as
{"id": 1, "username": "bob", "is_staff": True}, - or any object with
id,is_activeandis_staff(oris_superuser) attributes.
Without a loader the package still works: keys keep their user_id, but nobody is ever staff, so the admin API stays
closed.
To filter the list endpoints beyond the built-in ordering and search, write a filter class and point the settings at it:
from fastapi_apikey_auth.filtering import BaseAPIKeyFilter
from fastapi_apikey_auth.models import APIKey
class ActiveOnlyFilter(BaseAPIKeyFilter):
def filter_query(self, statement, params):
if params.get("active_only") == "1":
return statement.where(APIKey.is_active.is_(True))
return statementAPIKEY_AUTH_API_FILTER_CLASS = "path.to.ActiveOnlyFilter"For more detailed info, refer to the Settings section.
This section explains how to leverage the APIKeyAuthentication dependency and the HasAPIKey permission in
fastapi-apikey-auth to secure your APIs. These components provide flexible and powerful mechanisms for API key-based
authentication and access control.
The APIKeyAuthentication dependency enables API key-based authentication for your FastAPI application. It validates
API keys passed in HTTP headers, checks their status (e.g., active, not expired), enforces rate limits, and optionally
associates them with a user.
FastAPI has no global authentication setting the way DRF does; you attach the dependency where you want it. This works on a single route, on a router, or on the whole application:
from fastapi import Depends, FastAPI
from fastapi_apikey_auth import authentication
app = FastAPI()
@app.get("/secure/")
async def secure(auth=Depends(authentication)):
return {"message": "This route requires an API key"}To apply it across every route in your project, attach it at the application or router level:
from fastapi import Depends, FastAPI
from fastapi_apikey_auth import authentication
app = FastAPI(dependencies=[Depends(authentication)])By default the dependency mirrors DRF: a request without an API key is allowed through unauthenticated, and the permission decides what to do about it. When you want the dependency itself to reject those requests, use the strict variant:
from fastapi import Depends
from fastapi_apikey_auth import required_authentication
@app.get("/secure/")
async def secure(auth=Depends(required_authentication)):
...- Header Extraction: Extracts the API key from the header specified by
APIKEY_AUTH_HEADER_NAME(default:Authorization) with an optional prefix fromAPIKEY_AUTH_HEADER_TYPE(default:None), e.g.,header_type <key>. - Validation: Checks the key against the
APIKeytable, ensuring it is active (is_active=True) and not expired (expires_at). - Rate Limiting: Enforces
APIKEY_AUTH_MAX_REQUESTS(if set), incrementingrequests_countand raising a 429 if exceeded. - Caching: Optionally caches key lookups using
APIKEY_AUTH_USE_CACHINGandAPIKEY_AUTH_CACHE_TIMEOUT_SECONDSfor performance. - User Association: Returns an
AuthResultcarryingapi_keyandprincipal, and attaches both torequest.state.api_keyandrequest.state.principal.
Important Note:
The
user_idfield on theAPIKeymodel is nullable. If a valid API key is provided but not linked to a user:
request.state.principalwill beNone.request.state.api_keywill still contain theAPIKeyinstance.This allows authentication of "anonymous" API keys, which is useful for public or shared access scenarios.
Send a request with an API key in the header:
curl -X GET http://your-api.com/endpoint/ -H "Authorization: header_type test-key-123"- If
test-key-123is valid and linked to a user,request.state.principalis that user, andrequest.state.api_keyis theAPIKeyinstance. - If
test-key-123is valid but not linked to a user,request.state.principalisNone, andrequest.state.api_keyis theAPIKeyinstance. - If invalid or expired, a
401 Unauthorizedis returned.
The HasAPIKey class is a permission designed to ensure that an API request is authenticated with a valid API key. It
complements APIKeyAuthentication by explicitly checking whether request.state.api_key is an APIKey instance.
This is how it is implemented:
from fastapi_apikey_auth.models import APIKey
from fastapi_apikey_auth.security import BasePermission, get_api_key
class HasAPIKey(BasePermission):
def has_permission(self, request, view=None) -> bool:
return isinstance(get_api_key(request), APIKey)- Check: Verifies that the request carries an
APIKeyinstance. - Purpose: Grants access only if the request was authenticated with a valid API key via
APIKeyAuthentication.
Permissions run authentication themselves, so attaching one is enough:
from fastapi import Depends, FastAPI
from fastapi_apikey_auth import HasAPIKey
app = FastAPI()
@app.get("/keys-only/", dependencies=[Depends(HasAPIKey())])
async def keys_only():
return {"message": "Access granted with API key"}HasAPIKey ensures that an API key is present, regardless of whether it's linked to a user. This is distinct from
IsAuthenticated, which requires an actual principal. Use both together for APIs requiring a user-linked API key:
from fastapi import Depends, FastAPI, Request
from fastapi_apikey_auth import HasAPIKey, IsAuthenticated
from fastapi_apikey_auth.security import get_principal
app = FastAPI()
@app.get(
"/user-keys-only/",
dependencies=[Depends(IsAuthenticated()), Depends(HasAPIKey())],
)
async def user_keys_only(request: Request):
return {"message": f"Welcome, {get_principal(request).extra['username']}"}IsAuthenticated: Ensures the key resolved to an active principal.HasAPIKey: Ensures the request carries anAPIKey.
- Nullable User: Since
APIKey.user_idis nullable,APIKeyAuthenticationauthenticates requests even without a user.HasAPIKeyallows these "anonymous" API keys, whileIsAuthenticateddoes not. - Flexibility: Use
HasAPIKeyfor APIs where only an API key is needed (e.g., public APIs), and combine withIsAuthenticatedfor user-specific APIs if needed. - Rate Limit Headers: When
max_requestsis set, theRateLimitHeadersMiddlewareaddsX-RateLimit-LimitandX-RateLimit-Remainingheaders to responses, which can be checked regardless of user association.
-
API Key Only:
- Route requires any valid API key.
- Use
HasAPIKeyalone. request.state.principalmay beNone.
-
User + API Key:
- Route requires a valid user authenticated via an API key.
- Use
IsAuthenticatedandHasAPIKey. request.state.principalis aPrincipal, andrequest.state.api_keyis anAPIKey.
This dual approach provides maximum flexibility for securing your APIs.
Permissions keep DRF's shape, so a custom one is a class with a has_permission(request, view) method:
from fastapi_apikey_auth.security import BasePermission, get_principal
class IsInternalService(BasePermission):
message = "Internal services only."
def has_permission(self, request, view=None) -> bool:
principal = get_principal(request)
return principal is not None and principal.extra.get("internal") is TrueAttach it to your own routes with Depends(IsInternalService()), or apply it to every route of the package through
APIKEY_AUTH_API_EXTRA_PERMISSION_CLASS.
This section provides a detailed overview of the fastapi-apikey-auth API, enabling administrators and users to manage
API keys securely within FastAPI applications. The API exposes two primary endpoints:
/apikey/- Admin API for managing all API keys (requires staff principals)./my-apikey/- User API for viewing their own API keys (authenticated principals only).
The apikey/ endpoint allows administrators (staff principals) to fully manage API keys. The available operations
include:
-
List API keys:
Fetches all API keys in the system. Controlled by the
APIKEY_AUTH_API_ALLOW_LISTsetting. -
Retrieve an API key:
Retrieves a specific API key by its ID. Controlled by the
APIKEY_AUTH_API_ALLOW_RETRIEVEsetting. -
Create an API key:
Creates a new API key with an associated user (optional) and an auto-generated key. Controlled by the
APIKEY_AUTH_API_ALLOW_CREATEsetting. -
Update an API key:
Updates an existing API key (e.g., toggling
is_activeor modifyingexpires_at). Controlled by theAPIKEY_AUTH_API_ALLOW_UPDATEsetting. -
Delete an API key:
Deletes an existing API key. Controlled by the
APIKEY_AUTH_API_ALLOW_DELETEsetting.
A disabled endpoint stays registered and answers 405 Method Not Allowed with a message pointing at the setting, so the
change takes effect immediately without rebuilding the router.
List API keys:
GET /apikey/
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"user": {
"id": 2,
"username": "user",
"email": "example@domain.com"
},
"key": "test-key-123",
"created_at": "2026-03-19T12:00:00Z",
"expires_at": "2027-03-19T12:00:00Z",
"is_active": true,
"requests_count": 5,
"max_requests": 100,
"reset_at": "2026-03-20T12:00:00Z"
}
]
}
Create an API Key:
POST /apikey/
Content-Type: application/json
{
"user_id": 2,
"expires_at": "2026-04-19T13:00:00Z"
}
Response:
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 3,
"user": {
"id": 2,
"username": "user",
"email": "example@domain.com"
},
"key": "auto-generated-key-789",
"created_at": "2026-03-19T13:00:00Z",
"expires_at": "2026-04-19T13:00:00Z",
"is_active": true,
"requests_count": 0,
"max_requests": null,
"reset_at": null
}
Update an API Key:
PATCH /apikey/1/
Content-Type: application/json
{
"is_active": false,
"expires_at": "2026-06-01T00:00:00Z"
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"user": {
"id": 2,
"username": "user",
"email": "example@domain.com"
},
"key": "test-key-123",
"created_at": "2026-03-19T12:00:00Z",
"expires_at": "2026-06-01T00:00:00Z",
"is_active": false,
"requests_count": 5,
"max_requests": 100,
"reset_at": "2026-03-20T12:00:00Z"
}
PATCH writes only the fields present in the body. PUT writes every editable field, clearing the ones you omit.
Delete an API Key:
DELETE /apikey/1/
Response:
HTTP/1.1 204 No Content
The my-apikey/ endpoint allows authenticated principals to view their own API keys.
Users can list and retrieve API keys, but cannot create, update, or delete them.
List User API Keys:
GET /my-apikey/
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"user": {
"id": 2,
"username": "user",
"email": "example@domain.com"
},
"key": "test-key-123",
"created_at": "2026-03-19T12:00:00Z",
"expires_at": "2027-03-19T12:00:00Z",
"is_active": true,
"requests_count": 5,
"max_requests": 100,
"reset_at": "2026-03-20T12:00:00Z"
}
]
}
Retrieve a User's API Key:
GET /my-apikey/1/
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"user": {
"id": 2,
"username": "user",
"email": "example@domain.com"
},
"key": "test-key-123",
"created_at": "2026-03-19T12:00:00Z",
"expires_at": "2027-03-19T12:00:00Z",
"is_active": true,
"requests_count": 5,
"max_requests": 100,
"reset_at": "2026-03-20T12:00:00Z"
}
A key belonging to somebody else answers 404, not 403, so the endpoint never confirms that an id exists.
id: Unique identifier of the API key.user: The owner of the API key, rendered through the configured user fields (nullable).key: The API key string (auto-generated on creation).created_at: Timestamp when the key was created.expires_at: Timestamp when the key expires (nullable).is_active: Boolean indicating if the key is active.requests_count: Number of requests made with the key.max_requests: Maximum allowed requests (nullable).reset_at: Timestamp when the request count resets (nullable).
The API includes a built-in throttling mechanism that limits the number of requests a client can make based on their role. You can customize these throttle limits in the settings.
To specify the throttle rates for regular users and staff members:
APIKEY_AUTH_BASE_USER_THROTTLE_RATE = "100/day"
APIKEY_AUTH_STAFF_USER_THROTTLE_RATE = "1000/day"Requests are bucketed by principal when one is known, then by API key, then by client IP. The valid time units are
second, minute, hour and day.
The default throttle keeps its history in process memory. For a multi-worker deployment, subclass
RoleBasedUserRateThrottle with a shared backend and point APIKEY_AUTH_API_THROTTLE_CLASS at it.
The API supports advanced query options:
- Ordering:
?ordering=-created_at,requests_count— comma separated,-for descending. Restricted to the fields inAPIKEY_AUTH_API_ORDERING_FIELDS. - Search:
?search=abc— matched case-insensitively against the fields inAPIKEY_AUTH_API_SEARCH_FIELDS. - Filtering: whatever your
APIKEY_AUTH_API_FILTER_CLASSimplements.
These configurations can be customized in the settings.
The API uses limit-offset pagination, allowing customization of minimum, maximum, and default page size limits:
?limit=25&offset=50. Limits below the minimum fall back to the default; limits above the maximum are clamped.
Setting APIKEY_AUTH_API_PAGINATION_CLASS = None returns every matching row in the same envelope.
- Admin API (
/apikey/): Restricted to active staff principals (IsAuthenticated+IsAdminUser). - User API (
/my-apikey/): Available to active principals (IsAuthenticated).
Both additionally apply APIKEY_AUTH_API_EXTRA_PERMISSION_CLASS when one is configured.
Each feature can be configured through the settings. For further details, refer to the Settings section.
This section provides a comprehensive guide on how to utilize the package's key features.
There is no settings.py in FastAPI, so the package reads its settings from two places, in order of precedence:
- Explicit configuration through
configure()or the keyword arguments ofsetup(). - Environment variables, using the same
APIKEY_AUTH_names.
from fastapi_apikey_auth import configure
configure(
max_requests=1000,
reset_request_interval="daily",
header_type="Bearer",
)export APIKEY_AUTH_MAX_REQUESTS=1000
export APIKEY_AUTH_RESET_REQUEST_INTERVAL=daily
export APIKEY_AUTH_HEADER_TYPE=BearerEnvironment values are converted using the type of the packaged default: booleans accept true/false, 1/0, yes/no
and on/off; lists accept either a JSON array or a comma-separated string.
Settings are read at request time, so a change made through configure() after startup takes effect immediately. The
configuration is validated when the routers are built, and an invalid value raises ImproperlyConfigured with the same
error ids dj-apikey-auth reports through Django's system checks:
from fastapi_apikey_auth.settings.checks import check_apikey_settings
for error in check_apikey_settings():
print(error)Outside the API, use the repository:
from fastapi_apikey_auth.repository import APIKeyRepository
async with SessionLocal() as session:
api_key = await APIKeyRepository(session).create(user_id=42)
print(api_key.key)Enable caching to skip resolving the 64 character key string on every request:
configure(use_caching=True, cache_timeout_seconds=300)The cache maps the key string to the row's primary key; the row itself is always loaded fresh, which keeps request
counters accurate. The default backend is process-local. For a shared backend, implement BaseCache and assign it:
from fastapi_apikey_auth import cache as cache_module
cache_module.cache = MyRedisCache()RateLimitHeadersMiddleware copies the quota of the authenticating key onto the response as X-RateLimit-Limit and
X-RateLimit-Remaining. setup() installs it by default; pass rate_limit_headers=False to leave it out, or install it
yourself:
from fastapi_apikey_auth import RateLimitHeadersMiddleware
app.add_middleware(RateLimitHeadersMiddleware)If you would rather not use setup(), build the routers yourself and override the session dependency:
from fastapi_apikey_auth import create_admin_router, create_user_router, get_session
app.dependency_overrides[get_session] = get_db
app.include_router(create_admin_router(prefix="/admin/apikey"))
app.include_router(create_user_router(prefix="/me/apikey"))The APIKeyListView provides a user-friendly interface for displaying a list of all API keys in the application. It
renders API keys in a modern, animated template, offering a sleek and interactive experience for administrators or users
with appropriate permissions.
- Access is restricted based on the permission configured in the
APIKEY_AUTH_VIEW_PERMISSION_CLASSsetting. The default isIsAdminUser. - The view uses the same permission classes as the API, requiring each class to implement a
has_permission(request, view)method that returns a boolean indicating whether access is granted. - If any permission check fails (e.g.,
has_permissionis missing or returnsFalse), a403 Forbiddenis returned.
- Comprehensive API Key List: Displays all API keys in the system, regardless of user association.
- Customizable Ordering: Keys are ordered according to the
APIKEY_AUTH_VIEW_ORDERING_FIELDSsetting, allowing flexible sorting. - Modern UI: Rendered in the
api_keys.htmlJinja2 template with smooth animations and a responsive design. - Permission Flexibility: Supports a dynamic permission class configured via settings.
- Masked Keys: Only the first and last four characters of each key are shown, with a copy button for the full value.
- Navigate to the API keys list URL in your application (e.g.,
/apikey_auth/api_keys/). - Ensure you meet the permission requirements specified in
APIKEY_AUTH_VIEW_PERMISSION_CLASS. - View the complete list of API keys, styled in a modern table with status indicators and copy functionality.
This section outlines the available settings for configuring the fastapi-apikey-auth package. You can customize these
settings through configure(), through the keyword arguments of setup(), or through environment variables of the same
name.
Below is an example configuration with default values:
# APIKey Settings
APIKEY_AUTH_RESET_REQUEST_INTERVAL = None
APIKEY_AUTH_MAX_REQUESTS = None
# Authentication Settings
APIKEY_AUTH_HEADER_NAME = "Authorization"
APIKEY_AUTH_HEADER_TYPE = None
APIKEY_AUTH_USE_CACHING = False
APIKEY_AUTH_CACHE_TIMEOUT_SECONDS = 300
APIKEY_AUTH_USER_LOADER = None
# Global API Settings
APIKEY_AUTH_API_ALLOW_LIST = True
APIKEY_AUTH_API_ALLOW_RETRIEVE = True
APIKEY_AUTH_API_ALLOW_CREATE = True
APIKEY_AUTH_API_ALLOW_UPDATE = True
APIKEY_AUTH_API_ALLOW_DELETE = False
APIKEY_AUTH_BASE_USER_THROTTLE_RATE = "30/minute"
APIKEY_AUTH_STAFF_USER_THROTTLE_RATE = "100/minute"
APIKEY_AUTH_API_THROTTLE_CLASS = (
"fastapi_apikey_auth.throttling.RoleBasedUserRateThrottle"
)
APIKEY_AUTH_API_PAGINATION_CLASS = (
"fastapi_apikey_auth.pagination.DefaultLimitOffSetPagination"
)
APIKEY_AUTH_API_EXTRA_PERMISSION_CLASS = None
APIKEY_AUTH_API_APIKEY_SCHEMA_CLASS = None
APIKEY_AUTH_API_USER_SCHEMA_CLASS = None
APIKEY_AUTH_API_USER_SCHEMA_FIELDS = ["id", "username", "email"]
APIKEY_AUTH_API_ORDERING_FIELDS = [
"id",
"max_requests",
"requests_count",
"created_at",
"expires_at",
"reset_at",
]
APIKEY_AUTH_API_SEARCH_FIELDS = ["id"]
APIKEY_AUTH_API_FILTER_CLASS = None
# Template View Settings
APIKEY_AUTH_VIEW_PERMISSION_CLASS = "fastapi_apikey_auth.security.IsAdminUser"
APIKEY_AUTH_VIEW_ORDERING_FIELDS = ["expires_at", "-created_at"]Below is a detailed description of each setting in fastapi-apikey-auth, so you can better understand and tweak them to
fit your project's needs.
Type: Optional[str]
Default: None
Description: Defines the interval after which the request count for API keys resets. Must be one of minutely, hourly, daily, or monthly. Set to None to disable automatic reset.
Type: Optional[int]
Default: None
Description: Sets the maximum number of requests allowed per API key before throttling is enforced. Set to None for unlimited requests. New keys inherit this value as their max_requests.
Type: str
Default: "Authorization"
Description: Specifies the HTTP header name used to pass the API key (e.g., "Authorization" or "X-API-Key"). Customize this to match your authentication setup.
Type: Optional[str]
Default: None
Description: Defines the prefix expected in the API key header (e.g., "Bearer" in "Bearer <key>"). Customize this to align with your authentication format.
Type: bool
Default: False
Description: Enables caching of API key lookups to improve performance. Set to True to resolve the key string from the cache instead of the database on every request.
Type: int
Default: 300
Description: Sets the duration (in seconds) that API key data is cached when caching is enabled. Adjust this to balance performance and freshness of data.
Type: Optional[str | Callable]
Default: None
Description: A callable, or the dotted path to one, that resolves the user_id of an API key into a user. It receives (session, user_id), may be sync or async, and may return a Principal, a mapping, or any user object. This is what makes IsAdminUser, the staff throttle rate and the nested user object in responses work.
Type: bool
Default: True
Description: Allows the API to list API keys. Set to False to disable this feature.
Type: bool
Default: True
Description: Allows retrieving individual API keys by ID via the API. Set to False to disable this feature.
Type: bool
Default: True
Description: Allows creating new API keys via the API. Set to False to disable this feature.
Type: bool
Default: True
Description: Allows updating existing API keys via the API (e.g., toggling is_active). Set to False to disable this feature.
Type: bool
Default: False
Description: Allows deleting API keys via the API. Set to True to enable this feature.
Type: str
Default: "30/minute"
Description: Sets the throttle rate (e.g., "100/day") for regular users in the API. Adjust this to limit request frequency. An empty value disables throttling for them.
Type: str
Default: "100/minute"
Description: Sets the throttle rate (e.g., "1000/day") for staff principals in the API. Adjust this to provide higher limits for privileged users.
Type: Optional[str]
Default: "fastapi_apikey_auth.throttling.RoleBasedUserRateThrottle"
Description: Specifies the throttle class used to limit API requests. Set to None to disable throttling on the package's routes.
Type: Optional[str]
Default: "fastapi_apikey_auth.pagination.DefaultLimitOffSetPagination"
Description: Defines the pagination class used in API responses. Set to None to return every matching row.
Type: Optional[str]
Default: None
Description: Optionally specifies an additional permission class applied to every route of the package (e.g., "path.to.IsInternalService"). This allows for fine-grained access control beyond authentication.
Type: List[str]
Default: ["id", "username", "email"]
Description: Defines the fields to be included in the nested user object in API responses. These are also the attributes read off a user object returned by the user loader.
Type: Optional[str]
Default: None (falls back to fastapi_apikey_auth.schemas.APIKeyRead)
Description: Specifies the Pydantic schema used for APIKey objects in the API. Customize this if you need a different representation.
Type: Optional[str]
Default: None (a schema is generated from APIKEY_AUTH_API_USER_SCHEMA_FIELDS)
Description: Specifies the Pydantic schema used for user objects in the API. Customize this if you need a different user representation.
Type: List[str]
Default: ["id", "max_requests", "requests_count", "created_at", "expires_at", "reset_at"]
Description: Specifies the fields available for ordering in API queries, allowing responses to be sorted by these fields. See all available fields below.
Type: List[str]
Default: ["id"]
Description: Specifies the fields that are searchable in the API, allowing users to filter results based on these fields. See all available fields below.
Type: Optional[str]
Default: None
Description: Specifies a custom filter class for API filtering. It must implement filter_query(statement, params) and is easiest to write by subclassing fastapi_apikey_auth.filtering.BaseAPIKeyFilter. Set to None to disable custom filtering.
Type: Optional[str]
Default: "fastapi_apikey_auth.security.IsAdminUser"
Description: Specifies the permission class for the APIKeyListView. Customize this to change access requirements for the view.
Type: List[str]
Default: ["expires_at", "-created_at"]
Description: Specifies the fields that the APIKeyListView is ordered by. Adjust this to sort the displayed API key list differently.
These are all fields available for searching and ordering in API key records:
id: Unique identifier of the API key (orderable, searchable).user_id: ID of the associated user (orderable, searchable).key: The API key string (orderable, searchable).created_at: Timestamp when the key was created (orderable).expires_at: Timestamp when the key expires (orderable).is_active: Boolean indicating if the key is active (orderable).requests_count: Number of requests made with the key (orderable).max_requests: Maximum allowed requests (orderable).reset_at: Timestamp when the request count resets (orderable).
The two packages share their settings names, endpoints, response fields and behaviour. What differs is what has no FastAPI equivalent:
| dj-apikey-auth | fastapi-apikey-auth |
|---|---|
apikey_auth Django app in INSTALLED_APPS |
setup(app, get_db) |
Django ORM APIKey model + migration |
SQLAlchemy APIKey model on Base.metadata |
settings.py constants |
configure(), setup(**settings) or APIKEY_AUTH_* environment variables |
| Django system checks | run_checks(), raising ImproperlyConfigured at router build time |
AUTH_USER_MODEL |
APIKEY_AUTH_USER_LOADER returning a Principal |
| DRF authentication class | APIKeyAuthentication dependency |
| DRF permission classes | The same classes, still exposing has_permission(request, view) |
request.user / request.auth |
request.state.principal / request.state.api_key |
| DRF serializers | Pydantic schemas |
request.META["X-RateLimit-*"] |
RateLimitHeadersMiddleware |
| Django cache framework | fastapi_apikey_auth.cache, swappable |
Django admin (APIKeyAdmin) |
No equivalent — use the admin API and the HTML dashboard |
django-filter FilterSet |
BaseAPIKeyFilter |
Disabled methods raise MethodNotAllowed in the viewset |
Routes stay registered and answer 405 per request |
Response bodies are unchanged apart from the nested user object, which is now driven by
APIKEY_AUTH_API_USER_SCHEMA_FIELDS instead of the Django user model, and list responses, which always use the
count/next/previous/results envelope even when pagination is disabled.
We hope this documentation has provided a comprehensive guide to using and understanding fastapi-apikey-auth.
- Version Compatibility: Ensure your project meets the compatibility requirements for both FastAPI and Python versions.
- API Integration: The package is designed for flexibility, allowing you to customize many features based on your application's needs.
- Contributions: Contributions are welcome! Feel free to check out the Contributing guide for more details.
If you encounter any issues or have feedback, please reach out via our GitHub Issues page.