Skip to main content

Axon Logo

PyPI Python 3.11+ Apache-2.0 License Chinese README

Axon is a small, extensible framework for defining, discovering, and running ordered flows. Each flow combines a strict Pydantic configuration, Python callables executed in order, a shared runtime context, and declared outputs. Applications install their flows as providers and expose them through the same axon command.

The distribution is named axonx; the Python package and command are both named axon.

Framework at a glance

Layer Contract Responsibility
Configuration BaseConfig Validates typed inputs with unknown fields forbidden.
Flow BaseFlow Owns configuration, logger, shared context, steps, and outputs.
Step Callable[[], None] Performs one unit of work and reads or updates the flow context.
Registry @register("name") Maps a normalized action name to one flow class.
Discovery axon.flows entry points Imports installed provider modules so registration runs.
Runtime axon --action --field value Parses inputs, validates configuration, executes steps, and emits JSON.

Axon deliberately keeps orchestration close to Python. A concrete list builds a fixed sequence; a generator can use normal if, for, and yield from control flow to decide later steps after earlier steps update the context. There is no separate workflow DSL or scheduler.

Installation

Axon requires Python 3.11 or newer.

python -m pip install axonx

For framework development:

git clone https://github.com/FlowLLM-AI/Axon.git
cd Axon/packages
python -m pip install -e ".[dev]"

Quick start

The framework includes a small demo flow:

axon --list
axon --demo --x 1 --y 2

The successful result is written to stdout as JSON:

{"result": 3}

Every configuration argument is a --field value pair, including booleans. Hyphens in action and field names are normalized to underscores. Unknown fields, duplicate fields, missing values, malformed values, and unknown actions fail before flow execution.

Define a flow

Subclass BaseConfig for inputs and BaseFlow for orchestration. Annotating config lets Axon infer the configuration class. build_steps() returns or yields zero-argument callables, while output_keys declares which context values must exist after execution.

from collections.abc import Iterable

from axon.cli import BaseConfig, BaseFlow, Step, register


class GreetConfig(BaseConfig):
    name: str
    times: int = 1


@register("greet")
class GreetFlow(BaseFlow):
    config: GreetConfig
    output_keys = ("message",)

    def build_steps(self) -> Iterable[Step]:
        yield self.build_message

    def build_message(self) -> None:
        self.context["message"] = " ".join([f"hello {self.config.name}"] * self.config.times)

Import the module containing the class, then run:

axon --greet --name Axon --times 2
{"message": "hello Axon hello Axon"}

The execution contract is intentionally small:

Element Rule
config annotation Must resolve to a BaseConfig subclass.
build_steps() Returns an iterable of zero-argument callables in execution order.
self.context Starts with constructor keyword arguments and carries state between steps.
output_keys Names required context keys and preserves their declared order in the result.
execute() Runs every yielded step, then raises if any declared output is missing.

Dynamic orchestration uses ordinary Python:

Pattern Expression
Task yield self.step
Sequence yield from self.build_subsequence()
Conditional Use if while lazily yielding steps.
For each Loop and yield a zero-argument callable; use functools.partial to bind arguments.

Because a generator resumes between steps, conditions placed after a yield can observe context written by the previous step.

Publish a flow provider

An external package exposes its flows through the axon.flows entry-point group. For example, this repository's pyproject.toml connects axon-core to the framework with:

[project.entry-points."axon.flows"]
default = "core.default"

Axon imports core.default, whose package initialization imports the modules containing @register(...). After the provider is installed, its flows appear automatically:

axon --list

Built-in flows

This table describes flows shipped by axonx. Provider packages should document their own flows in the same format, making the catalog easy to extend as new flows are added.

Flow Config Inputs Output Purpose
demo DemoConfig x: int, y: int result Demonstrates task, sequence, conditional, and loop-based step generation by adding two integers.

Utilities

The supported helpers are exported from axon.utils. Add one row when a new public utility is introduced so this table remains the compact public catalog.

Utility Signature Configuration Behavior
load_env load_env(path=None, *, override=True) -> dict[str, str] Optional file path Loads an explicit file or the nearest .env in the working directory or first five parents. Returns only values written to the environment.
get_logger get_logger() AXON_LOG_DIR Lazily creates the shared Loguru INFO logger with stderr and daily rotating file sinks; file retention is seven days.
send_dingtalk_message send_dingtalk_message(title, text, msgtype="markdown", timeout=10.0) -> str DINGTALK_CLIENT_ID, DINGTALK_CLIENT_SECRET, DINGTALK_CONVERSATIONS Sends Markdown or text through a DingTalk application robot to every configured, deduplicated conversation.

DINGTALK_CONVERSATIONS must be a JSON object whose non-empty names map to non-empty conversation IDs, for example {"research":"cidxxx","operations":"cidyyy"}. Credentials and group IDs are omitted from transport errors. Network calls occur only when send_dingtalk_message() is invoked.

Environment variables

Axon calls load_env() before CLI provider discovery, allowing provider imports to resolve environment-based defaults.

Variable Used by Default Purpose
AXON_LOG_DIR Shared logger logs Directory for timestamped process log files.
DINGTALK_CLIENT_ID DingTalk helper Required on use Application key and robot code.
DINGTALK_CLIENT_SECRET DingTalk helper Required on use Application secret used to obtain an access token.
DINGTALK_CONVERSATIONS DingTalk helper Required on use JSON object mapping names to group conversation IDs.

Provider-specific variables belong in the provider's documentation rather than the framework package.

Package layout

Path Contents
axon/cli.py Configuration and flow bases, registry, provider discovery, argument parsing, execution, and CLI.
axon/flows/ Built-in flows; importing the package registers them.
axon/utils/ Environment, logging, and notification helpers.
tests/ Fast tests using temporary files and mocked network boundaries.

Development

python -m pytest -v --tb=long
pre-commit run --all-files
python -m build

Keep provider-specific business logic outside the framework. A provider may depend on axonx; axonx must not depend on that provider.

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Download files

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

Source Distribution

axonx-0.0.1.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

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

axonx-0.0.1-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file axonx-0.0.1.tar.gz.

File metadata

  • Download URL: axonx-0.0.1.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for axonx-0.0.1.tar.gz
Algorithm Hash digest
SHA256 64bc73e85d4355d2045d8b608ba4466d3a52b704c1f22f810df3a6aeb042e422
MD5 330fa1f44b311da9507612c1afe2f941
BLAKE2b-256 0454b2e7ed3288573523e6d6bda095721d2afe698590899ce20d186cbef7c712

See more details on using hashes here.

File details

Details for the file axonx-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: axonx-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 17.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for axonx-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c265ef1410d62b380e94a8b58990459e624dddaed05b40294995d6882bb5f08d
MD5 7fc83ed7870a970454ab9b49749c4c36
BLAKE2b-256 f055383ae980cadc7789e7502356541870794c52725a6114a1a6ccaf86860943

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 Sentry Error logging StatusPage Status page