Skip to content

georgekhananaev/fastapi-docshield

Repository files navigation

FastAPI DocShield

A simple FastAPI integration to protect documentation endpoints with HTTP Basic Authentication.

PyPI version License: MIT Python Versions Tests Status UV Compatible

About

Protect FastAPI's /docs, /redoc, and /openapi.json endpoints with HTTP Basic Authentication.

Installation

From PyPI

# Install with pip pip install fastapi-docshield # Or with uv uv pip install fastapi-docshield

From Source

git clone https://github.com/georgekhananaev/fastapi-docshield.git cd fastapi-docshield pip install -e .

Quick Usage

Single User

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"} )

Multiple Users

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" } )

CDN Fallback Mode (Default)

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 )

Prefer Local Files

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 )

CDN Only (No Fallback)

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 )

Custom CSS and JavaScript

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 )

Using with fastapi-swagger-dark

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 )

Alternative: Load from URL

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

Running Demo

# Run the demo app python demo.py # Visit http://localhost:8000/docs # Username: admin # Password: password123

Running Tests

# Install test dependencies pip install pytest httpx # Run all tests pytest # Run with coverage pytest --cov=fastapi_docshield

Features

  • 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

Changelog

Version 0.2.1 (2025-08-17)

  • 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
  • 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

Version 0.2.0 (2025-08-17)

  • 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
  • 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" and src="None", causing white/blank pages
    • Now properly handles default CDN URLs when custom URLs are not specified

Version 0.1.0 (2025-01-15)

  • Initial release
  • Basic HTTP authentication for FastAPI documentation endpoints
  • Support for multiple users

License

MIT License - Copyright (c) 2025 George Khananaev

About

A simple FastAPI integration to protect documentation endpoints with HTTP Basic Authentication.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages