Skip to main content

Actio Project

Pure Python actor system for building concurrent and distributed applications with async/await support.

Features

Async/await native - Built on Python 3.11+ asyncio

Hierarchical actors - Parent-child relationships with supervision

Message routing - Path-based message delivery between actors

Lifecycle management - Started/receive/stopped hooks with error handling

Type safe - Full type annotations with Pylance/MyPy support

Quick Start

# test_standalone.py
# -*- coding: utf-8 -*-
"""Standalone mode test for actio library."""

import asyncio
import logging

from actio import Actor
from actio import ActorSystem
from actio import actio
from actio import ActorRef
from actio.registry import flush_pending_definitions
from actio.registry import get_default_registry

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)

log = logging.getLogger("test_standalone")


@actio(name="TestActor", parent=None, replicas=1)
class TestActor(Actor):
    """Test root actor."""

    def __init__(self) -> None:
        super().__init__()
        self.message_count: int = 0

    async def started(self) -> None:
        log.info(f"✅ {self.name} started")

    async def receive(
        self,
        sender: ActorRef,
        message: any
    ) -> None:
        self.message_count += 1
        log.info(f"📨 {self.name} received #{self.message_count}: {message}")

        if isinstance(message, dict) and message.get("action") == "ping":
            # ✅ Проверка на None sender
            if sender is not None:
                self.tell(sender, {"action": "pong", "count": self.message_count})

    async def stopped(self) -> None:
        log.info(f"🛑 {self.name} stopped")

@actio(name="ChildActor", parent="TestActor", dynamic=True)
class ChildActor(Actor):
    """Test dynamic child actor."""

    async def started(self) -> None:
        log.info(f"✅ {self.name} started")

    async def receive(
        self,
        sender: ActorRef,
        message: any
    ) -> None:
        log.info(f"📨 {self.name} received: {message}")

    async def stopped(self) -> None:
        log.info(f"🛑 {self.name} stopped")


async def main() -> None:
    """Main test function."""
    log.info("🚀 Starting standalone test...")
    registry = get_default_registry()

    await flush_pending_definitions(registry)

    system = ActorSystem(registry=registry)

    await registry.build_actor_tree(system, timeout=5.0)
    root_ref = system.get_actor_ref_by_name("TestActor")
    if not root_ref:
        log.error("Failed to get TestActor reference")
        log.error(f"Available actors: {list(registry._definitions.keys())}")
        return

    log.info(f"Root actor created: {root_ref.path}")

    system.tell(root_ref, {"action": "ping"})
    system.tell(root_ref, {"action": "test", "data": "hello"})

    root_instance = system.get_actor_instance(root_ref)
    if root_instance:
        child_ref = await root_instance.create(ChildActor(), name="Child-1")
        log.info(f"✅ Child actor created: {child_ref.path}")

        system.tell(child_ref, {"action": "child_message"})

    await asyncio.sleep(1.0)

    registry.print_actor_tree()
    log.info("🛑 Shutting down...")
    await system.shutdown(timeout=5.0)

    log.info("✅ Standalone test complete!")


if __name__ == "__main__":
    asyncio.run(main())

License

MIT License - see LICENSE file for details.

Metadata

Release files for actio 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for actio 0.1.6
File Size Uploaded Provenance
actio-0.1.6.tar.gz 31.6 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 70.3 kB

Release files / actio-0.1.6.tar.gz

Download URL actio-0.1.6.tar.gz
Size 31.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bdace75f298364f783695be24c8ff9019eaad200a561f3e1008459e18d15cd24
BLAKE2b-256 checksum
How to use checksums
e715610964dc33f646a8b6ac7482351b5e20149db8a458f307349e635d65cc8f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / actio-0.1.6-py3-none-any.whl

Download URL actio-0.1.6-py3-none-any.whl
Size 38.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b807aa314e13820ad2347742fd16a636b1447bb2ee6727dca919152fd42dd31
BLAKE2b-256 checksum
How to use checksums
e96212c07180dfb211f4736cd53289dedab2113cfd89e86217400ecc3a0775a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Security for actio 0.1.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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