Skip to main content

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 raise statements
  • Transitive Detection: Follows function calls to detect exceptions raised in dependencies
  • FastAPI Integration: Understands FastAPI router decorators and their exceptions parameter
  • 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

  1. Parse: Parses Python files using AST to find FastAPI router decorators
  2. Extract: Extracts declared exceptions from the exceptions parameter
  3. Analyze: Analyzes endpoint function bodies for raise statements
  4. Trace: Follows function calls to detect transitively raised exceptions
  5. Compare: Compares declared vs. detected exceptions
  6. 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 found
  • 1: Undeclared exceptions found
  • 2: 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 HTTPException status 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

faex-0.1.0.tar.gz (58.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

faex-0.1.0-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

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

Hashes for faex-0.1.0.tar.gz
Algorithm Hash digest
SHA256 941b95f48432f77b8c9eb3cfee86e90ae3c3178e6a47378706efe2554cc3148e
MD5 5b60cc5943cc2799cf04b17b75d4b96c
BLAKE2b-256 a98cc37d520716feecb8f952d35e58e8eb2d8bf085bbf3eb76a7a144b4708674

See more details on using hashes here.

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

Hashes for faex-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4254e5d32651bb60f576f63ea52ff5a98b4a63751c07436ac9b6be58feb97293
MD5 29ff7ba57bedf1bdddcbc77eef265887
BLAKE2b-256 193f7f68a61c730f17671752c1c9ed07aacae343d98575f30fb4aa48446c2608

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page