Skip to main content

Python schema-first GraphQL library based on GraphQL-core

Project description

python-gql

Python schema-first GraphQL library based on GraphQL-core.

Requirements

Python 3.7+

Installation

pip install python-gql

Getting start

import graphql
from gql import gql, build_schema, query, mutate

type_defs = gql("""
type Query {
    hello(name: String!): String!
}

type Post {
    author: String!
    comment: String!
}
type Mutation {
    addPost(author: String, comment: String): Post!
}
""")


@query
def hello(parent, info, name: str) -> str:
    return name


@mutate
def add_post(parent, info, author: str = None, comment: str = None) -> dict:
    return {'author': author, 'comment': comment}


schema = build_schema(type_defs)

q = """
query {
    hello(name: "graphql")
}
"""
result = graphql.graphql_sync(schema, q)
print(result.data)

# result: {'hello': 'graphql'}

q = """
mutation {
    addPost(author: "syfun", comment: "This is a good library.") {
        author
        comment
    }
}
"""
result = graphql.graphql_sync(schema, q)
print(result.data)

# result: {'addPost': {'author': 'syfun', 'comment': 'This is a good library.'}}

Build schema

This library is schema-first, so you must build a schema explicitly.

Here, we have two methods to build a schema, by a type definitions or a schema file.

from gql import gql, build_schema

type_defs = gql("""
type Query {
    hello(name: String!): String!
}
""")

schema = build_schema(type_defs)

gql function will check your type definitions syntax.

from gql import build_schema_from_file

schema = build_schema_from_file('./schema.graphql')

Resolver decorators

In Python, decorator is my favorite function, it save my life!

We can use query, mutation, subscribe to bind functions to GraphQL resolvers.

@query
def hello(parent, info, name: str) -> str:
    return name

These decorators will auto convert the snake function to camel one.

# add_port => addPost
@mutate
def add_post(parent, info, author: str = None, comment: str = None) -> dict:
    return {'author': author, 'comment': comment}

When the funcation name different from the resolver name, you can give a name argument to these decorators.

@query('hello')
def hello_function(parent, info, name: str) -> str:
    return name

About subscribe, please see gql-subscriptions.

Enum type decorator

Use enum_type decorator with a python Enum class.

from enum import Enum

from gql import enum_type


@enum_type
class Gender(Enum):
    MALE = 1
    FEMALE = 2

Custom Scalar

Use scalar_type decorator with a python class.

from gql import scalar_type


@scalar_type
class JSONString:
    description = "The `JSONString` represents a json string."

    @staticmethod
    def serialize(value: Any) -> str:
        return json.dumps(value)

    @staticmethod
    def parse_value(value: Any) -> dict:
        if not isinstance(value, str):
            raise TypeError(f'JSONString cannot represent non string value: {inspect(value)}')
        return json.loads(value)

    @staticmethod
    def parse_literal(ast, _variables=None):
        if isinstance(ast, StringValueNode):
            return json.loads(ast.value)

        return INVALID

Framework support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python-gql-0.0.14.tar.gz (13.2 kB view hashes)

Uploaded Source

Built Distribution

python_gql-0.0.14-py3-none-any.whl (13.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page