What is the meta subclass in graphene?
Asked Answered
B

1

6

I'm learning how to use GraphQL and python. I've found the graphene project along with it's SQLAlchemy and Flask extensions. I've been reading tutorials and docs and I'm having trouble figuring out what class Meta is used for when defining a schema. I'm currently following this tutorial. I've googled around and can't seem to find anything.

Here's some code from the tutorial. I've commented on the line that's confusing me.

from graphene_sqlalchemy import SQLAlchemyObjectType
from database.model_people import ModelPeople
import graphene


# Create a generic class to mutualize description of people attributes for both queries and mutations
class PeopleAttribute:
    name = graphene.String(description="Name of the person.")
    height = graphene.String(description="Height of the person.")
    mass = graphene.String(description="Mass of the person.")
    hair_color = graphene.String(description="Hair color of the person.")
    skin_color = graphene.String(description="Skin color of the person.")
    eye_color = graphene.String(description="Eye color of the person.")
    birth_year = graphene.String(description="Birth year of the person.")
    gender = graphene.String(description="Gender of the person.")
    planet_id = graphene.ID(description="Global Id of the planet from which the person comes from.")
    url = graphene.String(description="URL of the person in the Star Wars API.")


class People(SQLAlchemyObjectType, PeopleAttribute):
    """People node."""

    # ---------- What's this class used for? Which part of the flask + graphene + sqlalchemy ecosystem uses it?
    class Meta:
        model = ModelPeople
        interfaces = (graphene.relay.Node,)
Beret answered 11/5, 2018 at 22:2 Comment(0)
H
7

I am in the same boat as you. Probably a little late for you but for anyone else running into this same question this is what I found when I was learning about GraphQL and Graphene.

I was confused about the subclass Meta class as well. This is what the documentation states.

Graphene uses a Meta inner class on ObjectType to set different options.

https://docs.graphene-python.org/en/latest/types/objecttypes/#objecttype-configuration-meta-class

The Meta class essentially allows you to change/modify the attributes of the class. For example you can change the name of how you would query that particular class by setting the name = <short name of class>.

By default the type name in the GraphQL schema will be the same as the class name that defines the ObjectType. This can be changed by setting the name property on the Meta class:

The example they use is this..

from graphene import ObjectType

class MyGraphQlSong(ObjectType):
    class Meta:
        name = 'Song'

So instead of having to query the "MyGraphQlSong" you can query it via "Song".

You can also add other things such as Description, and the interfaces that your parent class is supposed to inherit from (all described in the link above).

The full list of attributes you can change/modify are in the API reference (this is specific to the ObjectType. Other types have other meta class options. It is explained in more detail here. https://docs.graphene-python.org/en/latest/api/

Meta class options (optional):

    name (str): Name of the GraphQL type (must be unique in schema). Defaults to class
        name.
    description (str): Description of the GraphQL type in the schema. Defaults to class
        docstring.
    interfaces (Iterable[graphene.Interface]): GraphQL interfaces to extend with this object.
        all fields from interface will be included in this object’s schema.
    possible_types (Iterable[class]): Used to test parent value object via isintance to see if
        this type can be used to resolve an ambigous type (interface, union).
    default_resolver (any Callable resolver): Override the default resolver for this
        type. Defaults to graphene default resolver which returns an attribute or dictionary key with the same name as the field.
    fields (Dict[str, graphene.Field]): Dictionary of field name to Field. Not recommended to
        use (prefer class attributes).

I had issues finding where "model = ..." was coming from in the SQLAlchemy examples. I could not find any documentation referencing what "model" meant but my guess was that since SQLAlchemyObjectType is a subclass of ObjectType, SQLAlchemyObjectType added a few of its own "options" that aren't really documented (as far as I can tell). I went and read through the source code and sure enough I found this reference to "model = ..."

https://github.com/graphql-python/graphene-sqlalchemy/blob/master/graphene_sqlalchemy/types.py#L174

The SQLAlchemyObjectType class adds three more options, model, registry, and connection. If you look through the code the model option is your SQLAlchemy model class. The SQLAlchemyObjectType class uses the model option to inspect your model and create your respective fields automatically.

Hopefully this saves some other people time from having to look this up.

Handful answered 12/6, 2019 at 21:27 Comment(1)
I am on the same boat as you guys, too, :p ... Thanks for the answer. I just have a little tip to add, if you're using a modern IDE such as VSCode, you can just right-click on the parent class name(be it like DjangoObjectType or SQLAlchemyObjectType ) and "Go to definition", you'll see the full list of the options.Viosterol

© 2022 - 2024 — McMap. All rights reserved.