Four levels of granularity
Each level overrides the one before it. First non-None wins.
Per-location parameters
Cases are specified per HTTP location, not one-for-all:body_case— JSON request body keys (default"camel")query_case— URL query string keys (default"snake")path_case— URL path parameter keys (default"snake")
Supported cases
Examples
Clean API (most common) — factory level only
camel_api_factory.py
API with snake_case everywhere
snake_api_factory.py
Mixed API — one endpoint differs
per_endpoint_case.py
Schema-level override (nested model)
schema_case.py
Field-level override (single field)
field_case.py
Resolution at serialization time
When no convention is right
The cascade converts a whole word at a time, and an acronym inside a field name is where that goes wrong.snake_to_camel capitalises each component, so
i_cal_uid becomes iCalUid — and Google Calendar documents iCalUID. The same
shape gives htmlUrl for htmlURL and ipAddress for IPAddress. No entry in
the cascade produces those, because they are not a convention.
WireName names the key outright, and wins over
every level above:
eventId and fileUrl are camelCase in Google’s own docs — so
check rather than guess.
This failure is silent, which is why it is worth a marker. Many APIs ignore a
query parameter they do not recognise, so the misspelled filter is dropped, the
unfiltered result comes back, and the call answers 200. Charter’s own Calendar
pack sent iCalUid for as long as it existed. Assert the parameter names on the
wire against a respx route; reading the schema is what misses it.
Related
WireName— the key the API documents, verbatimCase— the field-level markerKeyCase— the type the*_casesettings accept- Casing and encoding — the resolved settings on a built
Tool - The builder — the
*_case_overrideparameters