Basic Usage
Learn the fundamentals of SmartAsync.
The @smartasync Decorator
Apply to any async method to make it work in both contexts:
from smartasync import smartasync
class MyClass:
@smartasync
async def my_method(self):
# async implementation
await some_async_operation()
return result
Calling from Sync Context
obj = MyClass()
result = obj.my_method() # No await needed
SmartAsync detects no event loop and automatically runs with asyncio.run().
Calling from Async Context
async def main():
obj = MyClass()
result = await obj.my_method() # Normal await
SmartAsync detects the event loop and returns a coroutine.
Sync Methods in Async Context
SmartAsync also handles sync methods called from async context:
@smartasync
def blocking_operation(self):
# Blocking sync code
time.sleep(1)
return result
async def handler():
obj = MyClass()
# Automatically offloaded to thread!
result = await obj.blocking_operation()
This prevents blocking the event loop.
Best Practices
Use async implementations when possible - Better performance
Decorate all public methods - Consistent API
Handle errors normally - SmartAsync is transparent to exceptions
Test both contexts - Ensure methods work in sync and async