koxudaxi / datamodel-code-generator

Pydantic model and dataclasses.dataclass generator for easy conversion of JSON, OpenAPI, JSON Schema, and YAML data sources.
https://koxudaxi.github.io/datamodel-code-generator/
MIT License
2.44k stars 281 forks source link

Generate Annotated types instead of root types for string constraints #2018

Open RonnyPfannschmidt opened 4 days ago

RonnyPfannschmidt commented 4 days ago

Is your feature request related to a problem? Please describe.

given a schema like

components:
  schemas:
    HereBeDragons:
      type: string
      pattern: here
    PassMe:
      type: object
      properties:
        mangled_string:
          anyOf:
            - $ref: '#/components/schemas/PettyNumber'
            - $ref: '#/components/schemas/HereBeDragons'
    PettyNumber:
      type: string
      pattern: '[0-9]{2,8}'

multiple root types are created and in turn create object indirection


from pydantic import BaseModel, Field, RootModel, constr

class HereBeDragons(RootModel[constr(pattern=r"here")]):
    root: constr(pattern=r"here")

class MoreValues(BaseModel):
    name: str
    age: int | None = None

class PettyNumber(RootModel[constr(pattern=r"[0-9]{2,8}")]):
    root: constr(pattern=r"[0-9]{2,8}")

class PassMe(BaseModel):
    mangled_string: PettyNumber | HereBeDragons | None = None

Describe the solution you'd like

decare the types more directly like

# using python 3.12+ syntax

from pydantic import BaseModel, Field, StringConstraints

type HereBeDragons = Annotated[str, StringConstraints(pattern=r"here")]
type PrettyNumber = Annotated[str, StringConstraints(pattern=r"[0-9]{2,8}")]

class PassMe(BaseModel):
    mangled_string: PettyNumber | HereBeDragons | None = None

Additional context Add any other context or screenshots about the feature request here.