Metadata-Version: 2.4
Name: stacklink
Version: 0.1.0
Summary: Health checks, config validation, and structured logging for FastAPI
Project-URL: Homepage, https://github.com/dressupdarling/stacklink
Project-URL: Repository, https://github.com/dressupdarling/stacklink
Project-URL: Issues, https://github.com/dressupdarling/stacklink/issues
Author-email: Yevgeny <yevgenyokun2@gmail.com>
License: MIT
License-File: LICENSE
Keywords: config,fastapi,health-check,logging,structured-logging
Classifier: Development Status :: 3 - Alpha
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: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.100.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: dev
Requires-Dist: black>=23.0; extra == 'dev'
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: httpx>=0.24.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Description-Content-Type: text/markdown

# stacklink

Health checks, config validation, and structured logging for FastAPI — in three lines of code.

Built for solo devs and small teams who want production-grade infrastructure without the setup overhead.

## Install

```bash
pip install stacklink
```

## Quick start

```python
from fastapi import FastAPI
from stacklink import Config, Field, health, logger

app = FastAPI()

class AppConfig(Config):
    env: str = Field(required=True)
    service: str = Field(default="my-api")
    port: int = Field(default=8080)
    db_url: str = Field(required=True, secret=True)

config = AppConfig()

logger.configure(config)
logger.info("server starting", port=config.port)

health.register(app, config=config)
```

That's it. You now have:

- Validated, typed config from `.env` and environment variables
- Structured JSON logging to stdout
- `/healthz` and `/readyz` endpoints on your FastAPI app

## Modules

### Config

Reads `.env` files and environment variables. Validates types. Fails loudly at startup if anything is wrong. Redacts secrets from output.

```python
from stacklink import Config, Field

class AppConfig(Config):
    env: str = Field(required=True)
    port: int = Field(default=8080)
    db_url: str = Field(required=True, secret=True)

config = AppConfig()
config.as_dict()  # {"env": "production", "port": 8080, "db_url": "***"}
```

Supported types: `str`, `int`, `float`, `bool`. Bool coerces from `true/false/1/0/yes/no`.

### Logger

Structured JSON logging. Every line is machine-parseable. Auto-tags with service name and environment when configured.

```python
from stacklink import logger

logger.info("request handled", method="GET", path="/users", status=200)
# {"timestamp": "...", "level": "INFO", "message": "request handled", "method": "GET", "path": "/users", "status": 200}
```

Set `LOG_LEVEL` env var to control filtering (default: `INFO`).

### Health

Registers `/healthz` (liveness) and `/readyz` (readiness) endpoints on your FastAPI app.

```python
from stacklink import health

health.register(app, config=config)

async def check_database():
    try:
        await db.execute("SELECT 1")
        return True
    except Exception:
        return False

health.add_check("database", check_database)
```

`/healthz` always returns `200`. `/readyz` returns `200` when all checks pass, `503` when any check fails.

## Documentation

- [Config](docs/config.md)
- [Logger](docs/logger.md)
- [Health](docs/health.md)

## Requirements

- Python 3.10+
- FastAPI 0.100+

## Development

```bash
pip install -e ".[dev]"
pytest
```

## License

MIT
