nishantXnova/IKAREM

IKAREM — industry-grade Python ASGI backend framework with a zero-dependency core. DI, validation, JWT auth, OpenAPI + MCP. pip install ikarem

Python

0

33 commits

updated Sep 30, 2026

See the code

See what people are saying

README

IKAREM

Zero-dependency Python ASGI framework, built for humans and LLMs.

IKAREM logo — a reversed K slashed through, over mirrored MERAKI, also slashed

CI PyPI Python License

FastAPI-style DX (DI, validation, OpenAPI, auth) + Django/Nest-style structure (plugins, config, RBAC) + a core that runs on stdlib alone. Pip-installable, zero required dependencies.

Install

pip install -e .                  # core only, zero dependencies
pip install -e ".[server,test]"   # uvicorn + pytest + httpx for dev
pip install -e ".[postgres]"      # asyncpg strategy
pip install -e ".[mysql]"         # aiomysql strategy
pip install -e ".[sqlserver]"     # aioodbc strategy

30-second example

from ikarem import Ikarem

app = Ikarem(debug=True)


@app.get("/")
async def home(req):
    return {"hello": "ikarem"}  # dict auto-becomes JSON


@app.get("/users/{uid:int}")
async def get_user(req, uid: int):
    return {"uid": uid}


if __name__ == "__main__":
    app.run()  # needs `pip install ikarem[server]`
python examples/basic.py
# or
ikarem run examples.basic:app --reload

Industry-grade example

from ikarem import (
    BackgroundTasks,
    Depends,
    Ikarem,
    Schema,
    CORSMiddleware,
    RateLimitMiddleware,
    create_token,
    require_roles,
)

app = Ikarem(auth_secret="secret")
app.use(CORSMiddleware())
app.use(RateLimitMiddleware(per_minute=120))


class Item(Schema):
    name: str
    qty: int = 1


def get_prefix():
    return "hi"


@app.post("/items")
async def create(req, item: Item, bg: BackgroundTasks, prefix=Depends(get_prefix)):
    bg.add(print, f"created {item.name}")
    return {"msg": f"{prefix} {item.name}", "qty": item.qty}  # validated + coerced


tok = create_token("u1", "secret", roles=["admin"])


@app.get("/admin")
async def adm(req, claims=Depends(require_roles("admin"))):
    return {"sub": claims["sub"]}  # 401 without token, 403 without role

Built-ins on every app: GET /healthz, GET /metrics, GET /openapi.json (OpenAPI 3.1 auto-gen), GET /docs (Swagger UI).

Production web apps

ikarem new myapp && cd myapp   # auth + sessions + SQLite CRUD (HTML + JSON), tests + Dockerfile
pytest -q && uvicorn app:app
from ikarem import SessionMiddleware, CSRFMiddleware, Field, Schema

app.use(SessionMiddleware())  # signed cookies: req.session["uid"] = ...
app.use(CSRFMiddleware())  # unsafe routes need X-CSRF-Token or _csrf_token field


class Signup(Schema):
    email: str = Field(..., email=True, max_length=254)
    password: str = Field(..., min_length=8, max_length=128)


class Note(Schema):
    text: str = Field(..., min_length=1, max_length=500)


@app.post("/notes")
async def add(req, note: Note):  # validates JSON *and* HTML form bodies
    form = await req.form()  # urlencoded + multipart, UploadFile files,
    f = form.get("doc")  # 413 past size caps
    await f.write(f"/uploads/{f.filename}")

TestClient keeps a cookie jar (login flows just work) and speaks get/post/put/patch/delete. ikarem check audits handlers, ikarem mcp serves every route as an LLM tool (plus ikarem://openapi.json and ikarem://manifest MCP resources), ikarem inspect prints a compact route manifest for LLM context, and site/llms.txt is the framework manual in one page. AGENTS.md holds the contributor laws for AI and human agents alike.

Flask's best, taken

from ikarem import Blueprint, MethodView, Templates, abort, flash

api = Blueprint("api", url_prefix="/api")


@api.get("/items/{uid:int}")  # own hooks, own errors, url_for("api.x")
async def one(req, uid: int): ...


app.register_blueprint(api)  # hooks wrap once — still zero per-request reflection

abort(403, "owner only")  # terse errors through the normal pipeline


class Items(MethodView):  # one class per resource, full DI per method
    async def get(self, req): ...
    async def post(self, req, item: Item): ...


app.route("/items", Items.methods())(Items.as_view("items"))

flash(req, "Saved.")  # session-backed, shown once in templates
Templates("templates/").response("hi.html", name="amy")  # Jinja2 via ikarem[jinja]

Deliberately not taken: context locals (g, global request proxies) and signals — explicit req params plus plugins and middleware cover that ground without the magic.

Ops batch: migrations, queues, cron, API keys

from ikarem import Migrator, QueuePlugin, require_scopes, APIKeyAuth, task
from ikarem.db import DatabasePlugin

app.register(DatabasePlugin("postgresql://..."))
app.register(QueuePlugin())  # durable jobs in app.state_queue


@task("welcome")  # name -> callable, worker-dispatched
async def welcome(to: str): ...


@app.post("/signup")
async def signup(req):
    await req.app.state_queue.enqueue("welcome", {"to": "a@b.co"})
    return {"ok": True}, 201


@app.every(300)  # or @app.cron("0 2 * * *")
async def nightly(): ...


# await app.start_scheduler()                  # explicit: nothing runs unless started
ikarem migrate new add_users && ikarem migrate up myapp:app
ikarem worker myapp:app                        # drain the queue until Ctrl+C

Plus the small ones the checklist demanded: Schema(extra="forbid") sanitization, XMLResponse/dict_to_xml, escape_html, APIKeyAuth (static keys or async lookup=), require_scopes() for JWT scopes, require_if() predicate (ABAC-lite). Out of scope on purpose: full ORM (strategy + validated schemas is the answer) and OAuth2 dance (JWT bearer covers service auth).

Stronger: timeouts, bulkheads, idempotency, rooms

from ikarem import TimeoutMiddleware, ConcurrencyLimitMiddleware, IdempotencyMiddleware, TrustedHostMiddleware

app.use(TimeoutMiddleware(30))  # hung handler -> 503 + Retry-After
app.use(ConcurrencyLimitMiddleware(100))  # bulkhead: fail fast past N in-flight
app.use(IdempotencyMiddleware())  # Idempotency-Key replays, no double charges
app.use(TrustedHostMiddleware(["example.com", ".example.com"]))

Plus Ikarem(max_body_bytes=...) DoS floor, latency fields in /metrics, atomic SQLite transactions, Room pub/sub for websockets (tested via TestClient.ws_connect), and a py.typed marker so downstream type checkers see the real types.

Live proof it all works: ledger/ — a personal-finance app (auth, dashboard with SVG charts, CRUD, receipt uploads, CSV export, JSON API) running on stock IKAREM + uvicorn.

Switching? Bring your routes

Meraki (5 minutes):

-from meraki import Meraki
+from ikarem.meraki_compat import Meraki

Your app runs unchanged (same routes, middleware, 404/405 bodies) on the IKAREM engine — then migrate handler-by-handler. From anywhere else:

Plus honest benchmarks: bench/RESULTS.md · extension registry: docs/ECOSYSTEM.md · 20 runnable recipes: docs/COOKBOOK.md · install: pip install ikarem.

Footnote: IKAREM started as an answer to Meraki — same decorator shape, working plugins, and everything Meraki's README promised but never shipped. The rivalry is archived; this section is just the moving van.

Why IKAREM

Rival featureIKAREM answer
pip package, minimal depsZero required deps. uvicorn/asyncpg/etc are optional extras. Core is pure stdlib + ASGI.
ASGI + Uvicorn boundaryStrict server boundary: Ikarem exposes __call__(scope, receive, send). Any ASGI server works (uvicorn, hypercorn, daphne). HTTP + WebSocket + lifespan.
Central app + lifecycleIkarem() + on_startup / on_shutdown + lifespan. Plugins hook in with priority + topological dependency order.
Request/ResponseLazy Request (query, headers, cookies, await body()/json()), Response helpers (JSON, text, html, stream, redirect, File). Handlers never touch raw ASGI.
RoutingCompiled routes with {param} + {param:int/float/uuid/path} converters, 404 vs 405 distinction, url_for, include_router(prefix), static mounts.
MiddlewareOnion pipeline, short-circuitable, global + composable: CORS, security headers, rate limiting (429 + Retry-After), request-ID/timing, metrics.
PluginsPlugin protocol (name, requires, priority, register, on_startup/shutdown/request/response). Manager sorts dependencies, detects cycles.
ConfigLayered Config: defaults < kwargs < dict < IKAREM_* env vars. Typed config.get(key, default, cast=...).
ErrorsHTTPException hierarchy + @app.exception_handler(ExcType) with MRO most-specific match. Tracebacks only when debug=True.
DB Strategy (pg/mysql/sqlite/mssql)DatabaseConnector async ABC (connect/disconnect/execute/fetch_one/fetch_all/execute_many/transaction). Lazy driver imports. SQLite runs on stdlib today. DatabasePlugin proves the extension model.
DI (FastAPI parity)Depends() with nesting, per-request cache (+ opt-out), sync/async/yield deps, finalizers guaranteed after response send and on the exception path, circular-dep rejection.
Validation (Pydantic-lite)Schema models from type hints: coercion, required/optional, nested models, ValidationError → 400. Zero deps.
AuthStdlib HS256 JWT (algorithm-confusion resistant, sub required, expiry enforced), pbkdf2 passwords, BearerAuth, require_roles() RBAC.
CachingMemoryCache + @cached (Redis-swappable CacheBackend interface).
Background workBackgroundTasks param — runs after the response is sent, never fails the response.
Realtime / filesapp.websocket(path) + WebSocket helper; mount_static() + FileResponse.
ObservabilityJSON logging, x-request-id + x-process-time-ms, /healthz, Prometheus-style /metrics.

Verification

208 passed, 3 skipped — framework plus both showcase apps, one command:

python -m pytest tests/ ledger/tests cadence/tests -q

CI runs the same suite on Python 3.10–3.13 × Ubuntu/macOS/Windows, plus a live-Postgres job, a Docker showcase build, a starter-template smoke job (ikarem new + template tests), ruff lint + format, and ikarem check ledger.app:app. Every behavior ships with a test; bugfix PRs include a regression test.

Layout

ikarem/            zero-dep stdlib core (v1.1.0) — optional integrations lazy-load behind extras
  app.py          Ikarem core + ASGI callable + lifespan + background/cleanup wiring
  compiled.py     one-time handler plans (no per-request reflection) + check/describe IR
  routing.py      compiled routes + converters + Did-you-mean 404s
  http.py         Request (+forms/uploads) + Response family (+cookies)
  di.py           Depends + nesting + cycle detection + run_cleanups
  validation.py   Schema models + Field() constraints (zero-dep validation)
  auth.py         JWT + passwords + Bearer/API-key auth + roles/scopes guards
  session.py      signed-cookie sessions + CSRF
  security.py     CORS + security headers + trusted hosts + rate limiting
  resilience.py   timeouts + bulkheads + idempotency
  cache.py        CacheBackend + MemoryCache + RedisCache + @cached
  db/             DatabaseConnector ABC + sqlite/postgres/mysql/sqlserver + plugin + factory
  queue.py        durable task queue + QueuePlugin + `ikarem worker`
  scheduler.py    cron/intervals + SchedulerPlugin
  migrations.py   versioned migrations + `ikarem migrate`
  resources.py    app.resource() validated CRUD
  blueprints.py   prefixed route groups + MethodView (views.py)
  middleware.py   Middleware base + stack
  plugins.py      Plugin protocol + dependency-sorted PluginManager
  config.py       layered Config
  errors.py       HTTPException hierarchy + handler registry
  openapi.py      OpenAPI 3.1 builder + /openapi.json + /docs
  mcp.py          routes-as-MCP-tools + resources + stdio server
  websocket.py    WebSocket + Room pub/sub + WSRouter
  static.py       FileResponse + escape-proof static mounts
  templating.py   Jinja2 via ikarem[jinja] + flashing.py one-shot messages
  observability.py  logging + request-ID + metrics + /healthz + /readyz + /metrics
  cli.py          `ikarem run|check|mcp|new|migrate|worker|inspect`
  testing.py      TestClient (cookie jar, all verbs, WS driving — no server needed)
  scaffold.py     `ikarem new` starter generator
  deprecation.py  deprecated() upgrade path + meraki_compat.py drop-in shim
tests/ + ledger/tests + cadence/tests   208-test suite (see Verification)
ledger/ + cadence/   production showcase apps (finance tracker, habit tracker)
examples/basic.py    minimal CRUD + DB plugin app
bench/            honest benches (bench_switch.py) + sustained-load proof (load.py)
docs/             COOKBOOK.md (20 runnable recipes) · ECOSYSTEM.md (extension registry) ·
                  MIGRATING_FROM_MERAKI.md · DEPLOY.md · PLUGINS.md · PHASE1.md (original spec)
site/             static docs site (no build step) + llms.txt framework manual

Project basics

  • Security: SECURITY.md — supported versions, how to report (GitHub private vulnerability reporting; no public issues for vulns).
  • Contributing: CONTRIBUTING.md — setup, per-PR checks, the five agent laws (zero-dep core, tests, no per-request reflection, fix-saying errors, Conventional Commits).
  • Changelog: CHANGELOG.md — every release cut from Conventional Commits, Keep-a-Changelog format.
  • Versioning (SemVer): 1.x keeps the public API backward-compatible — ikarem/__init__.py exports, ASGI behavior, CLI commands, response shapes. Minor versions add; breaking changes wait for a major.
  • Deprecation policy: removals land only in majors, announced at least one minor earlier via deprecated(since=, removal=, use_instead=) — upgrades warn with the version, the removal target, and the replacement.
  • CI: Python 3.10–3.13 × Ubuntu/macOS/Windows, live Postgres, Docker build, scaffold smoke, ruff lint + format.
api-framework
asgi
authentication
backend-framework
dependency-injection
jwt
mcp
middleware
openapi
postgresql
python
rest-api
sqlite
validation
web-framework
websockets

nishantXnova/IKAREM

IKAREM — industry-grade Python ASGI backend framework with a zero-dependency core. DI, validation, JWT auth, OpenAPI + MCP. pip install ikarem

Python

0

33 commits

updated Sep 30, 2026

See the code

See what people are saying

README

IKAREM

Zero-dependency Python ASGI framework, built for humans and LLMs.

IKAREM logo — a reversed K slashed through, over mirrored MERAKI, also slashed

CI PyPI Python License

FastAPI-style DX (DI, validation, OpenAPI, auth) + Django/Nest-style structure (plugins, config, RBAC) + a core that runs on stdlib alone. Pip-installable, zero required dependencies.

Install

pip install -e .                  # core only, zero dependencies
pip install -e ".[server,test]"   # uvicorn + pytest + httpx for dev
pip install -e ".[postgres]"      # asyncpg strategy
pip install -e ".[mysql]"         # aiomysql strategy
pip install -e ".[sqlserver]"     # aioodbc strategy

30-second example

from ikarem import Ikarem

app = Ikarem(debug=True)


@app.get("/")
async def home(req):
    return {"hello": "ikarem"}  # dict auto-becomes JSON


@app.get("/users/{uid:int}")
async def get_user(req, uid: int):
    return {"uid": uid}


if __name__ == "__main__":
    app.run()  # needs `pip install ikarem[server]`
python examples/basic.py
# or
ikarem run examples.basic:app --reload

Industry-grade example

from ikarem import (
    BackgroundTasks,
    Depends,
    Ikarem,
    Schema,
    CORSMiddleware,
    RateLimitMiddleware,
    create_token,
    require_roles,
)

app = Ikarem(auth_secret="secret")
app.use(CORSMiddleware())
app.use(RateLimitMiddleware(per_minute=120))


class Item(Schema):
    name: str
    qty: int = 1


def get_prefix():
    return "hi"


@app.post("/items")
async def create(req, item: Item, bg: BackgroundTasks, prefix=Depends(get_prefix)):
    bg.add(print, f"created {item.name}")
    return {"msg": f"{prefix} {item.name}", "qty": item.qty}  # validated + coerced


tok = create_token("u1", "secret", roles=["admin"])


@app.get("/admin")
async def adm(req, claims=Depends(require_roles("admin"))):
    return {"sub": claims["sub"]}  # 401 without token, 403 without role

Built-ins on every app: GET /healthz, GET /metrics, GET /openapi.json (OpenAPI 3.1 auto-gen), GET /docs (Swagger UI).

Production web apps

ikarem new myapp && cd myapp   # auth + sessions + SQLite CRUD (HTML + JSON), tests + Dockerfile
pytest -q && uvicorn app:app
from ikarem import SessionMiddleware, CSRFMiddleware, Field, Schema

app.use(SessionMiddleware())  # signed cookies: req.session["uid"] = ...
app.use(CSRFMiddleware())  # unsafe routes need X-CSRF-Token or _csrf_token field


class Signup(Schema):
    email: str = Field(..., email=True, max_length=254)
    password: str = Field(..., min_length=8, max_length=128)


class Note(Schema):
    text: str = Field(..., min_length=1, max_length=500)


@app.post("/notes")
async def add(req, note: Note):  # validates JSON *and* HTML form bodies
    form = await req.form()  # urlencoded + multipart, UploadFile files,
    f = form.get("doc")  # 413 past size caps
    await f.write(f"/uploads/{f.filename}")

TestClient keeps a cookie jar (login flows just work) and speaks get/post/put/patch/delete. ikarem check audits handlers, ikarem mcp serves every route as an LLM tool (plus ikarem://openapi.json and ikarem://manifest MCP resources), ikarem inspect prints a compact route manifest for LLM context, and site/llms.txt is the framework manual in one page. AGENTS.md holds the contributor laws for AI and human agents alike.

Flask's best, taken

from ikarem import Blueprint, MethodView, Templates, abort, flash

api = Blueprint("api", url_prefix="/api")


@api.get("/items/{uid:int}")  # own hooks, own errors, url_for("api.x")
async def one(req, uid: int): ...


app.register_blueprint(api)  # hooks wrap once — still zero per-request reflection

abort(403, "owner only")  # terse errors through the normal pipeline


class Items(MethodView):  # one class per resource, full DI per method
    async def get(self, req): ...
    async def post(self, req, item: Item): ...


app.route("/items", Items.methods())(Items.as_view("items"))

flash(req, "Saved.")  # session-backed, shown once in templates
Templates("templates/").response("hi.html", name="amy")  # Jinja2 via ikarem[jinja]

Deliberately not taken: context locals (g, global request proxies) and signals — explicit req params plus plugins and middleware cover that ground without the magic.

Ops batch: migrations, queues, cron, API keys

from ikarem import Migrator, QueuePlugin, require_scopes, APIKeyAuth, task
from ikarem.db import DatabasePlugin

app.register(DatabasePlugin("postgresql://..."))
app.register(QueuePlugin())  # durable jobs in app.state_queue


@task("welcome")  # name -> callable, worker-dispatched
async def welcome(to: str): ...


@app.post("/signup")
async def signup(req):
    await req.app.state_queue.enqueue("welcome", {"to": "a@b.co"})
    return {"ok": True}, 201


@app.every(300)  # or @app.cron("0 2 * * *")
async def nightly(): ...


# await app.start_scheduler()                  # explicit: nothing runs unless started
ikarem migrate new add_users && ikarem migrate up myapp:app
ikarem worker myapp:app                        # drain the queue until Ctrl+C

Plus the small ones the checklist demanded: Schema(extra="forbid") sanitization, XMLResponse/dict_to_xml, escape_html, APIKeyAuth (static keys or async lookup=), require_scopes() for JWT scopes, require_if() predicate (ABAC-lite). Out of scope on purpose: full ORM (strategy + validated schemas is the answer) and OAuth2 dance (JWT bearer covers service auth).

Stronger: timeouts, bulkheads, idempotency, rooms

from ikarem import TimeoutMiddleware, ConcurrencyLimitMiddleware, IdempotencyMiddleware, TrustedHostMiddleware

app.use(TimeoutMiddleware(30))  # hung handler -> 503 + Retry-After
app.use(ConcurrencyLimitMiddleware(100))  # bulkhead: fail fast past N in-flight
app.use(IdempotencyMiddleware())  # Idempotency-Key replays, no double charges
app.use(TrustedHostMiddleware(["example.com", ".example.com"]))

Plus Ikarem(max_body_bytes=...) DoS floor, latency fields in /metrics, atomic SQLite transactions, Room pub/sub for websockets (tested via TestClient.ws_connect), and a py.typed marker so downstream type checkers see the real types.

Live proof it all works: ledger/ — a personal-finance app (auth, dashboard with SVG charts, CRUD, receipt uploads, CSV export, JSON API) running on stock IKAREM + uvicorn.

Switching? Bring your routes

Meraki (5 minutes):

-from meraki import Meraki
+from ikarem.meraki_compat import Meraki

Your app runs unchanged (same routes, middleware, 404/405 bodies) on the IKAREM engine — then migrate handler-by-handler. From anywhere else:

Plus honest benchmarks: bench/RESULTS.md · extension registry: docs/ECOSYSTEM.md · 20 runnable recipes: docs/COOKBOOK.md · install: pip install ikarem.

Footnote: IKAREM started as an answer to Meraki — same decorator shape, working plugins, and everything Meraki's README promised but never shipped. The rivalry is archived; this section is just the moving van.

Why IKAREM

Rival featureIKAREM answer
pip package, minimal depsZero required deps. uvicorn/asyncpg/etc are optional extras. Core is pure stdlib + ASGI.
ASGI + Uvicorn boundaryStrict server boundary: Ikarem exposes __call__(scope, receive, send). Any ASGI server works (uvicorn, hypercorn, daphne). HTTP + WebSocket + lifespan.
Central app + lifecycleIkarem() + on_startup / on_shutdown + lifespan. Plugins hook in with priority + topological dependency order.
Request/ResponseLazy Request (query, headers, cookies, await body()/json()), Response helpers (JSON, text, html, stream, redirect, File). Handlers never touch raw ASGI.
RoutingCompiled routes with {param} + {param:int/float/uuid/path} converters, 404 vs 405 distinction, url_for, include_router(prefix), static mounts.
MiddlewareOnion pipeline, short-circuitable, global + composable: CORS, security headers, rate limiting (429 + Retry-After), request-ID/timing, metrics.
PluginsPlugin protocol (name, requires, priority, register, on_startup/shutdown/request/response). Manager sorts dependencies, detects cycles.
ConfigLayered Config: defaults < kwargs < dict < IKAREM_* env vars. Typed config.get(key, default, cast=...).
ErrorsHTTPException hierarchy + @app.exception_handler(ExcType) with MRO most-specific match. Tracebacks only when debug=True.
DB Strategy (pg/mysql/sqlite/mssql)DatabaseConnector async ABC (connect/disconnect/execute/fetch_one/fetch_all/execute_many/transaction). Lazy driver imports. SQLite runs on stdlib today. DatabasePlugin proves the extension model.
DI (FastAPI parity)Depends() with nesting, per-request cache (+ opt-out), sync/async/yield deps, finalizers guaranteed after response send and on the exception path, circular-dep rejection.
Validation (Pydantic-lite)Schema models from type hints: coercion, required/optional, nested models, ValidationError → 400. Zero deps.
AuthStdlib HS256 JWT (algorithm-confusion resistant, sub required, expiry enforced), pbkdf2 passwords, BearerAuth, require_roles() RBAC.
CachingMemoryCache + @cached (Redis-swappable CacheBackend interface).
Background workBackgroundTasks param — runs after the response is sent, never fails the response.
Realtime / filesapp.websocket(path) + WebSocket helper; mount_static() + FileResponse.
ObservabilityJSON logging, x-request-id + x-process-time-ms, /healthz, Prometheus-style /metrics.

Verification

208 passed, 3 skipped — framework plus both showcase apps, one command:

python -m pytest tests/ ledger/tests cadence/tests -q

CI runs the same suite on Python 3.10–3.13 × Ubuntu/macOS/Windows, plus a live-Postgres job, a Docker showcase build, a starter-template smoke job (ikarem new + template tests), ruff lint + format, and ikarem check ledger.app:app. Every behavior ships with a test; bugfix PRs include a regression test.

Layout

ikarem/            zero-dep stdlib core (v1.1.0) — optional integrations lazy-load behind extras
  app.py          Ikarem core + ASGI callable + lifespan + background/cleanup wiring
  compiled.py     one-time handler plans (no per-request reflection) + check/describe IR
  routing.py      compiled routes + converters + Did-you-mean 404s
  http.py         Request (+forms/uploads) + Response family (+cookies)
  di.py           Depends + nesting + cycle detection + run_cleanups
  validation.py   Schema models + Field() constraints (zero-dep validation)
  auth.py         JWT + passwords + Bearer/API-key auth + roles/scopes guards
  session.py      signed-cookie sessions + CSRF
  security.py     CORS + security headers + trusted hosts + rate limiting
  resilience.py   timeouts + bulkheads + idempotency
  cache.py        CacheBackend + MemoryCache + RedisCache + @cached
  db/             DatabaseConnector ABC + sqlite/postgres/mysql/sqlserver + plugin + factory
  queue.py        durable task queue + QueuePlugin + `ikarem worker`
  scheduler.py    cron/intervals + SchedulerPlugin
  migrations.py   versioned migrations + `ikarem migrate`
  resources.py    app.resource() validated CRUD
  blueprints.py   prefixed route groups + MethodView (views.py)
  middleware.py   Middleware base + stack
  plugins.py      Plugin protocol + dependency-sorted PluginManager
  config.py       layered Config
  errors.py       HTTPException hierarchy + handler registry
  openapi.py      OpenAPI 3.1 builder + /openapi.json + /docs
  mcp.py          routes-as-MCP-tools + resources + stdio server
  websocket.py    WebSocket + Room pub/sub + WSRouter
  static.py       FileResponse + escape-proof static mounts
  templating.py   Jinja2 via ikarem[jinja] + flashing.py one-shot messages
  observability.py  logging + request-ID + metrics + /healthz + /readyz + /metrics
  cli.py          `ikarem run|check|mcp|new|migrate|worker|inspect`
  testing.py      TestClient (cookie jar, all verbs, WS driving — no server needed)
  scaffold.py     `ikarem new` starter generator
  deprecation.py  deprecated() upgrade path + meraki_compat.py drop-in shim
tests/ + ledger/tests + cadence/tests   208-test suite (see Verification)
ledger/ + cadence/   production showcase apps (finance tracker, habit tracker)
examples/basic.py    minimal CRUD + DB plugin app
bench/            honest benches (bench_switch.py) + sustained-load proof (load.py)
docs/             COOKBOOK.md (20 runnable recipes) · ECOSYSTEM.md (extension registry) ·
                  MIGRATING_FROM_MERAKI.md · DEPLOY.md · PLUGINS.md · PHASE1.md (original spec)
site/             static docs site (no build step) + llms.txt framework manual

Project basics

  • Security: SECURITY.md — supported versions, how to report (GitHub private vulnerability reporting; no public issues for vulns).
  • Contributing: CONTRIBUTING.md — setup, per-PR checks, the five agent laws (zero-dep core, tests, no per-request reflection, fix-saying errors, Conventional Commits).
  • Changelog: CHANGELOG.md — every release cut from Conventional Commits, Keep-a-Changelog format.
  • Versioning (SemVer): 1.x keeps the public API backward-compatible — ikarem/__init__.py exports, ASGI behavior, CLI commands, response shapes. Minor versions add; breaking changes wait for a major.
  • Deprecation policy: removals land only in majors, announced at least one minor earlier via deprecated(since=, removal=, use_instead=) — upgrades warn with the version, the removal target, and the replacement.
  • CI: Python 3.10–3.13 × Ubuntu/macOS/Windows, live Postgres, Docker build, scaffold smoke, ruff lint + format.
api-framework
asgi
authentication
backend-framework
dependency-injection
jwt
mcp
middleware
openapi
postgresql
python
rest-api
sqlite
validation
web-framework
websockets

Languages

Python

81.4%

HTML

12.7%

CSS

5.1%