Skip to main content

Semblance

PyPI Read the Docs Python 3.10+ Ruff License: 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, rate limiting, pagination, stateful mode, optional response validation

Requirements

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

Installation

pip install semblance

Optional unofficial adapters (separate packages):

pip install semblance-foundry
pip install semblance-databricks

From source (development):

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

Quick Start

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(seed=42)


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


app = api.as_fastapi()

You can register PUT, PATCH, and DELETE endpoints the same way (@api.put(...), @api.patch(...), @api.delete(..., output=None) for 204).

Run:

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

Try:

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

Example output (with SemblanceAPI(seed=42) and list_count=2 for reproducibility):

[
  {"name": "alice", "created_at": "2024-08-21T09:22:43.516168"},
  {"name": "alice", "created_at": "2024-01-10T03:05:39.176702"}
]

Responses are generated from your output model: name comes from the query, created_at is 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

# Scaffold a minimal app (app.py and optional semblance.yaml)
semblance init [-c] [--force]

# Validate routes and link bindings without starting a server (CI-friendly)
semblance validate module:attr

# Run a Semblance app (module:attr or just module when unambiguous)
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 OpenAPI + JSON fixtures per endpoint (GET, POST, PUT, PATCH, DELETE)
semblance export fixtures app:api [-o DIR]

Examples

Runnable examples in examples/:

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
semblance run examples.put_patch_delete.app:api --port 8000
semblance run examples.stateful_crud.app:api --port 8000
semblance run examples.request_links.app:api --port 8000
Example Description
basic Minimal GET list with FromInput, DateRangeFrom
pagination PageParams, PaginatedResponse
nested Nested model linking
stateful POST stores items, GET returns stored list
advanced WhenInput, ComputedFrom, filter_by
error_simulation error_rate, error_codes
plugins Custom link (FromEnv)
put_patch_delete PUT, PATCH, DELETE (non-stateful)
stateful_crud Full stateful CRUD: GET by id, PUT, PATCH, DELETE
request_links FromHeader, FromCookie

Testing

Use the same api from Quick Start (with app = api.as_fastapi()). With the test client you get deterministic responses without starting a server:

from semblance import SemblanceAPI, test_client

# api and app from Quick Start above
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)
# data is a list of User dicts, e.g. [{"name": "testuser", "created_at": "..."}, ...]

Deterministic seeding for reproducible tests:

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

Plugins

Register custom link types:

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, POST, PUT, PATCH, DELETE 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
Rate limiting rate_limit=N — 429 when exceeded (per endpoint, sliding window)
Filtering filter_by for list endpoints
Stateful mode SemblanceAPI(stateful=True) — POST stores; GET (list + by-id), PUT/PATCH/DELETE by id use store
Response validation SemblanceAPI(validate_responses=True) — verify output conforms to model
OpenAPI summary, description, tags on endpoints
Property-based testing semblance.property_testing: strategy_for_input_model(), test_endpoint() (Hypothesis)

Competitors & Alternatives

Feature Semblance fastapi-mock Prism json-server Schemathesis Mockoon
Mock API server ✅ ✅ ✅ ✅ ❌ ✅
Python / FastAPI native ✅ ✅ ❌ ❌ ✅ ❌
Zero endpoint logic ✅ ❌ ✅ ✅ ❌ ✅
Realistic example generation ✅ 🟡 ✅ ❌ ❌ 🟡
Input→output binding ✅ ❌ ❌ ❌ ❌ 🟡
Deterministic seeding ✅ ❌ ✅ ❌ ✅ 🟡
Pagination helpers ✅ ❌ 🟡 ✅ ❌ 🟡
Error simulation ✅ ❌ 🟡 ❌ ❌ 🟡
Stateful mode ✅ ❌ ❌ ✅ ❌ 🟡
Extensible (plugins) ✅ 🟡 ❌ ❌ ✅ 🟡
OpenAPI schema ✅ ✅ ✅ ❌ ✅ 🟡
CI / pytest integration ✅ ✅ ✅ ✅ ✅ ❌
Property-based testing ✅ ❌ ❌ ❌ ✅ ❌

🟡 = partial or configurable

Documentation

Full documentation: semblance.readthedocs.io

Development

See CONTRIBUTING.md for setup and contribution guidelines.

git clone https://github.com/eddiethedean/semblance.git
cd semblance
pip install -e ".[dev]"
pip install -e packages/semblance-foundry[dev]
pip install -e packages/semblance-databricks[dev]
pytest tests/ -v -m "not sdk"
pytest packages/semblance-foundry/tests -v -m "not sdk"
pytest packages/semblance-databricks/tests -v -m "not sdk"

License

MIT License.

Metadata

Release files for semblance 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for semblance 0.9.0
File Size Uploaded
semblance-0.9.0.tar.gz 56.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for semblance 0.9.0
File Interpreter ABI Platform
semblance-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 96.0 kB

Release files / semblance-0.9.0.tar.gz

Download URL semblance-0.9.0.tar.gz
Size 56.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bad42288a4e2cf688b24a143acd90872978b214ac4a7580def5d97a9e3eca05c
BLAKE2b-256 checksum
How to use checksums
51cf407bcd60f1043f7d1421310bb3ecead6c723b93a2943bdc9b391163177b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / semblance-0.9.0-py3-none-any.whl

Download URL semblance-0.9.0-py3-none-any.whl
Size 39.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e341f43619d294677216b13a34091ae4e3632c053976762557e0412f6761329d
BLAKE2b-256 checksum
How to use checksums
19c5f5a9ae4f17be35bf17bb93163114ac40c71c3440ad1a5dd925b1f70df96e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page