Async model actor library
Project description
astage
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())
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file astage-0.1.1.tar.gz.
File metadata
- Download URL: astage-0.1.1.tar.gz
- Upload date:
- Size: 12.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.5.30
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0753bd1be907dfc1ce4099948f2c8f628b3960662c887526975e720afe95f7b6
|
|
| MD5 |
410567fd86eccb2383784bdae974c7af
|
|
| BLAKE2b-256 |
cd64e447bef30364a876dc50d8f5f848aa5257f3889983c79b63d7e64a00ea2d
|
File details
Details for the file astage-0.1.1-py3-none-any.whl.
File metadata
- Download URL: astage-0.1.1-py3-none-any.whl
- Upload date:
- Size: 6.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.5.30
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c0e75dc5c78223d1a66af6cb75231c00dc326facf1b7c5102ccdf3b159b0b58
|
|
| MD5 |
2ac8275979566e47e62e4c9aecc4edf3
|
|
| BLAKE2b-256 |
027e69d08167a03af566a90103a8fe2c77e8b02a744956ad9cefeaa1f721ca35
|