Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]Allow to query Releases using GraphQL #4036

Merged
merged 2 commits into from Jun 29, 2020

Conversation

karmadolkar
Copy link
Collaborator

ref #4024
Signed-off-by: Karma Dolkar karmadolkar29@gmail.com

@karmadolkar karmadolkar requested a review from a team as a code owner May 25, 2020 08:12
@lgtm-com
Copy link

lgtm-com bot commented May 25, 2020

This pull request introduces 9 alerts when merging 3ca6391 into e0fcce5 - view on LGTM.com

new alerts:

  • 6 for Unused import
  • 2 for Module is imported with 'import' and 'import from'
  • 1 for Unreachable code

@karmadolkar karmadolkar changed the title Allow to query Releases using GraphQL [WIP]Allow to query Releases using GraphQL May 25, 2020
Copy link
Contributor

@StephenCoady StephenCoady left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job so far! I left some small comments.

@view_config()
def graphql_view(request):
context = {'session': request.session}
return serve_graphql_request(request, schema, context_value=context)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line can be deleted



class Query(graphene.ObjectType):
release = graphene.List(Release)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you call this allReleases or something similar then it will be more obvious to the user what this does

return serve_graphql_request(request, schema, context_value=context)

# Setting graphiql=True
return serve_graphql_request(request, schema, graphiql=True, context_value=context)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think the flag here should be graphiql_enabled=True.

It doesn't matter for now as the default is True but it will matter once we set this based on a variable :)

@StephenCoady
Copy link
Contributor

Also, it looks like you have some unused imports in the schema and service file, so the CI will fail.

If you need to fix those, you can run flake8 . :)


class Release(SQLAlchemyObjectType):
"""
Type object representing a distribution release, such as Fedora 27.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in the doc string here we should just reference that this is using the Release object from models.py so that we don't have to maintain the Attributes list and documentation here.

Comment on lines 19 to 21
from cornice import Service
from webob_graphql import serve_graphql_request
import graphene
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this import at the top of the import

Suggested change
from cornice import Service
from webob_graphql import serve_graphql_request
import graphene
import graphene
Suggested change
from cornice import Service
from webob_graphql import serve_graphql_request
import graphene
import graphene
from cornice import Service
from webob_graphql import serve_graphql_request

Args:
request (pyramid.Request): The current request.
Returns:
The response from Bodhi to the request.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The graphql response to the query

"""
context = {'session': request.session}

# Setting graphiql_enabled=True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this comment

context = {'session': request.session}

# Setting graphiql_enabled=True
return serve_graphql_request(request, schema, graphiql_enabled=True, context_value=context)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to have the graphiql_enabled value to be configure in the configuration so that we can have it set to True in the development environment and False in production.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the configuration key could be something like enable_graphiql



@graphql.post()
def graphql_post(request):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not 100% sure here (@StephenCoady might look at that), but I am not sure that we need 2 function here we could have only one with the following declaration

@graphql.post()
@graphql.get()
def graphql_endpoint(request):
....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct, function with both post and get will work the same

@cverna
Copy link
Contributor

cverna commented Jun 1, 2020

We also need to update the tests 😄

@@ -109,6 +109,21 @@
name: jinja2-cli
executable: pip3

- name: pip install WebOb-GraphQL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here you can use a loop in ansible instead of repeating the tasks 4 times. See https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#iterating-over-a-simple-list

@cverna
Copy link
Contributor

cverna commented Jun 1, 2020

When trying to use the endpoint with graphiql and using the following query

{
  allReleases {
    id
    name
    longName
  }
}

I don't get any releases in the response, I would have expected to see a json list of all the releases.

But I might be doing something wrong :-)

image

@karmadolkar
Copy link
Collaborator Author

I don't get any releases in the response, I would have expected to see a json list of all the releases.

Yes, I think a resolver function for each field is required to fetch the data.


allReleases = graphene.List(Release)

def resolve_releases(self, info):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like @cverna was right, graphene handles the mapping under the hood for us, so resolve_allReleases will work here.


def test_allReleases(self):
"""Testing allReleases"""
client = Client(Release)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So Release here isn't actually your schema. The schema you want to pass to your test client here is the collection of queries and mutations you have created. Graphene sqlalchemy actually creates this for you when you call graphene.Schema(query=Query). If you check graphql.py you've already done that there so you can use the schema variable :)

@karmadolkar
Copy link
Collaborator Author

Riot isn't working on my end right now (Connectivity to server has been lost). :( I'll text there as soon as it works!

@karmadolkar karmadolkar force-pushed the queryrelease branch 2 times, most recently from 3867fe0 to 58a0f74 Compare June 25, 2020 13:14


class Release(SQLAlchemyObjectType):
"""Type object representing a distribution release from bodhi.server.models, such as Fedora 27."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the line that is breaking your lint, if you make it multi-line the flake8 run should pass

self.db.add(release)
self.db.commit()

executed = client.execute("""{ allReleases{ name }}""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to test for some of the trickier fields like state or package_manager (or both!). You could request it from allReleases and make sure it matched the value provided to db.add(). I think that could be a separate test.



class Release(SQLAlchemyObjectType):
"""Type object representing a distribution release from bodhi.server.models, like Fedora 27"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the line that is breaking your lint, if you make it multi-line the flake8 run should pass

… query allReleases that allows to fetch all Release objects from the database using GraphQL. Fixes fedora-infra#4024.

Signed-off-by: Karma Dolkar <karmadolkar29@gmail.com>
@cverna
Copy link
Contributor

cverna commented Jun 29, 2020

This lgtm, @StephenCoady if you want to give it another look :-)

Copy link
Contributor

@StephenCoady StephenCoady left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me. great work :)

@mergify mergify bot merged commit 84fdcb4 into fedora-infra:develop Jun 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants