API#

Anything documented here is part of the public API that Magql provides, unless otherwise indicated. Anything not documented here is considered internal or private and may change at any time.

Schema#

class magql.schema.Schema(types=None, description=None)#

A schema describes all the types and fields in a GraphQL API. Collectively, the objects and fields form the graph, and the remaining types define inputs and outputs. Unlike GraphQL-Core, Magql’s schema and nodes can be modified after definition, before finally being converted to a GraphQL-Core schema.

Parameters:
  • types (list[nodes.NamedType] | None) – Maps names to defined type instances (objects, input objects, enums, and scalars). Used to provide type definitions for types that are only referred to by name in the graph. (forward references).

  • description (str | None) – Help text to show in the schema.

query: Object#

The object containing the top-level query fields.

mutation: Object#

The object containing the top-level mutation fields.

type_map: dict[str, magql.nodes.NamedType | None]#

Maps names to type instances. Initially populated only with default types and passed in types, then filled in when calling to_graphql(). If the types have only partially been defined so far, some values may be None.

description: str | None#

Help text to show in the schema.

add_type(type)#

Add a named type to type_map. Used to provide type definitions for types that are only referred to by name in the graph (forward references).

Parameters:

type (NamedType) – The named type instance to add.

Return type:

None

to_graphql()#

Finalize the Magql schema by converting it and all its nodes to a GraphQL-Core schema. Will return the same instance each time it is called.

Changes to the Magql schema after this is called will not be reflected in the GraphQL schema.

Each GraphQL node will have a node.extensions["magql"] key with a reference back to the Magql node that generated it.

Return type:

GraphQLSchema

execute(source, root=None, context=None, variables=None, operation=None)#

Execute a GraphQL operation (query or mutation). Shortcut for calling to_magql() then calling graphql.graphql_sync() on the GraphQL schema.

The schema from to_magql() is cached, so calling this multiple times will not result in multiple compilations.

s.execute(...)

# equivalent to
gs = s.to_graphql()
import graphql
graphql.graphql_sync(gs, ...)

Only the basic arguments to graphql_sync are accepted, advanced use should call it directly.

Parameters:
  • source (str | Source) – The operation (query or mutation) written in GraphQL language to execute on the schema.

  • root (Any) – The parent data passed to top-level field resolvers.

  • context (Any) – Passed to resolvers as info.context. Useful for passing through shared resources such as a database connection or cache.

  • variables (dict[str, Any] | None) – Maps placeholder names in the source to input values passed along with the request.

  • operation (str | None) – The name of the operation if the source defines multiple.

Return type:

ExecutionResult

to_document()#

Format the schema as a document in the GraphQL schema language. Shortcut for calling to_magql() then calling graphql.graphql_sync().

Return type:

str

Nodes#

class magql.nodes.Object(name, fields=None, interfaces=None, description=None)#

A named collection of fields. Can be used as the type of a field. Cannot be used as the type of an argument, use InputObject instead.

Parameters:
  • name (str) – The name used to refer to this type.

  • fields (dict[str, str | Type | Field] | None) – Fields within this object. Each value may be the name of a type defined elsewhere, or a type instance, instead of a full field instance.

  • interfaces (list[str | Interface] | None) – Interfaces providing more fields for this object. Each item may be the name of an Interface defined elsewhere.

  • description (str | None) – Help text to show in the schema.

field(name, type, args=None, validators=None, description=None, deprecation=None)#

Shortcut to add a field to the object by decorating a resolver function.

Parameters:
  • name (str) – The name of the field on the object.

  • type (str | Type) – The type of the value returned by this field’s resolver. May be the string name of a type defined elsewhere.

  • args (dict[str, str | magql.nodes.Type | magql.nodes.Argument] | None) – Arguments available to this field’s resolver. Each value may be the string name of a type, or a type instance, instead of the full argument instance.

  • validators (list[magql.validators.DataValidatorCallable] | None) – Data validators applied to the collection of arguments.

  • description (str | None) – Help text to show in the schema.

  • deprecation (str | None) – Deprecation message to show in the schema.

Return type:

Callable[[ResolverCallable], ResolverCallable]

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

fields: dict[str, magql.nodes.Field]#

Dictionary mapping field names to instances. Type names or instances passed in have been converted to full field instances.

interfaces: list[str | magql.nodes.Interface]#

List of Interface instances that this type implements. Each item may be the name of a type defined elsewhere.

description: str | None#

Help text to show in the schema.

name: str#

The name used to refer to this type.

class magql.nodes.Field(type, args=None, validators=None, resolve=resolve_attr, description=None, deprecation=None)#

A field on an Object.

Each field has a resolver function to get its value from the parent object. Magql adds a validation system for the arguments before calling the resolver with those arguments.

The default resolver, resolve_attr(), looks up the field name as an attribute on the parent. If the parent is a dict, use resolve_item() instead to use the field name as a key.

Parameters:
  • type (str | Type) – The type of the value returned by this field’s resolver. May be the name of a type defined elsewhere.

  • args (dict[str, str | Type | Argument] | None) – Arguments available to this field’s resolver. Each value may be the name of a type, or a type instance, instead of the full argument instance.

  • validators (list[DataValidatorCallable] | None) – Data validators applied to the collection of arguments.

  • resolve (ResolverCallable) – The function to use to resolve this field, returning a value to the query. Defaults to attribute lookup by the name of the field in the object.

  • description (str | None) – Help text to show in the schema.

  • deprecation (str | None) – Deprecation message to show in the schema.

type: str | Type#

The type of the value returned by this field’s resolver. May be the name of a type defined elsewhere.

args: dict[str, magql.nodes.Argument]#

Arguments available to this field’s resolver. Type names or instances passed in have been converted to full argument instances.

description: str | None#

Help text to show in the schema.

deprecation: str | None#

Deprecation message to show in the schema.

pre_resolver(f)#

Call the decorated function at the beginning of the resolve process, before validating arguments or resolving the value.

This is useful to check permissions or log access. Raise a ValidationError to stop with an error instead.

Parameters:

f (ResolverCallable) –

Return type:

ResolverCallable

resolver(f)#

Call the decorated function to resolve the value of the field.

Raise a ValidationError to stop with an error instead.

Parameters:

f (ResolverCallable) –

Return type:

ResolverCallable

resolve(parent, info, **kwargs)#

The full resolver behavior provided by Magql. If a pre_resolve() function was registered, it is called first. Then validate() validates the input arguments. Finally, the resolver is called to get a value. Any part of this process can raise a ValidationError to stop with an error instead.

Do not override this function. Instead, use resolver(), validator(), and pre_resolver() to modify the behavior.

Parameters:
Return type:

Any

validator(f)#

Decorate a function to append to the list of validators.

Parameters:

f (_VCT) –

Return type:

_VCT

validators: list[_VCT]#

A list of functions that perform validation. More can be added by using the validator() decorator or adding to the list.

class magql.nodes.Argument(type, default=graphql.Undefined, validators=None, description=None, deprecation=None)#

An input argument to a Field resolver.

Parameters:
  • type (str | Type) – The type of the value passed to this argument. May be the name of a type defined elsewhere.

  • default (t.Any) – The default Python value to use if input is not provided. By default, it will not be passed to the resolver, which is not the same as a default of None.

  • validators (list[ValueValidatorCallable] | None) – Value validators applied to the input value.

  • description (str | None) – Help text to show in the schema.

  • deprecation (str | None) – Deprecation message to show in the schema.

type: str | Type#

The type of the value passed to this argument. May be the name of a type defined elsewhere.

default: Any#

The default Python value to use if input is not provided. By default, it will not be passed to the resolver, which is not the same as a default of None.

description: str | None#

Help text to show in the schema.

deprecation: str | None#

Deprecation message to show in the schema.

validate(info, value, data)#

Validate a given value by calling each validator in validators on this item’s value.

Parameters:
  • info (GraphQLResolveInfo) – GraphQL resolve info. Mainly useful for info.context.

  • value (Any) – The value being validated.

  • data (dict[str, Any]) – All input items being validated, of which this is one item.

Return type:

None

validator(f)#

Decorate a function to append to the list of validators.

Parameters:

f (_VCT) –

Return type:

_VCT

validators: list[_VCT]#

A list of functions that perform validation. More can be added by using the validator() decorator or adding to the list.

class magql.nodes.Interface(name, fields=None, interfaces=None, description=None)#

A named collection of fields that can are shared between multiple objects. Cannot be used as the type of a field.

Parameters:
  • name (str) – The name used to refer to this type.

  • fields (dict[str, str | Type | Field] | None) – Fields within this interface. Each value may be the name of a type defined elsewhere, or a type instance, instead of a full field instance.

  • interfaces (list[str | Interface] | None) – Interfaces providing more fields for this interface. Each item may be the name of an Interface defined elsewhere.

  • description (str | None) – Help text to show in the schema.

field(name, type, args=None, validators=None, description=None, deprecation=None)#

Shortcut to add a field to the object by decorating a resolver function.

Parameters:
  • name (str) – The name of the field on the object.

  • type (str | Type) – The type of the value returned by this field’s resolver. May be the string name of a type defined elsewhere.

  • args (dict[str, str | magql.nodes.Type | magql.nodes.Argument] | None) – Arguments available to this field’s resolver. Each value may be the string name of a type, or a type instance, instead of the full argument instance.

  • validators (list[magql.validators.DataValidatorCallable] | None) – Data validators applied to the collection of arguments.

  • description (str | None) – Help text to show in the schema.

  • deprecation (str | None) – Deprecation message to show in the schema.

Return type:

Callable[[ResolverCallable], ResolverCallable]

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

fields: dict[str, magql.nodes.Field]#

Dictionary mapping field names to instances. Type names or instances passed in have been converted to full field instances.

interfaces: list[str | magql.nodes.Interface]#

List of Interface instances that this type implements. Each item may be the name of a type defined elsewhere.

description: str | None#

Help text to show in the schema.

name: str#

The name used to refer to this type.

class magql.nodes.Union(name, types=None, description=None)#

A named group of objects. Can be used as the type of a field; when resolved the field must be one of the objects.

Parameters:
  • name (str) – The name used to refer to this type.

  • types (dict[type[t.Any], str | Object] | None) – Maps Python classes to Magql Object types. Each value may be the name of a type defined elsewhere.

  • description (str | None) – Help text to show in the schema.

types: list[str | magql.nodes.Object]#

List of Object types in this union. Each value may be the name of a type defined elsewhere.

Use add_type() instead of modifying this directly.

py_to_name: dict[type[Any], str]#

Map of Python classes to type names. Used to tell GraphQL what type from the union to use when resolving the value.

Use add_type() instead of modifying this directly.

description: str | None#

Help text to show in the schema.

add_type(py_type, gql_type=None)#

Add a new type to this union. The given Python class will be resolved to the given GraphQL type.

Parameters:
  • py_type (type[Any]) – The Python side of the type.

  • gql_type (str | Object | None) – The GraphQL side of the type.

Return type:

None

resolve_type(value, info, node)#

Resolves the Python value returned by a field’s resolver to a specific object name within this union.

Parameters:
  • value (Any) – The value returned by the field’s resolver.

  • info (GraphQLResolveInfo) – GraphQL resolve info. Mainly useful for info.context.

  • node (GraphQLUnionType) – The GraphQL union being resolved.

Return type:

str

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

name: str#

The name used to refer to this type.

class magql.nodes.InputObject(name, fields=None, validators=None, description=None)#

A named collection of input fields. Can be used as the type of an argument. Cannot be used as the type of a field, use Object instead.

Allows using a JSON object as the input value to an argument.

Parameters:
  • name (str) – The name used to refer to this type.

  • fields (dict[str, str | Type | InputField] | None) – Fields within this object. Each value may be the name of a type defined elsewhere, or a type instance, instead of a full field instance.

  • validators (list[DataValidatorCallable] | None) – Data validators applied to the collection of input fields.

  • description (str | None) – Help text to show in the schema.

fields: dict[str, magql.nodes.InputField]#

Fields within this object. Type names or instances passed in have been converted to full input field instances.

description: str | None#

Help text to show in the schema.

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

validator(f)#

Decorate a function to append to the list of validators.

Parameters:

f (_VCT) –

Return type:

_VCT

name: str#

The name used to refer to this type.

validators: list[_VCT]#

A list of functions that perform validation. More can be added by using the validator() decorator or adding to the list.

class magql.nodes.InputField(type, default=graphql.Undefined, validators=None, description=None, deprecation=None)#

An input field within an InputObject.

Parameters:
  • type (str | Type) – The type of the value passed to this field. May be the name of a type defined elsewhere.

  • default (t.Any) – The default Python value to use if input is not provided. By default, it will not be present in the dict, which is not the same as a default of None.

  • validators (list[ValueValidatorCallable] | None) – Value validators applied to the input value.

  • description (str | None) – Help text to show in the schema.

  • deprecation (str | None) – Deprecation message to show in the schema.

type: str | Type#

The type of the value passed to this argument. May be the name of a type defined elsewhere.

default: Any#

The default Python value to use if input is not provided. By default, it will not be present in the dict, which is not the same as a default of None.

description: str | None#

Help text to show in the schema.

deprecation: str | None#

Deprecation message to show in the schema.

validate(info, value, data)#

Validate a given value by calling each validator in validators on this item’s value.

Parameters:
  • info (GraphQLResolveInfo) – GraphQL resolve info. Mainly useful for info.context.

  • value (Any) – The value being validated.

  • data (dict[str, Any]) – All input items being validated, of which this is one item.

Return type:

None

validator(f)#

Decorate a function to append to the list of validators.

Parameters:

f (_VCT) –

Return type:

_VCT

validators: list[_VCT]#

A list of functions that perform validation. More can be added by using the validator() decorator or adding to the list.

class magql.nodes.NonNull(type)#

Indicates that null may not be used in place of a value of the wrapped type.

If you have a type object already, use its non_null property. Creating this class directly is useful when you need to reference the type by name instead.

Parameters:

type (str | Type) – The wrapped type. May be the name of a type defined elsewhere.

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

type: str | Type#

The wrapped type. May be the name of a type defined elsewhere.

class magql.nodes.List(type)#

Indicates that the value is a list of values of the wrapped type.

If you have a type object already, use its list property. Creating this class directly is useful when you need to reference the type by name instead.

When defining a list type, consider whether the value should be marked as non-null as well, and if items will always be non-null.

Arbitrarily nested list types can be created.

If you provide a single value as input, GraphQL-Core will wrap it in a list. However, its behavior when doing this for nested list types may be unexpected.

Parameters:

type (str | Type) – The wrapped type. May be the name of a type defined elsewhere.

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

type: str | Type#

The wrapped type. May be the name of a type defined elsewhere.

class magql.nodes.Enum(name, values, description=None)#

A set of possible values for a field or argument. The values are essentially strings in the schema, but when used as input or output they can map to other Python types.

Parameters:
  • name (str) – The name used to refer to this type.

  • values (t.Union[list[str], dict[str, t.Any], type[enum.Enum]]) – The possible string values mapped to Python values. A list of strings will use the same value on both sides. A Python :class:~enum.Enum` will use the member names mapped to the instances.

  • description (str | None) – Help text to show in the schema.

values: dict[str, Any]#

Maps string values used by GraphQL to Python values seen by the resolver. A list or Enum passed in has been converted to a dict.

description: str | None#

Help text to show in the schema.

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

name: str#

The name used to refer to this type.

class magql.nodes.Scalar(name, serialize=_identity, parse_value=_identity, description=None, specified_by=None)#

A plain value, as opposed to an object with nested fields.

Values are serialized when sent between client and server. The serialization format (typically JSON) may not be able to represent a type directly, so the scalar must be able to convert to and from the Python value.

Parameters:
  • name (str) – The name used to refer to this type.

  • serialize (t.Callable[[t.Any], t.Any]) – A function that converts a Python value to a format appropriate for the output serialization format. By default the value is returned unchanged.

  • parse_value (t.Callable[[t.Any], t.Any]) – A function that converts a value in the input serialization format to Python. By default the value is returned unchanged.

  • description (str | None) – Help text to show in the schema.

  • specified_by (str | None) – A reference to the specification defining this type. Shown alongside description in the schema.

property list: List#

Wrap this type in List, indicating that the value is a list of items of this type. Will return the same instance every time it is accessed.

property non_null: NonNull#

Wrap this type in NonNull, indicating that the value may not be null and must be of this type. Will return the same instance every time it is accessed.

name: str#

The name used to refer to this type.

serialize: Callable[[Any], Any]#

Convert a Python value to the output serialization format.

parse_value: Callable[[Any], Any]#

Convert a value in the input serialization format to Python.

description: str | None#

Help text to show in the schema.

specified_by: str | None#

A reference to the specification defining this type. Shown alongside description in the schema.

GraphQL Scalars#

GraphQL-Core provides implementations for the 5 built-in scalar types in the GraphQL spec. They are already used by GraphQL’s built-in introspection queries, and so must be patched by Magql rather than overridden.

magql.scalars.String: Scalar = <Scalar String>#

Built-in GraphQL String type.

magql.scalars.Int: Scalar = <Scalar Int>#

Built-in GraphQL Int type. Extends GraphQL-Core implementation to accept string values. Strings are common when using HTML forms.

magql.scalars.Float: Scalar = <Scalar Float>#

Built-in GraphQL Float type. Extends GraphQL-Core implementation to accept string values. Strings are common when using HTML forms.

magql.scalars.Boolean: Scalar = <Scalar Boolean>#

Built-in GraphQL Boolean type. Extends GraphQL-Core implementation to accept common case-insensitive string values; 1, on, true; 0, off, false. In particular, HTML forms send “on”.

magql.scalars.ID: Scalar = <Scalar ID>#

Built-in GraphQL ID type. Accepts strings, ints, and floats, converting them all to strings.

Magql Scalars#

Extra scalar types that are not provided by GraphQL-Core.

magql.scalars.DateTime: Scalar = <Scalar DateTime>#

Date, time, and timezone in ISO 8601 format. Uses dateutil’s isoparse. Input without a timezone is assumed to be UTC. Always returns a timezone-aware DateTime value.

magql.scalars.JSON: Scalar = <Scalar JSON>#

A raw JSON value. The inner shape of the object is not specified by or queried through the GraphQL schema. Useful for large blobs of opaque data, such as GeoJSON.

magql.scalars.Upload: Scalar = <Scalar Upload>#

An uploaded file, provided alongside the GraphQL request. Should only be used as an input type. See https://github.com/jaydenseric/graphql-multipart-request-spec. The spec is implemented by Magql’s Flask integration.

Resolvers#

magql.nodes.resolve_attr(parent, info, **kwargs)#

Resolve a field by getting the attribute of the same name from the parent. Equivalent to parent.field_name.

This is the default resolver.

Parameters:
Return type:

Any

magql.nodes.resolve_item(parent, info, **kwargs)#

Resolve a field by getting the key of the same name from the parent. Equivalent to parent["field_name"].

Parameters:
Return type:

Any

Validators#

exception magql.validators.ValidationError(message)#

A validator raises this in order to stop validation and add one or more error messages to the result.

Depending on the context, the messages can be different formats. Data validators (Field and InputObject) should always use a dict mapping field names to messages. Value validators (Argument and InputField) should always use a list of messages for a single field. Individual validator callables can also return a single message as a shortcut for a list.

Parameters:

message (t.Union[str, list[t.Any], dict[str, t.Any]]) – One or more error messages to add to the result.

Return type:

None

Data Source Base API#

This API is typically implemented and managed by a data source integration.

class magql.search.Search(providers=None, field_name='search')#

Query field and resolver that performs a global search and returns results for any object type. This is handled generically by registering a list of provider functions. Each function is called with the search term, combining all results.

The resolver returns a list of SearchResult items.

Parameters:
  • providers (list[SearchProvider] | None) – List of search provider functions.

  • field_name (str) – The name to use for this field in the top-level query object.

field: Field#

The query field.

type Query {
    search(value: String!): [SearchResult!]!
}
field_name: str#

The name to use for this field in the top-level query object.

provider(f)#

Decorate a function to append to the list of providers.

Parameters:

f (_SearchProvider) –

Return type:

_SearchProvider

register(schema)#

If at least one search provider is registered, register the field on the given Search instance.

Parameters:

schema (Schema) – The schema instance to register on.

Return type:

None

class magql.search.SearchResult(type, id, value, extra=None)#

The Search, and Search provider functions, must return a list of these values. search_result is the Magql type corresponding to this Python type.

A UI should be able to link to a given result by its type and id.

Parameters:
type: str#

The model name.

id: Any#

The row id.

value: str#

The value to display as the result.

extra: dict[str, Any] | None = None#

Arbitrary extra data about the result.

magql.search.search_result: Object = <Object SearchResult>#

The result type for the Search query. SearchResult is the Python type corresponding to this Magql type.

type SearchResult {
    type: String!
    id: ID!
    value: String!
    extra: JSON
}
class magql.check_delete.BaseCheckDelete(field_name='check_delete')#

Base class for implementations of the check_delete query.

Query field and resolver that shows what would be affected by deleting a row, without actually deleting it. Rather than creating a separate query per model, this is a generic API using the model name and id.

The resolver returns CheckDeleteResult, which is a collection of SearchResult items.

  • Affected - Items that will have references to the deleted item removed, such as many-to-many or nullable foreign keys.

  • Deleted - Items that will be deleted along with the deleted item.

  • Prevented - Items that will not be deleted or have references removed prevent the item from being deleted.

This shouldn’t need to be created directly, it’s implemented and managed by a specific data source integration.

Parameters:

field_name (str) – The name to use for this field in the top-level query object.

field: Field#

The query field.

type Query {
    check_delete(type: String!, id: ID!): CheckDeleteResult!
}
field_name: str#

The name to use for this field in the top-level query object.

register(schema)#

Register the field on the given Search instance.

Parameters:

schema (Schema) – The schema instance to register on.

Return type:

None

class magql.check_delete.CheckDeleteResult(affected=<factory>, deleted=<factory>, prevented=<factory>)#

The value returned by the CheckDelete resolver. check_delete_result is the Magql type corresponding to this Python type.

The items in each list are SearchResult, so that UI behavior can be shared between CheckDelete and Search.

Parameters:
affected: list[magql.search.SearchResult]#

Items that will have references to the deleted item removed, such as many-to-many or nullable foreign keys.

deleted: list[magql.search.SearchResult]#

Items that will be deleted along with the deleted item.

prevented: list[magql.search.SearchResult]#

Items that will not be deleted or have references removed prevent the item from being deleted.

magql.check_delete.check_delete_result: Object = <Object CheckDeleteResult>#

The result type for the CheckDelete query. CheckDeleteResult is the Python type corresponding to this Magql type.

The items in each list are search_result.

type CheckDeleteResult {
    affected: [SearchResult!]!
    deleted: [SearchResult!]!
    prevented: [SearchResult!]!
}
magql.filters.filter_item: InputObject = <InputObject FilterItem>#

The input type for the filter argument to data source list resolvers.

input FilterItem {
    path: String!
    op: String!
    not: Boolean! = false
    value: [JSON]!
}