summaryrefslogtreecommitdiff
path: root/python-graphene-pydantic.spec
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-05-10 06:08:49 +0000
committerCoprDistGit <infra@openeuler.org>2023-05-10 06:08:49 +0000
commit2a4faf46f44f2f0e500b629318b8b5a7f40aac77 (patch)
tree60c649edbb077220051be6987f52d7248df5b391 /python-graphene-pydantic.spec
parent044561454880d89090b4575ac933d6da65c663b2 (diff)
automatic import of python-graphene-pydantic
Diffstat (limited to 'python-graphene-pydantic.spec')
-rw-r--r--python-graphene-pydantic.spec924
1 files changed, 924 insertions, 0 deletions
diff --git a/python-graphene-pydantic.spec b/python-graphene-pydantic.spec
new file mode 100644
index 0000000..48f524c
--- /dev/null
+++ b/python-graphene-pydantic.spec
@@ -0,0 +1,924 @@
+%global _empty_manifest_terminate_build 0
+Name: python-graphene-pydantic
+Version: 0.4.0
+Release: 1
+Summary: Graphene Pydantic integration
+License: Apache-2.0
+URL: https://github.com/graphql-python/graphene-pydantic
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/ec/c1/3242beba52d5f59b4cfc6c6e80d4b6ac336c64a2fe9ed223c5ac97f40d24/graphene_pydantic-0.4.0.tar.gz
+BuildArch: noarch
+
+Requires: python3-graphene
+Requires: python3-pydantic
+Requires: python3-pydantic
+
+%description
+# ![Graphene Logo](http://graphene-python.org/favicon.png) graphene-pydantic [![Build status](https://circleci.com/gh/upsidetravel/graphene-pydantic.svg?style=svg)](https://circleci.com/gh/upsidetravel/graphene-pydantic) [![PyPI version](https://badge.fury.io/py/graphene-pydantic.svg)](https://badge.fury.io/py/graphene-pydantic) [![Coverage Status](https://coveralls.io/repos/upsidetravel/graphene-pydantic/badge.svg?branch=master&service=github)](https://coveralls.io/github/upsidetravel/graphene-pydantic?branch=master)
+
+
+
+A [Pydantic](https://pydantic-docs.helpmanual.io/) integration for [Graphene](http://graphene-python.org/).
+
+## Installation
+
+```bash
+pip install "graphene-pydantic"
+```
+
+## Examples
+
+Here is a simple Pydantic model:
+
+```python
+import uuid
+import pydantic
+
+class PersonModel(pydantic.BaseModel):
+ id: uuid.UUID
+ first_name: str
+ last_name: str
+```
+
+To create a GraphQL schema for it you simply have to write the following:
+
+```python
+import graphene
+from graphene_pydantic import PydanticObjectType
+
+class Person(PydanticObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+class Query(graphene.ObjectType):
+ people = graphene.List(Person)
+
+ @staticmethod
+ def resolve_people(parent, info):
+ # fetch actual PersonModels here
+ return [PersonModel(id=uuid.uuid4(), first_name="Beth", last_name="Smith")]
+
+schema = graphene.Schema(query=Query)
+```
+
+Then you can simply query the schema:
+
+```python
+query = """
+ query {
+ people {
+ firstName,
+ lastName
+ }
+ }
+"""
+result = schema.execute(query)
+print(result.data['people'][0])
+```
+
+### Input Object Types
+
+You can also create input object types from Pydantic models for mutations and queries:
+
+```python
+from graphene_pydantic import PydanticInputObjectType
+
+class PersonInput(PydanticInputObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+class CreatePerson(graphene.Mutation):
+ class Arguments:
+ person = PersonInput()
+
+ Output = Person
+
+ @staticmethod
+ def mutate(parent, info, person):
+ personModel = PersonModel(id=uuid.uuid4(), first_name=person.first_name, last_name=person.last_name)
+ # save PersonModel here
+ return person
+
+class Mutation(graphene.ObjectType):
+ createPerson = CreatePerson.Field()
+
+schema = graphene.Schema(mutation=Mutation)
+```
+
+Then execute with the input:
+
+```python
+mutation = '''
+mutation {
+ createPerson(person: {
+ firstName: "Jerry",
+ lastName: "Smith"
+ }) {
+ firstName
+ }
+}
+'''
+result = schema.execute(mutation)
+print(result.data['createPerson']['firstName'])
+```
+
+### Custom resolve functions
+
+Since `PydanticObjectType` inherits from `graphene.ObjectType` you can add custom resolve functions as explained [here](https://docs.graphene-python.org/en/stable/api/#object-types). For instance:
+
+```python
+class Person(PydanticObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+ full_name = graphene.String()
+
+ def resolve_full_name(self, info, **kwargs):
+ return self.first_name + ' ' + self.last_name
+```
+
+
+### Forward declarations and circular references
+
+`graphene_pydantic` supports forward declarations and circular references, but you will need to call the `resolve_placeholders()` method to ensure the types are fully updated before you execute a GraphQL query. For instance:
+
+``` python
+class NodeModel(BaseModel):
+ id: int
+ name: str
+ labels: 'LabelsModel'
+
+class LabelsModel(BaseModel):
+ node: NodeModel
+ labels: typing.List[str]
+
+class Node(PydanticObjectType):
+ class Meta:
+ model = NodeModel
+
+class Labels(PydanticObjectType):
+ class Meta:
+ model = LabelsModel
+
+
+Node.resolve_placeholders() # make the `labels` field work
+Labels.resolve_placeholders() # make the `node` field work
+```
+
+### Full Examples
+
+Please see [the examples directory](./examples) for more.
+
+### License
+
+This project is under the [Apache License](./LICENSE.md).
+
+### Third Party Code
+
+This project depends on third-party code which is subject to the licenses set forth in [Third Party Licenses](./THIRD_PARTY_LICENSES.md).
+
+### Contributing
+
+Please see the [Contributing Guide](./CONTRIBUTING.md). Note that you must sign the [CLA](./CONTRIBUTOR_LICENSE_AGREEMENT.md).
+
+### Caveats
+
+#### Mappings
+
+Note that even though Pydantic is perfectly happy with fields that hold mappings (e.g. dictionaries), because [GraphQL's type system doesn't have them](https://graphql.org/learn/schema/) those fields can't be exported to Graphene types. For instance, this will fail with an error `Don't know how to handle mappings in Graphene`:
+
+``` python
+import typing
+from graphene_pydantic import PydanticObjectType
+
+class Pet:
+ pass
+
+class Person:
+ name: str
+ pets_by_name: typing.Dict[str, Pet]
+
+class GraphQLPerson(PydanticObjectType):
+ class Meta:
+ model = Person
+```
+
+However, note that if you use `exclude_fields` or `only_fields` to exclude those values, there won't be a problem:
+
+``` python
+class GraphQLPerson(PydanticObjectType):
+ class Meta:
+ model = Person
+ exclude_fields = ("pets_by_name",)
+```
+
+#### Union types
+
+There are some caveats when using Unions. Let's take the following pydantic models as an example for this section:
+
+```python
+class EmployeeModel(pydantic.BaseModel):
+ name: str
+
+
+class ManagerModel(EmployeeModel):
+ title: str
+
+
+class DepartmentModel(pydantic.BaseModel):
+ employees: T.List[T.Union[ManagerModel, EmployeeModel]]
+```
+
+##### You have to implement the class method `is_type_of` in the graphene models
+
+To get the Union between `ManagerModel` and `EmployeeModel` to successfully resolve
+in graphene, you need to implement `is_type_of` like this:
+
+```python
+class Employee(PydanticObjectType):
+ class Meta:
+ model = EmployeeModel
+
+ @classmethod
+ def is_type_of(cls, root, info):
+ return isinstance(root, (cls, EmployeeModel))
+
+
+class Manager(PydanticObjectType):
+ class Meta:
+ model = ManagerModel
+
+ @classmethod
+ def is_type_of(cls, root, info):
+ return isinstance(root, (cls, ManagerModel))
+
+
+class Department(PydanticObjectType):
+ class Meta:
+ model = DepartmentModel
+```
+
+Otherwise GraphQL will throw an error similar to `"[GraphQLError('Abstract type
+UnionOfManagerModelEmployeeModel must resolve to an Object type at runtime for
+field Department.employees ..."`
+
+##### For unions between subclasses, you need to put the subclass first in the type annotation
+
+Looking at the `employees` field above, if you write the type annotation with Employee first,
+`employees: T.List[T.Union[EmployeeModel, ManagerModel]]`, you will not be able to query
+manager-related fields (in this case `title`). In a query containing a spread like this:
+
+```
+...on Employee {
+ name
+}
+...on Manager {
+ name
+ title
+}
+```
+
+... the objects will always resolve to being an `Employee`. This can be avoided if you put
+the subclass first in the list of annotations: `employees: T.List[T.Union[ManagerModel, EmployeeModel]]`.
+
+##### Unions between subclasses don't work in Python 3.6
+
+If a field on a model is a Union between a class and a subclass (as in our example),
+Python 3.6's typing will not preserve the Union and throws away the annotation for the subclass.
+See [this issue](https://github.com/upsidetravel/graphene-pydantic/issues/11) for more details.
+The solution at present is to use Python 3.7.
+
+##### Input Object Types don't support unions as fields
+
+This is a GraphQL limitation. See [this RFC](https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md) for the progress on supporting input unions. If you see an error like '{union-type} may only contain Object types', you are most likely encountering this limitation.
+
+
+%package -n python3-graphene-pydantic
+Summary: Graphene Pydantic integration
+Provides: python-graphene-pydantic
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-graphene-pydantic
+# ![Graphene Logo](http://graphene-python.org/favicon.png) graphene-pydantic [![Build status](https://circleci.com/gh/upsidetravel/graphene-pydantic.svg?style=svg)](https://circleci.com/gh/upsidetravel/graphene-pydantic) [![PyPI version](https://badge.fury.io/py/graphene-pydantic.svg)](https://badge.fury.io/py/graphene-pydantic) [![Coverage Status](https://coveralls.io/repos/upsidetravel/graphene-pydantic/badge.svg?branch=master&service=github)](https://coveralls.io/github/upsidetravel/graphene-pydantic?branch=master)
+
+
+
+A [Pydantic](https://pydantic-docs.helpmanual.io/) integration for [Graphene](http://graphene-python.org/).
+
+## Installation
+
+```bash
+pip install "graphene-pydantic"
+```
+
+## Examples
+
+Here is a simple Pydantic model:
+
+```python
+import uuid
+import pydantic
+
+class PersonModel(pydantic.BaseModel):
+ id: uuid.UUID
+ first_name: str
+ last_name: str
+```
+
+To create a GraphQL schema for it you simply have to write the following:
+
+```python
+import graphene
+from graphene_pydantic import PydanticObjectType
+
+class Person(PydanticObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+class Query(graphene.ObjectType):
+ people = graphene.List(Person)
+
+ @staticmethod
+ def resolve_people(parent, info):
+ # fetch actual PersonModels here
+ return [PersonModel(id=uuid.uuid4(), first_name="Beth", last_name="Smith")]
+
+schema = graphene.Schema(query=Query)
+```
+
+Then you can simply query the schema:
+
+```python
+query = """
+ query {
+ people {
+ firstName,
+ lastName
+ }
+ }
+"""
+result = schema.execute(query)
+print(result.data['people'][0])
+```
+
+### Input Object Types
+
+You can also create input object types from Pydantic models for mutations and queries:
+
+```python
+from graphene_pydantic import PydanticInputObjectType
+
+class PersonInput(PydanticInputObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+class CreatePerson(graphene.Mutation):
+ class Arguments:
+ person = PersonInput()
+
+ Output = Person
+
+ @staticmethod
+ def mutate(parent, info, person):
+ personModel = PersonModel(id=uuid.uuid4(), first_name=person.first_name, last_name=person.last_name)
+ # save PersonModel here
+ return person
+
+class Mutation(graphene.ObjectType):
+ createPerson = CreatePerson.Field()
+
+schema = graphene.Schema(mutation=Mutation)
+```
+
+Then execute with the input:
+
+```python
+mutation = '''
+mutation {
+ createPerson(person: {
+ firstName: "Jerry",
+ lastName: "Smith"
+ }) {
+ firstName
+ }
+}
+'''
+result = schema.execute(mutation)
+print(result.data['createPerson']['firstName'])
+```
+
+### Custom resolve functions
+
+Since `PydanticObjectType` inherits from `graphene.ObjectType` you can add custom resolve functions as explained [here](https://docs.graphene-python.org/en/stable/api/#object-types). For instance:
+
+```python
+class Person(PydanticObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+ full_name = graphene.String()
+
+ def resolve_full_name(self, info, **kwargs):
+ return self.first_name + ' ' + self.last_name
+```
+
+
+### Forward declarations and circular references
+
+`graphene_pydantic` supports forward declarations and circular references, but you will need to call the `resolve_placeholders()` method to ensure the types are fully updated before you execute a GraphQL query. For instance:
+
+``` python
+class NodeModel(BaseModel):
+ id: int
+ name: str
+ labels: 'LabelsModel'
+
+class LabelsModel(BaseModel):
+ node: NodeModel
+ labels: typing.List[str]
+
+class Node(PydanticObjectType):
+ class Meta:
+ model = NodeModel
+
+class Labels(PydanticObjectType):
+ class Meta:
+ model = LabelsModel
+
+
+Node.resolve_placeholders() # make the `labels` field work
+Labels.resolve_placeholders() # make the `node` field work
+```
+
+### Full Examples
+
+Please see [the examples directory](./examples) for more.
+
+### License
+
+This project is under the [Apache License](./LICENSE.md).
+
+### Third Party Code
+
+This project depends on third-party code which is subject to the licenses set forth in [Third Party Licenses](./THIRD_PARTY_LICENSES.md).
+
+### Contributing
+
+Please see the [Contributing Guide](./CONTRIBUTING.md). Note that you must sign the [CLA](./CONTRIBUTOR_LICENSE_AGREEMENT.md).
+
+### Caveats
+
+#### Mappings
+
+Note that even though Pydantic is perfectly happy with fields that hold mappings (e.g. dictionaries), because [GraphQL's type system doesn't have them](https://graphql.org/learn/schema/) those fields can't be exported to Graphene types. For instance, this will fail with an error `Don't know how to handle mappings in Graphene`:
+
+``` python
+import typing
+from graphene_pydantic import PydanticObjectType
+
+class Pet:
+ pass
+
+class Person:
+ name: str
+ pets_by_name: typing.Dict[str, Pet]
+
+class GraphQLPerson(PydanticObjectType):
+ class Meta:
+ model = Person
+```
+
+However, note that if you use `exclude_fields` or `only_fields` to exclude those values, there won't be a problem:
+
+``` python
+class GraphQLPerson(PydanticObjectType):
+ class Meta:
+ model = Person
+ exclude_fields = ("pets_by_name",)
+```
+
+#### Union types
+
+There are some caveats when using Unions. Let's take the following pydantic models as an example for this section:
+
+```python
+class EmployeeModel(pydantic.BaseModel):
+ name: str
+
+
+class ManagerModel(EmployeeModel):
+ title: str
+
+
+class DepartmentModel(pydantic.BaseModel):
+ employees: T.List[T.Union[ManagerModel, EmployeeModel]]
+```
+
+##### You have to implement the class method `is_type_of` in the graphene models
+
+To get the Union between `ManagerModel` and `EmployeeModel` to successfully resolve
+in graphene, you need to implement `is_type_of` like this:
+
+```python
+class Employee(PydanticObjectType):
+ class Meta:
+ model = EmployeeModel
+
+ @classmethod
+ def is_type_of(cls, root, info):
+ return isinstance(root, (cls, EmployeeModel))
+
+
+class Manager(PydanticObjectType):
+ class Meta:
+ model = ManagerModel
+
+ @classmethod
+ def is_type_of(cls, root, info):
+ return isinstance(root, (cls, ManagerModel))
+
+
+class Department(PydanticObjectType):
+ class Meta:
+ model = DepartmentModel
+```
+
+Otherwise GraphQL will throw an error similar to `"[GraphQLError('Abstract type
+UnionOfManagerModelEmployeeModel must resolve to an Object type at runtime for
+field Department.employees ..."`
+
+##### For unions between subclasses, you need to put the subclass first in the type annotation
+
+Looking at the `employees` field above, if you write the type annotation with Employee first,
+`employees: T.List[T.Union[EmployeeModel, ManagerModel]]`, you will not be able to query
+manager-related fields (in this case `title`). In a query containing a spread like this:
+
+```
+...on Employee {
+ name
+}
+...on Manager {
+ name
+ title
+}
+```
+
+... the objects will always resolve to being an `Employee`. This can be avoided if you put
+the subclass first in the list of annotations: `employees: T.List[T.Union[ManagerModel, EmployeeModel]]`.
+
+##### Unions between subclasses don't work in Python 3.6
+
+If a field on a model is a Union between a class and a subclass (as in our example),
+Python 3.6's typing will not preserve the Union and throws away the annotation for the subclass.
+See [this issue](https://github.com/upsidetravel/graphene-pydantic/issues/11) for more details.
+The solution at present is to use Python 3.7.
+
+##### Input Object Types don't support unions as fields
+
+This is a GraphQL limitation. See [this RFC](https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md) for the progress on supporting input unions. If you see an error like '{union-type} may only contain Object types', you are most likely encountering this limitation.
+
+
+%package help
+Summary: Development documents and examples for graphene-pydantic
+Provides: python3-graphene-pydantic-doc
+%description help
+# ![Graphene Logo](http://graphene-python.org/favicon.png) graphene-pydantic [![Build status](https://circleci.com/gh/upsidetravel/graphene-pydantic.svg?style=svg)](https://circleci.com/gh/upsidetravel/graphene-pydantic) [![PyPI version](https://badge.fury.io/py/graphene-pydantic.svg)](https://badge.fury.io/py/graphene-pydantic) [![Coverage Status](https://coveralls.io/repos/upsidetravel/graphene-pydantic/badge.svg?branch=master&service=github)](https://coveralls.io/github/upsidetravel/graphene-pydantic?branch=master)
+
+
+
+A [Pydantic](https://pydantic-docs.helpmanual.io/) integration for [Graphene](http://graphene-python.org/).
+
+## Installation
+
+```bash
+pip install "graphene-pydantic"
+```
+
+## Examples
+
+Here is a simple Pydantic model:
+
+```python
+import uuid
+import pydantic
+
+class PersonModel(pydantic.BaseModel):
+ id: uuid.UUID
+ first_name: str
+ last_name: str
+```
+
+To create a GraphQL schema for it you simply have to write the following:
+
+```python
+import graphene
+from graphene_pydantic import PydanticObjectType
+
+class Person(PydanticObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+class Query(graphene.ObjectType):
+ people = graphene.List(Person)
+
+ @staticmethod
+ def resolve_people(parent, info):
+ # fetch actual PersonModels here
+ return [PersonModel(id=uuid.uuid4(), first_name="Beth", last_name="Smith")]
+
+schema = graphene.Schema(query=Query)
+```
+
+Then you can simply query the schema:
+
+```python
+query = """
+ query {
+ people {
+ firstName,
+ lastName
+ }
+ }
+"""
+result = schema.execute(query)
+print(result.data['people'][0])
+```
+
+### Input Object Types
+
+You can also create input object types from Pydantic models for mutations and queries:
+
+```python
+from graphene_pydantic import PydanticInputObjectType
+
+class PersonInput(PydanticInputObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+class CreatePerson(graphene.Mutation):
+ class Arguments:
+ person = PersonInput()
+
+ Output = Person
+
+ @staticmethod
+ def mutate(parent, info, person):
+ personModel = PersonModel(id=uuid.uuid4(), first_name=person.first_name, last_name=person.last_name)
+ # save PersonModel here
+ return person
+
+class Mutation(graphene.ObjectType):
+ createPerson = CreatePerson.Field()
+
+schema = graphene.Schema(mutation=Mutation)
+```
+
+Then execute with the input:
+
+```python
+mutation = '''
+mutation {
+ createPerson(person: {
+ firstName: "Jerry",
+ lastName: "Smith"
+ }) {
+ firstName
+ }
+}
+'''
+result = schema.execute(mutation)
+print(result.data['createPerson']['firstName'])
+```
+
+### Custom resolve functions
+
+Since `PydanticObjectType` inherits from `graphene.ObjectType` you can add custom resolve functions as explained [here](https://docs.graphene-python.org/en/stable/api/#object-types). For instance:
+
+```python
+class Person(PydanticObjectType):
+ class Meta:
+ model = PersonModel
+ # exclude specified fields
+ exclude_fields = ("id",)
+
+ full_name = graphene.String()
+
+ def resolve_full_name(self, info, **kwargs):
+ return self.first_name + ' ' + self.last_name
+```
+
+
+### Forward declarations and circular references
+
+`graphene_pydantic` supports forward declarations and circular references, but you will need to call the `resolve_placeholders()` method to ensure the types are fully updated before you execute a GraphQL query. For instance:
+
+``` python
+class NodeModel(BaseModel):
+ id: int
+ name: str
+ labels: 'LabelsModel'
+
+class LabelsModel(BaseModel):
+ node: NodeModel
+ labels: typing.List[str]
+
+class Node(PydanticObjectType):
+ class Meta:
+ model = NodeModel
+
+class Labels(PydanticObjectType):
+ class Meta:
+ model = LabelsModel
+
+
+Node.resolve_placeholders() # make the `labels` field work
+Labels.resolve_placeholders() # make the `node` field work
+```
+
+### Full Examples
+
+Please see [the examples directory](./examples) for more.
+
+### License
+
+This project is under the [Apache License](./LICENSE.md).
+
+### Third Party Code
+
+This project depends on third-party code which is subject to the licenses set forth in [Third Party Licenses](./THIRD_PARTY_LICENSES.md).
+
+### Contributing
+
+Please see the [Contributing Guide](./CONTRIBUTING.md). Note that you must sign the [CLA](./CONTRIBUTOR_LICENSE_AGREEMENT.md).
+
+### Caveats
+
+#### Mappings
+
+Note that even though Pydantic is perfectly happy with fields that hold mappings (e.g. dictionaries), because [GraphQL's type system doesn't have them](https://graphql.org/learn/schema/) those fields can't be exported to Graphene types. For instance, this will fail with an error `Don't know how to handle mappings in Graphene`:
+
+``` python
+import typing
+from graphene_pydantic import PydanticObjectType
+
+class Pet:
+ pass
+
+class Person:
+ name: str
+ pets_by_name: typing.Dict[str, Pet]
+
+class GraphQLPerson(PydanticObjectType):
+ class Meta:
+ model = Person
+```
+
+However, note that if you use `exclude_fields` or `only_fields` to exclude those values, there won't be a problem:
+
+``` python
+class GraphQLPerson(PydanticObjectType):
+ class Meta:
+ model = Person
+ exclude_fields = ("pets_by_name",)
+```
+
+#### Union types
+
+There are some caveats when using Unions. Let's take the following pydantic models as an example for this section:
+
+```python
+class EmployeeModel(pydantic.BaseModel):
+ name: str
+
+
+class ManagerModel(EmployeeModel):
+ title: str
+
+
+class DepartmentModel(pydantic.BaseModel):
+ employees: T.List[T.Union[ManagerModel, EmployeeModel]]
+```
+
+##### You have to implement the class method `is_type_of` in the graphene models
+
+To get the Union between `ManagerModel` and `EmployeeModel` to successfully resolve
+in graphene, you need to implement `is_type_of` like this:
+
+```python
+class Employee(PydanticObjectType):
+ class Meta:
+ model = EmployeeModel
+
+ @classmethod
+ def is_type_of(cls, root, info):
+ return isinstance(root, (cls, EmployeeModel))
+
+
+class Manager(PydanticObjectType):
+ class Meta:
+ model = ManagerModel
+
+ @classmethod
+ def is_type_of(cls, root, info):
+ return isinstance(root, (cls, ManagerModel))
+
+
+class Department(PydanticObjectType):
+ class Meta:
+ model = DepartmentModel
+```
+
+Otherwise GraphQL will throw an error similar to `"[GraphQLError('Abstract type
+UnionOfManagerModelEmployeeModel must resolve to an Object type at runtime for
+field Department.employees ..."`
+
+##### For unions between subclasses, you need to put the subclass first in the type annotation
+
+Looking at the `employees` field above, if you write the type annotation with Employee first,
+`employees: T.List[T.Union[EmployeeModel, ManagerModel]]`, you will not be able to query
+manager-related fields (in this case `title`). In a query containing a spread like this:
+
+```
+...on Employee {
+ name
+}
+...on Manager {
+ name
+ title
+}
+```
+
+... the objects will always resolve to being an `Employee`. This can be avoided if you put
+the subclass first in the list of annotations: `employees: T.List[T.Union[ManagerModel, EmployeeModel]]`.
+
+##### Unions between subclasses don't work in Python 3.6
+
+If a field on a model is a Union between a class and a subclass (as in our example),
+Python 3.6's typing will not preserve the Union and throws away the annotation for the subclass.
+See [this issue](https://github.com/upsidetravel/graphene-pydantic/issues/11) for more details.
+The solution at present is to use Python 3.7.
+
+##### Input Object Types don't support unions as fields
+
+This is a GraphQL limitation. See [this RFC](https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md) for the progress on supporting input unions. If you see an error like '{union-type} may only contain Object types', you are most likely encountering this limitation.
+
+
+%prep
+%autosetup -n graphene-pydantic-0.4.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-graphene-pydantic -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Wed May 10 2023 Python_Bot <Python_Bot@openeuler.org> - 0.4.0-1
+- Package Spec generated