mirror of
https://github.com/koxudaxi/datamodel-code-generator.git
synced 2024-03-18 14:54:37 +03:00
* Add scalar data type and template for this * Add union data type and template for this * Updater union template * Add typing.TypeAlias to default imports * Add graphql parser * Add first test * Formatted code style * Fix for test_main_simple_star_wars * Use poetry run ./scripts/format.sh * Fix `typename__` field for graphql object Set default literal value for `typename__` field * Add graphql docs * Add test: Check all GraphQL field types; * Add test: Check custom scalar py type; * Add test: Check graphql field aliases; * Run poetry run ./scripts/format.sh * Update graphql docs: Add section `Custom scalar types`; * poetry run ./scripts/format.sh
4.7 KiB
4.7 KiB
Generate from GraphQL
The code generator can create pydantic models from GraphQL schema definitions.
Simple example
$ datamodel-codegen --input schema.graphql --input-file-type graphql --output model.py
Let's consider a simple GraphQL schema (more details in https://graphql.org/learn/schema/).
schema.graphql
type Book {
id: ID!
title: String
author: Author
}
type Author {
id: ID!
name: String
books: [Book]
}
input BooksInput {
ids: [ID!]!
}
input AuthorBooksInput {
id: ID!
}
type Query {
getBooks(input: BooksInput): [Book]
getAuthorBooks(input: AuthorBooksInput): [Book]
}
model.py
# generated by datamodel-codegen:
# filename: schema.graphql
# timestamp: 2023-11-20T17:04:42+00:00
from __future__ import annotations
from typing import List, Optional, TypeAlias
from pydantic import BaseModel, Field
from typing_extensions import Literal
# The `Boolean` scalar type represents `true` or `false`.
Boolean: TypeAlias = bool
# The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
ID: 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.
String: TypeAlias = str
class Author(BaseModel):
books: Optional[List[Optional[Book]]] = Field(default_factory=list)
id: ID
name: Optional[String] = None
typename__: Optional[Literal['Author']] = Field('Author', alias='__typename')
class Book(BaseModel):
author: Optional[Author] = None
id: ID
title: Optional[String] = None
typename__: Optional[Literal['Book']] = Field('Book', alias='__typename')
class AuthorBooksInput(BaseModel):
id: ID
typename__: Optional[Literal['AuthorBooksInput']] = Field(
'AuthorBooksInput', alias='__typename'
)
class BooksInput(BaseModel):
ids: List[ID]
typename__: Optional[Literal['BooksInput']] = Field(
'BooksInput', alias='__typename'
)
Response deserialization
For the following response of getAuthorBooks GraphQL query
response.json
{
"getAuthorBooks": [
{
"author": {
"id": "51341cdscwef14r13",
"name": "J. K. Rowling"
},
"id": "1321dfvrt211wdw",
"title": "Harry Potter and the Prisoner of Azkaban"
},
{
"author": {
"id": "51341cdscwef14r13",
"name": "J. K. Rowling"
},
"id": "dvsmu12e19xmqacqw9",
"title": "Fantastic Beasts: The Crimes of Grindelwald"
}
]
}
main.py
from model import Book
response = {...}
books = [
Book.parse_obj(book_raw) for book_raw in response["getAuthorBooks"]
]
print(books)
# [Book(author=Author(books=[], id='51341cdscwef14r13', name='J. K. Rowling', typename__='Author'), id='1321dfvrt211wdw', title='Harry Potter and the Prisoner of Azkaban', typename__='Book'), Book(author=Author(books=[], id='51341cdscwef14r13', name='J. K. Rowling', typename__='Author'), id='dvsmu12e19xmqacqw9', title='Fantastic Beasts: The Crimes of Grindelwald', typename__='Book')]
Custom scalar types
$ datamodel-codegen --input schema.graphql --input-file-type graphql --output model.py --extra-template-data data.json
schema.graphql
scalar Long
type A {
id: ID!
duration: Long!
}
data.json
{
"Long": {
"py_type": "int"
}
}
model.py
# generated by datamodel-codegen:
# filename: custom-scalar-types.graphql
# timestamp: 2019-07-26T00:00:00+00:00
from __future__ import annotations
from typing import Optional, TypeAlias
from pydantic import BaseModel, Field
from typing_extensions import Literal
# The `Boolean` scalar type represents `true` or `false`.
Boolean: TypeAlias = bool
# The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
ID: TypeAlias = str
Long: TypeAlias = int
# 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.
String: TypeAlias = str
class A(BaseModel):
duration: Long
id: ID
typename__: Optional[Literal['A']] = Field('A', alias='__typename')