diff --git a/docs/execution/dataloader.rst b/docs/execution/dataloader.rst index 3cd36fccc..d78543a3b 100644 --- a/docs/execution/dataloader.rst +++ b/docs/execution/dataloader.rst @@ -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) diff --git a/docs/execution/execute.rst b/docs/execution/execute.rst index f4a1e7596..2d750a222 100644 --- a/docs/execution/execute.rst +++ b/docs/execution/execute.rst @@ -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,22 +41,23 @@ 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) { + """ + query getUser($id: ID) { user(id: $id) { - id - firstName - lastName + id + firstName + lastName + } } - } - ''', - variables={'id': 12}, + """, + variables={"id": 12}, ) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index fc333fae2..a33ca7508 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -12,7 +12,7 @@ Let’s 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! diff --git a/docs/relay/connection.rst b/docs/relay/connection.rst index c2379cbc1..ac239647b 100644 --- a/docs/relay/connection.rst +++ b/docs/relay/connection.rst @@ -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): diff --git a/docs/relay/mutations.rst b/docs/relay/mutations.rst index c6099594c..99a3ba747 100644 --- a/docs/relay/mutations.rst +++ b/docs/relay/mutations.rst @@ -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 Input: - pass - # nothing needed for uploading file + class UploadFile(ClientIDMutation): + class Input: + pass + # nothing needed for uploading file - # your return fields - success = graphene.String() + # your return fields + success = String() @classmethod def mutate_and_get_payload(cls, root, info, **input): diff --git a/docs/relay/nodes.rst b/docs/relay/nodes.rst index 7af00ea1e..dddd84ff8 100644 --- a/docs/relay/nodes.rst +++ b/docs/relay/nodes.rst @@ -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() diff --git a/docs/testing/index.rst b/docs/testing/index.rst index 0103779cf..bf1965d22 100644 --- a/docs/testing/index.rst +++ b/docs/testing/index.rst @@ -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 }""")) diff --git a/docs/types/abstracttypes.rst b/docs/types/abstracttypes.rst index 093cfd931..93c2d64f2 100644 --- a/docs/types/abstracttypes.rst +++ b/docs/types/abstracttypes.rst @@ -20,18 +20,20 @@ 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): - pass + class UserFields(AbstractType): + name = String() + - class UserInput(graphene.InputObjectType, UserFields): + class User(ObjectType, UserFields): pass + class UserInput(InputObjectType, UserFields): + pass + .. code:: type User { diff --git a/docs/types/enums.rst b/docs/types/enums.rst index 02cc267c6..725a62278 100644 --- a/docs/types/enums.rst +++ b/docs/types/enums.rst @@ -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 diff --git a/docs/types/interfaces.rst b/docs/types/interfaces.rst index f2073d6a3..a2533d614 100644 --- a/docs/types/interfaces.rst +++ b/docs/types/interfaces.rst @@ -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, ) - - starships = graphene.List(Starship) - home_planet = graphene.String() + class Human(ObjectType, interfaces=(Character,)): + starships = List(Starship) + home_planet = 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 diff --git a/docs/types/list-and-nonnull.rst b/docs/types/list-and-nonnull.rst index a127a9d24..99c8c3dde 100644 --- a/docs/types/list-and-nonnull.rst +++ b/docs/types/list-and-nonnull.rst @@ -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: diff --git a/docs/types/mutations.rst b/docs/types/mutations.rst index 8532595ea..809c1248f 100644 --- a/docs/types/mutations.rst +++ b/docs/types/mutations.rst @@ -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(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 Person(graphene.ObjectType): - name = graphene.String() - age = graphene.Int() - class MyMutations(graphene.ObjectType): + class MyMutations(ObjectType): create_person = CreatePerson.Field() + # We must define a query for our schema - class Query(graphene.ObjectType): - person = graphene.Field(Person) + class Query(ObjectType): + person = Field(Person) - schema = graphene.Schema(query=Query, mutation=MyMutations) + + 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 PersonInput(InputObjectType): + name = String(required=True) + age = Int(required=True) - class CreatePerson(graphene.Mutation): + + 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() + class LatLngInput(InputObjectType): + lat = Float() + lng = Float() - #A location has a latlng associated to it - class LocationInput(graphene.InputObjectType): - name = graphene.String() - latlng = graphene.InputField(LatLngInput) + + # 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 diff --git a/docs/types/objecttypes.rst b/docs/types/objecttypes.rst index 1579258d8..edf450d81 100644 --- a/docs/types/objecttypes.rst +++ b/docs/types/objecttypes.rst @@ -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(ObjectType): + first_name = String() + last_name = 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 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/ diff --git a/docs/types/scalars.rst b/docs/types/scalars.rst index b4552cfb7..ad0778888 100644 --- a/docs/types/scalars.rst +++ b/docs/types/scalars.rst @@ -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 - # Is equivalent to: - class Person(graphene.ObjectType): - name = graphene.Field(graphene.String) + class Person(ObjectType): + name = String() + + # Is equivalent to: + 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)) diff --git a/docs/types/schema.rst b/docs/types/schema.rst index 3832b6f9c..9493d1e55 100644 --- a/docs/types/schema.rst +++ b/docs/types/schema.rst @@ -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``. diff --git a/docs/types/unions.rst b/docs/types/unions.rst index 2c5c5a756..e1ccc2b1e 100644 --- a/docs/types/unions.rst +++ b/docs/types/unions.rst @@ -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. diff --git a/examples/complex_example.py b/examples/complex_example.py index 3c2d77ba2..b5aa9f8e4 100644 --- a/examples/complex_example.py +++ b/examples/complex_example.py @@ -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 @@ def mutate(self, info, geo): 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}) { diff --git a/examples/context_example.py b/examples/context_example.py index 9b5fd1a50..862216314 100644 --- a/examples/context_example.py +++ b/examples/context_example.py @@ -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 { diff --git a/examples/simple_example.py b/examples/simple_example.py index 9bff3070b..472ae5f7b 100644 --- a/examples/simple_example.py +++ b/examples/simple_example.py @@ -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 { diff --git a/examples/starwars/schema.py b/examples/starwars/schema.py index a05957341..5d67554d4 100644 --- a/examples/starwars/schema.py +++ b/examples/starwars/schema.py @@ -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,) +class Human(ObjectType, interfaces=(Character,)): + home_planet = String() - home_planet = graphene.String() +class Droid(ObjectType, interfaces=(Character,)): + primary_function = String() -class Droid(graphene.ObjectType): - class Meta: - interfaces = (Character,) - primary_function = graphene.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 @@ def resolve_droid(self, info, id): return get_droid(id) -schema = graphene.Schema(query=Query) +schema = Schema(query=Query) diff --git a/examples/starwars_relay/schema.py b/examples/starwars_relay/schema.py index 3a1cd980f..743846533 100644 --- a/examples/starwars_relay/schema.py +++ b/examples/starwars_relay/schema.py @@ -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 Meta: - interfaces = (relay.Node,) +class Faction(ObjectType, interfaces=(relay.Node,)): + """A faction in the Star Wars saga.""" - 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 @@ def get_node(cls, info, id): 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 @@ def mutate_and_get_payload( 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 @@ def resolve_empire(self, info): 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) diff --git a/graphene/types/field.py b/graphene/types/field.py index a14286328..92ea349ac 100644 --- a/graphene/types/field.py +++ b/graphene/types/field.py @@ -41,7 +41,7 @@ def __init__( 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: diff --git a/graphene/types/tests/test_field.py b/graphene/types/tests/test_field.py index 13c755fca..1f961a1a8 100644 --- a/graphene/types/tests/test_field.py +++ b/graphene/types/tests/test_field.py @@ -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(): diff --git a/graphene/types/tests/test_structures.py b/graphene/types/tests/test_structures.py index 5359278f5..eaf5af75c 100644 --- a/graphene/types/tests/test_structures.py +++ b/graphene/types/tests/test_structures.py @@ -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 with NonNull(String)." )