Litestar Autowire wires domain packages into a Litestar application. Put each domain's controllers, listeners, and queue tasks beside the domain code, then register the domain root once.

Use it to keep app setup small while each domain owns its Litestar surface.

Get Started

Install the plugin and wire a domains/ package into Litestar.

Getting Started
Changelog

Review what changed in each release.

Changelog

Quick Example

my_app/
  domains/
    accounts/
      controllers.py
      events.py
      jobs.py
from litestar import Litestar
from litestar_autowire import AutowireConfig, AutowirePlugin

app = Litestar(
    plugins=[
        AutowirePlugin(
            AutowireConfig(domain_packages=["my_app.domains"]),
        )
    ],
)

Discovery Rules

Component

Module names

Controllers

controllers, routes, controller, route

Event listeners

events, listeners

Queue tasks

jobs

Integrations

Use string aliases for built-in integrations:

AutowireConfig(
    domain_packages=["my_app.domains"],
    integrations=["dishka", "queues"],
)

Unknown strings fail fast. Custom behavior belongs in integration objects passed to integrations. Use AutowireLoader for registries that need to load per-domain modules with a callable such as "my_app.jobs:discover_jobs". Integer loader return values contribute to the startup task count.

API

class litestar_autowire.AutowireConfig(*, domain_packages: Iterable[str] | str = (), integrations: Iterable[str | AutowireIntegration] | str | AutowireIntegration = (), discover_controllers: bool = True, discover_listeners: bool = True, controller_modules: Iterable[str] | str = ('controllers', 'routes', 'controller', 'route'), listener_modules: Iterable[str] | str = ('events', 'listeners'), task_modules: Iterable[str] | str = ('jobs',), router_class: type[Any] | None = None, before_request: Any | None = None, after_response: Any | None = None, force_reload_tasks: bool = False, log_discovered: bool = True, extensions: Any | None = None)[source]

Bases: object

Configure domain package-based Litestar component discovery.

domain_packages

Dotted domain package names to inspect. Each package and its direct child packages are checked for configured controller, listener, and task submodules.

Type:

tuple[str, ...]

integrations

Optional built-in integration names or custom integration objects. Supported built-in values are "dishka" to wrap discovered controllers in Dishka's Litestar router and "queues" to import task modules with litestar_queues.discover_tasks.

Type:

tuple[litestar_autowire.integrations.AutowireIntegration, ...]

discover_controllers

Register discovered Controller subclasses.

Type:

bool

discover_listeners

Register discovered Litestar event listeners.

Type:

bool

controller_modules

Submodule names that may contain controllers.

Type:

tuple[str, ...]

listener_modules

Submodule names that may contain event listeners.

Type:

tuple[str, ...]

task_modules

Subpackage names that may contain litestar_queues tasks.

Type:

tuple[str, ...]

router_class

Optional router class used to wrap discovered controllers. Pass litestar.Router or a compatible router type.

Type:

type[Any] | None

before_request

Optional hook attached to the wrapper router.

Type:

Any | None

after_response

Optional hook attached to the wrapper router.

Type:

Any | None

force_reload_tasks

Re-import task modules already loaded by litestar_queues.

Type:

bool

log_discovered

Emit startup logs summarizing discovered components.

Type:

bool

__init__(*, domain_packages: Iterable[str] | str = (), integrations: Iterable[str | AutowireIntegration] | str | AutowireIntegration = (), discover_controllers: bool = True, discover_listeners: bool = True, controller_modules: Iterable[str] | str = ('controllers', 'routes', 'controller', 'route'), listener_modules: Iterable[str] | str = ('events', 'listeners'), task_modules: Iterable[str] | str = ('jobs',), router_class: type[Any] | None = None, before_request: Any | None = None, after_response: Any | None = None, force_reload_tasks: bool = False, log_discovered: bool = True, extensions: Any | None = None) None[source]

Initialize and normalize discovery configuration.

integration_enabled(name: str) bool[source]

Return whether an integration with name is enabled.

class litestar_autowire.AutowireContext(app_config: AppConfig, config: AutowireConfig, feature_packages: tuple[str, ...], controllers: list[type[Controller]], listeners: list[EventListener], router_class: type[~typing.Any] | None = None, task_names: set[str] = <factory>, loaded_task_count: int = 0)[source]

Bases: object

Shared state passed to Autowire integrations.

property task_count: int

Return the total task count reported by integrations.

record_task_count(count: int) None[source]

Add a task count reported by a loader integration.

__init__(app_config: AppConfig, config: AutowireConfig, feature_packages: tuple[str, ...], controllers: list[type[Controller]], listeners: list[EventListener], router_class: type[~typing.Any] | None = None, task_names: set[str] = <factory>, loaded_task_count: int = 0) None
class litestar_autowire.AutowireIntegration(*args, **kwargs)[source]

Bases: Protocol

Protocol for extending Autowire's discovery lifecycle.

property name: str

Integration name used for validation and diagnostics.

on_autowire(context: AutowireContext) None[source]

Apply integration behavior to the shared Autowire context.

__init__(*args, **kwargs)
class litestar_autowire.AutowireLoader(*, name: str, modules: Iterable[str] | str, loader: Callable[[str], object] | str)[source]

Bases: object

Load discovered feature modules with a callable or dotted callable string.

__init__(*, name: str, modules: Iterable[str] | str, loader: Callable[[str], object] | str) None[source]

Initialize the loader integration.

Parameters:
  • name -- Integration name used for validation and diagnostics.

  • modules -- Submodule names to load below each discovered feature package.

  • loader -- Callable or "pkg.module:func" string called with each existing module path.

on_autowire(context: AutowireContext) None[source]

Load configured modules for every discovered feature package.

class litestar_autowire.AutowirePlugin(config: AutowireConfig | None = None)[source]

Bases: InitPluginProtocol

Discover and register Litestar components from configured domain packages.

__init__(config: AutowireConfig | None = None) None[source]

Initialize the plugin.

Parameters:

config -- Discovery configuration. The default config performs no discovery until domain packages are provided.

on_app_init(app_config: AppConfig) AppConfig[source]

Discover configured components and add them to the app config.

litestar_autowire.discover_feature_packages(packages: tuple[str, ...] | list[str]) tuple[str, ...][source]

Discover configured package roots and their direct feature child packages.

litestar_autowire.discover_controllers(packages: tuple[str, ...] | list[str], module_names: tuple[str, ...] | list[str] = ('controllers', 'routes', 'controller', 'route')) list[type[Controller]][source]

Discover Controller subclasses under package feature folders.

litestar_autowire.discover_listeners(packages: tuple[str, ...] | list[str], module_names: tuple[str, ...] | list[str] = ('events', 'listeners')) list[EventListener][source]

Discover Litestar event listeners under package feature folders.

litestar_autowire.discover_queue_tasks(packages: tuple[str, ...] | list[str], module_names: tuple[str, ...] | list[str] = ('jobs',), *, force_reload: bool = False) tuple[str, ...][source]

Import litestar_queues task modules below the configured packages.

Returns:

A sorted tuple of registered task names reported by litestar_queues.

Raises:

RuntimeError -- If task discovery is enabled without installing litestar-autowire[queues] or a compatible litestar_queues.