-
-
Notifications
You must be signed in to change notification settings - Fork 408
Description
Is your feature request related to a problem? Please describe.
This library lets you generate pydantic types from graohql schemas. But responses from a server can't be validated against that pydantic class because the request can contain only a subset of the fields from the gql schema so even required fields may be None. You can get around this issue using the --force-optional flag, but that makes every field optional, even the ones that were included in the request.
It would be awesome if users were also able to specify the query object they are using so the generated types can have the appropriate fields be mandatory.
Describe the solution you'd like
In the input file, along with the graphql schema definition elements, allow query definitions. Each query should generate its own pydantic class with only the queried fields present. The field should be optional if the schema defines it as optional. It should be missing if the query doesn't include it.
Eaxample:
# schema.gql
type Query {
getProducts: GetProductsResponse!
getTags: GetTagsResponse!
}
type GetProductsResponse {
id: Int!
name: String!
}
type GetTagsResponse {
id: Int!
name: String
}
query getAllProducts {
getProducts {
id
name
}
}
query getAllTags {
getTags {
name
}
}Could generate (run python -m datamodel_code_generator --input-file-type=graphql --input=schema.gql --output-model-type=pydantic_v2.BaseModel --output schema.py):
# generated by datamodel-codegen:
# filename: schema.gql
# timestamp: 2025-10-28T16:27:05+00:00
from __future__ import annotations
from typing import Literal, Optional, TypeAlias
from pydantic import BaseModel, Field
Boolean: TypeAlias = bool
"""
The `Boolean` scalar type represents `true` or `false`.
"""
Int: TypeAlias = int
"""
The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
"""
String: TypeAlias = str
"""
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
"""
class GetProductsResponse(BaseModel):
id: Int
name: String
typename__: Optional[Literal['GetProductsResponse']] = Field(
'GetProductsResponse', alias='__typename'
)
class GetTagsResponse(BaseModel):
id: Int
name: Optional[String] = None
typename__: Optional[Literal['GetTagsResponse']] = Field(
'GetTagsResponse', alias='__typename'
)
# These are the proposed types to be generated from the queries
class QueryGetAllProducts(BaseModel):
getProducts: QueryGetAllProductsGetProducts
class QueryGetAllProductsGetProducts(BaseModel):
id: Int
typename__: Optional[Literal['GetProductsResponse']] = Field(
'GetProductsResponse', alias='__typename'
)
class QueryGetAllTags(BaseModel):
getTags: QueryGetAllTagsGetTags
class QueryGetAllTagsGetTags(BaseModel):
name: Optional[String] = None
typename__: Optional[Literal['GetTagsResponse']] = Field(
'GetTagsResponse', alias='__typename'
)Describe alternatives you've considered
- Have this be in a completely separate library. Doesn't seem necessary since this library is already doing most of the heavy lifting.
- Have a separate
--input-file-typefor this. Ideally I would like to have each query as a separate.gqlfile, but generating the models requires both the schema definition and the query, so I figured combining them would make sense. If there is a way to provide the schema definition file though (maybe a separate flag), I think this would be even better.
Additional context
Add any other context or screenshots about the feature request here.