FastAPI Exception Validator - Static analysis tool for validating exception declarations in FastAPI endpoints
Project description
faex
FastAPI Exception Validator - A static analysis tool that validates exception declarations in FastAPI router endpoints.
Overview
faex analyzes your FastAPI codebase to ensure all explicitly raised exceptions in endpoint handlers are properly declared in the router decorator's exceptions parameter. This helps maintain accurate API documentation and ensures clients are aware of all possible error responses.
Problem Statement
In FastAPI, you can declare expected exceptions in router decorators:
@router.get(
"/summary",
response_model=make_success_response_type(
code=0, data_model=list[InfluencerSummaryElement], prefix="InfSummaryInfo"
),
exceptions=[UnauthorizedException],
)
async def get_summary():
if not user.is_authenticated:
raise UnauthorizedException() # Declared in exceptions=[]
if not user.has_permission:
raise ForbiddenException() # Missing from exceptions=[]!
return get_data()
Without tooling, it's easy to:
- Forget to declare exceptions when adding new error handling
- Leave stale exception declarations after refactoring
- Miss exceptions raised by called functions
faex solves this by statically analyzing your code and reporting discrepancies.
Features
- Static Analysis: Analyzes Python AST to detect
raisestatements - Transitive Detection: Follows function calls to detect exceptions raised in dependencies
- FastAPI Integration: Understands FastAPI router decorators and their
exceptionsparameter - CLI Tool: Easy-to-use command-line interface
- CI/CD Ready: Exit codes suitable for automated pipelines
- Configurable: Customize analysis depth, ignored exceptions, and more
Installation
# Using pip
pip install faex
# Using uv
uv add faex
# Using pipx (recommended for CLI usage)
pipx install faex
Quick Start
# Analyze a single file
faex check app/routers/users.py
# Analyze a directory
faex check app/routers/
# Analyze entire project
faex check .
# Show detailed report
faex check app/ --verbose
# Output as JSON
faex check app/ --format json
Usage
Basic Commands
# Check for undeclared exceptions
faex check <path>
# List all detected exceptions in endpoints
faex list <path>
# Generate exception declarations
faex suggest <path>
Options
faex check <path> [OPTIONS]
Options:
--depth INT Maximum call depth for transitive analysis (default: 3)
--ignore CLASS Exception classes to ignore (can be repeated)
--format FORMAT Output format: text, json, github (default: text)
--strict Fail on any undeclared exception
--config FILE Path to configuration file
-v, --verbose Show detailed analysis
-q, --quiet Only show errors
--help Show this message and exit
Configuration File
Create a faex.toml or pyproject.toml with [tool.faex] section:
[tool.faex]
# Maximum depth for following function calls
depth = 3
# Exception classes to ignore globally
ignore = [
"HTTPException", # Generic FastAPI exception
"ValidationError", # Pydantic validation
]
# Paths to exclude from analysis
exclude = [
"tests/",
"**/test_*.py",
]
# Custom exception base classes to track
exception_bases = [
"app.exceptions.BaseAPIException",
]
Example Output
$ faex check app/routers/
app/routers/users.py:45 - get_user_profile
Undeclared exceptions:
- NotFoundException (raised at line 52)
- ForbiddenException (raised in get_user_data at app/services/users.py:23)
app/routers/orders.py:78 - create_order
Undeclared exceptions:
- PaymentFailedException (raised in process_payment at app/services/payment.py:45)
- InventoryException (raised in check_inventory at app/services/inventory.py:12)
Found 4 undeclared exceptions in 2 endpoints.
How It Works
- Parse: Parses Python files using AST to find FastAPI router decorators
- Extract: Extracts declared exceptions from the
exceptionsparameter - Analyze: Analyzes endpoint function bodies for
raisestatements - Trace: Follows function calls to detect transitively raised exceptions
- Compare: Compares declared vs. detected exceptions
- Report: Reports discrepancies with file locations and call traces
Integration
Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/hail-kang/faex
rev: v0.1.0
hooks:
- id: faex
args: [check, --strict]
GitHub Actions
# .github/workflows/lint.yml
- name: Check FastAPI Exceptions
run: |
pip install faex
faex check app/ --format github
CI Exit Codes
0: No issues found1: Undeclared exceptions found2: Configuration or parsing error
Development
This project uses uv for dependency management with pyproject.toml.
# Clone the repository
git clone https://github.com/hail-kang/faex.git
cd faex
# Create virtual environment in project root
uv venv
# Install dependencies from pyproject.toml
uv sync
# Run tests
uv run pytest
# Run type checking
uv run pyright
# Run linting
uv run ruff check .
# Run formatter
uv run ruff format .
Requirements
- Python 3.10+
- FastAPI (for the projects being analyzed)
License
MIT License - see LICENSE for details.
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
Roadmap
- Support for
HTTPExceptionstatus code tracking - Exception inheritance analysis
- Auto-fix capability to add missing declarations
- IDE plugins (VS Code, PyCharm)
- Support for other frameworks (Starlette, Litestar)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file faex-0.1.0.tar.gz.
File metadata
- Download URL: faex-0.1.0.tar.gz
- Upload date:
- Size: 58.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
941b95f48432f77b8c9eb3cfee86e90ae3c3178e6a47378706efe2554cc3148e
|
|
| MD5 |
5b60cc5943cc2799cf04b17b75d4b96c
|
|
| BLAKE2b-256 |
a98cc37d520716feecb8f952d35e58e8eb2d8bf085bbf3eb76a7a144b4708674
|
File details
Details for the file faex-0.1.0-py3-none-any.whl.
File metadata
- Download URL: faex-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4254e5d32651bb60f576f63ea52ff5a98b4a63751c07436ac9b6be58feb97293
|
|
| MD5 |
29ff7ba57bedf1bdddcbc77eef265887
|
|
| BLAKE2b-256 |
193f7f68a61c730f17671752c1c9ed07aacae343d98575f30fb4aa48446c2608
|