Getting Started¶
Installation¶
pip install litestar-autowire
Install optional integrations only when the app uses them:
pip install "litestar-autowire[dishka]"
pip install "litestar-autowire[queues]"
Domain Layout¶
Autowire is for Litestar apps that group code by domain instead of by framework layer:
my_app/
domains/
accounts/
controllers.py
events.py
jobs.py
billing/
controllers.py
Each domain package owns its HTTP routes, event listeners, and background task modules.
Wire Domains¶
# my_app/domains/accounts/controllers.py
from litestar import Controller, get
class AccountController(Controller):
path = "/accounts"
@get("/", sync_to_thread=False)
def list_accounts(self) -> dict[str, str]:
return {"status": "ok"}
Register the domain root once:
from litestar import Litestar
from litestar_autowire import AutowireConfig, AutowirePlugin
app = Litestar(
plugins=[
AutowirePlugin(
AutowireConfig(domain_packages=["my_app.domains"]),
)
],
)
Autowire checks the configured domain package root and its direct child domain packages for:
Component |
Module names |
|---|---|
Controllers |
|
Event listeners |
|
Queue tasks |
|
Optional Integrations¶
Built-in integrations use string aliases:
AutowireConfig(
domain_packages=["my_app.domains"],
integrations=["dishka", "queues"],
)
dishka wraps discovered controllers in Dishka's Litestar router. Dishka is
not enabled merely because it is installed; configure Dishka separately with
setup_dishka(...).
queues imports task modules with litestar_queues.discover_tasks.
Litestar Queues still owns queue configuration, execution, workers, schedules,
and task results.
Unknown string aliases raise ValueError.
Autowire Loader¶
Use AutowireLoader when another registry needs each discovered domain module
loaded:
from litestar_autowire import AutowireConfig, AutowireLoader
config = AutowireConfig(
domain_packages=["my_app.domains"],
integrations=[
AutowireLoader(
name="inventory_jobs",
modules="jobs",
loader="my_app.jobs:discover_jobs",
)
],
)
The loader receives existing module paths such as
my_app.domains.accounts.jobs. Use the pkg.module:func form to make the
module import and callable lookup explicit. If the loader returns an integer,
Autowire adds it to the startup task count.
Custom Integrations¶
Custom integration objects run after built-in discovery and can mutate the shared Autowire context:
from litestar_autowire import AutowireConfig, AutowireContext
class InventoryIntegration:
name = "inventory"
def on_autowire(self, context: AutowireContext) -> None:
context.app_config.state["autowire_domain_packages"] = context.config.domain_packages
config = AutowireConfig(
domain_packages=["my_app.domains"],
integrations=[InventoryIntegration()],
)
Custom integration names cannot reuse built-in names such as dishka or
queues.
Discovery Logs¶
By default, Autowire defers discovery logs to the Litestar startup lifespan.
The summary includes controller, domain, listener, and task counts. Debug
logging includes the controller inventory grouped by domain. Set
log_discovered=False to disable these logs.