mirror of
				https://github.com/koxudaxi/datamodel-code-generator.git
				synced 2024-03-18 14:54:37 +03:00 
			
		
		
		
	 6e1de9b970
			
		
	
	6e1de9b970
	
	
	
		
			
			* 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
		
			
				
	
	
		
			196 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Generate from GraphQL
 | |
| 
 | |
| The code generator can create pydantic models from GraphQL schema definitions.
 | |
| 
 | |
| ## Simple example
 | |
| 
 | |
| ```bash
 | |
| $ 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**
 | |
| ```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**
 | |
| ```python
 | |
| # 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**
 | |
| ```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**
 | |
| ```python
 | |
| 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
 | |
| 
 | |
| ```bash
 | |
| $ datamodel-codegen --input schema.graphql --input-file-type graphql --output model.py --extra-template-data data.json
 | |
| ```
 | |
| 
 | |
| **schema.graphql**
 | |
| ```graphql
 | |
| scalar Long
 | |
| 
 | |
| type A {
 | |
|   id: ID!
 | |
|   duration: Long!
 | |
| }
 | |
| ```
 | |
| 
 | |
| **data.json**
 | |
| ```json
 | |
| {
 | |
|   "Long": {
 | |
|     "py_type": "int"
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| **model.py**
 | |
| ```python
 | |
| # 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')
 | |
| 
 | |
| ```
 |