Asyncio Support

With the rise of async/await in Python and popular web frameworks like FastAPI, it’s important to support asyncio. This section will cover how to use the asyncio client, as well as recommended patterns for using it with libraries like FastAPI.

Installation

Async support is not included in the default installation. You can install it via:

pip install autumn-py[aio]

This will install the aiohttp library, which is required for async support. You may optionally choose to install some speedups provided by the aiohttp library. Note that these speedups are not required for the library to work, but they may improve performance, but may not be available on all platforms.

pip install aiohttp[speedups]

Warning

View the aiohttp documentation for more information on the speedups. Windows users may need to adjust their event loop.

Usage

Autumn supports asyncio. You can use the AsyncClient class to interact with the API asynchronously.

Basic Usage

The basic usage of the asyncio client is the same as the sync client. You can use the AsyncClient class to interact with the API asynchronously.

import asyncio

from autumn import Autumn
# from autumn.aio import AsyncClient

async def main():
    client = Autumn(token="your_api_key")
    await client.attach(
        "customer_id",
        product_id="chat_messages"
    )

asyncio.run(main())

ASGI compatible frameworks

The Python SDK now supports automatic mounting of backend routes that the autumn-js JavaSript library uses. This means you can easily use a stack where you have a React frontend and a Python backend.

Note

The starlette and aiohttp libraries are required for ASGI support. You can install them via pip.

You must provide an asynchronous identify method that takes in a Starlette Request object. You are required to return your logged in user’s information, specifically their name, their internal user_id (the User ID on your systems) and their email.

Examples have been provided below.

Warning

You must mount the AutumnASGI app at /api/autumn. Any other route will cause autumn-js to break.

from __future__ import annotations

import os
from typing import TYPE_CHECKING

from litestar import Litestar
from litestar.handlers import asgi
from litestar.config.cors import CORSConfig

from autumn.asgi import AutumnASGI

if TYPE_CHECKING:
    from starlette.requests import Request
    from autumn.asgi import AutumnIdentifyData


async def identify(request: Request) -> AutumnIdentifyData:
    # db = request.state.postgres
    # session = request.session

    return {
        "customer_id": "user_123",
        "customer_data": {"name": "John Doe", "email": "djohn@gmail.com"},
    }


autumn = AutumnASGI(token=os.environ["AUTUMN_KEY"], identify=identify)


async def close_autumn(_):
    await autumn.close()


autumn_asgi = asgi(path="/api/autumn", is_mount=True, copy_scope=True)(autumn)

# CORS must be configured correctly.
# You must allow the GET, POST and OPTIONS methods at a minimum.
# Pass your frontend url here.
DOMAINS = ["<Your Frontend URL>"]
app = Litestar(
    debug=True,
    route_handlers=[autumn_asgi],
    cors_config=CORSConfig(
        allow_origins=DOMAINS,
        allow_credentials=True,
        allow_headers=["*"],
        allow_methods=["*"],
    ),
    on_shutdown=[close_autumn],
)

Finally, on your frontend, simply adjust the <AutumnHandler /> component’s backendUrl attribute to the URL of your Python API.

For a complete example, check out the python-ssr-autumn-template.

That’s it! Enjoy using Autumn!