Metadata-Version: 2.4
Name: faex
Version: 0.1.0
Summary: FastAPI Exception Validator - Static analysis tool for validating exception declarations in FastAPI endpoints
Project-URL: Homepage, https://github.com/hail-kang/faex
Project-URL: Repository, https://github.com/hail-kang/faex
Project-URL: Issues, https://github.com/hail-kang/faex/issues
Author: hail-kang
License: MIT
License-File: LICENSE
Keywords: api,exceptions,fastapi,linting,static-analysis
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: click>=8.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: pyright>=1.1.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# 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:

```python
@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

```bash
# Using pip
pip install faex

# Using uv
uv add faex

# Using pipx (recommended for CLI usage)
pipx install faex
```

## Quick Start

```bash
# 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

```bash
# Check for undeclared exceptions
faex check <path>

# List all detected exceptions in endpoints
faex list <path>

# Generate exception declarations
faex suggest <path>
```

### Options

```bash
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:

```toml
[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

```yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/hail-kang/faex
    rev: v0.1.0
    hooks:
      - id: faex
        args: [check, --strict]
```

### GitHub Actions

```yaml
# .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](https://github.com/astral-sh/uv) for dependency management with `pyproject.toml`.

```bash
# 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](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)
