mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 20:54:16 +03:00
Update schema.py
This commit is contained in:
parent
18cd3451f9
commit
ea4e6d65e9
|
@ -391,3 +391,137 @@ class TypeMap(dict):
|
|||
return graphql_type
|
||||
|
||||
return type_
|
||||
|
||||
|
||||
class Schema:
|
||||
"""Schema Definition.
|
||||
A Graphene Schema can execute operations (query, mutation, subscription) against the defined
|
||||
types. For advanced purposes, the schema can be used to lookup type definitions and answer
|
||||
questions about the types through introspection.
|
||||
Args:
|
||||
query (Type[ObjectType]): Root query *ObjectType*. Describes entry point for fields to *read*
|
||||
data in your Schema.
|
||||
mutation (Optional[Type[ObjectType]]): Root mutation *ObjectType*. Describes entry point for
|
||||
fields to *create, update or delete* data in your API.
|
||||
subscription (Optional[Type[ObjectType]]): Root subscription *ObjectType*. Describes entry point
|
||||
for fields to receive continuous updates.
|
||||
types (Optional[List[Type[ObjectType]]]): List of any types to include in schema that
|
||||
may not be introspected through root types.
|
||||
directives (List[GraphQLDirective], optional): List of custom directives to include in the
|
||||
GraphQL schema. Defaults to only include directives defined by GraphQL spec (@include
|
||||
and @skip) [GraphQLIncludeDirective, GraphQLSkipDirective].
|
||||
auto_camelcase (bool): Fieldnames will be transformed in Schema's TypeMap from snake_case
|
||||
to camelCase (preferred by GraphQL standard). Default True.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
query=None,
|
||||
mutation=None,
|
||||
subscription=None,
|
||||
types=None,
|
||||
directives=None,
|
||||
auto_camelcase=True,
|
||||
):
|
||||
self.query = query
|
||||
self.mutation = mutation
|
||||
self.subscription = subscription
|
||||
type_map = TypeMap(
|
||||
query, mutation, subscription, types, auto_camelcase=auto_camelcase
|
||||
)
|
||||
self.graphql_schema = GraphQLSchema(
|
||||
type_map.query,
|
||||
type_map.mutation,
|
||||
type_map.subscription,
|
||||
type_map.types,
|
||||
directives,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return print_schema(self.graphql_schema)
|
||||
|
||||
def __getattr__(self, type_name):
|
||||
"""
|
||||
This function let the developer select a type in a given schema
|
||||
by accessing its attrs.
|
||||
Example: using schema.Query for accessing the "Query" type in the Schema
|
||||
"""
|
||||
_type = self.graphql_schema.get_type(type_name)
|
||||
if _type is None:
|
||||
raise AttributeError(f'Type "{type_name}" not found in the Schema')
|
||||
if isinstance(_type, GrapheneGraphQLType):
|
||||
return _type.graphene_type
|
||||
return _type
|
||||
|
||||
def lazy(self, _type):
|
||||
return lambda: self.get_type(_type)
|
||||
|
||||
def execute(self, *args, **kwargs):
|
||||
"""Execute a GraphQL query on the schema.
|
||||
Use the `graphql_sync` function from `graphql-core` to provide the result
|
||||
for a query string. Most of the time this method will be called by one of the Graphene
|
||||
:ref:`Integrations` via a web request.
|
||||
Args:
|
||||
request_string (str or Document): GraphQL request (query, mutation or subscription)
|
||||
as string or parsed AST form from `graphql-core`.
|
||||
root_value (Any, optional): Value to use as the parent value object when resolving
|
||||
root types.
|
||||
context_value (Any, optional): Value to be made available to all resolvers via
|
||||
`info.context`. Can be used to share authorization, dataloaders or other
|
||||
information needed to resolve an operation.
|
||||
variable_values (dict, optional): If variables are used in the request string, they can
|
||||
be provided in dictionary form mapping the variable name to the variable value.
|
||||
operation_name (str, optional): If multiple operations are provided in the
|
||||
request_string, an operation name must be provided for the result to be provided.
|
||||
middleware (List[SupportsGraphQLMiddleware]): Supply request level middleware as
|
||||
defined in `graphql-core`.
|
||||
execution_context_class (ExecutionContext, optional): The execution context class
|
||||
to use when resolving queries and mutations.
|
||||
Returns:
|
||||
:obj:`ExecutionResult` containing any data and errors for the operation.
|
||||
"""
|
||||
kwargs = normalize_execute_kwargs(kwargs)
|
||||
return graphql_sync(self.graphql_schema, *args, **kwargs)
|
||||
|
||||
async def execute_async(self, *args, **kwargs):
|
||||
"""Execute a GraphQL query on the schema asynchronously.
|
||||
Same as `execute`, but uses `graphql` instead of `graphql_sync`.
|
||||
"""
|
||||
kwargs = normalize_execute_kwargs(kwargs)
|
||||
return await graphql(self.graphql_schema, *args, **kwargs)
|
||||
|
||||
async def subscribe(self, query, *args, **kwargs):
|
||||
"""Execute a GraphQL subscription on the schema asynchronously."""
|
||||
# Do parsing
|
||||
try:
|
||||
document = parse(query)
|
||||
except GraphQLError as error:
|
||||
return ExecutionResult(data=None, errors=[error])
|
||||
|
||||
# Do validation
|
||||
validation_errors = validate(self.graphql_schema, document)
|
||||
if validation_errors:
|
||||
return ExecutionResult(data=None, errors=validation_errors)
|
||||
|
||||
# Execute the query
|
||||
kwargs = normalize_execute_kwargs(kwargs)
|
||||
return await subscribe(self.graphql_schema, document, *args, **kwargs)
|
||||
|
||||
def introspect(self):
|
||||
introspection = self.execute(introspection_query)
|
||||
if introspection.errors:
|
||||
raise introspection.errors[0]
|
||||
return introspection.data
|
||||
|
||||
|
||||
def normalize_execute_kwargs(kwargs):
|
||||
"""Replace alias names in keyword arguments for graphql()"""
|
||||
if "root" in kwargs and "root_value" not in kwargs:
|
||||
kwargs["root_value"] = kwargs.pop("root")
|
||||
if "context" in kwargs and "context_value" not in kwargs:
|
||||
kwargs["context_value"] = kwargs.pop("context")
|
||||
if "variables" in kwargs and "variable_values" not in kwargs:
|
||||
kwargs["variable_values"] = kwargs.pop("variables")
|
||||
if "operation" in kwargs and "operation_name" not in kwargs:
|
||||
kwargs["operation_name"] = kwargs.pop("operation")
|
||||
return kwargs
|
||||
|
|
Loading…
Reference in New Issue
Block a user