graphql-python / graphene-pydantic Goto Github PK
View Code? Open in Web Editor NEWIntegrate GraphQL with your Pydantic models
License: Other
Integrate GraphQL with your Pydantic models
License: Other
I've two pydantic models. Each in his own module (file). One Model, the TUser depends on the TAddress.
address_model.py
class TAddress(BaseModel):
id: Optional[int]
address: Optional[constr(max_length=100, strip_whitespace=True)]
city: Optional[constr(max_length=80, strip_whitespace=True)]
postal_code: Optional[constr(max_length=15, strip_whitespace=True)]
country: Optional[constr(max_length=3)]
user_model.py
class TUser(BaseModel):
id: UUID = None
email: Optional[EmailStr]
address: Optional[TAddress]
is_active: Optional[bool]
is_email_verified: Optional[bool]
created_at: Optional[datetime.datetime]
If I use the TUser model know for my PydanticObjectType
class UserType(PydanticObjectType):
class Meta:
model = TUser
I get the following error message:
graphene_pydantic.converters.ConversionError: Don't know how to convert the Pydantic field ModelField(name='address', type=Optional[TAddress], required=False, default=None) (<class 'app.address.serializers.TAddress'>)
It seems like that there is a problem when using pydantic models from different modules that depends on each other.
What is the solution for this use case?
Any idea?
pydantic has support for Json field, i think that maps directly to https://docs.graphene-python.org/en/latest/_modules/graphene/types/json/ of graphene?
@necaris I get AssertionError: Found different types with the same name in the schema: Foo, Foo.
if I run test_query
from test_forward_refs.py
twice!
When installing graphene-pydantic with pip, I get this error message
ERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.
We recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.
graphene-pydantic 0.1.0 requires pydantic<=1.6,>=1.0, but you'll have pydantic 1.6.1 which is incompatible.
This does not affect installation in any way but it would help updating the library to use the latest pydantic version
I was delighted that the following works (I copied something from django_graphene code), but AFAICT it's not a documented feature
class Resolution(PydanticObjectType):
class Meta:
model = ResolutionModel
exclude_fields = ("status",)
status = graphene.String()
def resolve_status(self, info, **kwargs):
return str(self.status)
I suppose you can add any additional field to a PydanticObjectType
by declaring it and adding a resolve function for it? It would be nice to add this to the docs.
Currently, library is built for pydantic:
pydantic = ">=1.0,<1.7"
But newer version 1.8.2 of pydantic is currently available making it impossible to use graphene-pydantic
with this version.
We think the following code produces an incorrect schema:
from pydantic import BaseModel
from graphene_pydantic import PydanticObjectType
import graphene
class ExampleModel(BaseModel):
attr: int = 0
class ExampleType(PydanticObjectType):
class Meta:
model = ExampleModel
class Query(graphene.ObjectType):
example = graphene.Field(ExampleType)
@staticmethod
def resolve_example(parent, info):
# fetch actual PersonModels here
return [ExampleType()]
schema = graphene.Schema(query=Query)
print(schema)
Result:
schema {
query: Query
}
type ExampleType {
attr: Int
}
type Query {
example: ExampleType
}
AFAICT, the Int
field on ExampleType
should not be nullable, since there will always be a default value and this value cannot be null. Instead it should be:
type ExampleType {
attr: Int!
}
I think it's a one line fix here, you need to change:
field_kwargs.setdefault("required", field.required)
to
field_kwargs.setdefault("required", not field.allow_none)
For reference, the Pydantic docs on distinguishing nullability (optional) and required fields.
If you agree with this, I'm happy to submit a PR - we are already doing this on our fork.
Right now, when my pydantic model looks like the following:
class MyClassModel(BaseModel):
myList: List[str]
and my graphene model looks like this:
class MyClassType(PydanticObjectType):
class Meta:
model = MyClassModel
fields = ("myList")
the GraphQL schema output for this field looks like this:
myList: [String]!
This means that introspection in TypeScript interprets each element in the List as a Maybe<String>
instead of a String
. What can I do here to ensure that the type is myList: [String!]!
?
Thanks!
These lines:
https://github.com/graphql-python/graphene-pydantic/blob/master/pyproject.toml#L23-L25
Make it sound as if the library should be supporting the "latest" Pydantic version(s). Shouldn't that be <= or ~ 1.7 then in order to include 1.7.3
(which is the latest at the moment)?
For this reason I had to downgrade pydantic in my project. Are there issues with using semver to stay under the same minor?
If you try to build an ObjectType and InputObjectType for pydantic models with the same enum, it tries to create the same enum twice. (This is not an issue with re-using the same enum in multiple ObjectTypes though.)
Here's a reproducible example:
import enum
import pydantic
import graphene
from graphene_pydantic import PydanticObjectType, PydanticInputObjectType
class Color(enum.Enum):
red = 1
green = 2
blue = 3
class ColorModel(pydantic.BaseModel):
color: Color
class ColorType(PydanticObjectType):
class Meta:
model = ColorModel
class ColorInputType(PydanticInputObjectType
):
class Meta:
model = ColorModel
class CreateColor(graphene.Mutation):
class Arguments:
data = graphene.Argument(ColorInputType)
ok = graphene.String()
def mutate(self, info, data):
return ColorModel(**data)
class Query(graphene.ObjectType):
color = graphene.Field(ColorType)
class Mutation(graphene.ObjectType):
createColor = CreateColor.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
And the error:
95 _type = map[type._meta.name]
96 if isinstance(_type, GrapheneGraphQLType):
---> 97 assert _type.graphene_type == type, (
98 "Found different types with the same name in the schema: {}, {}."
99 ).format(_type.graphene_type, type)
AssertionError: Found different types with the same name in the schema: Color, Color.
The workaround is just to manually define the enum type, but thought it would be helpful to know.
For others who got this error:
ColorEnumType = graphene.Enum.from_enum(Color)
class ColorType(PydanticObjectType):
class Meta:
model = ColorModel
color = graphene.Field(ColorEnumType)
class ColorInputType(PydanticInputObjectType
):
class Meta:
model = ColorModel
color = graphene.Argument(ColorEnumType)
Hi team!
I think this package could be a great addition to the GraphQL-Python organization.
Let me know if you would be interested in adding this repo to the org! ❤️
See #10 -- while the examples work fine in Python 3.7, it would be ideal if we could make them work (or document where they don't) in 3.6
looks like v3 is not supported yet, because it's throwing errors during installation
Hello,
I wanted to use nested pydantic.BaseModel with PydanticInputObjectType, but I struggle to make it work
Something like this:
from pydantic import BaseModel
from graphene_pydantic import PydanticInputObjectType
import graphene
class A(BaseModel):
x: str
class B(BaseModel):
a: A
class BInput(PydanticInputObjectType):
class Meta:
model = B
class createB(graphene.Mutation):
class Arguments:
b = BInput()
output = graphene.String()
def mutate(self, info, b):
return "42"
class Mutation(graphene.ObjectType):
createB = createB.Field()
schema = graphene.Schema(mutation=Mutation)
Gives me:
Traceback (most recent call last):
File "[PATH]/lib/python3.9/site-packages/graphene/types/schema.py", line 122, in add_type
name = graphene_type._meta.name
AttributeError: 'Placeholder' object has no attribute '_meta'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "[PATH]/lib/python3.9/site-packages/graphql/type/definition.py", line 1456, in fields
fields = resolve_thunk(self._fields)
File "[PATH]/lib/python3.9/site-packages/graphql/type/definition.py", line 300, in resolve_thunk
return thunk() if callable(thunk) else thunk
File "[PATH]/lib/python3.9/site-packages/graphene/types/schema.py", line 312, in create_fields_for_type
field_type = create_graphql_type(field.type)
File "[PATH]/lib/python3.9/site-packages/graphene/types/schema.py", line 120, in add_type
return GraphQLNonNull(self.add_type(graphene_type.of_type))
File "[PATH]/lib/python3.9/site-packages/graphene/types/schema.py", line 124, in add_type
raise TypeError(f"Expected Graphene type, but received: {graphene_type}.")
TypeError: Expected Graphene type, but received: Placeholder(<class '__main__.A'>).
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "[PATH]/lib/python3.9/site-packages/graphene/types/schema.py", line 440, in __init__
self.graphql_schema = GraphQLSchema(
File "[PATH]/lib/python3.9/site-packages/graphql/type/schema.py", line 226, in __init__
collect_referenced_types(mutation)
File "[PATH]/lib/python3.9/site-packages/graphql/type/schema.py", line 435, in collect_referenced_types
collect_referenced_types(arg.type)
File "[PATH]/lib/python3.9/site-packages/graphql/type/schema.py", line 438, in collect_referenced_types
for field in named_type.fields.values():
File "[PATH]/lib/python3.9/functools.py", line 993, in __get__
val = self.func(instance)
File "[PATH]/lib/python3.9/site-packages/graphql/type/definition.py", line 1459, in fields
raise cls(f"{self.name} fields cannot be resolved. {error}") from error
TypeError: BInput fields cannot be resolved. Expected Graphene type, but received: Placeholder(<class '__main__.A'>).
I tried using resolve_placeholders
, but then I get an error:
from pydantic import BaseModel
from graphene_pydantic import PydanticInputObjectType
import graphene
class A(BaseModel):
x: str
class B(BaseModel):
a: A
class BInput(PydanticInputObjectType):
class Meta:
model = B
BInput.resolve_placeholders()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "[PATH]/lib/python3.9/site-packages/graphene_pydantic/inputobjecttype.py", line 152, in resolve_placeholders
meta.registry.register_object_field(
TypeError: register_object_field() got an unexpected keyword argument 'model'
My versions are:
graphene==3.3
pydantic==2.7.1
graphene_pdantic==0.6.1
Is there any way to use PydanticInputObjectType in nested case?
Dataclasses are really useful in some instances. Pydantic has a drop-in replacement for dataclasses - but does not seem to supported by this library. Not sure how difficult it would be to include it? I know the classes have a __pydantic_model__
variable.
The current supported type is inconsistent with the type supported by pydantic ,for example EmailStr UrlStr etc.
Hey.
Is there a way to handle reserved keywords in schema?
Pydantic model that works fine:
class Model(BaseModel):
class_: str
class Config:
fields = {
'class_': 'class'
}
But with this model, graphene don't see field named class
. Only class_
.
It has been released, with huge performance boosts:
Hi,
I am running into an issue in which my pydantic model defines a union of scalar types, as follows:
class ImageModel(BaseModel):
url: str
filename: str
modified: Union[str, int]
key: str
size: int
My graphene object type:
class Image(PydanticObjectType):
class Meta:
model = ImageModel
Attempting to generate a graphql schema from this results in the error:
AttributeError: 'GraphQLScalarType' object has no attribute 'graphene_type'
at
graphene/types/typemap.py(251)
The caveats for unions seem to be for custom object types only. Are scalars supported?
Thanks.
EDIT
This may be a graphene specific issue?
Hey.
Can't make this code work. Fails with error
graphene_pydantic.converters.ConversionError: Don't know how to convert the Pydantic field ModelField(name='nodes', type=Optional[NodeModel], required=False, default=None) (<class 'app.graphql.schemas.blablabla.NodeModel'>)
Code example
from typing import Optional, Union
from pydantic import BaseModel
from graphene_pydantic import PydanticObjectType
class NodeModel(BaseModel):
id: int
name: str
# nodes: Union['NodeModel', None]
nodes: Optional['NodeModel']
NodeModel.update_forward_refs()
class NodeModelSchema(PydanticObjectType):
class Meta: # noqa: too-few-public-methods
model = NodeModel
@classmethod
def is_type_of(cls, root, info):
return isinstance(root, (cls, NodeModel))
NodeModelSchema.resolve_placeholders()
Am I doing something wrong?
I am trying to use pydantic's AnyUrl type:
class SomePydanticModel(pydantic.BaseModel):
url: pydantic.AnyUrl = pydantic.Field()
class SomeGrapheneObject(graphene_pydantic.PydanticObjectType):
class Meta:
model = SomePydanticModel
But I receive the following error:
graphene_pydantic.converters.ConversionError: Don't know how to convert the Pydantic field FieldInfo(annotation=Url, required=True) (<class 'pydantic_core._pydantic_core.Url'>)
Is there a way to support this field?
graphene==3.3
graphene-pydantic==0.6.1
In the following example, add the foo: Dict[str, str] member to Person model causes an error. Is there another way that I can use a Dict, which works great in pydantic?
import uuid
from typing import Dict
import pydantic
import graphene
from graphene_pydantic import PydanticObjectType
class PersonModel(pydantic.BaseModel):
id: uuid.UUID
first_name: str
last_name: str
foo: Dict[str, str]
class Person(PydanticObjectType):
class Meta:
model = PersonModel
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")]
Produces:
Traceback (most recent call last):
File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/home/dylan/.vscode/extensions/ms-python.python-2021.2.582707922/pythonFiles/lib/python/debugpy/__main__.py", line 45, in <module>
cli.main()
File "/home/dylan/.vscode/extensions/ms-python.python-2021.2.582707922/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 444, in main
run()
File "/home/dylan/.vscode/extensions/ms-python.python-2021.2.582707922/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 285, in run_file
runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
File "/usr/lib/python3.8/runpy.py", line 265, in run_path
return _run_module_code(code, init_globals, run_name,
File "/usr/lib/python3.8/runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/home/dylan/work/als-computing/splash-ml/examples/test_graphql.py", line 17, in <module>
class Person(PydanticObjectType):
File "/home/dylan/work/als-computing/splash-ml/env/lib/python3.8/site-packages/graphene/types/objecttype.py", line 30, in __new__
base_cls = super().__new__(
File "/home/dylan/work/als-computing/splash-ml/env/lib/python3.8/site-packages/graphene/utils/subclass_with_meta.py", line 46, in __init_subclass__
super_class.__init_subclass_with_meta__(**options)
File "/home/dylan/work/als-computing/splash-ml/env/lib/python3.8/site-packages/graphene_pydantic/objecttype.py", line 90, in __init_subclass_with_meta__
construct_fields(
File "/home/dylan/work/als-computing/splash-ml/env/lib/python3.8/site-packages/graphene_pydantic/objecttype.py", line 46, in construct_fields
converted = convert_pydantic_field(
File "/home/dylan/work/als-computing/splash-ml/env/lib/python3.8/site-packages/graphene_pydantic/converters.py", line 130, in convert_pydantic_field
convert_pydantic_type(
File "/home/dylan/work/als-computing/splash-ml/env/lib/python3.8/site-packages/graphene_pydantic/converters.py", line 166, in convert_pydantic_type
raise ConversionError("Don't know how to handle mappings in Graphene.")
graphene_pydantic.converters.ConversionError: Don't know how to handle mappings in Graphene.
I am using graphene-pydantic to generate a GraphQL schema for my mutation. I have gone through the documentation and it's working fine for all the types but the problem is when I use discriminators in the modules. Below is the sample code with discriminators and that's throwing an error.
from graphene_pydantic import PydanticInputObjectType, PydanticObjectType
import graphene
from typing import Literal, Union
from pydantic import BaseModel, Field
class Cat(BaseModel):
pet_type: Literal['cat']
meows: int
class Dog(BaseModel):
pet_type: Literal['dog']
barks: float
class Lizard(BaseModel):
pet_type: Literal['reptile', 'lizard']
scales: bool
class Model(BaseModel):
pet: Union[Cat, Dog, Lizard] = Field(..., discriminator='pet_type')
n: int
# print(Model(pet={'pet_type': 'dog', 'barks': 3.14, 'eats': 'biscuit'}, n=1))
class Input(PydanticInputObjectType):
class Meta:
model = Model
# exclude specified fields
exclude_fields = ("id",)
class Output(PydanticObjectType):
class Meta:
model = Model
# exclude specified fields
exclude_fields = ("id",)
class CreateAnimal(graphene.Mutation):
class Arguments:
input = Input()
output = Output
@staticmethod
def mutate(parent, info, input):
print(input)
# save model here
return input
class Mutation(graphene.ObjectType):
createPerson = CreateAnimal.Field()
schema = graphene.Schema(mutation=Mutation)
print(schema)
The error getting from graphene is like below and it is like a generalized error.
File "\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\type\definition.py", line 1338, in fields raise TypeError(f"{self.name} fields cannot be resolved. {error}")
TypeError: Input fields cannot be resolved. The input field type must be a GraphQL input type.
Can someone help on this?
I see the following comment in PydanticObjectType.__init_subclass_with_meta__
:
# TODO: We don't currently do anything with interfaces, and it would
# be great to handle them as well. Some options include:
# - throwing an error if they're present, because we _can't_ handle them
# - finding a model class with that name and generating an interface
# from it
# - using the nearest common ancestor of multiple types in a Union
Are there any concrete plans to add support for interfaces in the near future? For my particular use case, I'd be happy with manually defining interfaces rather than deducing them. For example, I'd like to be able to do this:
# this model will be used to define an interface
class HasIdentityModel(pydantic.BaseModel):
name: str
id: str
class IdentityListModel(pydantic.BaseModel):
things_with_ids: list[HasIdentityModel]
class PersonModel(HasIdentityModel):
age: int
class BusinessModel(HasIdentityModel):
owner: PersonModel
# would have to define PydanticInterfaceType similarly to PydanticObjectType
class HasIdentity(PydanticInterfaceType):
class Meta:
model = HasIdentityModel
class IdentityList(PydanticObjectType):
class Meta:
model = IdentityListModel
class Person(PydanticObjectType):
class Meta:
model = PersonModel
interfaces = (HasIdentity,) # or (HasIdentityModel, ) if that's more appropriate
class Business(PydanticObjectType):
class Meta:
model = BusinessModel
interfaces = (HasIdentity,) # as above
and then query the thingsWithIds
field as
thingsWithId: {
name
id
...on Person {
age
}
...on Business {
owner {
name
}
}
}
without having to put the name
and id
fields on the Person
or Business
fragments.
I'm trying to pass a description from one of the pydantic fields to the graphiQL documentation. I can't seem to get it to be recognized. It seems to be supported in graphene directly on the fields like this:
class Person(ObjectType):
first_name = graphene.String(required=True)
last_name = graphene.Field(String, description='Surname')
In pydantic it's supported like this:
class MainModel(BaseModel):
"""
This is the description of the main model
"""
snap: int = Field(
42,
title='The Snap',
description='this is the value of snap',
gt=30,
lt=50,
)
I've implemented the pydantic style description and don't see any change to the GraphiQL documentation on that field. Any ideas how to pass it over, or is this simply not supported with this library? I'm following the excellent tutorial here: https://testdriven.io/blog/fastapi-graphql/ but they don't spend any time on the self-documenting nature of graphql which is something really enjoy.
Thanks!
@necaris I have some requirements on a project that graphene-pydantic==0.3.0
doesn't support.
mutations
- those fields that were not passed - still come as None
. As a result, when parsing a dictionary into a Type[BaseModel]
, these fields are also passed through and an entry is added to the database with these values. exclude_default
, exclude_unset
- don't work. It is not correct.null
comes from the client
to the Int
field - I get an error. The field must be nullable.I corrected them - #75
Hi,
I was playing around with this library and tried running the departments.py script and got an error:
$ python departments.py
[GraphQLError('Unknown type "Manager".',)]
null
I removed the Manager part of the query:
$ git diff
diff --git a/examples/departments.py b/examples/departments.py
index c77e131..2637cb9 100644
--- a/examples/departments.py
+++ b/examples/departments.py
@@ -115,14 +115,6 @@ if __name__ == "__main__":
hiredOn
salary { rating }
}
- ...on Manager {
- name
- salary {
- rating
- amount
- }
- teamSize
- }
}
}
}
and got:
$ python departments.py
None
{
"listDepartments": [
{
"id": "48809bd6-0ff7-4942-94b6-b2c6a77e3621",
"name": "Administration",
"employees": [
{
"id": "467ae7ca-6398-41d4-b780-ab5f39ed24d3",
"name": "Jason",
"hiredOn": null,
"salary": {
"rating": "GS-11"
}
},
{
"id": "4eace3f7-190b-4b49-a9f3-faab3fba8ce7",
"name": "Carmen",
"hiredOn": "2019-01-01T15:26:00",
"salary": {
"rating": "GS-9"
}
},
{
"id": "08a791cf-0b36-4f0b-9c87-a1a1f17a5113",
"name": "Derek",
"hiredOn": null,
"salary": null
}
]
}
]
}
Is the union functionality not working?
I have the following challenge:
I am getting data from a database in json format / as dict.
This works great when I am directly grabbing the data in the query and "upgrading" it to the defined and in meta class registered pedantic data model.
Example:
class GrapheneModel(PydanticObjectType):
class Meta:
model = PydanticModel
...
class Queries(ObjectType):
examples = List(
GrapheneModel
)
@staticmethod
def resolve_examples(root, info, **kwargs):
result = fetch_from_db() # return a list of dicts
return [PydanticModel.model_validate(q) for q in result]
But I also have other cases where I come through an interface.
I can overlay the is_type_of method to get to the right GrapheneModel
, but the data that comes in is then a dict, which does not work... Do you guys have an idea how the data can be upgraded within the Graphene Model?
I cannot do it in the interface as I do not know the type there...
Thanks for any advise.
I'm a little confused how this happened, but 0.0.6 on PyPI specifies Pydantic <= 1.3, even though master specifies <= 1.4 and there don't appear to be any intervening commits.
Also, FYI, there is no tag that GitHub can see for 0.0.6.
Currently attempting to convert a constrained type will result in:
graphene_pydantic.converters.ConversionError: Don't know how to convert the Pydantic field ModelField(name='id', type=ConstrainedIntValue, required=True) (<class 'pydantic.types.ConstrainedIntValue'>)
Tried to install this package to a newly created FastAPI app. Got an "Incompatible versions in the resolved dependencies" error. Pipenv logs below:
Installing graphene-pydantic...
Adding graphene-pydantic to Pipfile's [packages]...
Installation Succeeded
Pipfile.lock (c505a8) out of date, updating to (9f8497)...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Locking...Building requirements...
Resolving dependencies...
Locking Failed!
[ResolutionFailure]: File "c:/users/akuani/appdata/local/programs/python/python38/lib/site-packages/pipenv/resolver.py", line 741, in _main
[ResolutionFailure]: resolve_packages(pre, clear, verbose, system, write, requirements_dir, packages, dev)
[ResolutionFailure]: File "c:/users/akuani/appdata/local/programs/python/python38/lib/site-packages/pipenv/resolver.py", line 702, in resolve_packages
[ResolutionFailure]: results, resolver = resolve(
[ResolutionFailure]: File "c:/users/akuani/appdata/local/programs/python/python38/lib/site-packages/pipenv/resolver.py", line 684, in resolve
[ResolutionFailure]: return resolve_deps(
[ResolutionFailure]: File "c:\users\akuani\appdata\local\programs\python\python38\lib\site-packages\pipenv\utils.py", line 1395, in resolve_deps
[ResolutionFailure]: results, hashes, markers_lookup, resolver, skipped = actually_resolve_deps(
[ResolutionFailure]: File "c:\users\akuani\appdata\local\programs\python\python38\lib\site-packages\pipenv\utils.py", line 1108, in actually_resolve_deps
[ResolutionFailure]: resolver.resolve()
[ResolutionFailure]: File "c:\users\akuani\appdata\local\programs\python\python38\lib\site-packages\pipenv\utils.py", line 833, in resolve
[ResolutionFailure]: raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: Could not find a version that matches graphene>=3.0b5 (from -r C:\Users\akuani\AppData\Local\Temp\pipenvnka3svhprequirements\pipenv-frhatc4t-constraints.txt (line 10))
Tried: 0.1.0, 0.1.1, 0.1.2, 0.1.3, 0.1.4, 0.1.5, 0.1.5.1, 0.1.5.2, 0.1.5.3, 0.1.6.0, 0.1.6.1, 0.3.0, 0.4.0, 0.4.0.1, 0.4.1, 0.4.1.1, 0.4.2, 0.4.3, 0.5.0, 0.6.0, 0.6.1, 0.7.0, 0.7.1, 0.7.2, 0.7.3, 0.8.0, 0.8.1, 0.9, 0.9.1, 0.10.0, 0.10.1, 0.10.2, 1.0, 1.0.1, 1.0.2,
1.1, 1.1.1, 1.1.2, 1.1.3, 1.2, 1.3, 1.4, 1.4.1, 1.4.2, 2.0, 2.0, 2.0.1, 2.0.1, 2.1, 2.1, 2.1.1, 2.1.1, 2.1.2, 2.1.2, 2.1.3, 2.1.3, 2.1.5, 2.1.5, 2.1.6, 2.1.6, 2.1.7, 2.1.7, 2.1.8, 2.1.8
Skipped pre-versions: 0.1.6a1, 0.9b1, 1.0.dev20160815004752, 1.0.dev20160816073455, 1.0.dev20160822080320, 1.0.dev20160823061102, 1.0.dev20160909040318, 1.0.dev20160909055438, 1.0.dev20160911044410, 1.0.dev20160911051803, 1.0.dev20160917190505, 1.0.dev2016091804123
9, 1.0.dev20160920015515, 1.0.dev20160920070441, 1.0.dev20160921153356, 1.0.dev20160922020647, 2.0.dev20170724064308, 2.0.dev20170725043308, 2.0.dev20170725061556, 2.0.dev20170727024417, 2.0.dev20170727061432, 2.0.dev20170801053013, 2.0.dev20170801053013, 2.0.dev20
170802065539, 2.0.dev20170802065539, 3.0.dev20190817210753, 3.0.dev20190817210753, 3.0a1, 3.0a1, 3.0b0, 3.0b0, 3.0b1, 3.0b1, 3.0b2, 3.0b2, 3.0b3, 3.0b3, 3.0b4, 3.0b4, 3.0b5, 3.0b5, 3.0b6, 3.0b6, 3.0b7, 3.0b7
There are incompatible versions in the resolved dependencies:
graphene (from -r C:\Users\akuani\AppData\Local\Temp\pipenvnka3svhprequirements\pipenv-frhatc4t-constraints.txt (line 10))
graphene>=3.0b5 (from graphene-pydantic==0.2.0->-r C:\Users\akuani\AppData\Local\Temp\pipenvnka3svhprequirements\pipenv-frhatc4t-constraints.txt (line 14))
I'm sorry for the title being vague but I didn't know how to present to you the problem.
Basically I was trying to hack up an API using FastAPI, Pydantic and GraphQL. I found this repo from an Issue there.
Following the readme, I couldn't query the data using GraphiQl(I hacked starlette and currently running on graphql playground).
for this query
query {
hackers {
id
}
}
I'm getting an error like this
{
"error": {
"data": {
"hackers": null
},
"errors": [
{
"message": "name 'get_hackers' is not defined",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"hackers"
]
}
]
}
}
My Pydantic Basemodel and ObjectType as
class HackerModel(BaseModel):
id: int
name: str
college: str
email: str
dob: date
class Hacker(PydanticObjectType):
class Meta:
model = HackerModel
only_fields=("name","college","id","email","dob")
class Config:
arbitrary_types_allowed = True
And my Query Class Looks like this
class Query(graphene.ObjectType):
hackers = graphene.List(Hacker)
def resolve_hackers(self, info):
return get_hackers()
I only followed your Readme Example . Any idea on How to resolve this?
I'm using some Literal['some-str']
field types in my pydantic models as a part of a discriminated union. I'd love to be able to use this with graphene-pydantic!
Unfortunately currently using Literal
field types seems to produce exceptions like the following:
server_1 | File "./main.py", line 11, in <module>
server_1 | import graphql_api
server_1 | File "./graphql_api.py", line 48, in <module>
server_1 | class BlockPlateSchema(PydanticObjectType):
server_1 | File "/opt/conda/lib/python3.7/site-packages/graphene/utils/subclass_with_meta.py", line 52, in __init_subclass__
server_1 | super_class.__init_subclass_with_meta__(**options)
server_1 | File "/opt/conda/lib/python3.7/site-packages/graphene_pydantic/objecttype.py", line 95, in __init_subclass_with_meta__
server_1 | exclude_fields=exclude_fields,
server_1 | File "/opt/conda/lib/python3.7/site-packages/graphene_pydantic/objecttype.py", line 47, in construct_fields
server_1 | field, registry, parent_type=obj_type, model=model
server_1 | File "/opt/conda/lib/python3.7/site-packages/graphene_pydantic/converters.py", line 130, in convert_pydantic_field
server_1 | declared_type, field, registry, parent_type=parent_type, model=model
server_1 | File "/opt/conda/lib/python3.7/site-packages/graphene_pydantic/converters.py", line 157, in convert_pydantic_type
server_1 | type_, field, registry, parent_type=parent_type, model=model
server_1 | File "/opt/conda/lib/python3.7/site-packages/graphene_pydantic/converters.py", line 211, in find_graphene_type
server_1 | type_, field, registry, parent_type=parent_type, model=model
server_1 | File "/opt/conda/lib/python3.7/site-packages/graphene_pydantic/converters.py", line 273, in convert_generic_python_type
server_1 | ) or issubclass(origin, collections.abc.Sequence):
server_1 | File "/opt/conda/lib/python3.7/abc.py", line 143, in __subclasscheck__
server_1 | return _abc_subclasscheck(cls, subclass)
server_1 | TypeError: issubclass() arg 1 must be a class
From what I could tell, there is currently no support for Literal
fields. Is that correct?
Python 3.7 is end-of-life as of June so we can safely drop it from our test matrix. Meanwhile, we need to add support for 3.12
Hey!
Thanks for all the work you have put in for graphene-pydantic. Is it possible to bump pydantic requirements ?
Take the following example, adapted from the README:
import uuid
import graphene
import pydantic
from graphene_pydantic import PydanticInputObjectType, PydanticObjectType
class PersonModel(pydantic.BaseModel):
id: uuid.UUID
first_name: str
last_name: str
class PersonInput(PydanticInputObjectType):
class Meta:
model = PersonModel
exclude_fields = ("id",)
class CreatePerson(graphene.Mutation):
class Arguments:
person = PersonInput()
@staticmethod
def mutate(parent, info, person: PersonInput): # I'd like to type hint this argument
personModel = PersonModel(
id=uuid.uuid4(),
first_name=person.first_name,
last_name=person.last_name
)
return person
It would be nice to be able to type hint the model properties that are defined on the InputObjectType
through introspection. Currently, the mutate
method generates type warnings:
this schema
class TestSchema(BaseModel):
date_field: datetime.date
breaks in tests that use freezegun to freeze time:
E graphene_pydantic.converters.ConversionError: Don't know how to convert the Pydantic field ModelField(name='date_field', type=date, required=True) (<class 'datetime.date'>)
I believe the issue is because freezegun overwrites the type of datetime.date
and datetime.datetime
, so these lines in the graphene_pydantic
converter (find_graphene_type()
) don't evaluate to true:
elif type_ == datetime.date:
return Date
pydantic code: https://github.com/graphql-python/graphene-pydantic/blob/master/graphene_pydantic/converters.py#L186
freezegun code: https://github.com/spulec/freezegun/blob/master/freezegun/api.py#L637
related freezegun issue: spulec/freezegun#170
I'm not sure if this is a weird fix or not, but changing the if condition to:
elif type_.__name__ == "date"
or
elif issubclass(type_, datetime.date):
fixes this use case.
A better suggestion (though I don't know the best way to implement) is to allow a custom type mappings so we don't have to rely on this switch statement.
Hi there!
Are there any plans to extend the graphene-pydantic magic to Graphene Mutations, in particular InputObjectTypes? It would be excellent to be able to validate Mutation arguments against Pydantic Models.
Hi there, thanks for creating the graphene-pydantic project :-) graphene-pydantic is currently locked into Pydantic version <=1.1,>=0.26
Do you have plans to keep up with the pydantic releases, or will you only update from time to time?
I found graphene-pydantic fails converting list[str]
field.
import graphene
import pydantic
import graphene_pydantic
class Model(pydantic.BaseModel):
field: list[str] = []
class GrapheneModel(graphene_pydantic.PydanticObjectType):
class Meta:
model = Model
class Query(graphene.ObjectType):
model = graphene.Field(GrapheneModel)
hello = graphene.String()
@staticmethod
def resolve_model(parent, info):
return Model()
schema = graphene.Schema(query=Query)
print(schema)
print(schema.execute('{model {field}}'))
saved as tmp.conao3/04_list.sample.py
and run like this
$ poetry run python tmp.conao3/04_list.sample.py
then, you see error.
Traceback (most recent call last):
File "/home/conao/dev/forks/graphene-pydantic/tmp.conao3/04_list.sample.py", line 11, in <module>
class GrapheneModel(graphene_pydantic.PydanticObjectType):
File "/home/conao/dev/forks/graphene-pydantic/.venv/lib/python3.10/site-packages/graphene/types/objecttype.py", line 45, in __new__
dataclass = make_dataclass(name_, fields, bases=())
File "/usr/lib/python3.10/dataclasses.py", line 1401, in make_dataclass
return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
File "/usr/lib/python3.10/dataclasses.py", line 1185, in dataclass
return wrap(cls)
File "/usr/lib/python3.10/dataclasses.py", line 1176, in wrap
return _process_class(cls, init, repr, eq, order, unsafe_hash,
File "/usr/lib/python3.10/dataclasses.py", line 956, in _process_class
cls_fields.append(_get_field(cls, name, type, kw_only))
File "/usr/lib/python3.10/dataclasses.py", line 813, in _get_field
raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'list'> for field field is not allowed: use default_factory
I use now main(2fd67a8)
and I use Python3.10
Currently pydantic is pinned to <=1.3.
Is this intentional or is it just because the version pinning is old?
Hi, is there any plans to release a PyPi version with the changes from the following PR: #71?
I saw there where some issues with this PR, but they where resolved. If there are more concerns, is there anyway I could help?
To reproduce create example models:
python 3.7
graphene==2.1.8
pydantic==1.7.1
graphene-pydantic==0.2.0
`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`
then when I try to run my app I receive:
` File "\site-packages\graphene\utils\subclass_with_meta.py", line 52, in __init_subclass__
super_class.__init_subclass_with_meta__(**options)
File "b\site-packages\graphene_pydantic\objecttype.py", line 95, in __init_subclass_with_meta__
exclude_fields=exclude_fields,
File "\site-packages\graphene_pydantic\objecttype.py", line 47, in construct_fields
field, registry, parent_type=obj_type, model=model
File "\site-packages\graphene_pydantic\converters.py", line 141, in convert_pydantic_field
return Field(resolver=get_attr_resolver(field.name), **field_kwargs)
TypeError: __init__() missing 1 required positional argument: 'type'
`
I believe the error is because constructor is expecting type
but it receives type
When I have changed locally line 129 in converters is working fine.
Here is my PR: #63
I added a comment to an already-merged PR, so creating an issue to keep track of this question.
Is dropping support for Graphene 2 intentional? It looked like there was a decision to specifically support Graphene 2 in 2022: #77
It looks like version 0.4.0 on PyPi supports Graphene 2, but version 0.4.1 does not, and I think it may be due to this change.
Sorry if I'm missing a deliberate choice to drop Graphene 2 support. Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.