Metadata-Version: 2.4
Name: api-bridgekeeper
Version: 0.1.0
Summary: Fail tests if APIs do not have input or output models
Author-email: Ashish Thomas Cherian <ufoundashish@gmail.com>
License: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: flask; extra == "dev"
Requires-Dist: fastapi; extra == "dev"
Requires-Dist: pydantic; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Dynamic: license-file

# Bridgekeeper
Fail tests if API's do not have input or output models  

**Supports:**
- FastAPI
- Flask

## Usage

You can use Bridgekeeper to validate your API endpoints and ensure they have explicitly typed input and output models. 

### Basic Example

```python
from fastapi import FastAPI
from bridgekeeper import check_models

app = FastAPI()

@app.get("/items/{item_id}")
def read_item(item_id: int) -> dict:
    return {"item_id": item_id}

# Run the checker against your initialized app
results = check_models(app)

# `results` will contain a list of endpoints missing type models
print(results)
```

### Options

`check_models(app, allow_list=None, check_only=None)`

- **`allow_list` (list of strings, optional)**: A list of API paths to ignore (e.g., `["/health", "/metrics"]`). If an endpoint matches a path in the list, it is skipped.
- **`check_only` (literal string, optional)**: If you only want to validate inputs or outputs exclusively, pass `"request"` or `"response"`.
- **`allow_any` (boolean, optional)**: Defaults to `False`. When `False`, explicitly typing a parameter or return type as `typing.Any` is flagged as missing a strict model. Set to `True` if you want to allow `Any` as a valid type hint.

```python
results = check_models(
    app, 
    allow_list=["/health"], 
    check_only="response",  # Will strictly look for missing return types
    allow_any=False         # typing.Any will be rejected
)
```

## Handling Complex Apps (Databases/Secrets)

If your FastAPI or Flask app connects to a database (like Postgres) or external service (like Redis) during initialization, trying to run `bridgekeeper` in a GitHub Action might crash when the app imports, before the tests even run.

Bridgekeeper provides generic mocking utilities to safely bypass these side effects. For highly complex apps where you don't want to list out every single dependency, you can use `auto_mock_missing=True` to seamlessly mock any module that isn't installed!

```python
from bridgekeeper import mock_modules, mock_env

# 1. Mock critical environment variables
mock_env({
    "DATABASE_URL": "sqlite:///:memory:",
    "SECRET_KEY": "dummy_secret_for_ci"
})

# 2. Automatically mock ANY missing dependency!
# This is extremely useful if you don't want to install heavy libraries (like SQLAlchemy, boto3, etc.)
# just to run a quick static analysis check.
mock_modules(auto_mock_missing=True)

# You can also explicitly mock specific modules with custom fakes:
# mock_modules({"app.core.db": PostgresTestDb}, auto_mock_missing=True)

# 3. Now it is safe to import the app
from myapp.main import app
from bridgekeeper import check_models

results = check_models(app)
```

## Why the name bridgekeeper?  
He guards the [Bridge of Death](https://montypython.fandom.com/wiki/Bridge_of_Death) and requires travelers to answer "questions three" before crossing safely.
