FastAPI Shield Architecture¶
This document explains the internal architecture of FastAPI Shield, helping developers understand how the library works and how to contribute effectively.
Core Concepts¶
FastAPI Shield is built around several key concepts:
Shields¶
Shields are the fundamental building blocks of FastAPI Shield's security model. A shield is a wrapper around a type that adds security and validation capabilities. Shields are implemented using Python's NewType
to provide type safety while maintaining compatibility with dependency injection systems.
Shield Factory¶
The Shield Factory pattern enables the creation of shields with specific configurations. It allows for conditional shield creation based on runtime factors and provides a unified interface for shield instantiation.
Method Interception¶
Method interception is the mechanism that allows shields to intercept and modify requests, perform validation, and enforce security policies. It works by wrapping endpoint methods and adding pre- and post-processing hooks.
Dependency Injection Integration¶
FastAPI Shield integrates with FastAPI's dependency injection system to provide seamless security enforcement. This integration is achieved through special dependency types like ShieldedDepends
and ShieldDepends
.
Package Structure¶
FastAPI Shield is organized into the following modules:
src/fastapi_shield/
├── __init__.py # Package exports and version
├── core/ # Core functionality
│ ├── __init__.py
│ ├── shield.py # Shield base class and factory
│ ├── depends.py # Custom dependency types
│ └── types.py # Type definitions
├── interceptors/ # Method interception logic
│ ├── __init__.py
│ ├── base.py # Base interceptor class
│ └── handlers.py # Interceptor handlers
├── validation/ # Validation utilities
│ ├── __init__.py
│ ├── string.py # String validation
│ └── type_check.py # Type checking utilities
└── utils/ # Utility functions
├── __init__.py
└── helpers.py # Helper functions
Core Components¶
Shield Class¶
The Shield
class is the central component of the library. It:
- Wraps a base type
- Provides validation logic
- Manages interceptor chains
- Integrates with FastAPI's dependency injection
class Shield(Generic[T]):
"""Base class for all shields."""
def __init__(
self,
base_type: Type[T],
validators: List[Callable] = None,
interceptors: List[Interceptor] = None
):
self.base_type = base_type
self.validators = validators or []
self.interceptors = interceptors or []
def __call__(self, value: Any) -> T:
# Validate and transform input
self._validate(value)
return self._transform(value)
ShieldedDepends¶
ShieldedDepends
extends FastAPI's Depends
to integrate shield validation with the dependency injection system:
class ShieldedDepends(Depends):
"""A dependency that applies a shield to the resolved value."""
def __init__(
self,
dependency: Callable,
shield: Shield,
use_cache: bool = True
):
super().__init__(dependency, use_cache)
self.shield = shield
async def __call__(self, *args, **kwargs):
# Resolve the dependency
value = await super().__call__(*args, **kwargs)
# Apply the shield
return self.shield(value)
Interceptors¶
Interceptors implement the method interception pattern:
class Interceptor:
"""Base class for interceptors."""
async def before(self, *args, **kwargs):
"""Run before the target method."""
pass
async def after(self, result, *args, **kwargs):
"""Run after the target method."""
return result
async def on_error(self, exception, *args, **kwargs):
"""Handle exceptions raised by the target method."""
raise exception
Request Flow¶
When a request comes into a FastAPI application using FastAPI Shield:
- The HTTP request arrives at a FastAPI endpoint
- Shield dependencies are resolved through FastAPI's dependency injection
- Shield interceptors run their
before
hooks - Shield validators check input data
- The endpoint logic executes
- Shield interceptors run their
after
hooks - The response is returned to the client
Type System¶
FastAPI Shield uses a sophisticated type system to provide type safety:
NewType
to create shield types that are distinct at the type level- Generics to maintain type information across shields
- Type hints to provide IDE support and static type checking
Extension Points¶
FastAPI Shield is designed to be extensible:
- Custom Shield types can be created by subclassing
Shield
- Custom interceptors can be implemented by subclassing
Interceptor
- Custom validators can be added to shields
- The Shield Factory pattern allows for customized shield creation
Integration with FastAPI¶
FastAPI Shield integrates with FastAPI:
- Dependency Injection:
ShieldedDepends
andShieldDepends
extend FastAPI's dependency system - Type Validation: Shields can leverage Pydantic models for validation
- Documentation: Shield type annotations appear in generated OpenAPI docs
Performance Considerations¶
FastAPI Shield is designed for minimal overhead:
- Lazy loading of interceptors and validators
- Selective application of shields only where needed
- Efficient type checking through Python's type system
- Caching of validation results where appropriate
Testing Architecture¶
FastAPI Shield's testing infrastructure:
- Unit tests for each component
- Integration tests for FastAPI integration
- Performance benchmarks
- Type checking tests to ensure type safety
- Documentation tests to ensure examples work