Skip to main content

Part of the Kontiki suite — Python runtime, registry, terminal UI, and fleet monitoring for distributed services.

Full suite overview → https://kontiki-org.github.io/

Ops demo → kontiki-monitor Quickstart.


Overview

Kontiki is a Python runtime for distributed services on RabbitMQ. You write @http, @rpc, @on_event, and @task. The decorators are the visible API; most of the leverage sits one layer deeper — identity, routing, delivery, fleet health, configuration, and testing. You express intentions in Kontiki terms, not broker topology by hand.

This repository is the runtime. Together with the registry, KontikiTUI, and kontiki-monitor, every Python workload — API, worker, cron job, ops service — is the same operable, testable, and observable unit.

Most applications don't need the full depth of a specialized ops stack. Kontiki takes the commonly useful part and aims to integrate it into the same service model, instead of giving you another platform to assemble and tune.

Why conventions

Services should differ primarily because of what they do, not because each one introduces another way of being built and operated.

  • An ops job fails months later: find the service in KontikiTUI instead of rediscovering its crontab, script, and log file.
  • A request failed after crossing several services: follow its flow_id tree in KontikiTUI instead of correlating timestamps across logs by hand.
  • Adding a new service — including a monitor: identity, configuration, lifecycle, logging, health, and failure reporting already follow the same conventions.

What Kontiki is not

Kontiki does not aim for maximum infrastructure choice. It is intentionally Python-first, RabbitMQ-based, and convention-driven. It does not abstract every broker, become a language-neutral platform, replace orchestration, or reproduce a tracing, long-term metrics, or IAM product. Those can coexist outside the common model; they are not the default for everyday needs.

Runtime

  • One model from dev to production: merged YAML config, cli.run, and the same entrypoint decorators in tests (kontiki.testing mocks on the bus) and in production.
  • Design interactions as messages: RPC for request/reply; events for async work. On @on_event, delivery is explicit — default (one instance per message, competing consumers), broadcast=True (every instance), in_session=True (one pinned instance via a session).
  • Route by event_type: the event name is the routing contract; deployment identity (kontiki.service_name, kontiki.peers) and environment-specific names live in config, not in code.
  • Fleet registry: heartbeats, degraded state (degraded_on), exception tracking, live instance ids (list_instances / GET /instances/{service_name}), and orchestrator live probes (GET /live/{service_name}). The bus runs without a registry; operating the fleet coherently assumes one.
  • Integrated operations: browse the fleet in KontikiTUI, alert from registry signals with kontiki-monitor.

For gotchas, controlled failures (rpc_error), and patterns beyond this overview, see docs/advanced-features.md. For a feature-by-feature reference, see docs/features.md.

Mental model (short)

Need Reach for
Sync API @http / @rpc
Async reaction @on_event
Time-driven work @task
One instance handles an event default @on_event (competing consumers)
Every instance handles it @on_event(..., broadcast=True)
One pinned instance @on_event(..., in_session=True) + open_session
RPC to one process call(..., instance_id=) / RpcProxy(..., instance_id=)
Route an event explicit event_type
Caller target from deploy config RpcProxy(..., peer="…") / open_session(peer="…") → kontiki.peers
Fleet health registry + degraded_on
Cross-service debug flow_id → KontikiTUI Flows (tree, exception, export)
Tests on the bus kontiki.testing
Gateway into Kontiki from FastAPI, etc. standalone Messenger

Kontiki suite

Kontiki is not only this runtime. The suite shares the same process model, registry, and terminal UI:

Component Role
Kontiki (this repo) Service runtime — entrypoints, messaging, registry client, config, testing
kontiki-tui Terminal UI over the registry and local logs — browse services, flows, and exceptions
kontiki-monitor Fleet checks, registry signals, and host disk alerts

When services register with the Kontiki registry, KontikiTUI gives a live picture of the fleet from the terminal:

KontikiTUI — services overview

Quickstart

Install Kontiki (via pip or Poetry):

pip install kontiki

Define a simple service. The service class wires entrypoints; a delegate holds business logic (recommended pattern — see docs/features.md):

from kontiki.delegate import ServiceDelegate
from kontiki.messaging import Messenger, on_event, rpc
from kontiki.runner import cli


class MyDelegate(ServiceDelegate):
    async def setup(self):
        pass  # optional: init from self.container.config

    def process(self, payload):
        return {"processed": payload}


class MyService:
    name = "compute-api"  # optional: overridden by kontiki.service_name in config
    delegate = MyDelegate()
    messenger = Messenger()

    @rpc
    async def compute(self, x):
        return self.delegate.process(x)

    @on_event("example.thing.happened")
    async def on_thing(self, payload):
        result = self.delegate.process(payload)
        await self.messenger.publish("example.thing.processed", result)


def run():
    cli.run(MyService, "Example Kontiki service.", version="0.1.0")

Expose it as a CLI command in pyproject.toml:

[tool.poetry.scripts]
my_service = "myapp.main:run"

Run your service:

my_service --config config.yaml

RPC plus a chained event — the shape most meshes grow from. In production, peers resolve from config (kontiki.peers), delivery modes are set on handlers, and the registry tracks the fleet. See examples/events/broadcast/, examples/events/session/, and examples/registry/.


Testing a service in isolation

kontiki.testing lets you exercise one service on the bus without running its peers. The usual form is a Gherkin feature: an executable spec of the service boundary.

The feature shows the timeline — config and initial state, incoming events or RPC, calls to peers and their controlled responses, published events, return values, state changes. That sequence stays in the .feature, not in Python fixtures.

From Boomerang's subscription-service: the service starts from its config, an RPC comes in, matching recipients come out.

Scenario: Return matching recipient for exact area and category
  Given the subscription service is running with the following configuration
    """
    kontiki:
      amqp:
        url: amqp://guest:guest@localhost/
      http:
        address: 127.0.0.1
        port: 8000
    logging:
      directory: logs
      handlers:
        file:
          class: logging.handlers.RotatingFileHandler
          level: INFO
          maxBytes: 10485760
          backupCount: 5
      root:
        handlers: [file]
        level: INFO
    app:
      subscriptions:
        wind-fr69:
          category: weather.wind
          event_type: "*"
          criteria:
            - key: area.zone
              operator: eq
              value: FR-69
          endpoints:
            - email.email_primary
    """
  When I call the RPC get_recipients_for_alert on the subscription service with the following arguments
    """
    {
      "alert": {
        "schema_version": "1.0",
        "alert_id": "wx_wind_fr69",
        "source": "test",
        "category": "weather.wind",
        "event_type": "hail",
        "severity": "moderate",
        "occurred_at": "2026-01-15T12:00:00Z",
        "title": "Wind warning",
        "body": "Strong winds expected in FR-69.",
        "areas": [
          {"type": "zone", "value": "FR-69"}
        ],
        "attributes": {}
      }
    }
    """
  Then the RPC response is
    """
    [
      {
        "channel": "email",
        "endpoint_key": "email_primary"
      }
    ]
    """

Mocks, controlled return values, and message capture live in kontiki.testing; Behave steps drive them. The feature is the behavioural source of truth. Steps execute it; they should not invent behaviour missing from it.

See docs/features.md (Testing) and tests/integration/.


Documentation

  • Features: docs/features.md
  • Advanced features (patterns & gotchas): docs/advanced-features.md
  • Configuration reference: docs/configuration.md
  • Example configuration: docs/kontiki-config.example.yaml
  • Contributing guidelines: CONTRIBUTING.md
  • License: LICENSE

Kontiki requires RabbitMQ ≥ 4.3 (for V2.0+ features like quorum queues). You do not declare exchanges or queues yourself — decorators and config declare the topology. To start a broker locally:

make run-amqp

Examples

Examples can be run via the Makefile (see targets such as run-rpc-service, run-rpc-example, run-rpc-instance-example, run-simple-events-service, run-task-service, etc.). Shared logging is examples/common.yaml: console StreamHandler, default Kontiki formatter (omit formatters in YAML).

Feature Example path
Basic RPC examples/rpc/
Targeted RPC examples/rpc/
Simple events examples/events/simple/
Broadcast events examples/events/broadcast/
Event serialization examples/events/serialization/
Session-based events examples/events/session/
Periodic tasks (interval and cron) examples/task/
Service registry (admin + client) examples/registry/
Heartbeats & degraded mode examples/heartbeat/
HTTP entrypoints examples/http/simple/

Misc

Kontiki did not come out of a naming workshop but from the album Kontiki by the band Cotton Mather. If you enjoy vintage 4-track indie pop as much as microservices, you should check it out.

Metadata

Release files for kontiki 2.1.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 kontiki 2.1.0
File Size Uploaded
kontiki-2.1.0.tar.gz 52.2 kB Details

Built distribution (wheel)

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

Total release size: 121.0 kB

Release files / kontiki-2.1.0.tar.gz

Download URL kontiki-2.1.0.tar.gz
Size 52.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b65717206e59d808f63b0aa47207f4c1d05eae884cae95ebfd73317fe4eaaddd
BLAKE2b-256 checksum
How to use checksums
aacf03ac5753ce664805591c9be6e7a3fc21135f49b65844c452c06a0166c7fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.13.7 Linux/6.8.0-142-generic

Release files / kontiki-2.1.0-py3-none-any.whl

Download URL kontiki-2.1.0-py3-none-any.whl
Size 68.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
52712f8fc8c3cc8d3e507932372ddba214f1046a34ea314e331db131195ba2cd
BLAKE2b-256 checksum
How to use checksums
2f7860a27a67cfd0f6ec40004d41605464885efb1fcf985a301cfd4a56786b42
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.13.7 Linux/6.8.0-142-generic

Release history Release notifications | RSS feed

2.3.2

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.0

2 release files

This release

2.1.0 This release

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.16.0

2 release files

1.15.0

2 release files

1.14.0

2 release files

1.13.0

2 release files

1.12.0

2 release files

1.11.1

2 release files

1.9.0

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.1

2 release files

1.7.0

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

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