Dependency Injection¶
FastAPI-style Depends() handler injection, scanner, and solver. See the Dependency Injection guide for usage patterns.
Depends¶
Depends ¶
Marker placed as the default value of a handler/dependency parameter.
The return type is annotated as T so the IDE and type checker
treat the parameter as the resolved dependency type, not as a
:class:Dependency sentinel. At runtime the function returns a
:class:Dependency object that the scanner picks up.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dependency
|
Callable[..., T]
|
A callable that produces the dependency. May be a
plain function, an async function, a sync generator, or an
async generator. Generators get teardown semantics —
anything after |
required |
use_cache
|
bool
|
When True (default), repeated references to the same callable within one request return the cached value. Set to False for resources that must be fresh per use (e.g. random IDs, timestamps). |
True
|
Returns:
| Type | Description |
|---|---|
T
|
Statically typed as |
T
|
At runtime returns a :class: |
Source code in src/agenticapi/dependencies/depends.py
Dependency
dataclass
¶
A resolved dependency description.
Carries the user-supplied callable plus its options. The runtime solver consumes these to build the per-request injection plan.
Attributes:
| Name | Type | Description |
|---|---|---|
callable |
Callable[..., Any]
|
The dependency provider. May be sync, async, a sync generator (yield-based teardown), or an async generator (async yield-based teardown). |
use_cache |
bool
|
When True (default), the same dependency callable yields the same value within one request. When False, the callable is invoked on every reference within the request. |
Source code in src/agenticapi/dependencies/depends.py
Scanner¶
The scanner inspects a handler's signature at registration time and produces an InjectionPlan describing how each parameter should be resolved.
scan_handler ¶
Scan a handler signature and return its :class:InjectionPlan.
Resolves string annotations via :func:typing.get_type_hints so
from __future__ import annotations is fully supported. Falls
back to raw inspect.Parameter.annotation strings when the
handler imports something only under TYPE_CHECKING.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
handler
|
Callable[..., Any]
|
The async or sync handler callable to scan. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
An |
InjectionPlan
|
class: |
Source code in src/agenticapi/dependencies/scanner.py
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | |
InjectionKind ¶
Bases: StrEnum
Categorisation of how a single parameter is filled.
Source code in src/agenticapi/dependencies/scanner.py
InjectionPlan
dataclass
¶
Cached injection plan for a single handler.
Attributes:
| Name | Type | Description |
|---|---|---|
params |
tuple[ParamPlan, ...]
|
Per-parameter resolution plans, in declaration order. |
legacy_positional_count |
int
|
How many of the leading parameters
should receive |
intent_payload_schema |
type[BaseModel] | None
|
Pydantic model parameter extracted from
an |
Source code in src/agenticapi/dependencies/scanner.py
ParamPlan
dataclass
¶
How a single handler parameter is resolved.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
The parameter's name in the handler signature. |
kind |
InjectionKind
|
Which injector handles this parameter. |
dependency |
Dependency | None
|
The user-supplied :class: |
annotation |
Any
|
The resolved annotation for diagnostics. |
Source code in src/agenticapi/dependencies/scanner.py
Solver¶
The solver applies an InjectionPlan to a live request, resolving all dependencies and producing a ResolvedHandlerCall that can be invoked through an AsyncExitStack.
solve
async
¶
solve(
plan: InjectionPlan,
*,
intent: Intent[Any],
context: AgentContext,
files: dict[str, Any] | None,
htmx_scope: dict[str, Any] | None,
overrides: dict[Callable[..., Any], Callable[..., Any]],
route_dependencies: list[Dependency] | None = None,
agent_stream: Any | None = None,
) -> ResolvedHandlerCall
Resolve a handler's :class:InjectionPlan for one request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plan
|
InjectionPlan
|
The handler's pre-computed injection plan. |
required |
intent
|
Intent[Any]
|
The parsed agent intent. |
required |
context
|
AgentContext
|
The active :class: |
required |
files
|
dict[str, Any] | None
|
Uploaded files keyed by form-field name (or |
required |
htmx_scope
|
dict[str, Any] | None
|
Raw ASGI scope for HTMX header parsing (or |
required |
overrides
|
dict[Callable[..., Any], Callable[..., Any]]
|
|
required |
route_dependencies
|
list[Dependency] | None
|
Optional list of route-level dependencies (D6) to resolve for side effects before the handler runs. Their teardown is registered on the same exit stack. |
None
|
agent_stream
|
Any | None
|
Optional :class: |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
ResolvedHandlerCall
|
class: |
ResolvedHandlerCall
|
closed after the handler completes. |
Source code in src/agenticapi/dependencies/solver.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
invoke_handler
async
¶
invoke_handler(
handler: Callable[..., Awaitable[Any] | Any],
resolved: ResolvedHandlerCall,
) -> Any
Invoke a handler with a resolved call and await its result.
Supports both sync and async handlers. Always closes the
exit_stack after the handler returns, even on failure, so
generator-style teardown runs reliably.
Source code in src/agenticapi/dependencies/solver.py
ResolvedHandlerCall
dataclass
¶
The product of resolving a handler's :class:InjectionPlan.
Attributes:
| Name | Type | Description |
|---|---|---|
kwargs |
dict[str, Any]
|
Keyword arguments to pass to the handler. |
positional |
tuple[Any, ...]
|
Positional arguments (Intent, AgentContext) for
handlers using the legacy |
tasks |
AgentTasks | None
|
The injected :class: |
exit_stack |
AsyncExitStack
|
The async exit stack that owns generator-based dependency teardown. Must be closed after the handler returns (success or failure). |
Source code in src/agenticapi/dependencies/solver.py
DependencyResolutionError ¶
Bases: AgentRuntimeError
Raised when a dependency cannot be resolved.
Carries the dependency call chain so debugging is straightforward.