Initial work refactoring class Meta to class arguments.

Initial work refactoring class Meta to class arguments.

Refactoring firehose imports to explicit imports.
More blackening of example code.
More refactoring of `class Meta` into class arguments.
This commit is contained in:
changeling 2019-06-02 17:55:35 -05:00
parent 67c4310c78
commit eefcf40360
26 changed files with 319 additions and 317 deletions

View File

@ -106,10 +106,10 @@ leaner code and at most 4 database requests, and possibly fewer if there are cac
.. code:: python
class User(graphene.ObjectType):
name = graphene.String()
best_friend = graphene.Field(lambda: User)
friends = graphene.List(lambda: User)
class User(ObjectType):
name = String()
best_friend = Field(lambda: User)
friends = List(lambda: User)
def resolve_best_friend(self, info):
return user_loader.load(self.best_friend_id)

View File

@ -7,8 +7,8 @@ For executing a query a schema, you can directly call the ``execute`` method on
.. code:: python
schema = graphene.Schema(...)
result = schema.execute('{ name }')
schema = Schema(...)
result = schema.execute("{ name }")
``result`` represents the result of execution. ``result.data`` is the result of executing the query, ``result.errors`` is ``None`` if no errors occurred, and is a non-empty list if an error occurred.
@ -21,14 +21,15 @@ You can pass context to a query via ``context``.
.. code:: python
class Query(graphene.ObjectType):
name = graphene.String()
class Query(ObjectType):
name = String()
def resolve_name(root, info):
return info.context.get('name')
return info.context.get("name")
schema = graphene.Schema(Query)
result = schema.execute('{ name }', context={'name': 'Syrus'})
schema = Schema(Query)
result = schema.execute("{ name }", context={"name": "Syrus"})
@ -40,15 +41,16 @@ You can pass variables to a query via ``variables``.
.. code:: python
class Query(graphene.ObjectType):
user = graphene.Field(User, id=graphene.ID(required=True))
class Query(ObjectType):
user = Field(User, id=ID(required=True))
def resolve_user(root, info, id):
return get_user_by_id(id)
schema = graphene.Schema(Query)
schema = Schema(Query)
result = schema.execute(
'''
"""
query getUser($id: ID) {
user(id: $id) {
id
@ -56,6 +58,6 @@ You can pass variables to a query via ``variables``.
lastName
}
}
''',
variables={'id': 12},
""",
variables={"id": 12},
)

View File

@ -12,7 +12,7 @@ Lets build a basic GraphQL schema from scratch.
Requirements
------------
- Python (2.7, 3.4, 3.5, 3.6, pypy)
- Python (3.6+, pypy)
- Graphene (2.0)
Project setup
@ -35,15 +35,17 @@ one field: ``hello`` and an input name. And when we query it, it should return `
.. code:: python
import graphene
from graphene import ObjectType, Schema, String
class Query(graphene.ObjectType):
hello = graphene.String(argument=graphene.String(default_value="stranger"))
class Query(ObjectType):
hello = String(argument=String(default_value="stranger"))
def resolve_hello(self, info, argument):
return 'Hello ' + argument
return f"Hello {argument}"
schema = graphene.Schema(query=Query)
schema = Schema(query=Query)
Querying
--------
@ -52,11 +54,11 @@ Then we can start querying our schema:
.. code:: python
result = schema.execute('{ hello }')
print(result.data['hello']) # "Hello stranger"
result = schema.execute("{ hello }")
print(result.data["hello"]) # "Hello stranger"
# or passing the argument in the query
result = schema.execute('{ hello (argument: "graph") }')
print(result.data['hello']) # "Hello graph"
print(result.data["hello"]) # "Hello graph"
Congrats! You got your first graphene schema working!

View File

@ -16,12 +16,9 @@ and ``other`` an extra field in the Connection Edge.
.. code:: python
class ShipConnection(Connection):
class ShipConnection(Connection, node=Ship):
extra = String()
class Meta:
node = Ship
class Edge:
other = String()
@ -37,8 +34,8 @@ that implements ``Node`` will have a default Connection.
.. code:: python
class Faction(graphene.ObjectType):
name = graphene.String()
class Faction(ObjectType):
name = String()
ships = relay.ConnectionField(ShipConnection)
def resolve_ships(self, info):

View File

@ -12,13 +12,12 @@ subclass of ``relay.ClientIDMutation``.
.. code:: python
class IntroduceShip(relay.ClientIDMutation):
class Input:
ship_name = graphene.String(required=True)
faction_id = graphene.String(required=True)
ship_name = String(required=True)
faction_id = String(required=True)
ship = graphene.Field(Ship)
faction = graphene.Field(Faction)
ship = Field(Ship)
faction = Field(Faction)
@classmethod
def mutate_and_get_payload(cls, root, info, **input):
@ -28,8 +27,6 @@ subclass of ``relay.ClientIDMutation``.
faction = get_faction(faction_id)
return IntroduceShip(ship=ship, faction=faction)
Accepting Files
---------------
@ -37,13 +34,13 @@ Mutations can also accept files, that's how it will work with different integrat
.. code:: python
class UploadFile(graphene.ClientIDMutation):
class UploadFile(ClientIDMutation):
class Input:
pass
# nothing needed for uploading file
# your return fields
success = graphene.String()
success = String()
@classmethod
def mutate_and_get_payload(cls, root, info, **input):

View File

@ -14,12 +14,10 @@ Example usage (taken from the `Starwars Relay example`_):
.. code:: python
class Ship(graphene.ObjectType):
'''A ship in the Star Wars saga'''
class Meta:
interfaces = (relay.Node, )
class Ship(ObjectType, interfaces=(relay.Node,)):
"""A ship in the Star Wars saga"""
name = graphene.String(description='The name of the ship.')
name = String(description="The name of the ship.")
@classmethod
def get_node(cls, info, id):
@ -45,26 +43,22 @@ Example of a custom node:
.. code:: python
class CustomNode(Node):
class Meta:
name = 'Node'
class CustomNode(Node, name="Node"):
@staticmethod
def to_global_id(type, id):
return '{}:{}'.format(type, id)
return "{}:{}".format(type, id)
@staticmethod
def get_node_from_global_id(info, global_id, only_type=None):
type, id = global_id.split(':')
type, id = global_id.split(":")
if only_type:
# We assure that the node type that we want to retrieve
# is the same that was indicated in the field type
assert type == only_type._meta.name, 'Received not compatible node.'
assert type == only_type._meta.name, "Received not compatible node."
if type == 'User':
if type == "User":
return get_user(id)
elif type == 'Photo':
elif type == "Photo":
return get_photo(id)
@ -94,7 +88,7 @@ Example usage:
.. code:: python
class Query(graphene.ObjectType):
class Query(ObjectType):
# Should be CustomNode.Field() if we want to use our custom Node
node = relay.Node.Field()

View File

@ -40,14 +40,11 @@ To use the test client, instantiate ``graphene.test.Client`` and retrieve GraphQ
from graphene.test import Client
def test_hey():
client = Client(my_schema)
executed = client.execute('''{ hey }''')
assert executed == {
'data': {
'hey': 'hello!'
}
}
executed = client.execute("""{ hey }""")
assert executed == {"data": {"hey": "hello!"}}
Execute parameters
@ -61,14 +58,11 @@ You can also add extra keyword arguments to the ``execute`` method, such as
from graphene.test import Client
def test_hey():
client = Client(my_schema)
executed = client.execute('''{ hey }''', context={'user': 'Peter'})
assert executed == {
'data': {
'hey': 'hello Peter!'
}
}
executed = client.execute("""{ hey }""", context={"user": "Peter"})
assert executed == {"data": {"hey": "hello Peter!"}}
Snapshot testing
@ -95,7 +89,7 @@ Here is a simple example on how our tests will look if we use ``pytest``:
# This will create a snapshot dir and a snapshot file
# the first time the test is executed, with the response
# of the execution.
snapshot.assert_match(client.execute('''{ hey }'''))
snapshot.assert_match(client.execute("""{ hey }"""))
If we are using ``unittest``:
@ -104,8 +98,9 @@ If we are using ``unittest``:
from snapshottest import TestCase
class APITestCase(TestCase):
def test_api_me(self):
"""Testing the API for /me"""
client = Client(my_schema)
self.assertMatchSnapshot(client.execute('''{ hey }'''))
self.assertMatchSnapshot(client.execute("""{ hey }"""))

View File

@ -20,17 +20,19 @@ plus the ones defined in ``UserFields``.
.. code:: python
import graphene
from graphene import AbstractType, ObjectType, InputObjectType, String
class UserFields(graphene.AbstractType):
name = graphene.String()
class User(graphene.ObjectType, UserFields):
class UserFields(AbstractType):
name = String()
class User(ObjectType, UserFields):
pass
class UserInput(graphene.InputObjectType, UserFields):
pass
class UserInput(InputObjectType, UserFields):
pass
.. code::

View File

@ -11,9 +11,10 @@ You can create an ``Enum`` using classes:
.. code:: python
import graphene
from graphene import Enum
class Episode(graphene.Enum):
class Episode(Enum):
NEWHOPE = 4
EMPIRE = 5
JEDI = 6
@ -22,7 +23,7 @@ But also using instances of Enum:
.. code:: python
Episode = graphene.Enum('Episode', [('NEWHOPE', 4), ('EMPIRE', 5), ('JEDI', 6)])
Episode = Enum("Episode", [("NEWHOPE", 4), ("EMPIRE", 5), ("JEDI", 6)])
Value descriptions
------------------
@ -32,7 +33,7 @@ needs to have the ``description`` property on it.
.. code:: python
class Episode(graphene.Enum):
class Episode(Enum):
NEWHOPE = 4
EMPIRE = 5
JEDI = 6
@ -40,9 +41,8 @@ needs to have the ``description`` property on it.
@property
def description(self):
if self == Episode.NEWHOPE:
return 'New Hope Episode'
return 'Other episode'
return "New Hope Episode"
return "Other episode"
Usage with Python Enums
-----------------------
@ -52,16 +52,16 @@ the ``Enum.from_enum`` function.
.. code:: python
graphene.Enum.from_enum(AlreadyExistingPyEnum)
Enum.from_enum(AlreadyExistingPyEnum)
``Enum.from_enum`` supports a ``description`` and ``deprecation_reason`` lambdas as input so
you can add description etc. to your enum without changing the original:
.. code:: python
graphene.Enum.from_enum(
Enum.from_enum(
AlreadyExistingPyEnum,
description=lambda v: return 'foo' if v == AlreadyExistingPyEnum.Foo else 'bar')
description=lambda v: return "foo" if v == AlreadyExistingPyEnum.Foo else "bar")
Notes
@ -76,19 +76,23 @@ In the Python ``Enum`` implementation you can access a member by initing the Enu
.. code:: python
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
assert Color(1) == Color.RED
assert Color(1) == Color.RED
However, in Graphene ``Enum`` you need to call get to have the same effect:
.. code:: python
from graphene import Enum
class Color(Enum):
RED = 1
GREEN = 2

View File

@ -9,12 +9,13 @@ character in the Star Wars trilogy:
.. code:: python
import graphene
from graphene import ID, Interface, String, List
class Character(graphene.Interface):
id = graphene.ID(required=True)
name = graphene.String(required=True)
friends = graphene.List(lambda: Character)
class Character(Interface):
id = ID(required=True)
name = String(required=True)
friends = List(lambda: Character)
Any ObjectType that implements ``Character`` will have these exact fields, with
@ -24,19 +25,13 @@ For example, here are some types that might implement ``Character``:
.. code:: python
class Human(graphene.ObjectType):
class Meta:
interfaces = (Character, )
class Human(ObjectType, interfaces=(Character,)):
starships = List(Starship)
home_planet = String()
starships = graphene.List(Starship)
home_planet = graphene.String()
class Droid(graphene.ObjectType):
class Meta:
interfaces = (Character, )
primary_function = graphene.String()
class Droid(ObjectType, interfaces=(Character,)):
primary_function = String()
Both of these types have all of the fields from the ``Character`` interface,
but also bring in extra fields, ``home_planet``, ``starships`` and
@ -75,20 +70,17 @@ For example, you can define a field ``hero`` that resolves to any
.. code:: python
class Query(graphene.ObjectType):
hero = graphene.Field(
Character,
required=True,
episode=graphene.Int(required=True)
)
class Query(ObjectType):
hero = Field(Character, required=True, episode=Int(required=True))
def resolve_hero(_, info, episode):
def resolve_hero(root, info, episode):
# Luke is the hero of Episode V
if episode == 5:
return get_human(name='Luke Skywalker')
return get_droid(name='R2-D2')
return get_human(name="Luke Skywalker")
return get_droid(name="R2-D2")
schema = graphene.Schema(query=Query, types=[Human, Droid])
schema = Schema(query=Query, types=[Human, Droid])
This allows you to directly query for fields that exist on the Character interface
as well as selecting specific fields on any type that implements the interface
@ -159,12 +151,12 @@ maps a data object to a Graphene type:
.. code:: python
class Character(graphene.Interface):
id = graphene.ID(required=True)
name = graphene.String(required=True)
class Character(Interface):
id = ID(required=True)
name = String(required=True)
@classmethod
def resolve_type(cls, instance, info):
if instance.type == 'DROID':
if instance.type == "DROID":
return Droid
return Human

View File

@ -11,11 +11,11 @@ NonNull
.. code:: python
import graphene
from graphene import ObjectType, NonNull, String
class Character(graphene.ObjectType):
name = graphene.NonNull(graphene.String)
class Character(ObjectType):
name = NonNull(String)
Here, we're using a ``String`` type and marking it as Non-Null by wrapping
it using the ``NonNull`` class. This means that our server always expects
@ -28,21 +28,22 @@ The previous ``NonNull`` code snippet is also equivalent to:
.. code:: python
import graphene
from graphene import ObjectType, String
class Character(graphene.ObjectType):
name = graphene.String(required=True)
class Character(ObjectType):
name = String(required=True)
List
----
.. code:: python
import graphene
from graphene import ObjectType, List, String
class Character(graphene.ObjectType):
appears_in = graphene.List(graphene.String)
class Character(ObjectType):
appears_in = List(String)
Lists work in a similar way: We can use a type modifier to mark a type as a
``List``, which indicates that this field will return a list of that type.
@ -57,10 +58,11 @@ any nullable items the type needs to be marked as ``NonNull``. For example:
.. code:: python
import graphene
from graphene import ObjectType, List, NonNull, String
class Character(graphene.ObjectType):
appears_in = graphene.List(graphene.NonNull(graphene.String))
class Character(ObjectType):
appears_in = List(NonNull(String))
The above results in the type definition:

View File

@ -10,14 +10,15 @@ This example defines a Mutation:
.. code:: python
import graphene
from graphene import Mutation, String, Boolean, Field
class CreatePerson(graphene.Mutation):
class CreatePerson(Mutation):
class Arguments:
name = graphene.String()
name = String()
ok = graphene.Boolean()
person = graphene.Field(lambda: Person)
ok = Boolean()
person = Field(lambda: Person)
def mutate(self, info, name):
person = Person(name=name)
@ -38,20 +39,37 @@ So, we can finish our schema like this:
.. code:: python
# ... the Mutation Class
from graphene import ObjectType, Mutation, String, Boolean, Field, Int, Schema
class Person(graphene.ObjectType):
name = graphene.String()
age = graphene.Int()
class MyMutations(graphene.ObjectType):
class Person(ObjectType):
name = String()
age = Int()
class CreatePerson(Mutation):
class Arguments:
name = String()
ok = Boolean()
person = Field(lambda: Person)
def mutate(self, info, name):
person = Person(name=name)
ok = True
return CreatePerson(person=person, ok=ok)
class MyMutations(ObjectType):
create_person = CreatePerson.Field()
# We must define a query for our schema
class Query(graphene.ObjectType):
person = graphene.Field(Person)
schema = graphene.Schema(query=Query, mutation=MyMutations)
# We must define a query for our schema
class Query(ObjectType):
person = Field(Person)
schema = Schema(query=Query, mutation=MyMutations)
Executing the Mutation
----------------------
@ -91,27 +109,25 @@ To use an InputField you define an InputObjectType that specifies the structure
.. code:: python
import graphene
from graphene import InputObjectType, Mutation, String, Field, Int
class PersonInput(graphene.InputObjectType):
name = graphene.String(required=True)
age = graphene.Int(required=True)
class CreatePerson(graphene.Mutation):
class PersonInput(InputObjectType):
name = String(required=True)
age = Int(required=True)
class CreatePerson(Mutation):
class Arguments:
person_data = PersonInput(required=True)
person = graphene.Field(Person)
person = Field(Person)
@staticmethod
def mutate(root, info, person_data=None):
person = Person(
name=person_data.name,
age=person_data.age
)
person = Person(name=person_data.name, age=person_data.age)
return CreatePerson(person=person)
Note that **name** and **age** are part of **person_data** now
Using the above mutation your new query would look like this:
@ -132,16 +148,18 @@ as complex of input data as you need
.. code:: python
import graphene
from graphene import InputObjectType, InputField, Float, String
class LatLngInput(graphene.InputObjectType):
lat = graphene.Float()
lng = graphene.Float()
#A location has a latlng associated to it
class LocationInput(graphene.InputObjectType):
name = graphene.String()
latlng = graphene.InputField(LatLngInput)
class LatLngInput(InputObjectType):
lat = Float()
lng = Float()
# A location has a latlng associated to it
class LocationInput(InputObjectType):
name = String()
latlng = InputField(LatLngInput)
Output type example
-------------------
@ -149,11 +167,12 @@ To return an existing ObjectType instead of a mutation-specific type, set the **
.. code:: python
import graphene
from graphene import Mutation, String
class CreatePerson(graphene.Mutation):
class CreatePerson(Mutation):
class Arguments:
name = graphene.String()
name = String()
Output = Person

View File

@ -18,15 +18,16 @@ This example model defines a Person, with a first and a last name:
.. code:: python
import graphene
from graphene import ObjectType, String
class Person(graphene.ObjectType):
first_name = graphene.String()
last_name = graphene.String()
full_name = graphene.String()
class Person(ObjectType):
first_name = String()
last_name = String()
full_name = String()
def resolve_full_name(root, info):
return '{} {}'.format(root.first_name, root.last_name)
return "{} {}".format(root.first_name, root.last_name)
**first\_name** and **last\_name** are fields of the ObjectType. Each
field is specified as a class attribute, and each attribute maps to a
@ -62,25 +63,24 @@ passed to the ``ObjectType``.
.. code:: python
import graphene
from graphene import ObjectType, Field, String
class Person(graphene.ObjectType):
first_name = graphene.String()
last_name = graphene.String()
class Query(graphene.ObjectType):
me = graphene.Field(Person)
best_friend = graphene.Field(Person)
class Person(ObjectType):
first_name = String()
last_name = String()
class Query(ObjectType):
me = Field(Person)
best_friend = Field(Person)
def resolve_me(_, info):
# returns an object that represents a Person
return get_human(name='Luke Skywalker')
return get_human(name="Luke Skywalker")
def resolve_best_friend(_, info):
return {
"first_name": "R2",
"last_name": "D2",
}
def resolve_best_friend(root, info):
return {"first_name": "R2", "last_name": "D2"}
Resolvers with arguments
@ -91,10 +91,11 @@ kwargs. For example:
.. code:: python
import graphene
from graphene import ObjectType, Field, String
class Query(graphene.ObjectType):
human_by_name = graphene.Field(Human, name=graphene.String(required=True))
class Query(ObjectType):
human_by_name = Field(Human, name=String(required=True))
def resolve_human_by_name(_, info, name):
return get_human(name=name)
@ -119,10 +120,11 @@ For example, given this schema:
.. code:: python
import graphene
from graphene import ObjectType, String
class Query(graphene.ObjectType):
hello = graphene.String(required=True, name=graphene.String())
class Query(ObjectType):
hello = String(required=True, name=String())
def resolve_hello(_, info, name):
return name if name else 'World'
@ -146,8 +148,8 @@ into a dict:
.. code:: python
class Query(graphene.ObjectType):
hello = graphene.String(required=True, name=graphene.String())
class Query(ObjectType):
hello = String(required=True, name=String())
def resolve_hello(_, info, **args):
return args.get('name', 'World')
@ -156,8 +158,8 @@ Or by setting a default value for the keyword argument:
.. code:: python
class Query(graphene.ObjectType):
hello = graphene.String(required=True, name=graphene.String())
class Query(ObjectType):
hello = String(required=True, name=String())
def resolve_hello(_, info, name='World'):
return name
@ -170,15 +172,15 @@ A field can use a custom resolver from outside the class:
.. code:: python
import graphene
from graphene import ObjectType, String
def resolve_full_name(person, info):
return '{} {}'.format(person.first_name, person.last_name)
class Person(graphene.ObjectType):
first_name = graphene.String()
last_name = graphene.String()
full_name = graphene.String(resolver=resolve_full_name)
class Person(ObjectType):
first_name = String()
last_name = String()
full_name = String(resolver=resolve_full_name)
Instances as data containers
@ -203,8 +205,7 @@ property on the ``Meta`` class:
.. code:: python
class MyGraphQlSong(graphene.ObjectType):
class Meta:
name = 'Song'
class MyGraphQlSong(ObjectType, name="Song"):
pass
.. _Interface: /docs/interfaces/

View File

@ -91,8 +91,9 @@ The following is an example for creating a DateTime scalar:
from graphene.types import Scalar
from graphql.language import ast
class DateTime(Scalar):
'''DateTime Scalar Description'''
"""DateTime Scalar Description"""
@staticmethod
def serialize(dt):
@ -101,8 +102,7 @@ The following is an example for creating a DateTime scalar:
@staticmethod
def parse_literal(node):
if isinstance(node, ast.StringValue):
return datetime.datetime.strptime(
node.value, "%Y-%m-%dT%H:%M:%S.%f")
return datetime.datetime.strptime(node.value, "%Y-%m-%dT%H:%M:%S.%f")
@staticmethod
def parse_value(value):
@ -116,13 +116,15 @@ Scalars mounted in a ``ObjectType``, ``Interface`` or ``Mutation`` act as
.. code:: python
class Person(graphene.ObjectType):
name = graphene.String()
from graphene import ObjectType, Field, String
class Person(ObjectType):
name = String()
# Is equivalent to:
class Person(graphene.ObjectType):
name = graphene.Field(graphene.String)
class Person(ObjectType):
name = Field(String)
**Note:** when using the ``Field`` constructor directly, pass the type and
not an instance.
@ -132,7 +134,7 @@ Types mounted in a ``Field`` act as ``Argument``\ s.
.. code:: python
graphene.Field(graphene.String, to=graphene.String())
Field(String, to=String())
# Is equivalent to:
graphene.Field(graphene.String, to=graphene.Argument(graphene.String))
Field(String, to=Argument(String))

View File

@ -37,7 +37,7 @@ To query a schema, call the ``execute`` method on it.
.. code:: python
my_schema.execute('{ lastName }')
my_schema.execute("{ lastName }")
Auto CamelCase field names
@ -51,9 +51,9 @@ For example with the ObjectType
.. code:: python
class Person(graphene.ObjectType):
last_name = graphene.String()
other_name = graphene.String(name='_other_Name')
class Person(ObjectType):
last_name = String()
other_name = String(name="_other_Name")
the ``last_name`` field name is converted to ``lastName``.

View File

@ -17,23 +17,26 @@ This example model defines several ObjectTypes with their own fields.
.. code:: python
import graphene
from graphene import ObjectType, String, Int, Union
class Human(graphene.ObjectType):
name = graphene.String()
born_in = graphene.String()
class Droid(graphene.ObjectType):
name = graphene.String()
primary_function = graphene.String()
class Human(ObjectType):
name = String()
born_in = String()
class Starship(graphene.ObjectType):
name = graphene.String()
length = graphene.Int()
class SearchResult(graphene.Union):
class Meta:
types = (Human, Droid, Starship)
class Droid(ObjectType):
name = String()
primary_function = String()
class Starship(ObjectType):
name = String()
length = Int()
class SearchResult(Union, types=(Human, Droid, Starship)):
pass
Wherever we return a SearchResult type in our schema, we might get a Human, a Droid, or a Starship.

View File

@ -1,21 +1,24 @@
from graphene import InputObjectType, Float, ObjectType, String, Field, Schema
# Naming confusion/conflict with class Mutation and explicit import of graphene.mutation.
import graphene
class GeoInput(graphene.InputObjectType):
lat = graphene.Float(required=True)
lng = graphene.Float(required=True)
class GeoInput(InputObjectType):
lat = Float(required=True)
lng = Float(required=True)
@property
def latlng(self):
return "({},{})".format(self.lat, self.lng)
class Address(graphene.ObjectType):
latlng = graphene.String()
class Address(ObjectType):
latlng = String()
class Query(graphene.ObjectType):
address = graphene.Field(Address, geo=GeoInput(required=True))
class Query(ObjectType):
address = Field(Address, geo=GeoInput(required=True))
def resolve_address(self, info, geo):
return Address(latlng=geo.latlng)
@ -31,11 +34,11 @@ class CreateAddress(graphene.Mutation):
return Address(latlng=geo.latlng)
class Mutation(graphene.ObjectType):
class Mutation(ObjectType):
create_address = CreateAddress.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
schema = Schema(query=Query, mutation=Mutation)
query = """
query something{
address(geo: {lat:32.2, lng:12}) {

View File

@ -1,19 +1,19 @@
import graphene
from graphene import ObjectType, ID, String, Field, Schema
class User(graphene.ObjectType):
id = graphene.ID()
name = graphene.String()
class User(ObjectType):
id = ID()
name = String()
class Query(graphene.ObjectType):
me = graphene.Field(User)
class Query(ObjectType):
me = Field(User)
def resolve_me(self, info):
return info.context["user"]
schema = graphene.Schema(query=Query)
schema = Schema(query=Query)
query = """
query something{
me {

View File

@ -1,21 +1,21 @@
import graphene
from graphene import ObjectType, ID, String, Int, Field, Schema
class Patron(graphene.ObjectType):
id = graphene.ID()
name = graphene.String()
age = graphene.Int()
class Patron(ObjectType):
id = ID()
name = String()
age = Int()
class Query(graphene.ObjectType):
class Query(ObjectType):
patron = graphene.Field(Patron)
patron = Field(Patron)
def resolve_patron(self, info):
return Patron(id=1, name="Syrus", age=27)
schema = graphene.Schema(query=Query)
schema = Schema(query=Query)
query = """
query something{
patron {

View File

@ -1,43 +1,37 @@
import graphene
from graphene import Enum, Interface, ID, List, ObjectType, String, Field, Schema
from .data import get_character, get_droid, get_hero, get_human
class Episode(graphene.Enum):
class Episode(Enum):
NEWHOPE = 4
EMPIRE = 5
JEDI = 6
class Character(graphene.Interface):
id = graphene.ID()
name = graphene.String()
friends = graphene.List(lambda: Character)
appears_in = graphene.List(Episode)
class Character(Interface):
id = ID()
name = String()
friends = List(lambda: Character)
appears_in = List(Episode)
def resolve_friends(self, info):
# The character friends is a list of strings
return [get_character(f) for f in self.friends]
class Human(graphene.ObjectType):
class Meta:
interfaces = (Character,)
home_planet = graphene.String()
class Human(ObjectType, interfaces=(Character,)):
home_planet = String()
class Droid(graphene.ObjectType):
class Meta:
interfaces = (Character,)
primary_function = graphene.String()
class Droid(ObjectType, interfaces=(Character,)):
primary_function = String()
class Query(graphene.ObjectType):
hero = graphene.Field(Character, episode=Episode())
human = graphene.Field(Human, id=graphene.String())
droid = graphene.Field(Droid, id=graphene.String())
class Query(ObjectType):
hero = Field(Character, episode=Episode())
human = Field(Human, id=String())
droid = Field(Droid, id=String())
def resolve_hero(self, info, episode=None):
return get_hero(episode)
@ -49,4 +43,4 @@ class Query(graphene.ObjectType):
return get_droid(id)
schema = graphene.Schema(query=Query)
schema = Schema(query=Query)

View File

@ -1,34 +1,27 @@
import graphene
from graphene import ObjectType, Schema, Field, String
from graphene import relay
from .data import create_ship, get_empire, get_faction, get_rebels, get_ship
class Ship(graphene.ObjectType):
"""A ship in the Star Wars saga"""
class Ship(ObjectType, interfaces=(relay.Node,)):
"""A ship in the Star Wars saga."""
class Meta:
interfaces = (relay.Node,)
name = graphene.String(description="The name of the ship.")
name = String(description="The name of the ship.")
@classmethod
def get_node(cls, info, id):
return get_ship(id)
class ShipConnection(relay.Connection):
class Meta:
node = Ship
class ShipConnection(relay.Connection, node=Ship):
pass
class Faction(graphene.ObjectType):
"""A faction in the Star Wars saga"""
class Faction(ObjectType, interfaces=(relay.Node,)):
"""A faction in the Star Wars saga."""
class Meta:
interfaces = (relay.Node,)
name = graphene.String(description="The name of the faction.")
name = String(description="The name of the faction.")
ships = relay.ConnectionField(
ShipConnection, description="The ships used by the faction."
)
@ -44,11 +37,11 @@ class Faction(graphene.ObjectType):
class IntroduceShip(relay.ClientIDMutation):
class Input:
ship_name = graphene.String(required=True)
faction_id = graphene.String(required=True)
ship_name = String(required=True)
faction_id = String(required=True)
ship = graphene.Field(Ship)
faction = graphene.Field(Faction)
ship = Field(Ship)
faction = Field(Faction)
@classmethod
def mutate_and_get_payload(
@ -59,9 +52,9 @@ class IntroduceShip(relay.ClientIDMutation):
return IntroduceShip(ship=ship, faction=faction)
class Query(graphene.ObjectType):
rebels = graphene.Field(Faction)
empire = graphene.Field(Faction)
class Query(ObjectType):
rebels = Field(Faction)
empire = Field(Faction)
node = relay.Node.Field()
def resolve_rebels(self, info):
@ -71,8 +64,8 @@ class Query(graphene.ObjectType):
return get_empire()
class Mutation(graphene.ObjectType):
class Mutation(ObjectType):
introduce_ship = IntroduceShip.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
schema = Schema(query=Query, mutation=Mutation)

View File

@ -808,14 +808,14 @@ class Signature(object):
def bind(self, *args, **kwargs):
"""Get a BoundArguments object, that maps the passed `args`
and `kwargs` to the function's signature. Raises `TypeError`
if the passed arguments can not be bound.
if the passed arguments cannot be bound.
"""
return self._bind(args, kwargs)
def bind_partial(self, *args, **kwargs):
"""Get a BoundArguments object, that partially maps the
passed `args` and `kwargs` to the function's signature.
Raises `TypeError` if the passed arguments can not be bound.
Raises `TypeError` if the passed arguments cannot be bound.
"""
return self._bind(args, kwargs, partial=True)

View File

@ -41,7 +41,7 @@ class Field(MountedType):
source and resolver
), "A Field cannot have a source and a resolver in at the same time."
assert not callable(default_value), (
'The default value can not be a function but received "{}".'
'The default value cannot be a function but received "{}".'
).format(base_type(default_value))
if required:

View File

@ -14,7 +14,7 @@ class Structure(UnmountedType):
cls_name = type(self).__name__
of_type_name = type(of_type).__name__
raise Exception(
"{} could not have a mounted {}() as inner type. Try with {}({}).".format(
"{} cannot have a mounted {}() as inner type. Try {}({}).".format(
cls_name, of_type_name, cls_name, of_type_name
)
)

View File

@ -57,7 +57,7 @@ def test_field_default_value_not_callable():
Field(MyType, default_value=lambda: True)
except AssertionError as e:
# substring comparison for py 2/3 compatibility
assert "The default value can not be a function but received" in str(e)
assert "The default value cannot be a function but received" in str(e)
def test_field_source():

View File

@ -19,7 +19,7 @@ def test_list_with_unmounted_type():
assert (
str(exc_info.value)
== "List could not have a mounted String() as inner type. Try with List(String)."
== "List cannot have a mounted String() as inner type. Try List(String)."
)
@ -97,7 +97,7 @@ def test_nonnull_with_unmounted_type():
assert (
str(exc_info.value)
== "NonNull could not have a mounted String() as inner type. Try with NonNull(String)."
== "NonNull cannot have a mounted String() as inner type. Try NonNull(String)."
)