An asynchronous helper framework for writing custom event wrapper class functions made with good typehinting that is based off aiosignal with better modifications added for better typehinting and easier usage with tools such as pyright or mypy allowing for arguments to be properly typehinted at when performing any created callback wich ultimately means less confusion and more action.
One of my biggest pet peves of all time is when static type-checkers don't pick up what functions parameters are being used. This library aims to fix static typecheckers when send() functions are being used, so that developers aren't second guessing what different paremeters are needed. This is a big advantage over aiosignal and was the main reson behind it's creation.
Aiocallback should be used when dealing with creating custom context objects or callbacks. An example might be scraping an api by a given hour and calling for that data that can be defined by multiple functions. However, there are many more creative ways to use this library.
- frozenlist we dropped aiosignal in favor of it's subclass since it's not deprecated and aiosignal's code was tiny enough to copy on over to our side and then start making improvements upon it's original work.
- typing-extensions Typehinting for Python 3.9, plan to drop typing-extensions when 3.9 hits End of Life so that ParamSpec can be utilized to it's fullest potential.
The easiest way is to install aiocallback is from PyPI using pip:
pip install aiocallback
First, import the library.
from aiocallback import event, subclassevent, contextevent
import asyncio
class Config:
"""an example of configuring callbacks"""
# NOTE: Typehinting will be passed to other objects
# Thanks in largepart to ParamSpec and Concatenate
# NOTE: @event considers the function to be an abstract method, However you can use a subclassevent to retain typechecking if you need something that isn't so abstract
@event
async def on_print(self, cb:str):
"""callbacks for a print method"""
@subclassevent
async def on_nonabstract(self, cb:str):
"""a nonabstract method can be called with other events as being part of the signal"""
print(f"I am callable! \"{cb}\"")
cfg = Config()
# You can also call the append method just like with aiosignal as ours is primarly a subclass of it.
@cfg.on_print
async def test(cb:str):
print(f"called test {cb}")
async def main():
# This uses aiosignal under the hood so remeber to freeze the callbacks when your setup is complete
cfg.on_print.freeze()
cfg.on_nonabstract.freeze()
await cfg.on_print.send("Hello world")
await cfg.on_nonabstract.send("Hello world")
if __name__ == "__main__":
asyncio.run(main())
There's an alternative way to use aiocallback where you don't need to freeze many Configurable event descriptors at a time. You should use it if your not planning to use a dataclass although we plan to implement a special EventList for msgspec.
from aiocallback import EventList, contextevent
-
Currently Aiohttp's Trace Config is a big example of this problem
-
One of the biggest problems with aiosignal and creating custom tracing tools like aiohttp's Trace is that it requries a few classes in order to work compared to working with just one.
-
it adds the unwanted time consumption when going in and making them and the fact that it needs to hop through a few properties in order to finally send the callback all this can be cut with a wrapper like this one
-
-
A Developer Wishing to Program via the Trace Config Approch Will be annoyed with the amount of code you need to write and there is a send_xx function on everything.
-
Writing a smaller project has greater sucess and chance of working than writing a big one by yourself.
-
From what I've learned in my past experiences is that developers tend to give up if the project becomes too big of a task. This is why smaller is better and aiocallback hopes to deliver a faster experience to the end developer as well as the user using whatever you choose to make or share. This is why fastapi for example gets more attention than aiohttp does.
-
The Faster the project gets done the better chance you have of testing it and making smarter changes to it.
-
- fix attrs support
- drop deprecated warnings
- Now that I am helping maintain aiosignal itself (Never thought I would see that coming) I will be transforming this library into just a member descriptor library and then readd aiosignal as a requirement again.