Skip to main content

onestep

English | 简体中文


onestep is a small async task runtime for queue, polling, schedule, and webhook workloads. You declare a task with a source and optional sink, and the runtime takes care of fetching, concurrency, retries, dead-lettering, and telemetry.

  • One decorator turns any async function into a managed task
  • Pluggable connectors for memory, MySQL, RabbitMQ, Redis, SQS, Kafka, Feishu
  • Scheduling via interval, cron, webhook, or DB-backed queues
  • Production-ready: retries, dead-letter, timeouts, state stores, metrics, and a control-plane reporter
  • Two config styles: plain Python, or declarative YAML
  • Python 3.9+

Quick start

Install:

pip install onestep
# optional extras:
pip install 'onestep[yaml]'          # YAML task definitions
pip install 'onestep[control-plane]' # push telemetry to onestep-control-plane
pip install 'onestep[kafka]'         # Kafka topic source/sink, Python 3.10+

Define an app, then run it with the onestep CLI:

from onestep import IntervalSource, OneStepApp

app = OneStepApp("billing-sync")


@app.task(source=IntervalSource.every(hours=1, immediate=True, overlap="skip"))
async def sync_billing(ctx, _):
    print("syncing billing data")
onestep run your_package.tasks:app
onestep check your_package.tasks:app   # validate the target before starting

What it does

Capability Where
Fetch work from a queue, schedule, webhook, or DB cursor MemoryQueue, IntervalSource, CronSource, WebhookSource, MySQL table_queue / incremental / binlog, RabbitMQ queue, Redis stream, SQS queue, Kafka kafka_topic
Emit results to a downstream sink any source doubles as a sink; MySQL table_sink; Kafka kafka_topic; HTTP http_sink; Feishu Bitable sink
Schedule recurring work IntervalSource.every(...), CronSource(...) with overlap control (allow / skip / queue)
Ingest external events WebhookSource with bearer auth, shared listeners, body parsing
Survive failures retry policies, dead_letter sink, per-task timeout_s, failure classification (error / timeout / cancelled)
Track state InMemoryStateStore, MySQL state/cursor stores; ctx.state namespace per task
Observe @app.on_event hooks, InMemoryMetrics, StructuredEventLogger, execution events
Operate control-plane reporter with remote commands: ping, shutdown, restart, drain, pause_task, resume_task, restart_task, sync_now

Core concepts

The whole runtime is built on four ideas:

  • OneStepApp — task registry and lifecycle manager
  • Source — fetches data from a queue, schedule, webhook, or polling backend
  • Sink — publishes processed results downstream
  • Delivery — a single fetched item exposing ack / retry / fail
from onestep import MemoryQueue, OneStepApp

app = OneStepApp("demo")
source = MemoryQueue("incoming")
sink = MemoryQueue("processed")


@app.task(source=source, emit=sink, concurrency=4)
async def double(ctx, item):
    return {"value": item["value"] * 2}


async def main():
    await source.publish({"value": 21})
    await app.serve()

Connectors

Each backend ships as its own package so you only install what you use:

Package Provides Install
core MemoryQueue, IntervalSource, CronSource, WebhookSource, http_sink, runtime, reporter pip install onestep
MySQL table_queue, incremental, binlog CDC, table_sink, state/cursor stores pip install onestep-mysql
PostgreSQL same primitives as MySQL, backed by PostgreSQL pip install onestep-postgres
RabbitMQ queue with exchange/routing-key binding and prefetch pip install onestep-mq
Redis stream with consumer groups, XACK, XCLAIM, maxlen pip install onestep-redis
SQS queue with batched deletes and heartbeat visibility pip install onestep-sqs
Kafka kafka_topic source/sink with manual offset commits pip install onestep-kafka
Feishu Bitable incremental source and upsert sink pip install onestep-feishu-bitable

Or install everything at once:

pip install 'onestep[all]'

Configuration styles

Plain Python

Best for application code. Each connector is a class you instantiate:

from onestep import OneStepApp
from onestep_redis import RedisConnector

app = OneStepApp("redis-demo")
redis = RedisConnector("redis://localhost:6379")
source = redis.stream("jobs", group="workers", batch_size=100)
out = redis.stream("processed")


@app.task(source=source, emit=out, concurrency=8)
async def process_job(ctx, item):
    return {"job": item["job"], "status": "done"}

YAML

Best for deployment wiring. Keep business logic in Python; describe the runtime — app, resources, hooks, tasks — declaratively.

app:
  name: billing-sync

resources:
  tick:
    type: interval
    minutes: 5
    immediate: true

tasks:
  - name: sync_billing
    source: tick
    handler:
      ref: your_package.handlers.billing:sync_billing
onestep run worker.yaml
onestep check --strict worker.yaml   # schema validation, unknown-field detection
onestep init billing-sync            # scaffold a minimal YAML project

The full YAML schema, resource types, conditional routing, and state binding are covered in docs/yaml-task-definition.md.

Deployment

  • systemd — minimal unit + preflight check template in deploy/
  • Official worker image — run YAML workers in Docker without packaging:
    docker run --rm \
      -e ONESTEP_TARGET=/workspace/worker.yaml \
      -v "$PWD:/workspace" \
      ghcr.io/mic1on/onestep-worker:1.4.7
    
    See deploy/worker-runtime-image.md.
  • Embed in a web app — recommended shape for FastAPI/Django in deploy/web-service-integration.md.

Control plane

onestep can push runtime telemetry (heartbeat, topology, metrics, events) to onestep-control-plane over a single WebSocket and accept remote commands — with no connector or task-code changes.

app:
  name: billing-sync

reporter: true

Required env: ONESTEP_CONTROL_PLANE_URL, ONESTEP_CONTROL_PLANE_TOKEN.

Handlers can report low-cardinality custom counters and gauges through the same reporter. The plane stores them and can expose them from its Prometheus /metrics endpoint:

async def sync_users(ctx, payload):
    success_count = 0
    failed_count = 0
    ...
    ctx.metrics.counter("rows_success").inc(success_count)
    ctx.metrics.counter("rows_failed").inc(failed_count)
    ctx.metrics.gauge("batch_size").set(success_count + failed_count)

For identity, multi-replica guidance, env vars, and a local demo, see docs/stable-instance-identity.md.

Examples

Runnable examples live in example/. Highlights:

# 5-second interval task
SYNC_INTERVAL_SECONDS=5 PYTHONPATH=src onestep run example.cli_app:app

# end-to-end: webhook -> queue -> worker -> dead-letter, with metrics + logs
PYTHONPATH=src python3 example/runtime_showcase.py

Upgrading

1.0.0 was a runtime rewrite. If you're coming from 0.5.x, see MIGRATION-0.5-to-1.0.0.md for the old-to-new API mapping, unsupported features, and rollout guidance.

More

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

onestep-1.4.7.tar.gz (138.3 kB view details)

Uploaded Source

Built Distribution

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

onestep-1.4.7-py3-none-any.whl (84.4 kB view details)

Uploaded Python 3

File details

Details for the file onestep-1.4.7.tar.gz.

File metadata

  • Download URL: onestep-1.4.7.tar.gz
  • Upload date:
  • Size: 138.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for onestep-1.4.7.tar.gz
Algorithm Hash digest
SHA256 85f272b161c214a7e3e49033a2f1c608d6a275a5a66f86eb391a36d4e7c1df94
MD5 33ad14a882d0a39f0143836932ca2c41
BLAKE2b-256 efb39be9774d70b849d4b691c38f8eed5506ed434945e8739ff3c49c907ffd58

See more details on using hashes here.

Provenance

The following attestation bundles were made for onestep-1.4.7.tar.gz:

Publisher: release.yml on mic1on/onestep

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file onestep-1.4.7-py3-none-any.whl.

File metadata

  • Download URL: onestep-1.4.7-py3-none-any.whl
  • Upload date:
  • Size: 84.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for onestep-1.4.7-py3-none-any.whl
Algorithm Hash digest
SHA256 802d412a4226040d5b2f1ccf5465a4103806aad3a3845c694701f14db9153aad
MD5 eb5c7d2624481ab9ada2b61067f79d76
BLAKE2b-256 11ad3f323557f33db764f5d3f1d7764e610d0a2a2560c53effbd1ff1afd9e516

See more details on using hashes here.

Provenance

The following attestation bundles were made for onestep-1.4.7-py3-none-any.whl:

Publisher: release.yml on mic1on/onestep

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

Supported by

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