diff options
author | CoprDistGit <copr-devel@lists.fedorahosted.org> | 2023-02-25 02:19:44 +0000 |
---|---|---|
committer | CoprDistGit <copr-devel@lists.fedorahosted.org> | 2023-02-25 02:19:44 +0000 |
commit | f97b20bc718bff2bc17273ba67f13676c58df3bb (patch) | |
tree | c6f9b3d70243fc37f3779147bbe7619bc187d677 | |
parent | a6ff0c0056d9a7d44499f856a73fc26a73bc8f96 (diff) |
automatic import of python3-graphql-relayopeneuler20.03
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-graphql-relay.spec | 916 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 918 insertions, 0 deletions
@@ -0,0 +1 @@ +/graphql-relay-3.2.0.tar.gz diff --git a/python-graphql-relay.spec b/python-graphql-relay.spec new file mode 100644 index 0000000..df6cc37 --- /dev/null +++ b/python-graphql-relay.spec @@ -0,0 +1,916 @@ +%global _empty_manifest_terminate_build 0 +Name: python-graphql-relay +Version: 3.2.0 +Release: 1 +Summary: Relay library for graphql-core +License: MIT +URL: https://github.com/graphql-python/graphql-relay-py +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/d1/13/98fbf8d67552f102488ffc16c6f559ce71ea15f6294728d33928ab5ff14d/graphql-relay-3.2.0.tar.gz +BuildArch: noarch + +Requires: python3-graphql-core +Requires: python3-typing-extensions + +%description +# Relay Library for GraphQL Python + +GraphQL-relay-py is the [Relay](https://relay.dev/) library for +[GraphQL-core](https://github.com/graphql-python/graphql-core). + +It allows the easy creation of Relay-compliant servers using GraphQL-core. + +GraphQL-Relay-Py is a Python port of +[graphql-relay-js](https://github.com/graphql/graphql-relay-js), +while GraphQL-Core is a Python port of +[GraphQL.js](https://github.com/graphql/graphql-js), +the reference implementation of GraphQL for JavaScript. + +Since version 3, GraphQL-Relay-Py and GraphQL-Core support Python 3.6 and above only. +For older versions of Python, you can use version 2 of these libraries. + +[](https://badge.fury.io/py/graphql-relay) + + +[](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) +[](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) +[](https://github.com/ambv/black) + +## Getting Started + +A basic understanding of GraphQL and of the GraphQL Python implementation is needed +to provide context for this library. + +An overview of GraphQL in general is available in the +[README](https://github.com/graphql-python/graphql-core/blob/master/README.md) for the +[Specification for GraphQL](https://github.com/graphql-python/graphql-core). + +This library is designed to work with the +the [GraphQL-Core](https://github.com/graphql-python/graphql-core) +Python reference implementation of a GraphQL server. + +An overview of the functionality that a Relay-compliant GraphQL server should provide +is in the [GraphQL Relay Specification](https://facebook.github.io/relay/docs/graphql-relay-specification.html) +on the [Relay website](https://facebook.github.io/relay/). +That overview describes a simple set of examples that exist +as [tests](tests) in this repository. +A good way to get started with this repository is to walk through that documentation +and the corresponding tests in this library together. + +## Using Relay Library for GraphQL Python (graphql-core) + +Install Relay Library for GraphQL Python + +```sh +pip install graphql-core +pip install graphql-relay +``` + +When building a schema for [GraphQL](https://github.com/graphql-python/graphql-core), +the provided library functions can be used to simplify the creation of Relay patterns. + +All the functions that are explained in the following sections must be +imported from the top level of the `graphql_relay` package, like this: +```python +from graphql_relay import connection_definitions +``` + +### Connections + +Helper functions are provided for both building the GraphQL types +for connections and for implementing the `resolve` method for fields +returning those types. + + - `connection_args` returns the arguments that fields should provide when +they return a connection type that supports bidirectional pagination. + - `forward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports forward pagination. + - `backward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports backward pagination. + - `connection_definitions` returns a `connection_type` and its associated +`edgeType`, given a name and a node type. + - `connection_from_array` is a helper method that takes an array and the +arguments from `connection_args`, does pagination and filtering, and returns +an object in the shape expected by a `connection_type`'s `resolve` function. + - `cursor_for_object_in_connection` is a helper method that takes an array and a +member object, and returns a cursor for use in the mutation payload. + - `offset_to_cursor` takes the index of a member object in an array + and returns an opaque cursor for use in the mutation payload. + - `cursor_to_offset` takes an opaque cursor (created with `offset_to_cursor`) +and returns the corresponding array index. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +ship_edge, ship_connection = connection_definitions(ship_type, "Ship") + +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", + fields=lambda: { + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( + ship_connection, + description="The ships used by the faction.", + args=connection_args, + resolve=lambda faction, _info, **args: connection_from_array( + [get_ship(ship) for ship in faction.ships], args + ), + ), + }, + interfaces=[node_interface], +) +``` + +This shows adding a `ships` field to the `Faction` object that is a connection. +It uses `connection_definitions(ship_type, "Ship")` to create the connection +type, adds `connection_args` as arguments on this function, and then implements +the resolver function by passing the array of ships and the arguments to +`connection_from_array`. + +### Object Identification + +Helper functions are provided for both building the GraphQL types +for nodes and for implementing global IDs around local IDs. + + - `node_definitions` returns the `Node` interface that objects can implement, + and returns the `node` root field to include on the query type. + To implement this, it takes a function to resolve an ID to an object, + and to determine the type of a given object. + - `to_global_id` takes a type name and an ID specific to that type name, + and returns a "global ID" that is unique among all types. + - `from_global_id` takes the "global ID" created by `to_global_id`, and + returns the type name and ID used to create it. + - `global_id_field` creates the configuration for an `id` field on a node. + - `plural_identifying_root_field` creates a field that accepts a list of + non-ID identifiers (like a username) and maps then to their corresponding + objects. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +def get_node(global_id, _info): + type_, id_ = from_global_id(global_id) + if type_ == "Faction": + return get_faction(id_) + if type_ == "Ship": + return get_ship(id_) + return None # pragma: no cover + +def get_node_type(obj, _info, _type): + if isinstance(obj, Faction): + return faction_type.name + return ship_type.name + +node_interface, node_field = node_definitions(get_node, get_node_type)[:2] + +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", + fields=lambda: { + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( + ship_connection, + description="The ships used by the faction.", + args=connection_args, + resolve=lambda faction, _info, **args: connection_from_array( + [get_ship(ship) for ship in faction.ships], args + ), + ), + }, + interfaces=[node_interface], +) + +query_type = GraphQLObjectType( + name="Query", + fields=lambda: { + "rebels": GraphQLField(faction_type, resolve=lambda _obj, _info: get_rebels()), + "empire": GraphQLField(faction_type, resolve=lambda _obj, _info: get_empire()), + "node": node_field, + }, +) +``` + +This uses `node_definitions` to construct the `Node` interface and the `node` +field; it uses `from_global_id` to resolve the IDs passed in the implementation +of the function mapping ID to object. It then uses the `global_id_field` method to +create the `id` field on `Faction`, which also ensures implements the +`node_interface`. Finally, it adds the `node` field to the query type, using the +`node_field` returned by `node_definitions`. + +### Mutations + +A helper function is provided for building mutations with +single inputs and client mutation IDs. + + - `mutation_with_client_mutation_id` takes a name, input fields, output fields, +and a mutation method to map from the input fields to the output fields, +performing the mutation along the way. It then creates and returns a field +configuration that can be used as a top-level field on the mutation type. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +class IntroduceShipMutation: + + def __init__(self, shipId, factionId, clientMutationId=None): + self.shipId = shipId + self.factionId = factionId + self.clientMutationId = clientMutationId + +def mutate_and_get_payload(_info, shipName, factionId, **_input): + new_ship = create_ship(shipName, factionId) + return IntroduceShipMutation(shipId=new_ship.id, factionId=factionId) + +ship_mutation = mutation_with_client_mutation_id( + "IntroduceShip", + input_fields={ + "shipName": GraphQLInputField(GraphQLNonNull(GraphQLString)), + "factionId": GraphQLInputField(GraphQLNonNull(GraphQLID)), + }, + output_fields={ + "ship": GraphQLField( + ship_type, resolve=lambda payload, _info: get_ship(payload.shipId) + ), + "faction": GraphQLField( + faction_type, resolve=lambda payload, _info: get_faction(payload.factionId) + ), + }, + mutate_and_get_payload=mutate_and_get_payload, +) + +mutation_type = GraphQLObjectType( + "Mutation", fields=lambda: {"introduceShip": ship_mutation} +) +``` + +This code creates a mutation named `IntroduceShip`, which takes a faction +ID and a ship name as input. It outputs the `Faction` and the `Ship` in +question. `mutate_and_get_payload` then gets each input field as keyword +parameter, performs the mutation by constructing the new ship, then returns +an object that will be resolved by the output fields. + +Our mutation type then creates the `introduceShip` field using the return +value of `mutation_with_client_mutation_id`. + +## Contributing + +After cloning this repository from GitHub, +we recommend using [Poetry](https://poetry.eustace.io/) +to create a test environment. With poetry installed, +you do this with the following command: + +```sh +poetry install +``` + +You can then run the complete test suite like this: + +```sh +poetry run pytest +``` + +In order to run only a part of the tests with increased verbosity, +you can add pytest options, like this: + +```sh +poetry run pytest tests/node -vv +``` + +In order to check the code style with flake8, use this: + +```sh +poetry run flake8 +``` + +Use the `tox` command to run the test suite with different +Python versions and perform all additional source code checks. +You can also restrict tox to an individual environment, like this: + +```sh +poetry run tox -e py39 +``` + + + + +%package -n python3-graphql-relay +Summary: Relay library for graphql-core +Provides: python-graphql-relay +BuildRequires: python3-devel +BuildRequires: python3-setuptools +%description -n python3-graphql-relay +# Relay Library for GraphQL Python + +GraphQL-relay-py is the [Relay](https://relay.dev/) library for +[GraphQL-core](https://github.com/graphql-python/graphql-core). + +It allows the easy creation of Relay-compliant servers using GraphQL-core. + +GraphQL-Relay-Py is a Python port of +[graphql-relay-js](https://github.com/graphql/graphql-relay-js), +while GraphQL-Core is a Python port of +[GraphQL.js](https://github.com/graphql/graphql-js), +the reference implementation of GraphQL for JavaScript. + +Since version 3, GraphQL-Relay-Py and GraphQL-Core support Python 3.6 and above only. +For older versions of Python, you can use version 2 of these libraries. + +[](https://badge.fury.io/py/graphql-relay) + + +[](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) +[](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) +[](https://github.com/ambv/black) + +## Getting Started + +A basic understanding of GraphQL and of the GraphQL Python implementation is needed +to provide context for this library. + +An overview of GraphQL in general is available in the +[README](https://github.com/graphql-python/graphql-core/blob/master/README.md) for the +[Specification for GraphQL](https://github.com/graphql-python/graphql-core). + +This library is designed to work with the +the [GraphQL-Core](https://github.com/graphql-python/graphql-core) +Python reference implementation of a GraphQL server. + +An overview of the functionality that a Relay-compliant GraphQL server should provide +is in the [GraphQL Relay Specification](https://facebook.github.io/relay/docs/graphql-relay-specification.html) +on the [Relay website](https://facebook.github.io/relay/). +That overview describes a simple set of examples that exist +as [tests](tests) in this repository. +A good way to get started with this repository is to walk through that documentation +and the corresponding tests in this library together. + +## Using Relay Library for GraphQL Python (graphql-core) + +Install Relay Library for GraphQL Python + +```sh +pip install graphql-core +pip install graphql-relay +``` + +When building a schema for [GraphQL](https://github.com/graphql-python/graphql-core), +the provided library functions can be used to simplify the creation of Relay patterns. + +All the functions that are explained in the following sections must be +imported from the top level of the `graphql_relay` package, like this: +```python +from graphql_relay import connection_definitions +``` + +### Connections + +Helper functions are provided for both building the GraphQL types +for connections and for implementing the `resolve` method for fields +returning those types. + + - `connection_args` returns the arguments that fields should provide when +they return a connection type that supports bidirectional pagination. + - `forward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports forward pagination. + - `backward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports backward pagination. + - `connection_definitions` returns a `connection_type` and its associated +`edgeType`, given a name and a node type. + - `connection_from_array` is a helper method that takes an array and the +arguments from `connection_args`, does pagination and filtering, and returns +an object in the shape expected by a `connection_type`'s `resolve` function. + - `cursor_for_object_in_connection` is a helper method that takes an array and a +member object, and returns a cursor for use in the mutation payload. + - `offset_to_cursor` takes the index of a member object in an array + and returns an opaque cursor for use in the mutation payload. + - `cursor_to_offset` takes an opaque cursor (created with `offset_to_cursor`) +and returns the corresponding array index. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +ship_edge, ship_connection = connection_definitions(ship_type, "Ship") + +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", + fields=lambda: { + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( + ship_connection, + description="The ships used by the faction.", + args=connection_args, + resolve=lambda faction, _info, **args: connection_from_array( + [get_ship(ship) for ship in faction.ships], args + ), + ), + }, + interfaces=[node_interface], +) +``` + +This shows adding a `ships` field to the `Faction` object that is a connection. +It uses `connection_definitions(ship_type, "Ship")` to create the connection +type, adds `connection_args` as arguments on this function, and then implements +the resolver function by passing the array of ships and the arguments to +`connection_from_array`. + +### Object Identification + +Helper functions are provided for both building the GraphQL types +for nodes and for implementing global IDs around local IDs. + + - `node_definitions` returns the `Node` interface that objects can implement, + and returns the `node` root field to include on the query type. + To implement this, it takes a function to resolve an ID to an object, + and to determine the type of a given object. + - `to_global_id` takes a type name and an ID specific to that type name, + and returns a "global ID" that is unique among all types. + - `from_global_id` takes the "global ID" created by `to_global_id`, and + returns the type name and ID used to create it. + - `global_id_field` creates the configuration for an `id` field on a node. + - `plural_identifying_root_field` creates a field that accepts a list of + non-ID identifiers (like a username) and maps then to their corresponding + objects. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +def get_node(global_id, _info): + type_, id_ = from_global_id(global_id) + if type_ == "Faction": + return get_faction(id_) + if type_ == "Ship": + return get_ship(id_) + return None # pragma: no cover + +def get_node_type(obj, _info, _type): + if isinstance(obj, Faction): + return faction_type.name + return ship_type.name + +node_interface, node_field = node_definitions(get_node, get_node_type)[:2] + +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", + fields=lambda: { + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( + ship_connection, + description="The ships used by the faction.", + args=connection_args, + resolve=lambda faction, _info, **args: connection_from_array( + [get_ship(ship) for ship in faction.ships], args + ), + ), + }, + interfaces=[node_interface], +) + +query_type = GraphQLObjectType( + name="Query", + fields=lambda: { + "rebels": GraphQLField(faction_type, resolve=lambda _obj, _info: get_rebels()), + "empire": GraphQLField(faction_type, resolve=lambda _obj, _info: get_empire()), + "node": node_field, + }, +) +``` + +This uses `node_definitions` to construct the `Node` interface and the `node` +field; it uses `from_global_id` to resolve the IDs passed in the implementation +of the function mapping ID to object. It then uses the `global_id_field` method to +create the `id` field on `Faction`, which also ensures implements the +`node_interface`. Finally, it adds the `node` field to the query type, using the +`node_field` returned by `node_definitions`. + +### Mutations + +A helper function is provided for building mutations with +single inputs and client mutation IDs. + + - `mutation_with_client_mutation_id` takes a name, input fields, output fields, +and a mutation method to map from the input fields to the output fields, +performing the mutation along the way. It then creates and returns a field +configuration that can be used as a top-level field on the mutation type. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +class IntroduceShipMutation: + + def __init__(self, shipId, factionId, clientMutationId=None): + self.shipId = shipId + self.factionId = factionId + self.clientMutationId = clientMutationId + +def mutate_and_get_payload(_info, shipName, factionId, **_input): + new_ship = create_ship(shipName, factionId) + return IntroduceShipMutation(shipId=new_ship.id, factionId=factionId) + +ship_mutation = mutation_with_client_mutation_id( + "IntroduceShip", + input_fields={ + "shipName": GraphQLInputField(GraphQLNonNull(GraphQLString)), + "factionId": GraphQLInputField(GraphQLNonNull(GraphQLID)), + }, + output_fields={ + "ship": GraphQLField( + ship_type, resolve=lambda payload, _info: get_ship(payload.shipId) + ), + "faction": GraphQLField( + faction_type, resolve=lambda payload, _info: get_faction(payload.factionId) + ), + }, + mutate_and_get_payload=mutate_and_get_payload, +) + +mutation_type = GraphQLObjectType( + "Mutation", fields=lambda: {"introduceShip": ship_mutation} +) +``` + +This code creates a mutation named `IntroduceShip`, which takes a faction +ID and a ship name as input. It outputs the `Faction` and the `Ship` in +question. `mutate_and_get_payload` then gets each input field as keyword +parameter, performs the mutation by constructing the new ship, then returns +an object that will be resolved by the output fields. + +Our mutation type then creates the `introduceShip` field using the return +value of `mutation_with_client_mutation_id`. + +## Contributing + +After cloning this repository from GitHub, +we recommend using [Poetry](https://poetry.eustace.io/) +to create a test environment. With poetry installed, +you do this with the following command: + +```sh +poetry install +``` + +You can then run the complete test suite like this: + +```sh +poetry run pytest +``` + +In order to run only a part of the tests with increased verbosity, +you can add pytest options, like this: + +```sh +poetry run pytest tests/node -vv +``` + +In order to check the code style with flake8, use this: + +```sh +poetry run flake8 +``` + +Use the `tox` command to run the test suite with different +Python versions and perform all additional source code checks. +You can also restrict tox to an individual environment, like this: + +```sh +poetry run tox -e py39 +``` + + + + +%package help +Summary: Development documents and examples for graphql-relay +Provides: python3-graphql-relay-doc +%description help +# Relay Library for GraphQL Python + +GraphQL-relay-py is the [Relay](https://relay.dev/) library for +[GraphQL-core](https://github.com/graphql-python/graphql-core). + +It allows the easy creation of Relay-compliant servers using GraphQL-core. + +GraphQL-Relay-Py is a Python port of +[graphql-relay-js](https://github.com/graphql/graphql-relay-js), +while GraphQL-Core is a Python port of +[GraphQL.js](https://github.com/graphql/graphql-js), +the reference implementation of GraphQL for JavaScript. + +Since version 3, GraphQL-Relay-Py and GraphQL-Core support Python 3.6 and above only. +For older versions of Python, you can use version 2 of these libraries. + +[](https://badge.fury.io/py/graphql-relay) + + +[](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) +[](https://pyup.io/repos/github/graphql-python/graphql-relay-py/) +[](https://github.com/ambv/black) + +## Getting Started + +A basic understanding of GraphQL and of the GraphQL Python implementation is needed +to provide context for this library. + +An overview of GraphQL in general is available in the +[README](https://github.com/graphql-python/graphql-core/blob/master/README.md) for the +[Specification for GraphQL](https://github.com/graphql-python/graphql-core). + +This library is designed to work with the +the [GraphQL-Core](https://github.com/graphql-python/graphql-core) +Python reference implementation of a GraphQL server. + +An overview of the functionality that a Relay-compliant GraphQL server should provide +is in the [GraphQL Relay Specification](https://facebook.github.io/relay/docs/graphql-relay-specification.html) +on the [Relay website](https://facebook.github.io/relay/). +That overview describes a simple set of examples that exist +as [tests](tests) in this repository. +A good way to get started with this repository is to walk through that documentation +and the corresponding tests in this library together. + +## Using Relay Library for GraphQL Python (graphql-core) + +Install Relay Library for GraphQL Python + +```sh +pip install graphql-core +pip install graphql-relay +``` + +When building a schema for [GraphQL](https://github.com/graphql-python/graphql-core), +the provided library functions can be used to simplify the creation of Relay patterns. + +All the functions that are explained in the following sections must be +imported from the top level of the `graphql_relay` package, like this: +```python +from graphql_relay import connection_definitions +``` + +### Connections + +Helper functions are provided for both building the GraphQL types +for connections and for implementing the `resolve` method for fields +returning those types. + + - `connection_args` returns the arguments that fields should provide when +they return a connection type that supports bidirectional pagination. + - `forward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports forward pagination. + - `backward_connection_args` returns the arguments that fields should provide when +they return a connection type that only supports backward pagination. + - `connection_definitions` returns a `connection_type` and its associated +`edgeType`, given a name and a node type. + - `connection_from_array` is a helper method that takes an array and the +arguments from `connection_args`, does pagination and filtering, and returns +an object in the shape expected by a `connection_type`'s `resolve` function. + - `cursor_for_object_in_connection` is a helper method that takes an array and a +member object, and returns a cursor for use in the mutation payload. + - `offset_to_cursor` takes the index of a member object in an array + and returns an opaque cursor for use in the mutation payload. + - `cursor_to_offset` takes an opaque cursor (created with `offset_to_cursor`) +and returns the corresponding array index. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +ship_edge, ship_connection = connection_definitions(ship_type, "Ship") + +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", + fields=lambda: { + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( + ship_connection, + description="The ships used by the faction.", + args=connection_args, + resolve=lambda faction, _info, **args: connection_from_array( + [get_ship(ship) for ship in faction.ships], args + ), + ), + }, + interfaces=[node_interface], +) +``` + +This shows adding a `ships` field to the `Faction` object that is a connection. +It uses `connection_definitions(ship_type, "Ship")` to create the connection +type, adds `connection_args` as arguments on this function, and then implements +the resolver function by passing the array of ships and the arguments to +`connection_from_array`. + +### Object Identification + +Helper functions are provided for both building the GraphQL types +for nodes and for implementing global IDs around local IDs. + + - `node_definitions` returns the `Node` interface that objects can implement, + and returns the `node` root field to include on the query type. + To implement this, it takes a function to resolve an ID to an object, + and to determine the type of a given object. + - `to_global_id` takes a type name and an ID specific to that type name, + and returns a "global ID" that is unique among all types. + - `from_global_id` takes the "global ID" created by `to_global_id`, and + returns the type name and ID used to create it. + - `global_id_field` creates the configuration for an `id` field on a node. + - `plural_identifying_root_field` creates a field that accepts a list of + non-ID identifiers (like a username) and maps then to their corresponding + objects. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +def get_node(global_id, _info): + type_, id_ = from_global_id(global_id) + if type_ == "Faction": + return get_faction(id_) + if type_ == "Ship": + return get_ship(id_) + return None # pragma: no cover + +def get_node_type(obj, _info, _type): + if isinstance(obj, Faction): + return faction_type.name + return ship_type.name + +node_interface, node_field = node_definitions(get_node, get_node_type)[:2] + +faction_type = GraphQLObjectType( + name="Faction", + description="A faction in the Star Wars saga", + fields=lambda: { + "id": global_id_field("Faction"), + "name": GraphQLField(GraphQLString, description="The name of the faction."), + "ships": GraphQLField( + ship_connection, + description="The ships used by the faction.", + args=connection_args, + resolve=lambda faction, _info, **args: connection_from_array( + [get_ship(ship) for ship in faction.ships], args + ), + ), + }, + interfaces=[node_interface], +) + +query_type = GraphQLObjectType( + name="Query", + fields=lambda: { + "rebels": GraphQLField(faction_type, resolve=lambda _obj, _info: get_rebels()), + "empire": GraphQLField(faction_type, resolve=lambda _obj, _info: get_empire()), + "node": node_field, + }, +) +``` + +This uses `node_definitions` to construct the `Node` interface and the `node` +field; it uses `from_global_id` to resolve the IDs passed in the implementation +of the function mapping ID to object. It then uses the `global_id_field` method to +create the `id` field on `Faction`, which also ensures implements the +`node_interface`. Finally, it adds the `node` field to the query type, using the +`node_field` returned by `node_definitions`. + +### Mutations + +A helper function is provided for building mutations with +single inputs and client mutation IDs. + + - `mutation_with_client_mutation_id` takes a name, input fields, output fields, +and a mutation method to map from the input fields to the output fields, +performing the mutation along the way. It then creates and returns a field +configuration that can be used as a top-level field on the mutation type. + +An example usage of these methods from the [test schema](tests/star_wars_schema.py): + +```python +class IntroduceShipMutation: + + def __init__(self, shipId, factionId, clientMutationId=None): + self.shipId = shipId + self.factionId = factionId + self.clientMutationId = clientMutationId + +def mutate_and_get_payload(_info, shipName, factionId, **_input): + new_ship = create_ship(shipName, factionId) + return IntroduceShipMutation(shipId=new_ship.id, factionId=factionId) + +ship_mutation = mutation_with_client_mutation_id( + "IntroduceShip", + input_fields={ + "shipName": GraphQLInputField(GraphQLNonNull(GraphQLString)), + "factionId": GraphQLInputField(GraphQLNonNull(GraphQLID)), + }, + output_fields={ + "ship": GraphQLField( + ship_type, resolve=lambda payload, _info: get_ship(payload.shipId) + ), + "faction": GraphQLField( + faction_type, resolve=lambda payload, _info: get_faction(payload.factionId) + ), + }, + mutate_and_get_payload=mutate_and_get_payload, +) + +mutation_type = GraphQLObjectType( + "Mutation", fields=lambda: {"introduceShip": ship_mutation} +) +``` + +This code creates a mutation named `IntroduceShip`, which takes a faction +ID and a ship name as input. It outputs the `Faction` and the `Ship` in +question. `mutate_and_get_payload` then gets each input field as keyword +parameter, performs the mutation by constructing the new ship, then returns +an object that will be resolved by the output fields. + +Our mutation type then creates the `introduceShip` field using the return +value of `mutation_with_client_mutation_id`. + +## Contributing + +After cloning this repository from GitHub, +we recommend using [Poetry](https://poetry.eustace.io/) +to create a test environment. With poetry installed, +you do this with the following command: + +```sh +poetry install +``` + +You can then run the complete test suite like this: + +```sh +poetry run pytest +``` + +In order to run only a part of the tests with increased verbosity, +you can add pytest options, like this: + +```sh +poetry run pytest tests/node -vv +``` + +In order to check the code style with flake8, use this: + +```sh +poetry run flake8 +``` + +Use the `tox` command to run the test suite with different +Python versions and perform all additional source code checks. +You can also restrict tox to an individual environment, like this: + +```sh +poetry run tox -e py39 +``` + + + + +%prep +%autosetup -n graphql-relay-3.2.0 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-graphql-relay -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Sat Feb 25 2023 Python_Bot <Python_Bot@openeuler.org> - 3.2.0-1 +- Package Spec generated @@ -0,0 +1 @@ +695440785f8f043a76a67375297f7cda graphql-relay-3.2.0.tar.gz |