TN-002: Open Schema for DeviceResponse (extra="allow")¶
Summary¶
DeviceResponse uses Pydantic's extra="allow" configuration so that unknown fields from the device firmware pass through without requiring a schema update.
Background¶
The OSECHI detector firmware (kurikintons) evolves independently of the kazunoko library. New firmware versions may add response fields at any time. If DeviceResponse had a closed schema (Pydantic's default extra="ignore" or extra="forbid"), every firmware update that introduced a new field would either silently drop data or raise a validation error — both unacceptable for a data acquisition library.
Decision¶
DeviceResponse is defined with model_config = ConfigDict(extra="allow").
Three fields are explicitly typed and validated:
| Field | Type | Notes |
|---|---|---|
type |
str |
Required. "response" or "event" |
status |
str \| None |
"ok" or "error" |
received_us |
int \| None |
Host-side receipt timestamp |
All other fields from the device are accepted as-is and accessible via dot notation or model_dump():
response = parse_jsonl('{"type":"response","status":"ok","version":"1.10.1","poll_count":10}')
print(response.version) # "1.10.1" ← not in schema, passes through
print(response.poll_count) # 10
Alternatives Considered¶
| Alternative | Reason Not Chosen |
|---|---|
| Explicit field per device attribute | Breaks on every firmware update; requires library release to accept new fields |
extra="ignore" (silently drop unknowns) |
Loses data; users cannot access new fields without a library update |
extra="forbid" |
Raises ValidationError on any new firmware field; too brittle |
| Separate typed models per command | Duplicates the open-field problem; N models instead of one |
Consequences¶
- New firmware fields are immediately available as attributes with no library change.
- Type checking tools (mypy) cannot infer the types of extra fields — callers must use
getattrormodel_dump()if accessing programmatically by name. - Malformed values in extra fields are not validated; only
type,status, andreceived_usare type-checked. model_dump()includes all fields, making serialization complete and lossless.