A simple FastAPI integration to protect documentation endpoints with HTTP Basic Authentication.
Protect FastAPI's /docs
, /redoc
, and /openapi.json
endpoints with HTTP Basic Authentication.
# Install with pip
pip install fastapi-docshield
# Or with uv
uv pip install fastapi-docshield
git clone https://github.com/georgekhananaev/fastapi-docshield.git
cd fastapi-docshield
pip install -e .
from fastapi import FastAPI
from fastapi_docshield import DocShield
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
# Add protection to docs with a single user
DocShield(
app=app,
credentials={"admin": "password123"}
)
from fastapi import FastAPI
from fastapi_docshield import DocShield
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
# Add protection to docs with multiple users
DocShield(
app=app,
credentials={
"admin": "admin_password",
"developer": "dev_password",
"viewer": "viewer_password"
}
)
from fastapi import FastAPI
from fastapi_docshield import DocShield
app = FastAPI()
# Default mode: Use CDN with automatic fallback to local files
DocShield(
app=app,
credentials={"admin": "password123"},
use_cdn_fallback=True # Default - automatically falls back to local if CDN fails
)
from fastapi import FastAPI
from fastapi_docshield import DocShield
app = FastAPI()
# Always use local files instead of CDN
DocShield(
app=app,
credentials={"admin": "password123"},
prefer_local=True # Serve documentation from bundled static files
)
from fastapi import FastAPI
from fastapi_docshield import DocShield
app = FastAPI()
# Use CDN without fallback (original behavior)
DocShield(
app=app,
credentials={"admin": "password123"},
use_cdn_fallback=False # Disable fallback, CDN only
)
from fastapi import FastAPI
from fastapi_docshield import DocShield
import requests
app = FastAPI()
# Load dark theme CSS from external source
# You can use https://github.com/georgekhananaev/fastapi-swagger-dark
dark_theme_url = "https://raw.githubusercontent.com/georgekhananaev/fastapi-swagger-dark/main/src/fastapi_swagger_dark/swagger_ui_dark.min.css"
custom_css = requests.get(dark_theme_url).text
# Custom JavaScript for analytics
custom_js = """
console.log('π Documentation accessed at:', new Date().toISOString());
document.addEventListener('DOMContentLoaded', function() {
console.log('Dark theme loaded!');
});
"""
# Apply with custom styling
DocShield(
app=app,
credentials={"admin": "password123"},
custom_css=custom_css,
custom_js=custom_js
)
You can download .css files from here: https://github.com/georgekhananaev/fastapi-swagger-ui-dark-theme
from fastapi import FastAPI
from fastapi_docshield import DocShield
from pathlib import Path
import logging
# Configure logging
logger = logging.getLogger(__name__)
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
# Load dark theme CSS from local file with error handling
try:
css_path = Path("static/swagger_ui_dark.min.css")
with open(css_path, "r", encoding="utf-8") as f:
dark_css = f.read()
logger.info("Dark theme CSS loaded successfully")
except FileNotFoundError:
logger.warning(f"Dark theme CSS file not found at {css_path}")
dark_css = "" # Fallback to default theme
except Exception as e:
logger.warning(f"Failed to load dark theme CSS - {type(e).__name__}: {str(e)}")
dark_css = "" # Fallback to default theme
# Apply DocShield with dark theme and authentication
DocShield(
app=app,
credentials={"admin": "admin123456"}, # Protect with authentication
custom_css=dark_css, # Apply dark theme (falls back to default if loading failed)
prefer_local=True # Use local files for better reliability
)
from fastapi import FastAPI
from fastapi_docshield import DocShield
import requests
app = FastAPI()
# Fetch dark theme CSS from GitHub
dark_theme_url = "https://raw.githubusercontent.com/georgekhananaev/fastapi-swagger-ui-dark/main/swagger_ui_dark.min.css"
dark_css = requests.get(dark_theme_url).text
DocShield(
app=app,
credentials={
"admin": "admin_password",
"developer": "dev_password" # Multiple users supported
},
custom_css=dark_css
)
See examples/custom_styling.py for more customization examples including:
- β¨ Minimal clean theme
- π’ Corporate theme with analytics
- π ReDoc customization
- π¨ Custom branding
# Run the demo app
python demo.py
# Visit http://localhost:8000/docs
# Username: admin
# Password: password123
# Install test dependencies
pip install pytest httpx
# Run all tests
pytest
# Run with coverage
pytest --cov=fastapi_docshield
- Protect Swagger UI, ReDoc, and OpenAPI JSON endpoints
- Customizable endpoint URLs
- Multiple username/password combinations
- Automatic CDN fallback - Falls back to local files if CDN is unavailable
- Local file preference option - Serve documentation from local files for better reliability
- Custom CSS and JavaScript injection - Fully customize the look and behavior of documentation
- Resilient documentation - Works even when CDN is down or blocked
- Tested on Python 3.7-3.13
- Compatible with uv package manager
- Fixed: Blank page issue after authentication for some users
- Improved handling of custom URL parameters by storing them as instance variables
- Simplified
_setup_routes()
method for better maintainability - Applied fix from PR #2 for more robust URL parameter handling
- Fixed: Route removal logic now correctly removes all default documentation routes
- Properly removes
/docs
,/redoc
, and/openapi.json
endpoints - Prevents 500 errors when accessing old endpoints
- Properly removes
- Improved: Example files and documentation
- Fixed
custom_styling.py
to work with uvicorn by adding default app variable - Standardized credentials across all custom styling examples
- Added
python-multipart
to dev dependencies for form data handling - Added clear run instructions in example files
- Fixed
- Added: Custom CSS and JavaScript injection support
- New
custom_css
parameter to inject custom styles into documentation pages - New
custom_js
parameter to inject custom JavaScript for enhanced functionality - Complete customization examples for dark theme, minimal theme, corporate branding, and analytics
- Support for both Swagger UI and ReDoc customization
- New
- Added: Automatic CDN fallback to local files for better reliability
- Documentation now automatically falls back to bundled static files if CDN is unavailable
- New
prefer_local
option to always serve from local files - New
use_cdn_fallback
option to control fallback behavior - Bundled Swagger UI and ReDoc static files for offline capability
- Fixed: Static file URL bug that caused blank documentation pages
- Previously, when no custom CDN URLs were provided, the package would pass
None
values to FastAPI's documentation functions - This resulted in HTML with
href="None"
andsrc="None"
, causing white/blank pages - Now properly handles default CDN URLs when custom URLs are not specified
- Previously, when no custom CDN URLs were provided, the package would pass
- Initial release
- Basic HTTP authentication for FastAPI documentation endpoints
- Support for multiple users
MIT License - Copyright (c) 2025 George Khananaev