GraphQL framework for Python

Graphene Logo Graphene Build Status PyPI version Coverage Status

💬 Join the community on Slack

We are looking for contributors! Please check the ROADMAP to see how you can help ❤️

The below readme is the documentation for the dev (prerelease) version of Graphene. To view the documentation for the latest stable Graphene version go to the v2 docs


Graphene is an opinionated Python library for building GraphQL schemas/types fast and easily.

  • Easy to use: Graphene helps you use GraphQL in Python without effort.
  • Relay: Graphene has builtin support for Relay.
  • Data agnostic: Graphene supports any kind of data source: SQL (Django, SQLAlchemy), NoSQL, custom Python objects, etc. We believe that by providing a complete API you could plug Graphene anywhere your data lives and make your data available through GraphQL.


Graphene has multiple integrations with different frameworks:

integration Package
Django graphene-django
SQLAlchemy graphene-sqlalchemy
Google App Engine graphene-gae

Also, Graphene is fully compatible with the GraphQL spec, working seamlessly with all GraphQL clients, such as Relay, Apollo and gql.


For instaling graphene, just run this command in your shell

pip install "graphene>=2.0"


Here is one example for you to get started:

import graphene

class Query(graphene.ObjectType):
    hello = graphene.String(description='A typical hello world')

    def resolve_hello(self, info):
        return 'World'

schema = graphene.Schema(query=Query)

Then Querying graphene.Schema is as simple as:

query = '''
    query SayHello {
result = schema.execute(query)

If you want to learn even more, you can also check the following examples:


Documentation and links to additional resources are available at


After cloning this repo, create a virtualenv and ensure dependencies are installed by running:

virtualenv venv
source venv/bin/activate
pip install -e ".[test]"

Well-written tests and maintaining good test coverage is important to this project. While developing, run new and existing tests with:

py.test graphene/relay/tests/ # Single file
py.test graphene/relay # All tests in directory

Add the -s flag if you have introduced breakpoints into the code for debugging. Add the -v ("verbose") flag to get more detailed test output. For even more detailed output, use -vv. Check out the pytest documentation for more options and test running controls.

You can also run the benchmarks with:

py.test graphene --benchmark-only

Graphene supports several versions of Python. To make sure that changes do not break compatibility with any of those versions, we use tox to create virtualenvs for each Python version and run tests with that version. To run against all Python versions defined in the tox.ini config file, just run:


If you wish to run against a specific version defined in the tox.ini file:

tox -e py36

Tox can only use whatever versions of Python are installed on your system. When you create a pull request, Travis will also be running the same tests and report the results, so there is no need for potential contributors to try to install every single version of Python on their own system ahead of time. We appreciate opening issues and pull requests to make graphene even more stable & useful!

Building Documentation

The documentation is generated using the excellent Sphinx and a custom theme.

An HTML version of the documentation is produced by running:

make docs
  • Graphene real-time subscriptions and Apollo client graphql integration

    Graphene real-time subscriptions and Apollo client graphql integration

    Hello @syrusakbary.

    Thanks for all your hard work on graphene and graphql-python. Awesome library!!

    I posted this on #393 earlier this week...reposting here so it's easier to discover.

    I implemented a port of the apollo graphql subscriptions modules (graphql-subscriptions and subscriptions-transport-ws) for graphene / python. They work w/ apollo-client.

    It is here.

    Same basic api as the Apollo modules. It is still very rough...but works so far, based on my limited internal testing. Uses redis-py, gevent-websockets, and syrusakbary/promises. I was going to add a simple example app, for easier install, and more info to the readme w/ the API, in the next few days. A brief example is below. Only works on python2 for now. My plan is to start working on tests as well. I figured I'd go ahead and share in this early stage in case anybody is interested...

    I'm very new to open source, so any critiques or pull requests are welcome.

    Simple example:

    Server (using Flask and Flask-Sockets):

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    from flask_sockets import Sockets
    from .subscription_manager import SubscriptionManager, RedisPubsub
    from .subscription_transport_ws import ApolloSubscriptionServer
    app = Flask(__name__)
    sockets = Sockets(app)
    pubsub = RedisPubsub()
    schema = graphene.Schema(
    subscription_mgr = SubscriptionManager(schema, pubsub)
    def socket_channel(websocket):
        subscription_server = ApolloSubscriptionServer(subscription_mgr, websocket)
        return []
    if __name__ == "__main__":
        from geventwebsocket import WebSocketServer
        server = WebSocketServer(('', 5000), app)
        print '  Serving at host\n'

    Of course on the server you have to "publish" each time you have a mutation (in this case to a redis channel). That could look something like this (using graphene / sql-alchemy):

    class Subscription(graphene.ObjectType):
        users = graphene_sqlalchemy.SQLAlchemyConnectionField(
        def resolve_users(self, args, context, info):
            query = User.get_query(context)
            return query.filter_by(id=info.root_value.get('id'))
    class AddUser(graphene.ClientIDMutation):
        class Input:
            username = graphene.String(required=True)
            email = graphene.String()
        ok = graphene.Boolean()
        user = graphene.Field(lambda: User)
        def mutate_and_get_payload(cls, args, context, info):
            _input = args.copy()
            del _input['clientMutationId']
            new_user = UserModel(**_input)
            ok = True
            if pubsub.subscriptions:
                pubsub.publish('users', new_user.as_dict())
            return AddUser(ok=ok, user=new_user)

    Client (using react-apollo client):

    import React from 'react'
    import ReactDOM from 'react-dom'
    import { graphql, ApolloProvider } from 'react-apollo'
    import gql from 'graphql-tag'
    import ApolloClient, { createNetworkInterface } from 'apollo-client'
    import { SubscriptionClient, addGraphQLSubscriptions } from 'subscriptions-transport-ws'
    import ChatApp from './screens/ChatApp'
    import ListBox from '../components/ListBox'
    const SUBSCRIPTION_QUERY = gql`
      subscription newUsers {
        users(active: true) {
          edges {
            node {
    const LIST_BOX_QUERY = gql`
      query AllUsers {
        users(active: true) {
          edges {
            node {
    class ChatListBox extends React.Component {
      componentWillReceiveProps(newProps) {
        if (! {
          if (this.subscription) {
          this.subscription ={
            document: SUBSCRIPTION_QUERY,
            updateQuery: (previousResult, {subscriptionData}) => {
              const newUser =
              const newResult = {
                users: {
                  edges: [
              return newResult
            onError: (err) => console.error(err)
      render() {
        return <ListBox data={} />
    const ChatListBoxWithData = graphql(LIST_BOX_QUERY)(ChatListBox)
    export default ChatListBoxWithData
    const networkInterface = createNetworkInterface({
      uri: 'http://localhost:5000/graphql'
    const wsClient = new SubscriptionClient(`ws://localhost:5000/socket`, {
      reconnect: true
    const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
    const client = new ApolloClient({
      dataIdFromObject: o =>,
      networkInterface: networkInterfaceWithSubscriptions
      <ApolloProvider client={client}>
        <ChatApp />
  • ☂️ Graphene v3

    ☂️ Graphene v3

    This issue is to track v3 of Graphene which will contain some breaking changes.

    Breaking changes

    • Upgrade to graphql-core to v3 which brings feature parity with GraphQL.js v14.6.0
    • Drop support for Python v2
    • Schema type changes
    • "Backends" have been removed
    • Switch arguments from type to type_ since type is a builtin:
    • Upgrade to graphql-core v.3.1 which corresponds to GraphQL.js v15 (will be released soon).
    • Change enum behaviour:
    • Remove to_const function


    • [x] Write up some proper release notes:
    • [x] Merge
    • [x] Switch arguments from type to type_ since type is a builtin:
    • [x] Remove to_const function: #1212
    • [x] Change enum behaviour:
    • [x] Set minimum graphql-core version to v3.1
    • [x] Upgrade graphene-sqlalchemy to v3 WIP
    • [x] Upgrade graphene-mongo to v3 WIP
  • Maintenance Plan

    Maintenance Plan


    We need to start working on a Maintenance plan for Graphene and it's sub-projects: graphene-django, graphene-sqlalchemy, graphql-core, graphql-core-next ... .


    Right now my main focus has diverged from Graphene.

    Because of that but also because my main focus is now on @wasmerio (which takes most of my time), we should plan a proper way to maintain Graphene in the long term without being blocked by my explicit approval, so it keeps growing at a healthy pace from contributors willing to take the time to make the project shine.

    How we will do it?

    Few months ago I've created an internal Slack channel, with people from Yelp, Reddit and other companies to have a direct way of communication with them. I would love to invite more people to join this channel, so we can discuss the maintainance plan in a realtime fashion. If you are interested in joining, please write your email as a comment on this issue :)

    Ideal Solution

    Ideally, we will form a committee of experts that have the knowledge and insight into what Graphene needs in both the short and long term. Done in a way that is not skewed on doing what only one or two companies need, but rather to focus on the community and the global needs.

    I do like the way Django and the PSF are doing this, but more ideas will also be more than welcome!

    At the same time, because all this years have gave me a lot of insight, I'll keep beign the belevolent dictator for Graphene, but my role will be more on the back side rather than in the front.

    Looking forward to hearing your thoughts! :)

  • Added support for subscription

    Added support for subscription

    This is my first ever pull request so please be kind :)

    This adds subscription functionality to v3 by introducing a subscribe method to the schema.

    import asyncio
    from datetime import datetime
    from graphene import ObjectType, String, Schema, Field
    # All schema must contain a query.
    class Query(ObjectType):
        hello = String()
        def resolve_hello(root, info):
            return 'Hello, world!'
    class Subscription(ObjectType):
        time_of_day = Field(String)
        async def subscribe_time_of_day(root, info):
            while True:
                yield { 'time_of_day':}
                await asyncio.sleep(1)
    SCHEMA = Schema(query=Query, subscription=Subscription)
    async def main(schema):
        subscription = 'subscription { timeOfDay }'
        result = await schema.subscribe(subscription)
        async for item in result:
  • Apollo Optics Integration

    Apollo Optics Integration

  • Django integration implementation

    Django integration implementation

    I'm creating this (work in progress) pull request given that #48 seems to have developed a sensible solution.

    This pull request currently represents the contents of the original proposed Gist which can be found at:


    • [x] Create a GlobalIDFilter and GlobalIDField field
    • ~~Consider allowing the new resolvers to be used as function decorators (as per @syrusakbary suggestion)~~
    • [x] Allow FilterSet classes to be created dynamically created upon passing a fields argument to DjangoFilterConnectionField (as per @syrusakbary suggestion)
    • [x] Write tests
    • [x] django-filter should be an optional package
    • [x] Filtering on to-many fields
    • [x] Change order parameter name to order rather than o
    • [x] Filtering information should be stored on the destination node's Meta class
    • [x] Filtering should be available on nodes without having to explicitly define the fields
    • ~~Filtering should be enabled explicitly (i.e. via Django setting) rather than implicit (via presence of django-filter).~~
    • [x] Documentation

    Useful, but perhaps for a second phase of development:

    • [ ] Support for lazy loading of related nodes
    • [ ] Loading of app-level query classes
  • Error handling

    Error handling

    We have decided to approach error handling like suggested in many blogs, by having errors defined as fields rather than raising exceptions.

    The thing with this is that we need to make sure we catch every exception that we want to handle and somehow keep track of them to be able to inform them.

    So we came up with:

    class BaseObjectType(graphene.ObjectType):
        class Meta:
            abstract = True
        def __init_subclass_with_meta__(
                interfaces, possible_types, default_resolver, _meta, **options)
            for f in cls._meta.fields:
                if f in ['errors']:
                resolver_name = "resolve_{}".format(f)
                if hasattr(cls, resolver_name):
                    setattr(cls, resolver_name, catch_errors(getattr(cls, resolver_name)))
    class BaseResponse(BaseObjectType):
        class Meta:
            abstract = True
        errors = graphene.String()
        def resolve_errors(root, info, **kwargs):
            operation_name = info.path[0]
            error_key = f"{operation_name}_errors"
            if not root.errors and error_key in info.context.errors:
                root.errors = ",".join(info.context.errors[error_key])
            return root.errors

    catch_errors just populates info.context.errors for each operation

    While implementing this approach for error handling I have also found an issue when resolving the error field. I have a base class that extends ObjectType by iterating over the resolvers and wrapping them to n catch any errors and setting an errors dict in the info.context.

    Problem is that when resolving a type field that throws an exception, I do catch it and set the error, but the error field was already processed/resolved. Is there a way to force a particular field to be processed at the end or to force it to update? I need to make sure every resolver runs before the error field is resolver so I make sure all errors are caught.

  • Saving null value for nullable fields

    Saving null value for nullable fields

    I had a problem saving the null values in the mutations. Is it possible to implement functionality to get_argument_values function could distinguish passed null value and not passed value? I think it can be implemented similar to the executor.ececute_fields using Undefined.

  • Add Documentation for Relay Edge implementation

    Add Documentation for Relay Edge implementation

    In the Relay mutation docs, performing RANGE_ADD requires that the new edge created by the mutation is provided in the payload.

    I do not know how to provide the correct cursor/Edge construction within the relay.ClientIDMutation subclass.

    The following code I wrote:

    new_object_edge = graphene.Field('ObjectEdge')

    I believed would solve my issue, with a proper resolve_new_object_edge(...) resolver.

    However, my resolver cannot reference the relay.ConnectionField that is specified on one of the other object types in my mutation, since it only has the context of my (in this case, Django) objects.

    I experimented with relay.Edge.for_node(SomeObjectType) as well but all of the solutions I have tried so far modify the schema correctly but cannot return the appropriate Edge.

    The implementation of this scenario in javascript can be found here in the Relay examples directory.

    Any idea of a best approach? I can take this question to stack overflow, but felt that people using Relay & Graphene would enjoy seeing an example solution in the docs.

  • Protection against malicious queries

    Protection against malicious queries

    Hey. I was looking for a lot of information on how to protect against malicious requests, and as a result I found several common approaches:

    • query cost or resource limitations (
    • limiting query depth (
    • query whitelisting
    • hide introspection for production mode (this is not common solution, but sounds good)

    All this approaches we can implement by meddleware and custom backend. But it will be cool if this solution is out of the box.

    Also, graphene don't have information about security into the documentation.

    ps: I can try to help, but if u have no reason why this is a bad idea.

  • Authorization for Node queries

    Authorization for Node queries


    It would be helpful to have a standard way to do authorization in graphene, specifically for Node Relay queries. In non-Node queries it's easy enough to enforce authorization in resolve_XXX (mentioned in but for Node we need a hook to inject type-specific and argument-specific checks.

    We're most using @ekampf 's graphene-gae so in theory we could inherit and override NdbObjectType.get_node but that would require doing a similar override in for non-ndb types.

    Any plans to support authorization directly in graphene?

  • Update docs for v3

    Update docs for v3

    The current documentation website hasn't been updated for Graphene v3:

    image image

    The release notes are helpful, but if you are starting using Graphene for the first time with v3, it is confusing to be faced with outdated docs.

  • Propsal: Add registry for enum conversion

    Propsal: Add registry for enum conversion

    Graphene offers a convenient method to convert a Python-Enum (PyEnum) to a graphene-compatible enum (GEnum) using the types.Enum.from_enum() function. However, this function creates a new type each time it is called, even when called with the same PyEnum twice:

    from enum import Enum as PyEnum
    from graphene import Enum
    class MyEnum(PyEnum):
        A = 1
        B = 2
        C = 3
    GEnum = Enum.from_enum(MyEnum)
    GEnum2 = Enum.from_enum(MyEnum)
    print(GEnum == GEnum2)

    graphene-sqlalchemy currently uses an enum registry to convert SQLAlchemy enums to corresponding graphene enums without duplication:

    I propose that we backport this method to graphene for use with all python Enum types. I don't see a use-case for having two converted enums referencing the same underlying enum. For backward compatibility, the old function could remain in code, or the use of the enum registry could be enabled/disabled using optional arguments. This change would be helpful for the automatic conversion of python enums to graphene enums. It might prevent user confusion when two types with the same properties are created from an underlying enum.

    Would work on a PR if this is desired. Let me know what you think!

  • Argument with wrong value type do not raise an error

    Argument with wrong value type do not raise an error

    Currently, setting the value of an input with the wrong type is not raising an error. For example if the input as the type UUID and that you provide the value 2 it doesn't fail.

    There are various cases like that (see tests in the pull request for an extensive list).

    This is due to the fact that now no value is represented by Undefined and not None in graphql-core.

  • from graphene.utils.str_converters import to_camel_case, to_const

    from graphene.utils.str_converters import to_camel_case, to_const

    • What is the current behavior?

    Getting error:

        from graphene_django.views import GraphQLView
      File "backend/lib/python3.8/site-packages/graphene_django/", line 1, in <module>
        from .types import (
      File "backend/lib/python3.8/site-packages/graphene_django/", line 9, in <module>
        from .converter import convert_django_field_with_choices
      File "backend/lib/python3.8/site-packages/graphene_django/", line 8, in <module>
        from graphene.utils.str_converters import to_camel_case, to_const
    ImportError: cannot import name 'to_const' from 'graphene.utils.str_converters' (backend/lib/python3.8/site-packages/graphene/utils/
  • Exception handeling in query

    Exception handeling in query


    all the solution mentioned in this issue are for mutation, is there a way to send custom output for a query?

    I am trying to handle permissions for different queries and have decorators that will filter premonitions from resolver example code would be like this:

    class OutputMixin:
        A class to all public classes extend to
        padronize the output
        success = graphene.Boolean(default_value=True)
        errors = graphene.Field(ExpectedErrorType)
    class ServerStatusType(DjangoObjectType, OutputMixin):
        class Meta:
            model = models.ServerStatusRecord
    def admin_only(fn):
        def wrapper(root, info  *args, **kwargs):
            user = info.context.user
            if user.is_admin:
                return fn(*args, **kwargs)
            return cls(success=False, errors=Messages.NOT_VERIFIED)
        return wrapper
    class StatusQuery(graphene.ObjectType):
        current_status = graphene.Field(ServerStatusType)
        def resolve_current_status(cls, root, info, **kwargs):
            return models.ServerStatusRecord.objects.latest()

    While this code works flawlessly with mutations it doesn't work with queries because the the resolve function isn't accepting the object type as the first argument the object exists under info.return_type.graphene_type(success=False, errors="fdsaf") but its seems like a terrible hack and all the fields are required so i cant return just that.

MGE-GraphQL is a Python library for building GraphQL mutations fast and easily

MGE-GraphQL Introduction MGE-GraphQL is a Python library for building GraphQL mutations fast and easily. Data Validations: A similar data validation w

Apr 23, 2022
GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations

BatchQL BatchQL is a GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations. This script is not complex, and

May 18, 2022
A Django GraphQL Starter that uses graphene and graphene_django to interface GraphQL.

Django GraphQL Starter GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data... According to the doc

Jan 10, 2022
GraphQL framework for Python

Graphene ?? Join the community on Slack We are looking for contributors! Please check the ROADMAP to see how you can help ❤️ The below readme is the d

May 19, 2022
GraphQL framework for Python

Graphene ?? Join the community on Slack We are looking for contributors! Please check the ROADMAP to see how you can help ❤️ The below readme is the d

May 20, 2022
Ariadne is a Python library for implementing GraphQL servers using schema-first approach.
Ariadne is a Python library for implementing GraphQL servers using schema-first approach.

Ariadne Ariadne is a Python library for implementing GraphQL servers. Schema-first: Ariadne enables Python developers to use schema-first approach to

May 19, 2022
GraphQL Engine built with Python 3.6+ / asyncio
GraphQL Engine built with Python 3.6+ / asyncio

Tartiflette is a GraphQL Server implementation built with Python 3.6+. Summary Motivation Status Usage Installation Installation dependencies Tartifle

May 22, 2022
A new GraphQL library for Python 🍓
A new GraphQL library for Python 🍓

Strawberry GraphQL Python GraphQL library based on dataclasses Installation ( Quick Start ) The quick start method provides a server and CLI to get go

May 17, 2022
A python graphql api, which serves ECB currency rates from last 90 days.
A python graphql api, which serves ECB currency rates from last 90 days.

Exchange Rate Api using GraphQL Get Code git pull Create .env file with following content and s

Nov 4, 2021
This is a simple Python that will parse instanceStats GraphQL Query into a CSV
This is a simple Python that will parse instanceStats GraphQL Query into a CSV

GraphQL Python Labs - by Gabs the CSE Table of Contents About The Project Getting Started Prerequisites Installation and Usage Roadmap Contributing Li

Oct 27, 2021
Pygitstats - a package that allows you to use the GitHub GraphQL API with ease in your Python programs

Pygitstats - a package that allows you to use the GitHub GraphQL API with ease in your Python programs

Mar 29, 2022
Graphql-codegen library - a pure python implementation

turms DEVELOPMENT Inspiration Turms is a pure python implementation of the awesome graphql-codegen library, following a simliar extensible design. It

May 7, 2022
tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine, do not hesitate to take a look of the Tartiflette project.
tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine, do not hesitate to take a look of the Tartiflette project.

tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine. You can take a look at the Tartiflette API documentation. U

Apr 27, 2022
ASGI support for the Tartiflette GraphQL engine
ASGI support for the Tartiflette GraphQL engine

tartiflette-asgi is a wrapper that provides ASGI support for the Tartiflette Python GraphQL engine. It is ideal for serving a GraphQL API over HTTP, o

May 13, 2022
GraphQL is a query language and execution engine tied to any backend service.

GraphQL The GraphQL specification is edited in the markdown files found in /spec the latest release of which is published at

May 18, 2022
Integrate GraphQL into your Django project.

Graphene-Django A Django integration for Graphene. ?? Join the community on Slack Documentation Visit the documentation to get started! Quickstart For

May 17, 2022
Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

May 20, 2022
A library to help construct a graphql-py server supporting react-relay

Relay Library for GraphQL Python GraphQL-relay-py is the Relay library for GraphQL-core. It allows the easy creation of Relay-compliant servers using

May 14, 2022
Django registration and authentication with GraphQL.
Django registration and authentication with GraphQL.

Django GraphQL Auth Django registration and authentication with GraphQL. Demo About Abstract all the basic logic of handling user accounts out of your

May 17, 2022