Skip to main content

astage

PyPI version Python versions

Initial MVP for Async actor model library for Python

Currently zero external dependencies outside of the Python standard library.

Features:

  • Concurrent actor model with asyncio
  • Maps message types to handler methods on the actor
  • Type hints on ask and tell methods on handler
  • Tell and ask methods for sending messages to the actor
  • Allows setting backpressure on the actor mailbox

Installation

The library is available on PyPI and can be installed with for example pip or uv.

With pip:

pip install astage

or uv

uv add astage

Example

import asyncio
from dataclasses import dataclass
from astage import Actor, handler

@dataclass
class IncrementMessage:
    value: int

@dataclass
class EchoMessage:
    text: str

CounterActorMsg = IncrementMessage | EchoMessage

# The type hints to the actor class enables type hints on the handlers ask and tell methods
# All message types the actor has handlers for should be specified
class CounterActor(Actor[CounterActorMsg]):
    def __init__(self):
        super().__init__()
        self.count = 0

    @handler
    async def increment(self, message: IncrementMessage):
        self.count += message.value
        print(f"Count is now: {self.count}")

    @handler
    async def echo(self, message: EchoMessage):
        return f"Echo: {message.text}"

async def main():
    actor = CounterActor()

    # start the actor which will run in a non-blocking asyncio.Task
    handle = await actor.start()

    # tell: send a message without waiting for a response
    await handle.tell(IncrementMessage(5))
    # Expected: Count is now: 5
    await handle.tell(IncrementMessage(5))
    # Expected: Count is now: 10

    # ask: send a message and wait for a response
    result = await handle.ask(EchoMessage("Hello, Actor!"))
    print(result)  # Expected: Echo: Hello, Actor!

    # it is possible to use tell and ask on all @handler methods
    # the return value of the ask will be the return value of the handler
    response = await handle.ask(IncrementMessage(5))
    print(response)  # Expected: None

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

The message types also works with Pydantic classes, although Pydantic is not a dependency of the library.

import asyncio
from pydantic import BaseModel
from astage import Actor, handler

class IncrementMessage(BaseModel):
    value: int

class CounterActor(Actor[IncrementMessage]):
    def __init__(self):
        super().__init__()
        self.count = 0

    @handler
    async def increment(self, message: IncrementMessage):
        self.count += message.value
        return f"Count is now {self.count}"

async def main():
    actor = CounterActor()
    handle = await actor.start()
    
    # create a message using a Pydantic class
    pydantic_msg = IncrementMessage(value=10)

    # ask: send a message and await a response
    result = await handle.ask(pydantic_msg)
    print(result)  # Expected: Count is now 10

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

Metadata

Release files for astage 0.1.1

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

Source distribution (sdist)

Source distribution for astage 0.1.1
File Size Uploaded
astage-0.1.1.tar.gz 12.9 kB Details

Built distribution (wheel)

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

Total release size: 19.4 kB

Release files / astage-0.1.1.tar.gz

Download URL astage-0.1.1.tar.gz
Size 12.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0753bd1be907dfc1ce4099948f2c8f628b3960662c887526975e720afe95f7b6
BLAKE2b-256 checksum
How to use checksums
cd64e447bef30364a876dc50d8f5f848aa5257f3889983c79b63d7e64a00ea2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.5.30

Release files / astage-0.1.1-py3-none-any.whl

Download URL astage-0.1.1-py3-none-any.whl
Size 6.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6c0e75dc5c78223d1a66af6cb75231c00dc326facf1b7c5102ccdf3b159b0b58
BLAKE2b-256 checksum
How to use checksums
027e69d08167a03af566a90103a8fe2c77e8b02a744956ad9cefeaa1f721ca35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.5.30

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

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