I've been having issues with one of my passed mutation arguments that keeps triggering the middleware exception leak checker on graphiql interface load. Migrations and server start are just fine, but loading the url for the interface delivers a "_ValueError at /graphql/ Unknown argument "assignee"._ " error about.
The following are the directly relevant code snippets.
So I've build a "chores" model as such:
class Chore(models.Model):
name = models.TextField(blank=True)
description = models.TextField(blank=True)
isAllDay = models.BooleanField(blank=False)
points = models.IntegerField(blank=False)
status = models.IntegerField(blank=False, null=False)
recurrence_pattern = models.IntegerField(null=False, blank=False)
recurrence_enddate = models.DateTimeField(null=True, blank=False)
deadline = models.DateTimeField(blank=False)
created_by = models.ForeignKey(
'users.User',
related_name='chores_created',
on_delete=models.SET_NULL,
null=True,
)
assigned_to = models.ForeignKey(
'users.User',
related_name='chores_assigned',
on_delete=models.SET_NULL,
null=True,
)
belongs_to = models.ForeignKey(
'households.Household',
related_name="chores",
on_delete=models.SET_NULL,
null=True,
)
Below is the relevant schema portion, including the Type decleration and the InputObjectType I'm utilizing within that same query. I've included these portions as I have a strong hunch that the "assignee" value has nothing to do with the actual error, alas, I cannot figure out what it may be.
class ChoreType(DjangoObjectType):
class Meta:
model = Chore
class ResourceCreateInput(graphene.InputObjectType):
name = graphene.String(required = True)
checked = graphene.Boolean(required = True)
class AddChore(graphene.Mutation):
chore = graphene.Field(ChoreType)
class Arguments:
name = graphene.String(),
description= graphene.String(),
isAllDay= graphene.Boolean,
points= graphene.Int(),
status= graphene.Int(),
recurrence_pattern= graphene.Int(),
recurrence_enddate= graphene.DateTime(),
deadline= graphene.DateTime(),
creator= graphene.Int(), # userid
assignee= graphene.Int(), # userid
resources= graphene.List(ResourceCreateInput)
def mutate(self, info, isAllDay, points, status, recurrence_pattern, recurrence_enddate, deadline, creator, assignee = None, resources = None, name = None, description = None):
cUser = User.objects.filter(id=creator).first()
if not cUser:
raise GraphQLError('Invalid Link!')
if assignee != None:
aUser = User.objects.filter(id=assignee).first()
if not aUser:
raise GraphQLError('Invalid Link!')
else:
aUser = None
household = Household.objects.filter(id = 1)
chore = Chore(
name = name,
description = description,
isAllDay = isAllDay,
points = points,
status = status,
recurrence_pattern = recurrence_pattern,
recurrence_enddate = recurrence_enddate,
deadline = deadline,
created_by = cUser,
assigned_to = aUser,
)
chore.save()
if resources != None:
for x in resources:
resource = Resource(
name = x.name,
checked = x.checked,
assigned_to = Chore.objects.get(id__exact = chore.id)
)
resource.save()
return AddChore(
id = chore.id,
)
Update:
Removing the "assignee" value causes "creator" to error out with the same catch, then "deadline" if "creator" is removed, moving upwards in alphabetical order.
@Rofltropter can you please share your graphQL mutation query that you're using to trigger these errors?
@phalt
No singular graphQL mutation is used. The error occurs upon attempting to load the Graphiql interface at http://localhost:8000/graphql on the applicable URL, and this particular mutation schema fails to pass the
`
try:
response = get_response(request)
```
automatic decorator for middleware exception leak detection in djangocorehandlersexception.py in inner.
If you need more data, you can check out the full project specifications here: https://github.com/Rofltropter/TheBenchV2-GraphQL/tree/master/TheBenchBackend/theBenchBackend
Err are there commas after each of your arguments?
I don't think that's valid python for a class declaration iirc? Unless I'm completely missing it. I usually only see commas when in the interfaces = (thing, other thing,)
What @ProjectCheshire said. The trailing comma bit works in a JSON structure, or to denote a tuple, but in this case, I'd first address those and see what you get.
@Rofltropter, I forked your project to take a look, and there are quite a few python issues. The comma thing, for one. You need to do some cleanup of those before you can get to the graphene issues.
For one example, instead of:
class Arguments:
name = graphene.String(),
description= graphene.String(),
isAllDay= graphene.Boolean,
points= graphene.Int(),
status= graphene.Int(),
recurrence_pattern= graphene.Int(),
recurrence_enddate= graphene.DateTime(),
deadline= graphene.DateTime(),
creator= graphene.Int(), # userid
assignee= graphene.ID(), # userid
resources= graphene.List(ResourceCreateInput)
This should look something like:
class Arguments:
name = graphene.String()
description= graphene.String()
isAllDay= graphene.Boolean()
points= graphene.Int()
status= graphene.Int()
recurrence_pattern= graphene.Int()
recurrence_enddate= graphene.DateTime()
deadline= graphene.DateTime()
creator= graphene.Int() # userid
assignee= graphene.ID() # userid
resources= graphene.List(ResourceCreateInput)
For another example, in some places, graphene.Boolean is being assigned as:
something = graphene.Boolean
and in others:
something = graphene.Boolean()
These should all be, I believe:
something = graphene.Boolean()
Cleaning up these types of issues at least brings the code to a point where there is a graphene related error:
Found different types with the same name in the schema: ResourceCreateInput, ResourceCreateInput.
This is something discussed in a few issues, and perhaps @ProjectCheshire or another is better suited to addressing that. I'm still getting my head around graphene, myself.
I've submitted a PR to your repository with the first two groups of issues mentioned above cleaned up a bit, though I only did a cursory run-through, so there will likely be a few other issues that crop up.
I took another look, and there are _actually_ two types named ResourceCreateInput, one in resources/schema.py and one in chores/schema.py.
I renamed one to ResourceCreateInputType and now your project loads, with graphiql opening, so it all looks good.
Added the change to my PR on your repository. Cheers!
I took another look, and there are _actually_ two types named ResourceCreateInput, one in resources/schema.py and one in chores/schema.py.
I renamed one to ResourceCreateInputType and now your project loads, with graphiql opening, so it all looks good.
Added the change to my PR on your repository. Cheers!
@changeling well done / thank you for helping out!
@changeling Thanks man! I didn't catch that at all. I've been slowly shifting back into Python after working in a Java environment for sometime so I totally missed that comma issue.
In terms of the .Boolean vs .Boolean(), I believe there is no actual difference in terms of execution, but rather the declarations that contained () may have previously had additional arguments piped in (like required = True) but were removed throughout development. Cheers for cleaning that up.
Lastly, that ResourceCreateInputType was a bit of a shocker to me! Thought schema sub-segregation would work that one out, but I'm glad it worked out great!
You've been an absolute gem, my hat is off to you.
Consider the issue closed!
@changeling well done / thank you for helping out!
Glad I could help! I'm becoming pretty attached to this project, and digging into other folks issues is part of getting my head around it all. :)
@Rofltropter You bet! Happy to help out. And I completely get the language-switching thing. I'm working on getting my head around react and continually using python syntax.
It doesn't help that class arguments _do_ use the syntax, a la this in the Relay tutorial:
class Query(
my_app.schema.Query, # Add your Query objects here
graphene.ObjectType
)
It's an easy trap to fall into.
The boolean thing, too, though I'll play with that now for my curiosity.. There _are_ places where calling in your declariation can trip you up in graphene. If you run into errors yelling at you about 'mounted' things, check your arguments first, like graphene.String vs graphene.String() within graphene.Field() definitions. I'm not actually sure if theBoolean` declaration matters.
And on the ResourceCreateInputType duplication, that one one bit me, too, at first. I thought the schema segregation was magic, too. Hopefully, that'll be addressed at some point, as there are a few Issues dedicated directly towards schema-integration as a pain-point.
Thanks for the diversion, and you're quite welcome!
(Sorry I ghosted this for a bit. Real life took precedence and it fell out of my notifications. I had to resort to searching for the word comma in gmail to find it again. ::cha-grin::)
You should check it out in its current state, it's about complete. I'm actually having a bit of a CORS error on the client side with a redirect issue going on. Here's the error I'm getting: "Access to fetch at 'http://localhost:8000/gql' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.".
My backend it getting the following ping: "OPTIONS /gql HTTP/1.1" 301 0".
I hear you can fix that by using corsheaders in the venv but unfortunately my pip install django-cors-headers doesn't actually generate a django-corsheaders in the venv and my entire thing fails to load.
Could you give me a hand patching the last thing on?
My front-end is a react-apollo setup
You should check it out in its current state, it's about complete.
I'll check it out!
I'm actually having a bit of a CORS error on the client side with a redirect issue going on. Here's the error I'm getting: "Access to fetch at 'http://localhost:8000/gql' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.".
I'm not positive, but you may be in luck. I just now solved my own CORS issues. I have _not_ had a chance to test it live, but I've incorporated the changes I made to my own project which solved CORS being a jerk. I've submitted a PR to your project and you can try it out. Let me know if it works for you, but don't see your frontend stuff in the repo, so can't confirm or deny that it works.
NOTE: You might want to create a new branch to merge the PR into. If you do, and need me to redirect the PR, lemme know.
HEADS UP: You may need to play around with the CORS_ORIGIN_WHITELIST settings, but they're currently handling my own React-Relay frontend just fine.
Also note that, in my Environment.js file, the network declaration looks like this:
const network = Network.create((operation, variables) => {
// 4
return fetch('http://localhost:8004/graphql', {
method: 'POST',
credentials: 'include',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: operation.text,
variables
}),
}).then(response => {
return response.json()
})
})
I hear you can fix that by using corsheaders in the venv but unfortunately my pip install django-cors-headers doesn't actually generate a django-corsheaders in the venv and my entire thing fails to load.
Yeah, that's one of those dmmit-it's-named-differently package things. django-cors-headers installs corsheaders and not django-cors-headers, though I believe you should have django_cors_headers-3.0.1.dist-info somewhere in there. If you don't see either one, double- and triple-check that you're installing them with your venv activated, and not system-wide.
Could you give me a hand patching the last thing on?
Hand given. :) Maybe.
Last note: I'm happy, if I have time, to help on occasion, but from here forward, it's prolly best if you contact me via github rather than in this issue, to avoid spamming here. I'm addressing this one because I'm just about to add the CORS thingie to the graphene-django wiki, so it seems to fit.
Cheers! And do let us know if this works or not. Pretty sure that'd be fine here.
Oh, and a big caveat here: This is _only_ setting up CORS here, and CSRF consideration is important when you approach deploying to the wild. This is a good local development solution, but before you deploy, be absolutely sure to read up on both CORS and CSRF, and the security implications involved.