litestar-org/litestar-skills/litestar-autowire

Claude Code and agent skill by litestar-org/litestar-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Use when working with litestar_autowire, AutowirePlugin, AutowireConfig, domain_packages, AutowireIntegration, AutowireLoader, or clear_autowire_cache. Not for manual Router composition — use explicit routes.

Install

npx vskill@latest install litestar-org/litestar-skills/litestar-autowire

SKILL.md

litestar-autowire

litestar-autowire 0.2.0 discovers Litestar controllers and event listeners from domain packages. It can also load optional integration modules without turning application setup into a central list of every domain component.

Use Autowire when the project already groups features into stable Python packages. Keep manual Router and plugin composition when the app is small, route registration is intentionally explicit, or packages do not follow a consistent convention.

Code Style Rules

  • Configure dotted package roots with domain_packages.
  • Import public APIs from litestar_autowire.
  • Keep controllers and listeners in their owning domain package.
  • Keep route handlers and listeners async when they perform I/O.
  • Configure third-party loaders via integrations (DishkaIntegration(), QueuesIntegration()).
  • Configure Dishka and Litestar Queues separately; Autowire only discovers or

wraps their domain-owned components.

  • Keep runtime-inspected controller imports (FromDishka, NamedDependency,

Request, injected service types, and DTOs) at module top-level with # noqa: TC001, TC002 (or "**/controllers.py" = ["TC001", "TC002", "TC003"] in Ruff per-file-ignores) when from __future__ import annotations is active.

  • Call clear_autowire_cache() when tests create, replace, or remove modules.

Quick Reference

Install
bash
pip install litestar-autowire==0.2.0

Install only the integrations already used by the project:

bash
pip install "litestar-autowire[dishka]==0.2.0"
pip install "litestar-autowire[queues]==0.2.0"
Domain layout
text
my_app/
└── domains/
├── accounts/
│ ├── controllers.py
│ ├── events.py
│ └── jobs.py
└── billing/
└── routes.py

Regular packages and PEP 420 namespace packages are supported. Autowire checks the configured root and each direct child package. Read Discovery before changing module conventions or debugging a missing component.

App setup
python
from litestar import Litestar
from litestar_autowire import AutowireConfig, AutowirePlugin
autowire = AutowirePlugin(
AutowireConfig(domain_packages=["my_app.domains"]),
)
app = Litestar(plugins=[autowire])

The default component modules are:

ComponentModule namesEnabled
Controllerscontrollers, routes, controller, routeYes
Event listenersevents, listenersYes
Litestar Queues tasksjobsOnly with integrations=["queues"]

AutowireConfig fields (all constructor arguments are keyword-only):

FieldDefaultContract
domain_packages()`str \Iterable[str] normalized to tuple[str, ...]`
integrations()Built-in names ("dishka", "queues") or AutowireIntegration objects
discover_controllersTrueRegister discovered Controller subclasses
discover_listenersTrueRegister discovered EventListener instances
controller_modules("controllers", "routes", "controller", "route")`str \Iterable[str] normalized to tuple[str, ...]`
listener_modules("events", "listeners")`str \Iterable[str] normalized to tuple[str, ...]`
task_modules("jobs",)`str \Iterable[str] normalized to tuple[str, ...]`
router_classNoneOptional router wrapper (litestar.Router or compatible type)
before_requestNoneOptional hook attached to the wrapper router
after_responseNoneOptional hook attached to the wrapper router
force_reload_tasksFalsePassed to litestar_queues.discover_tasks(force_reload=...)
log_discoveredTrueDefer discovery summary logs to the Litestar startup hook

Use config.integration_enabled(name) to check whether an integration with name is configured.

Customize module names without changing the domain layout:

python
config = AutowireConfig(
domain_packages=["my_app.domains"],
controller_modules=["http"],
listener_modules=["subscribers"],
discover_listeners=False,
)
Router selection

By default, discovered controller classes are appended directly to AppConfig.route_handlers. Set router_class=Router when the project needs a wrapper for router-level before_request or after_response hooks:

python
from litestar import Router
from litestar_autowire import AutowireConfig
config = AutowireConfig(
domain_packages=["my_app.domains"],
router_class=Router,
before_request=set_request_context,
after_response=record_response,
)

The wrapper is constructed with path="/", the discovered controller classes, and the configured hooks. Use integrations=["dishka"] instead when the project already uses Dishka and needs DishkaRouter. See Integrations.

<workflow>

Workflow

  1. Inspect the project layout and confirm domains are importable package roots.
  2. Choose Autowire only when domain packages follow consistent controller or

listener module conventions.

  1. Register one AutowirePlugin(AutowireConfig(...)) in the app plugin list.
  2. Keep the default module names or configure explicit module-name tuples.
  3. Enable only integrations already present in the project stack.
  4. Configure Dishka or Litestar Queues through their own application plugins.
  5. Test discovery, error propagation, and cache isolation with the patterns in

Testing.

</workflow>

<guardrails>

Guardrails

  • Do not describe Autowire as recursive domain discovery. It discovers the

configured root and direct feature children; component modules may themselves contain importable leaf modules.

  • Do not claim arbitrary route-handler discovery. Autowire registers

Controller subclasses and EventListener objects.

  • Do not invent registry or discovered-item wrapper types. Autowire 0.2.0

exports AutowirePlugin, AutowireConfig, AutowireContext, AutowireIntegration, AutowireLoader, DishkaIntegration, QueuesIntegration, clear_autowire_cache, discover_controllers, discover_feature_packages, discover_listeners, discover_queue_tasks, find_controllers_in_module, and find_listeners_in_module. There is no AutowireRegistry, DomainMetadata, DiscoveredCLI, DiscoveredController, DiscoveredJob, DiscoveredProvider, DiscoveredSchema, DiscoveredSignal, LitestarQueuesIntegration, or SAQIntegration (use AutowireLoader for SAQ or custom module registries).

  • Do not imply queue tasks are enabled by default. The queues integration

must be selected and its optional dependency installed.

  • Do not suppress dependency import failures. Only an absent configured

package or absent target component module is skipped.

  • Do not use both a custom `router_class` and expect Dishka to replace it.

DishkaIntegration preserves an already selected router class.

  • **Do not hide FromDishka[...] types under if TYPE_CHECKING: when

from __future__ import annotations is enabled in controller modules.** DishkaRouter.register calls typing.get_type_hints() on each controller handler at registration time, which raises NameError if injected types are absent from runtime module globals or defined only in a function scope. Keep those imports at module top-level with # noqa: TC001, TC002 (or configure Ruff per-file-ignores for controller modules).

  • **Do not reuse a Controller class across unit tests after DishkaRouter

registration without restoring get_route_handlers or providing a Dishka container.** DishkaRouter.register monkey-patches ControllerSubclass.get_route_handlers in-place on the class, so mounting that controller on an isolated Litestar test app without setup_dishka fails at request time with AttributeError: 'State' object has no attribute 'dishka_container'.

  • Do not give custom integrations the names `dishka` or `queues`. Built-in

name collisions fail during configuration.

  • Do not reuse stale discovery state in tests or reload tooling. Clear the

process-local caches before rediscovery.

</guardrails>

<validation>

Validation Checkpoint

  • [ ] domain_packages contains importable dotted package roots.
  • [ ] The configured roots and component module names match the source layout.
  • [ ] Controller classes are defined in the discovered module, not merely

re-exported into it.

  • [ ] Queue task discovery is enabled only with the Queues extra and integration.
  • [ ] Dishka and Litestar Queues retain their own application configuration.
  • [ ] Controller modules wired with Dishka keep FromDishka[...] dependency

types importable at runtime (# noqa: TC001, TC002) rather than inside if TYPE_CHECKING: under from __future__ import annotations.

  • [ ] Custom integrations satisfy AutowireIntegration and use unique names.
  • [ ] Router hooks are paired with a compatible router_class.
  • [ ] Tests call clear_autowire_cache() around dynamic module changes and

restore Controller.get_route_handlers when reusing controllers with Dishka.

  • [ ] Missing dependency imports still fail instead of silently dropping a

domain.

</validation>

<example>

Example

python
from litestar import Controller, get
class AccountController(Controller):
path = "/accounts"
@get()
async def list_accounts(self) -> list[dict[str, str]]:
return [{"name": "primary"}]
python
from litestar import Litestar
from litestar_autowire import AutowireConfig, AutowirePlugin
app = Litestar(
plugins=[
AutowirePlugin(
AutowireConfig(
domain_packages=["my_app.domains"],
discover_controllers=True,
discover_listeners=True,
)
)
],
)

Autowire imports my_app.domains.accounts.controllers, registers AccountController, and checks the configured listener module names. It does not load jobs.py until the queues integration is selected.

</example>

References Index

  • Discovery — package traversal, PEP 420 behavior,

component selection, caches, and import failures

AutowireLoader, router selection, Dishka, and Litestar Queues

  • Testing — deterministic cache isolation and

package-discovery tests

router composition

and workers

dependency overrides

Official References

  • <https://github.com/cofin/litestar-autowire/releases/tag/v0.2.0>
  • <https://github.com/cofin/litestar-autowire/tree/v0.2.0/litestar_autowire>
  • <https://github.com/cofin/litestar-autowire/blob/v0.2.0/tests/unit/test_autowire_plugin.py>

Shared Styleguide Baseline

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
13
7-day trend score
13

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/litestar-org/litestar-skills/litestar-autowire/badge)](https://verified-skill.com/skills/litestar-org/litestar-skills/litestar-autowire)

Something wrong with this skill or its page? Tell us.