Skip to content

Python: add an option to keep valid original property names #3099

Description

@foobra

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:

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

Generate Python:

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

The generated model contains:

class Request(BaseModel):
    source_m3_u8: str

Parsing the real API payload fails:

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions