server.negotiation

Page actions AI-ready formats and sharing
Open LLM text
Share with AI
Ask Claude Ask ChatGPT Ask Gemini Ask Copilot

Content negotiation — maps return values to Response objects.

The ContentNegotiator inspects the return value from a route handler and produces the appropriate Response. isinstance-based dispatch, no magic, fully predictable.

Content negotiation — maps return values to Response objects.

The ContentNegotiator inspects the return value from a route handler and produces the appropriate Response. isinstance-based dispatch, no magic, fully predictable.

server.negotiation

Name Type Default Description
type
qualified_name
element_type
description
source_file
line_number
is_autodoc
autodoc_element
_autodoc_template
_autodoc_url_path
_autodoc_page_type
title
doc_content_hash

Symbols on this page

function _is_skill_envelope

Structural Envelope check without importingchirp.skillon the hot path.

Eagerfrom chirp.skill.envelope import Enveloperegresses suspense_first_chunk(provisional skill package must stay lazy).

Jump to symbol
function _minimal_kida_env

Create a bare kida Environment for inline template rendering.

Used when no template_dir is configured but an InlineTemplate needs to be rendered (prototyping without…

Jump to symbol
function _html_response

Build a text/html response with explicit render intent.

Jump to symbol
function _fragment_response

Build a text/html response for fragment-returning endpoints.

Jump to symbol
function _require_kida_env

Raise ConfigurationError if kida_env is None (template return types need it).

Jump to symbol
function _trace_request_content_type

Return bounded request media metadata for a debug response header.

Jump to symbol
function _normalize_hx_redirect_response

Strip conflicting redirect headers for htmx vs non-htmx clients (#272).

Jump to symbol
function _with_current_path_in_context

Return value withcurrent_pathmerged into context (copy-on-write).

Avoids mutating a sharedcontextdict when handlers reuse a frozen Template/Page/LayoutPage…

Jump to symbol
function _render_composition

Shared 5-step pipeline: shell updates → plan → execute → serialize → response.

SetsVary: HX-Request, HX-Request-Typebecause the response varies by htmx transport…

Jump to symbol
function _set_layout_debug_from_plan

Set layout debug metadata for LayoutDebugMiddleware when config.debug.

Jump to symbol
function negotiate

Convert a route handler's return value to a Response.

Dispatch order:

  1. Response-> pass through
  2. Redirect-> 302 with Location header
  3. MutationResult-> htmx:…
Jump to symbol
_is_skill_envelope
function
def _is_skill_envelope(value: object) -> bool

Structural Envelope check without importingchirp.skillon the hot path.

Eagerfrom chirp.skill.envelope import Enveloperegresses suspense_first_chunk(provisional skill package must stay lazy).

Parameters

Name Type Default Description
value object
_minimal_kida_env
function
def _minimal_kida_env() -> Environment

Create a bare kida Environment for inline template rendering.

Used when no template_dir is configured but an InlineTemplate needs to be rendered (prototyping without any file templates).

No parameters.

_html_response
function
def _html_response(body: str, *, intent: RenderIntent) -> Response

Build a text/html response with explicit render intent.

Parameters

Name Type Default Description
body str
intent RenderIntent
_fragment_response
function
def _fragment_response(body: str) -> Response

Build a text/html response for fragment-returning endpoints.

Parameters

Name Type Default Description
body str
_require_kida_env
function
def _require_kida_env(kida_env: Environment | None, return_type: str) -> Environment

Raise ConfigurationError if kida_env is None (template return types need it).

Parameters

Name Type Default Description
kida_env Environment | None
return_type str
_trace_request_content_type
function
def _trace_request_content_type(request: Request | None) -> str | None

Return bounded request media metadata for a debug response header.

Parameters

Name Type Default Description
request Request | None
_normalize_hx_redirect_response
function
def _normalize_hx_redirect_response(response: Response, request: Request | None) -> Response

Strip conflicting redirect headers for htmx vs non-htmx clients (#272).

Parameters

Name Type Default Description
response Response
request Request | None
_with_current_path_in_context
function
def _with_current_path_in_context(value: Template | Page | LayoutPage, request: Request | None) -> Template | Page | LayoutPage

Return value withcurrent_pathmerged into context (copy-on-write).

Avoids mutating a sharedcontextdict when handlers reuse a frozen Template/Page/LayoutPageacross requests.

Template/Page/LayoutPage use custom __init__— construct fresh instances instead ofdataclasses.replace (which does not pass template_name).

Parameters

Name Type Default Description
value Template | Page | LayoutPage
request Request | None
_render_composition
function
def _render_composition(composition: PageComposition, request: Request | None, fragment_target_registry: FragmentTargetRegistry | None, kida_env: Environment, validate_blocks: bool, oob_registry: OOBRegistry | None, shell_actions_renderer: ShellActionsRenderer | None = None) -> Response

Shared 5-step pipeline: shell updates → plan → execute → serialize → response.

SetsVary: HX-Request, HX-Request-Typebecause the response varies by htmx transport and by htmx 4 full/partial intent. Without this, HTTP caches may replay the wrong fragment width or serve a fragment to a full-page request.

Parameters

Name Type Default Description
composition PageComposition
request Request | None
fragment_target_registry FragmentTargetRegistry | None
kida_env Environment
validate_blocks bool
oob_registry OOBRegistry | None
shell_actions_renderer ShellActionsRenderer | None None
_set_layout_debug_from_plan
function
def _set_layout_debug_from_plan(plan: Any, request: Request | None) -> None

Set layout debug metadata for LayoutDebugMiddleware when config.debug.

Parameters

Name Type Default Description
plan Any
request Request | None
negotiate
function
def negotiate(value: Any, *, kida_env: Environment | None = None, request: Request | None = None, validate_blocks: bool = False, oob_registry: OOBRegistry | None = None, fragment_target_registry: FragmentTargetRegistry | None = None, suspense_error_template: str | None = None, suspense_error_block: str = 'fallback', shell_actions_renderer: ShellActionsRenderer | None = None) -> Response | StreamingResponse | SSEResponse

Convert a route handler's return value to a Response.

Dispatch order:

  1. Response-> pass through
  2. Redirect-> 302 with Location header
  3. MutationResult-> htmx: fragments or HX-Redirect; non-htmx: 303
  4. Template-> render via kida -> Response
  5. Fragment-> render block via kida -> Response
  6. Page-> Template or Fragment based on request headers
  7. Action-> empty Response + optional HX headers
  8. ValidationError-> Fragment + 422 + optional HX-Retarget
  9. OOB-> primary + hx-swap-oob fragments
  10. Stream-> kida render_stream() -> StreamingResponse
    (async sources resolved concurrently)
    
  11. TemplateStream-> kida render_stream_async() -> StreamingResponse
  12. Suspense-> shell + deferred OOB blocks -> StreamingResponse
    (first paint instant, blocks fill in)
    
  13. EventStream-> SSEResponse (handler dispatches to SSE)
  14. str-> 200, text/html
  15. bytes-> 200, application/octet-stream
  16. dict / list-> 200, application/json
  17. (value, int)-> negotiate value, override status
  18. (value, int, dict)-> negotiate value, override status + headers

Parameters

Name Type Default Description
value Any
kida_env Environment | None None
request Request | None None
validate_blocks bool False
oob_registry OOBRegistry | None None
fragment_target_registry FragmentTargetRegistry | None None
suspense_error_template str | None None
suspense_error_block str 'fallback'
shell_actions_renderer ShellActionsRenderer | None None

View source · /home/runner/work/chirp/chirp/site/../src/chirp/server/negotiation.py:1