Skip to main content

Config-driven microservice framework with WebSocket, SQLite, and expression language

Project description

mkio

Config-driven microservice framework for Python. Define your schema, services, and data flows in a TOML file — zero coding required for standard configurations.

A single TCP port serves HTTP and WebSocket, backed by an embedded SQLite database. Designed for restricted environments where runtime downloads aren't possible — everything installs via pip.

Quick Start

pip install mkio

Create mkio.toml:

port = 8080

[tables.orders]
columns = { id = "TEXT PRIMARY KEY", symbol = "TEXT NOT NULL", qty = "INTEGER", status = "TEXT DEFAULT 'pending'" }

[services.add_order]
type = "transaction"
table = "orders"
op_type = "insert"
fields = ["id", "symbol", "qty"]

[services.all_orders]
type = "query"
primary_table = "orders"
filterable = ["status", "symbol"]

[static]
"/" = "./static"

Run:

mkio serve

Or programmatically:

from mkio import serve
serve("mkio.toml")
serve({...})  # or pass a dict

Features

  • Single port — HTTP pages and WebSocket messages on one port
  • Config-driven — define tables, transactions, and live data services in TOML
  • Transaction services — insert, update, delete, upsert across multiple tables atomically
  • SubPub — in-memory cache with live push to subscribers, client-side filtering, server-side where and publish formatting
  • Stream — append-only ring buffer with cursor-based reconnection
  • Query — snapshot + change feed from SQLite
  • Expression language — safe, extensible filter and formatter expressions (qty > 100 AND status == 'pending')
  • Schema migration — automatic detection of safe/destructive changes with interactive confirmation
  • Write batching — hundreds of writes committed in a single SQLite transaction for high throughput
  • Reconnection recovery — ref-based delta sync across all service types, persisted across server restarts via _mkio_ref column
  • Client libraries — Python and JavaScript clients with auto-reconnect and ref tracking
  • Graceful shutdown — drains pending writes, checkpoints WAL, clean close
  • Service monitoring — tap into any service's inbound/outbound message flow via CLI or WebSocket
  • Service discoveryGET /api/services list and GET /api/services/<name> detail endpoints, mkio services CLI
  • CLI tools — send transactions, subscribe to live data, monitor traffic, inspect services

Service Types

Transaction

Execute INSERT, UPDATE, DELETE, or UPSERT operations. Supports multi-table atomic transactions with named ops and cross-op bind references.

[services.orders]
type = "transaction"

[services.orders.ops]
new = [
    { table = "orders", op_type = "insert", fields = ["side", "symbol", "qty", "price"] },
    { table = "audit_log", op_type = "insert", defaults = { event = "new" }, bind = { order_id = "$0.id", status = "$0.status" } },
]
accept = [
    { table = "orders", op_type = "update", key = ["id"], fields = ["status"], defaults = { status = "accepted" } },
    { table = "audit_log", op_type = "insert", defaults = { event = "accepted" }, bind = { order_id = "$0.id", status = "$0.status" } },
]

Bind references ($0.id) pull values from a prior op's RETURNING row. Op-level defaults provide static values the client doesn't need to send — here, event and status are set automatically per operation.

SubPub

Subscribe to get a snapshot from an in-memory cache, then receive live updates as data changes. Supports client filters, server-side where filtering (rows that don't match are never cached or published), and publish formatting with expressions including IF(cond, then, else).

[services.last_trade]
type = "subpub"
primary_table = "orders"
key = "symbol"
where = "status == 'filled'"
change_log_size = 10000

[services.last_trade.publish]
symbol = "symbol"
price = "IF(side == 'Buy', price, -price)"

Stream

Append-only data with ring buffer and ref-based cursor reconnection.

[services.audit_feed]
type = "stream"
primary_table = "audit_log"
buffer_size = 10000

Query

Snapshot from SQLite with change feed. Supports delta reconnection.

[services.all_orders]
type = "query"
primary_table = "orders"
filterable = ["status"]

WebSocket Protocol

Connect to /ws (general) or /ws/{service_name} (per-service).

// Transaction
{"service": "add_order", "ref": "...", "data": {"id": "1", "symbol": "AAPL", "qty": 100}}

// Named op transaction
{"service": "orders", "ref": "...", "op": "new", "data": {"side": "Buy", "symbol": "AAPL", "qty": 100, "price": 150}}

// Transaction with msgid (echoed back on result/error for async correlation)
{"service": "orders", "ref": "...", "op": "new", "msgid": "req-42", "data": {"side": "Buy", "symbol": "AAPL", "qty": 100, "price": 150}}

// Subscribe
{"service": "all_orders", "type": "subscribe", "filter": "status == 'pending'"}

// Reconnect with ref (resumes from last seen position)
{"service": "audit_feed", "type": "subscribe", "ref": "20260404 15:30:45.123456000000"}

Client Libraries

Python

from mkio.client import MkioClient

async with MkioClient("ws://localhost:8080/ws") as client:
    result = await client.send("add_order", {"id": "1", "symbol": "AAPL", "qty": 100})

    async for msg in client.subscribe("all_orders", filter="status == 'pending'"):
        print(msg)
        # msg["ref"] tracks position for recovery on reconnect

JavaScript

Auto-served at /mkio.js — no CDN or bundler needed.

<script src="/mkio.js"></script>
<script>
const client = new MkioClient("ws://localhost:8080/ws");
await client.connect();

client.subscribe("all_orders", {
    filter: "status == 'pending'",
    onSnapshot: (rows) => renderTable(rows),
    onUpdate: (op, row) => updateRow(op, row),
});
</script>

Expression Language

Used for client filters, server-side where filters, and publish formatters.

Category Syntax
Comparison ==, !=, >, <, >=, <=
Logical AND, OR, NOT
Arithmetic +, -, *, /
String CONTAINS, STARTS_WITH
Null IS NULL, IS NOT NULL
Functions UPPER(), LOWER(), ROUND(), ABS(), COALESCE(), IF(cond, then, else)

Extend with custom functions:

from mkio import register_function

register_function("MASK_PAN", lambda s: "****" + s[-4:])

Performance

  • Write batching — collects writes over a 2ms window, commits as single SQLite transaction with per-request SAVEPOINTs
  • WAL mode — dual connections (write + read) for concurrent reads during writes
  • Zero-copy fan-out — change events serialized once, same bytes sent to all subscribers
  • Optional accelerationpip install mkio[fast] for orjson (5-10x JSON) and uvloop (2-4x I/O)

CLI Tools

List and inspect services

mkio services http://localhost:8080                # List all services
mkio services http://localhost:8080 orders         # Show detail for one service

Detail view shows fields, types, required/optional, auto-generated columns, and example commands.

Send transactions

mkio send http://localhost:8080 orders --op new '{"side":"Buy","symbol":"AAPL","qty":100,"price":150}'
mkio send http://localhost:8080 orders --op new orders.json    # From JSON file
mkio send http://localhost:8080 orders --op new orders.csv     # From CSV file
mkio send http://localhost:8080 orders mixed.csv                 # CSV with per-row op column

Subscribe to live data

mkio subscribe http://localhost:8080 all_orders
mkio subscribe http://localhost:8080 all_orders --filter "status == 'pending'"
mkio subscribe http://localhost:8080 all_orders --ref "20260404 15:30:45.123456000000"  # Resume from ref

Monitor a service

Tap into a service's inbound and outbound message flow in real time:

mkio monitor http://localhost:8080 last_trade
[15:30:45.123] >> IN  subscribe
{ "type": "subscribe", "service": "last_trade" }

[15:30:45.125] << OUT snapshot
{ "type": "snapshot", "rows": [...] }

The monitor protocol is a native framework feature — any mkio application supports it.

Using mkio from a Claude-Based Project

mkio ships agent-facing docs inside the package for AI-assisted integration. Three files in src/mkio/agents/:

  • AGENTS.md — protocol, refs, discovery, service types (always needed)
  • AGENTS.python.md — Python client API + worked example
  • AGENTS.js.md — JS client API + worked example

Option A: Reference in your project's CLAUDE.md

# Python-only consumer
@/path/to/mkio/src/mkio/agents/AGENTS.md
@/path/to/mkio/src/mkio/agents/AGENTS.python.md

# JS-only consumer
@/path/to/mkio/src/mkio/agents/AGENTS.md
@/path/to/mkio/src/mkio/agents/AGENTS.js.md

# Both
@/path/to/mkio/src/mkio/agents/AGENTS.md
@/path/to/mkio/src/mkio/agents/AGENTS.python.md
@/path/to/mkio/src/mkio/agents/AGENTS.js.md

To find the installed path: python -c "import mkio, os; print(os.path.join(os.path.dirname(mkio.__file__), 'agents'))"

Option B: Install the Claude Code skill

cp -r <mkio-checkout>/skills/mkio ~/.claude/skills/

The skill auto-triggers on mkio-related work and reads the agent docs from the installed package.

Runtime service discovery

A stdlib-only helper fetches service descriptors as LLM-friendly JSON:

python -m mkio.skill_helpers.discover http://localhost:8080           # list services
python -m mkio.skill_helpers.discover http://localhost:8080 orders    # full descriptor

Schema Migration

When the config schema changes between restarts, mkio detects and classifies each difference:

  • Safe (new table, nullable column) — applied automatically
  • Potentially destructive (type change, PK change) — requires confirmation
  • Destructive (remove column/table) — requires confirmation

Set auto_migrate = true in config for non-interactive environments.

License

Apache-2.0

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

mkio-0.1.2.tar.gz (73.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mkio-0.1.2-py3-none-any.whl (63.4 kB view details)

Uploaded Python 3

File details

Details for the file mkio-0.1.2.tar.gz.

File metadata

  • Download URL: mkio-0.1.2.tar.gz
  • Upload date:
  • Size: 73.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mkio-0.1.2.tar.gz
Algorithm Hash digest
SHA256 528877be72ede47b5ad91ee4b7731aa8efa9e4db1c0c59ae5d89d697f2fda332
MD5 93425dc9f8fac98ae9a21996b8ddcfba
BLAKE2b-256 5e53b3333ae90889c1174145460163c56aaf0e997e238f925106f5c1934c247b

See more details on using hashes here.

File details

Details for the file mkio-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: mkio-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 63.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mkio-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1af5b496edcebcee5502d8215535d07a0d7737349537851d3290197b6d2ca9dd
MD5 ef1ba0a47ab692130cc18d21be8efc46
BLAKE2b-256 b0e6b019a8d688f8337d7a8d7212c2f5e3b4406f9644a1fe4bc878356f131acc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page