Metadata-Version: 2.4
Name: semblance
Version: 0.2.0
Summary: Schema-driven REST API simulation with FastAPI, Pydantic, and Polyfactory
Author: Semblance Contributors
License-Expression: MIT
Project-URL: Documentation, https://github.com/eddiethedean/semblance#readme
Project-URL: Repository, https://github.com/eddiethedean/semblance
Keywords: fastapi,pydantic,polyfactory,api,mock,simulation,testing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
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 :: Testing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE.md
Requires-Dist: fastapi>=0.115.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: polyfactory>=2.0.0
Requires-Dist: uvicorn>=0.30.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: httpx>=0.25.0; extra == "dev"
Requires-Dist: ruff>=0.8.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: bandit>=1.7.0; extra == "dev"
Requires-Dist: pip-audit>=2.0.0; extra == "dev"
Requires-Dist: pre-commit>=4.0.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.5.0; extra == "docs"
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
Dynamic: license-file

# Semblance

[![PyPI](https://img.shields.io/pypi/v/semblance.svg)](https://pypi.org/project/semblance/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![Ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://docs.astral.sh/ruff/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Schema-driven REST API simulation** with FastAPI, Pydantic, and Polyfactory.

Define API behavior declaratively using schemas and dependency metadata—no endpoint logic required. Semblance is built for **contract testing**, **prototyping**, **frontend development**, and **integration testing** against realistic API simulators.

## Features

- **Zero endpoint logic** — Schemas and link metadata define responses
- **FastAPI-native** — Full OpenAPI, validation, async
- **Deterministic** — Seeded generation for reproducible tests
- **Extensible** — Custom link types via plugins
- **Production-ready** — Error simulation, latency, pagination, stateful mode

## Requirements

- Python 3.10+
- FastAPI, Pydantic, Polyfactory, Uvicorn (installed with semblance)

## Installation

```bash
pip install semblance
```

From source (development):

```bash
git clone https://github.com/eddiethedean/semblance.git
cd semblance
pip install -e ".[dev]"
```

## Quick Start

```python
from datetime import date, datetime
from typing import Annotated

from pydantic import BaseModel
from semblance import DateRangeFrom, FromInput, SemblanceAPI


class UserQuery(BaseModel):
    name: str = "alice"
    start_date: date = date(2020, 1, 1)
    end_date: date = date(2025, 12, 31)


class User(BaseModel):
    name: Annotated[str, FromInput("name")]
    created_at: Annotated[
        datetime,
        DateRangeFrom("start_date", "end_date"),
    ]


api = SemblanceAPI()


@api.get("/users", input=UserQuery, output=list[User])
def users():
    pass


app = api.as_fastapi()
```

Run:

```bash
semblance run app:api --port 8000
# or
uvicorn app:app --reload
```

Try:

```bash
curl "http://127.0.0.1:8000/users?name=alice&start_date=2024-01-01&end_date=2024-12-31"
```

Responses are generated from your output model: `name` comes from the query, `created_at` is random in the date range.

## Use Cases

| Use Case | Description |
|----------|-------------|
| **Contract testing** | Validate client behavior against a schema-accurate mock |
| **Frontend development** | Run a mock API for UI work without a backend |
| **Prototyping** | Ship realistic API shapes before implementation |
| **Integration tests** | Deterministic, isolated API simulators in CI |

## CLI

```bash
# Run a Semblance app
semblance run app:api [--host HOST] [--port PORT] [--reload]

# Export OpenAPI schema (optionally with response examples)
semblance export openapi app:api [-o FILE] [--examples]

# Export JSON fixtures per endpoint
semblance export fixtures app:api [-o DIR]
```

## Examples

Runnable examples in [examples/](https://github.com/eddiethedean/semblance/tree/main/examples):

```bash
semblance run examples.basic.app:api --port 8000
semblance run examples.pagination.app:api --port 8000
semblance run examples.nested.app:api --port 8000
semblance run examples.stateful.app:api --port 8000
semblance run examples.advanced.app:api --port 8000
semblance run examples.error_simulation.app:api --port 8000
semblance run examples.plugins.app:api --port 8000
```

| Example | Description |
|---------|-------------|
| [basic](https://github.com/eddiethedean/semblance/tree/main/examples/basic) | Minimal GET list with FromInput, DateRangeFrom |
| [pagination](https://github.com/eddiethedean/semblance/tree/main/examples/pagination) | PageParams, PaginatedResponse |
| [nested](https://github.com/eddiethedean/semblance/tree/main/examples/nested) | Nested model linking |
| [stateful](https://github.com/eddiethedean/semblance/tree/main/examples/stateful) | POST stores items, GET returns stored list |
| [advanced](https://github.com/eddiethedean/semblance/tree/main/examples/advanced) | WhenInput, ComputedFrom, filter_by |
| [error_simulation](https://github.com/eddiethedean/semblance/tree/main/examples/error_simulation) | error_rate, error_codes |
| [plugins](https://github.com/eddiethedean/semblance/tree/main/examples/plugins) | Custom link (FromEnv) |

## Testing

```python
from semblance import SemblanceAPI, test_client

app = api.as_fastapi()
client = test_client(app)

r = client.get("/users?name=testuser")
assert r.status_code == 200
data = r.json()
assert all(u["name"] == "testuser" for u in data)
```

Deterministic seeding for reproducible tests:

```python
api = SemblanceAPI(seed=42)
# or per-endpoint: seed_from="seed" with a query param
```

## Plugins

Register custom link types:

```python
from semblance import register_link, SemblanceAPI
from typing import Annotated

class FromEnv:
    def __init__(self, env_var: str):
        self.env_var = env_var
    def resolve(self, input_data, rng):
        import os
        return os.environ.get(self.env_var)

register_link(FromEnv)

class User(BaseModel):
    name: Annotated[str, FromEnv("USER_NAME")]
```

## API Overview

| Feature | Description |
|---------|-------------|
| **SemblanceAPI** | GET and POST endpoints with input/output models |
| **Links** | FromInput, DateRangeFrom, WhenInput, ComputedFrom |
| **Pagination** | PageParams, PaginatedResponse[T] |
| **Seeding** | `SemblanceAPI(seed=42)` or `seed_from="seed"` |
| **Error simulation** | `error_rate`, `error_codes` |
| **Latency** | `latency_ms`, `jitter_ms` |
| **Filtering** | `filter_by` for list endpoints |
| **Stateful mode** | `SemblanceAPI(stateful=True)` — POST stores, GET returns stored |
| **OpenAPI** | summary, description, tags on endpoints |

## Documentation

- [Getting Started](https://github.com/eddiethedean/semblance/blob/main/docs/guides/getting-started.md)
- [Input and Output Binding](https://github.com/eddiethedean/semblance/blob/main/docs/guides/input-output-binding.md)
- [Advanced Links](https://github.com/eddiethedean/semblance/blob/main/docs/guides/advanced-links.md)
- [Pagination](https://github.com/eddiethedean/semblance/blob/main/docs/guides/pagination.md)
- [Simulation Options](https://github.com/eddiethedean/semblance/blob/main/docs/guides/simulation-options.md)
- [Stateful Mode](https://github.com/eddiethedean/semblance/blob/main/docs/guides/stateful-mode.md)
- [CLI](https://github.com/eddiethedean/semblance/blob/main/docs/guides/cli.md)
- [Plugins](https://github.com/eddiethedean/semblance/blob/main/docs/guides/plugins.md)
- [Testing](https://github.com/eddiethedean/semblance/blob/main/docs/guides/testing.md)
- [Roadmap](https://github.com/eddiethedean/semblance/blob/main/docs/roadmap.md)
- [API Reference](https://github.com/eddiethedean/semblance/blob/main/docs/api/index.md)

## Development

See [CONTRIBUTING.md](https://github.com/eddiethedean/semblance/blob/main/CONTRIBUTING.md) for setup and contribution guidelines.

```bash
git clone https://github.com/eddiethedean/semblance.git
cd semblance
pip install -e ".[dev]"
pytest tests/ -v
```

## License

MIT License.
