Services¶
Protocols (lenient)¶
CreateService ¶
Bases: Protocol[InputT, ResultT]
Structural shape for a create-action service callable.
Lenient by design: **kwargs: Any is the escape hatch that lets the
framework pass any extras (URL kwargs, ServiceSpec.kwargs /
get_service_kwargs returns) without requiring the service to declare
them. Services may freely omit parameters they do not need; the framework
inspects the signature and only passes what is declared.
Annotate against this Protocol for IDE / type-checker help on the known
pool keys. For full enforcement (no **kwargs escape hatch), use
:class:StrictCreateService.
UpdateService ¶
Bases: Protocol[InputT, InstanceT, ResultT]
Structural shape for an update-action service callable.
Receives the resolved instance plus the validated data. Returning
None instructs the framework to render the in-memory instance
(mirroring DRF's UpdateAPIView shape).
Lenient by design — see :class:CreateService for rationale.
DeleteService ¶
Bases: Protocol[InstanceT, ResultT]
Structural shape for a delete-action service callable.
Receives the resolved instance. Most delete services return None;
if you need a response body, return a value and configure
ServiceSpec.output_serializer (or output_selector).
Lenient by design — see :class:CreateService for rationale.
Protocols (strict)¶
StrictCreateService ¶
Bases: Protocol[InputT, ResultT, ExtraT]
Strict shape for a create-action service.
Identical to :class:CreateService except the **kwargs: Any escape
hatch is replaced with **extras: Unpack[ExtraT] (:pep:692). When
ExtraT is a TypedDict, type checkers enforce that the service
declares exactly the extra keys delivered by ServiceSpec.kwargs —
nothing more, nothing less.
Use it for services where you want drift-free signatures::
class CreateAuthorKwargs(TypedDict):
tenant_id: int
def create_author(
*,
data: AuthorIn,
request: HttpRequest,
user: UserT,
tenant_id: int,
) -> Author: ...
# Static check that the function matches the strict Protocol:
_: StrictCreateService[AuthorIn, Author, CreateAuthorKwargs] = create_author
StrictUpdateService ¶
Bases: Protocol[InputT, InstanceT, ResultT, ExtraT]
Strict shape for an update-action service.
See :class:StrictCreateService for rationale. Pin the extras delivered
by ServiceSpec.kwargs via a TypedDict::
class UpdateAuthorKwargs(TypedDict):
tenant_id: int
def update_author(
*,
instance: Author,
data: AuthorIn,
request: HttpRequest,
user: UserT,
tenant_id: int,
) -> Author: ...
_: StrictUpdateService[AuthorIn, Author, Author, UpdateAuthorKwargs] = update_author
StrictDeleteService ¶
Bases: Protocol[InstanceT, ResultT, ExtraT]
Strict shape for a delete-action service.
See :class:StrictCreateService for rationale. Most delete services
return None; that's fine — annotate ResultT as None.