Generate JSON Schema and GraphQL schemas directly from Python types. Supports all JSON Schema versions and provides comprehensive GraphQL schema generation with built-in types, decorators, and Relay patterns.
Generate JSON schemas for deserialization and serialization with support for all major JSON Schema versions and comprehensive constraint handling.
def deserialization_schema(
tp: AnyType,
*,
all_refs: bool = True,
version: Optional[JsonSchemaVersion] = None,
aliaser: Optional[Aliaser] = None,
additional_properties: Optional[bool] = None,
refs_set: Optional[RefsSet] = None,
with_definitions_schema: bool = False,
) -> Dict[str, Any]:
"""
Generate JSON schema for deserializing into the given type.
Parameters:
- tp: Type to generate schema for
- all_refs: Include all referenced type definitions
- version: JSON Schema version to use
- aliaser: Function to transform field names
- additional_properties: Allow additional properties in objects
- refs_set: Set to track references for circular handling
- with_definitions_schema: Include full definitions schema
Returns:
JSON Schema as dictionary
"""
def serialization_schema(
tp: AnyType,
*,
all_refs: bool = True,
version: Optional[JsonSchemaVersion] = None,
aliaser: Optional[Aliaser] = None,
additional_properties: Optional[bool] = None,
refs_set: Optional[RefsSet] = None,
with_definitions_schema: bool = False,
) -> Dict[str, Any]:
"""
Generate JSON schema for serializing the given type.
Parameters:
- tp: Type to generate schema for
- all_refs: Include all referenced type definitions
- version: JSON Schema version to use
- aliaser: Function to transform field names
- additional_properties: Allow additional properties in objects
- refs_set: Set to track references for circular handling
- with_definitions_schema: Include full definitions schema
Returns:
JSON Schema as dictionary
"""
def definitions_schema(
types: Iterable[AnyType],
*,
version: Optional[JsonSchemaVersion] = None,
aliaser: Optional[Aliaser] = None,
additional_properties: Optional[bool] = None,
) -> Dict[str, Any]:
"""
Generate schema definitions for multiple types.
Parameters:
- types: Iterable of types to generate definitions for
- version: JSON Schema version to use
- aliaser: Function to transform field names
- additional_properties: Allow additional properties in objects
Returns:
Schema definitions dictionary
"""Support for all major JSON Schema versions with automatic schema formatting.
class JsonSchemaVersion(Enum):
"""Supported JSON Schema versions."""
DRAFT_4 = "http://json-schema.org/draft-04/schema#"
DRAFT_6 = "http://json-schema.org/draft-06/schema#"
DRAFT_7 = "http://json-schema.org/draft-07/schema#"
DRAFT_2019_09 = "https://json-schema.org/draft/2019-09/schema"
DRAFT_2020_12 = "https://json-schema.org/draft/2020-12/schema"Generate complete GraphQL schemas from Python types with support for queries, mutations, subscriptions, and advanced features.
def graphql_schema(
query: Optional[Collection[Callable]] = None,
mutation: Optional[Collection[Callable]] = None,
subscription: Optional[Collection[Callable]] = None,
*,
types: Iterable[AnyType] = (),
directives: Optional[Collection[GraphQLDirective]] = None,
id_types: Optional[AbstractSet[AnyType]] = None,
scalar_serializers: Optional[Mapping[AnyType, ScalarSerializer]] = None,
) -> GraphQLSchema:
"""
Generate GraphQL schema from Python types and functions.
Parameters:
- query: Query operation functions or Query class
- mutation: Mutation operation functions or Mutation class
- subscription: Subscription operation functions or Subscription class
- types: Additional types to include in schema
- directives: Custom GraphQL directives
- id_types: Types to treat as GraphQL ID type
- scalar_serializers: Custom scalar serialization functions
Returns:
GraphQLSchema object from graphql-core
"""Built-in types and base classes for GraphQL schema definition.
class Query:
"""Base class for GraphQL query operations."""
pass
class Mutation:
"""Base class for GraphQL mutation operations."""
pass
class Subscription:
"""Base class for GraphQL subscription operations."""
pass
ID = NewType("ID", str) # GraphQL ID typeDecorators for enhanced GraphQL functionality and type definitions.
def resolver(func: Func) -> Func:
"""
Mark function as GraphQL resolver.
Parameters:
- func: Function to mark as resolver
Returns:
Decorated function
"""
def interface(cls: Cls) -> Cls:
"""
Mark class as GraphQL interface.
Parameters:
- cls: Class to mark as interface
Returns:
Decorated class
"""from dataclasses import dataclass
from typing import List, Optional
from apischema.json_schema import deserialization_schema, JsonSchemaVersion
@dataclass
class User:
id: int
name: str
email: Optional[str] = None
tags: List[str] = field(default_factory=list)
# Generate deserialization schema
schema = deserialization_schema(User)
print(schema)
# {
# "$schema": "https://json-schema.org/draft/2020-12/schema",
# "type": "object",
# "properties": {
# "id": {"type": "integer"},
# "name": {"type": "string"},
# "email": {"type": "string"},
# "tags": {"type": "array", "items": {"type": "string"}, "default": []}
# },
# "required": ["id", "name"],
# "additionalProperties": false
# }
# Use specific JSON Schema version
schema = deserialization_schema(User, version=JsonSchemaVersion.DRAFT_7)
print(schema["$schema"]) # "http://json-schema.org/draft-07/schema#"from apischema import schema
@dataclass
class Product:
name: str = field(metadata=schema(min_len=1, max_len=100))
price: float = field(metadata=schema(min=0, exc_max=10000))
category: str = field(metadata=schema(pattern=r"^[a-z]+$"))
schema_def = deserialization_schema(Product)
print(schema_def["properties"]["name"])
# {"type": "string", "minLength": 1, "maxLength": 100}
print(schema_def["properties"]["price"])
# {"type": "number", "minimum": 0, "exclusiveMaximum": 10000}
print(schema_def["properties"]["category"])
# {"type": "string", "pattern": "^[a-z]+$"}from typing import List
from apischema.graphql import graphql_schema, ID
from graphql import print_schema
@dataclass
class User:
id: ID
name: str
email: str
# Define GraphQL operations as functions
def get_user(id: ID) -> Optional[User]:
"""Get user by ID."""
pass
def list_users(limit: int = 10) -> List[User]:
"""List users with pagination."""
pass
def create_user(name: str, email: str) -> User:
"""Create a new user."""
pass
def update_user(id: ID, name: Optional[str] = None) -> User:
"""Update user information."""
pass
# Generate GraphQL schema
schema = graphql_schema(
query=[get_user, list_users],
mutation=[create_user, update_user],
id_types={UUID} # Treat UUID as GraphQL ID
)
# Print GraphQL SDL
print(print_schema(schema))
# type Query {
# getUser(id: ID!): User
# listUsers(limit: Int = 10): [User!]!
# }
#
# type Mutation {
# createUser(name: String!, email: String!): User!
# updateUser(id: ID!, name: String): User!
# }
#
# type User {
# id: ID!
# name: String!
# email: String!
# }class Query:
def user(self, id: ID) -> Optional[User]:
pass
def users(self, limit: int = 10) -> List[User]:
pass
class Mutation:
def create_user(self, name: str, email: str) -> User:
pass
# Generate schema from classes
schema = graphql_schema(query=Query, mutation=Mutation)from apischema.graphql import interface
@interface
@dataclass
class Node:
id: ID
@dataclass
class User(Node):
name: str
email: str
@dataclass
class Post(Node):
title: str
content: str
author_id: ID
def node(id: ID) -> Optional[Node]:
"""Get any node by ID."""
pass
schema = graphql_schema(query=[node])
print(print_schema(schema))
# interface Node {
# id: ID!
# }
#
# type User implements Node {
# id: ID!
# name: String!
# email: String!
# }@dataclass
class Address:
street: str
city: str
country: str
@dataclass
class Company:
name: str
address: Address
@dataclass
class Employee:
name: str
company: Company
# Generate schema with all referenced types
schema = definitions_schema([Employee, Company, Address])
print(schema.keys()) # dict_keys(['$defs', '$schema'])
print(schema['$defs'].keys()) # dict_keys(['Employee', 'Company', 'Address'])RefsSet = Set[str] # Set for tracking schema references
ScalarSerializer = Callable[[Any], Any] # Function for custom scalar serialization