#3099·quicktype

Python: add an option to keep valid original property names

Author: foobraCreated Jul 31, 2026Updated Jul 31, 2026

Summary

The Python renderer's default nice-property-names behavior splits valid identifiers at digit/letter boundaries. For example, the JSON property source_m3u8 becomes the Python field source_m3_u8.

This is surprising for protocol/API fields and causes a practical problem with the existing --pydantic-base-model option: FastAPI/Pydantic validates request bodies against the generated Python field name, but the JSON payload still contains source_m3u8.

Reproduction

Input schema:

json
{
  "type": "object",
  "properties": {
    "source_m3u8": { "type": "string" }
  },
  "required": ["source_m3u8"]
}

Generate Python:

bash
quicktype \
  --src schema.json \
  --src-lang schema \
  --lang py \
  --python-version 3.7 \
  --pydantic-base-model \
  --top-level Request

The generated model contains:

python
class Request(BaseModel):
    source_m3_u8: str

Parsing the real API payload fails:

python
Request.model_validate({"source_m3u8": "https://example.test/live.m3u8"})
# ValidationError: source_m3_u8 - Field required

The generated from_dict helper does reference obj.get("source_m3u8"), but FastAPI/Pydantic does not call that helper when validating a request model.

Using --no-nice-property-names is not an adequate workaround because it produces sourcem3u8, which still does not preserve the original property name.

Proposed behavior

Add an opt-in Python renderer option, for example --keep-property-names:

  • default remains false, preserving current output;
  • when enabled, keep the original name if it is a valid Python identifier;
  • continue using the existing naming/legalization behavior for invalid identifiers and Python keywords.

This keeps the change backwards compatible while allowing generated Pydantic models to match API JSON keys directly.