Model/Interface/Controller boilerplate for Python services — FastAPI/Litestar parity, JWT service auth, SQLModel storage, Prometheus + JSON logs, cookiecutter scaffold
This project has been archived.
The maintainers of this project have marked this project as archived. No new releases are expected.
Project description
mic-struct
Model / Interface / Controller boilerplate for Python microservices. Build production-grade services with strict contracts, framework-agnostic HTTP, JWT service-to-service auth, pluggable storage, and a cookiecutter scaffold that lands at 100 % test coverage out of the box.
mic-struct ships 25 modules as composable building blocks — you
assemble what you need, the library has no opinion on your stack. Every
optional integration (Redis, Postgres, Mongo, Neo4j, NATS, Kafka, gRPC, …)
lives behind a pip extra, so a minimal install pulls only Pydantic.
What's inside
Core — HTTP, contracts, auth
| Module | What it gives you |
|---|---|
mic.contracts |
StrictSchema (Pydantic v2, extra=forbid, frozen=True), HttpSuccessEnvelope[T], wrap_http_success() |
mic.model |
DomainError(code, message, details) + TransientError (4xx vs 503 mapping) |
mic.http |
Framework-agnostic HttpRouteSpec / HttpResponseSpec / HttpRequestContext + adapters for FastAPI and Litestar (handlers stay identical across both) |
mic.auth |
ServiceAuthSigner / ServiceAuthVerifier — HS256 audience-bound JWT with double-key rotation + issuer whitelist |
mic.client |
ServiceHttpClient — thin httpx wrapper with auto-signing + canonical error mapping |
mic.cli |
build_parser() — argparse-based operator CLI scaffold (stdlib only) |
Data — storage, caching, sharding
| Module | What it gives you |
|---|---|
mic.datastorage |
DataStorage ABC + SqlDataStorage (SQLModel) / DocumentDataStorage (MongoDB) / GraphDataStorage (Neo4j) / InMemoryKeyValueDataStorage / InMemoryDocumentDataStorage |
mic.cache |
CacheBackend ABC + RedisCache / RedisClusterCache / InMemoryCache |
mic.response_cache |
ASGI middleware — HTTP response caching with ETag, stampede protection, SHA-256 vary keys |
mic.read_models |
CQRS read-model projection helpers |
mic.shard |
Application-level Postgres sharding (consistent-hash router) |
Messaging — events, queues, realtime
| Module | What it gives you |
|---|---|
mic.eventbus |
EventBus ABC — sync pub/sub (InMemoryEventBus, RedisStreamsEventBus) |
mic.queue |
AsyncEventBus ABC — durable async pub/sub (NATSEventBus, KafkaEventBus, in-memory) |
mic.realtime |
WebSocket endpoints + rooms, RealtimeBackend ABC (in-memory / Redis Streams) |
mic.outbox |
Transactional outbox pattern — OutboxStore + OutboxDispatcher (at-least-once delivery) |
Reliability — resilience, rate limiting, idempotency, locking
| Module | What it gives you |
|---|---|
mic.resilience |
CircuitBreaker (sync + async), with half-open probing |
mic.ratelimit |
RateLimiter ABC — token bucket (InMemoryRateLimiter, RedisRateLimiter with server-side clock) |
mic.idempotency |
Idempotency-Key store with single-flight protection (TOCTOU-safe via a distributed lock) |
mic.locking |
DistributedLock ABC — InMemoryDistributedLock / RedisDistributedLock |
Policy & observability
| Module | What it gives you |
|---|---|
mic.authz |
AuthorizationEngine ABC — RBAC inline / OPA Rego / OpenFGA ReBAC |
mic.observability |
configure_logging() (JSON / text, trace-id auto-injection) + Prometheus counter() / gauge() / histogram() |
mic.healthcheck |
ReadinessChecker + probes — distinguishes /health (liveness) from /ready (dependency readiness) |
Transports
| Module | What it gives you |
|---|---|
mic.grpc |
Audience-bound gRPC interceptor + client + health-check service |
Template
| Path | What it gives you |
|---|---|
template/ |
Cookiecutter scaffold — answer 3 questions, get a complete service that passes make gate at 100 % coverage |
Install
# Just contracts + model (minimal — only pulls Pydantic)
pip install mic-struct
# Add an HTTP adapter (one of, or both)
pip install "mic-struct[fastapi]"
pip install "mic-struct[litestar]"
# SQL datastorage / auth / HTTP client / observability — pick what you need
pip install "mic-struct[postgres,auth,client,observability]"
# Pub/sub backends
pip install "mic-struct[redis]" # mic.eventbus (sync) + mic.realtime (WebSocket)
pip install "mic-struct[messaging]" # mic.queue (NATS + Kafka, async durable)
# Full observability stack (prometheus + sentry + tracing)
pip install "mic-struct[full-observability]"
# Everything
pip install "mic-struct[all]"
Voir pyproject.toml pour la matrice complète des extras.
Quickstart — define a route, plug into FastAPI
mic.http provides the framework-agnostic primitives (HttpRouteSpec,
HttpResponseSpec, HttpCookieSpec, HttpRequestContext). The
opt-in packages mic.fastapi and mic.litestar ship adapters that
translate those primitives into the corresponding framework — pull
them via the [fastapi] / [litestar] extras when (and only when)
you need them.
from fastapi import FastAPI
from mic.contracts import StrictSchema, wrap_http_success
from mic.fastapi import build_fastapi_router
from mic.http import HttpResponseSpec, HttpRouteSpec
class CreateItemPayload(StrictSchema):
name: str
quantity: int = 0
def _create_item(*, payload: CreateItemPayload) -> HttpResponseSpec:
return HttpResponseSpec(
status_code=201,
body=wrap_http_success({"name": payload.name, "qty": payload.quantity}),
)
routes = (
HttpRouteSpec(
method="POST", path="/items",
name="items.create", category="items",
handler=_create_item,
),
)
app = FastAPI()
app.include_router(build_fastapi_router(routes=routes))
Litestar is symmetric : from mic.litestar import build_litestar_router
(via the [litestar] extra). A consumer who needs neither framework
imports only mic.http primitives and never pulls FastAPI / Litestar
transitively.
Switch to Litestar by replacing build_fastapi_router with
build_litestar_router — handlers stay identical.
MELT redaction (logs · traces · events · metrics)
PII and secrets must never leak into observability sinks. mic-struct ships
one redaction mechanism per MELT pillar: you inject the policy (which
field → which strategy, derived from your data-classification ADR), the library
applies it consistently. All four reuse the FieldRedactors type
(dict[str, Callable[[Any], Any]]) and the shared strategies from
mic.outbox — redact_drop (secrets), redact_hash (correlatable, blake2b),
redact_mask.
from mic.outbox import redact_drop, redact_hash # shared strategies
Logs — RedactingLogFilter (stdlib logging.Filter), recursive over nested
dicts/lists and exception locals:
from mic.observability import RedactingLogFilter
handler.addFilter(RedactingLogFilter(redactors={
"email": redact_hash,
"access_token": redact_drop,
}))
Traces — RedactingSpanProcessor (OTel SpanProcessor), scrubs span and
span-event attributes before export (OTLP / Tempo):
from mic.observability import RedactingSpanProcessor
provider.add_span_processor(RedactingSpanProcessor(redactors={
"db.statement": redact_drop,
"http.request.body": redact_drop,
"exception.message": redact_hash,
}))
Events — sanitize_payload + TopicRedactionPolicy, applied before the row
hits outbox_events, configurable per topic (returns a redacted copy):
from mic.outbox import TopicRedactionPolicy, sanitize_payload
POLICY = TopicRedactionPolicy(
default={"otp_code": redact_drop},
per_topic={"application.received": {"email": redact_hash}},
)
safe = sanitize_payload(event, policy=POLICY)
Metrics — SanitizingMetricsBackend decorates any MetricsBackend: rejects
sensitive/secret label names and caps label cardinality. strict=True
(dev/CI) raises MetricLabelViolation; strict=False (prod) warns, drops the
offending emission and bumps an internal *_rejected_total counter:
from mic.observability import SanitizingMetricsBackend
metrics = SanitizingMetricsBackend(
prometheus_backend, denied_labels={"email", "access_token"}, strict=False,
)
metrics.increment("orders_total", labels={"status_class": "2xx"}) # OK
The mechanism lives in mic-struct; each service injects its own policy.
Generate a new service from the template
pip install cookiecutter
cookiecutter https://gitlab.com/mic-struct/mic-struct.git --directory=template
# service_name [example-service] : my-service
# service_description : My new microservice
# http_framework [fastapi] : fastapi # or litestar
cd my-service
make bootstrap-dev && source .venv/bin/activate
make gate # → green at 100 % coverage from first run
make run # → uvicorn on :8000, GET /health, GET /metrics
The generated service comes with:
/health+/ready+/metricsendpoints- An example CRUD module (SQLModel-backed)
- Mirror tests at 100 % coverage
- A
Makefilewithgate(= black + ruff + mypy strict + 100 % pytest)
Quality bar
mic-struct itself:
- 1100+ tests, 100 % line + branch coverage (with all extras installed)
mypy --strictclean,ruff+blackenforcedbandit+pip-auditin the gate- Mutation testing (
mutmut) and performance benchmarks run nightly - Cookiecutter template (FastAPI + Litestar variants) generates a
service that passes
make gatefrom the first run
See CONTRIBUTING.md for the test-quality rules
(match= enforcement, ABC-vs-Protocol convention, fakes-over-mocks),
and docs/decisions/ for the architecture decision
records.
Versioning
mic-struct follows SemVer 2.0. See
CHANGELOG.md for the per-release breakdown.
Contributing
git clone https://gitlab.com/mic-struct/mic-struct.git && cd mic-struct
make bootstrap-dev
make gate # must stay green
100 % line + branch coverage is mandatory on every change — the CI enforces it. Cf. CONTRIBUTING.md.
License
MIT — © 2026 mic-struct contributors.
Links
- 📦 PyPI
- 📋 Changelog
- 🛠 Contributing guide
- 🚢 Releasing guide (maintainers)
- 🐛 Issues
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mic_struct-0.0.3.tar.gz.
File metadata
- Download URL: mic_struct-0.0.3.tar.gz
- Upload date:
- Size: 244.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90491f7d66ec7771f2befc32262e31859fd0069c9cb9f6ca2cc7c45b51604d2a
|
|
| MD5 |
228a1db2bffeb2281f0a40f4e245329a
|
|
| BLAKE2b-256 |
3218143336f63306b37200f194b96a960320ca02b462352bf58621da1d12b4c0
|
File details
Details for the file mic_struct-0.0.3-py3-none-any.whl.
File metadata
- Download URL: mic_struct-0.0.3-py3-none-any.whl
- Upload date:
- Size: 282.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82654f735e9af695617205cbb33c860f30030c0b9d2eb6aa5fcfc7406ae4c73e
|
|
| MD5 |
e19e687d4f070d365126c34b7410801e
|
|
| BLAKE2b-256 |
29dbecb18f2ab92f10ed8a5d162359d284eae9c8c8e453b1b2302f776156bd07
|