From 1be960bd9ea4776c6f71c8cc0e20f42ad6ebecba Mon Sep 17 00:00:00 2001 From: Karma Dolkar Date: Mon, 25 May 2020 13:40:29 +0530 Subject: [PATCH] query releases --- bodhi/server/config.py | 3 ++ bodhi/server/graphql_schemas.py | 34 +++++++++++++++++ bodhi/server/services/graphql.py | 30 +++++++++++++-- bodhi/tests/server/services/test_graphql.py | 41 +++++++++++++++++++-- devel/ansible/roles/bodhi/tasks/main.yml | 9 +++++ devel/development.ini.example | 2 + production.ini | 6 +++ requirements.txt | 3 ++ 8 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 bodhi/server/graphql_schemas.py diff --git a/bodhi/server/config.py b/bodhi/server/config.py index e3f4b962fd..93b999dd0e 100644 --- a/bodhi/server/config.py +++ b/bodhi/server/config.py @@ -361,6 +361,9 @@ class BodhiConfig(dict): 'initial_bug_msg': { 'value': '%s has been submitted as an update to %s. %s', 'validator': str}, + 'graphiql_enabled': { + 'value': False, + 'validator': _validate_bool}, 'greenwave_api_url': { 'value': 'https://greenwave-web-greenwave.app.os.fedoraproject.org/api/v1.0', 'validator': _validate_rstripped_str}, diff --git a/bodhi/server/graphql_schemas.py b/bodhi/server/graphql_schemas.py new file mode 100644 index 0000000000..6025ea2cb0 --- /dev/null +++ b/bodhi/server/graphql_schemas.py @@ -0,0 +1,34 @@ +# Copyright © 2020 Red Hat Inc., and others. +# +# This file is part of Bodhi. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +"""Defines schemas related to GraphQL objects.""" +from graphene import relay, Field, String +from graphene_sqlalchemy import SQLAlchemyObjectType + +from bodhi.server.models import Release as ReleaseModel + + +class Release(SQLAlchemyObjectType): + """Type object representing a distribution release from bodhi.server.models, such as Fedora 27.""" + + class Meta: + """Allow to set different options to the class.""" + + model = ReleaseModel + interfaces = (relay.Node, ) + state = Field(String) + package_manager = Field(String) diff --git a/bodhi/server/services/graphql.py b/bodhi/server/services/graphql.py index a15b7f9016..ccb92c3e71 100644 --- a/bodhi/server/services/graphql.py +++ b/bodhi/server/services/graphql.py @@ -16,19 +16,43 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """Defines API endpoints related to GraphQL objects.""" +import graphene from cornice import Service +from webob_graphql import serve_graphql_request + +from bodhi.server.config import config +from bodhi.server.graphql_schemas import Release + graphql = Service(name='graphql', path='/graphql', description='graphql service') @graphql.get() +@graphql.post() def graphql_get(request): """ - Return "Hello World". + Perform a GET request. Args: request (pyramid.Request): The current request. Returns: - str: A string "Hello World". + The GraphQL response to the request. """ - return "Hello World" + context = {'session': request.session} + return serve_graphql_request( + request, schema, graphiql_enabled=config.get('graphiql_enabled'), + context_value=context) + + +class Query(graphene.ObjectType): + """Allow querying objects.""" + + allReleases = graphene.List(Release) + + def resolve_allReleases(self, info): + """Answer Queries by fetching data from the Schema.""" + query = Release.get_query(info) # SQLAlchemy query + return query.all() + + +schema = graphene.Schema(query=Query) diff --git a/bodhi/tests/server/services/test_graphql.py b/bodhi/tests/server/services/test_graphql.py index 85ec592626..710e114434 100644 --- a/bodhi/tests/server/services/test_graphql.py +++ b/bodhi/tests/server/services/test_graphql.py @@ -15,12 +15,47 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +from graphene.test import Client + from bodhi.tests.server import base +from bodhi.server.services.graphql import schema +from bodhi.server.models import PackageManager, Release class TestGraphQLService(base.BasePyTestCase): """This class contains tests for a /graphql endpoint""" def test_get(self): - """Ensure that "Hello World" is returned""" - res = self.app.get('/graphql') - assert res.body == b'"Hello World"' + """Ensure that a GraphQL response is returned""" + res = self.app.get('/graphql?query={%0A%20 allReleases{%0A%20%20%20 name%0A%20 }%0A}') + assert res.body == b'{"data":{"allReleases":[{"name":"F17"}]}}' + + def test_allReleases(self): + """Testing allReleases""" + client = Client(schema) + release = Release( + name='F22', long_name='Fedora 22', + id_prefix='FEDORA', version='22', + dist_tag='f22', stable_tag='f22-updates', + testing_tag='f22-updates-testing', + candidate_tag='f22-updates-candidate', + pending_signing_tag='f22-updates-testing-signing', + pending_testing_tag='f22-updates-testing-pending', + pending_stable_tag='f22-updates-pending', + override_tag='f22-override', + branch='f22', + package_manager=PackageManager.dnf, + testing_repository='updates-testing') + + self.db.add(release) + self.db.commit() + + executed = client.execute("""{ allReleases{ name }}""") + assert executed == { + "data": { + "allReleases": [{ + "name": "F17" + }, { + "name": "F22" + }] + } + } diff --git a/devel/ansible/roles/bodhi/tasks/main.yml b/devel/ansible/roles/bodhi/tasks/main.yml index 241b4199e4..0f923d898f 100644 --- a/devel/ansible/roles/bodhi/tasks/main.yml +++ b/devel/ansible/roles/bodhi/tasks/main.yml @@ -109,6 +109,15 @@ name: jinja2-cli executable: pip3 +- name: pip install packages for GraphQL + pip: + name: "{{ item }}" + executable: pip3 + loop: + - WebOb-GraphQL + - graphene + - graphene-sqlalchemy + - name: Fake a pungi install file: src: /usr/bin/true diff --git a/devel/development.ini.example b/devel/development.ini.example index c060cb22ea..6aba48861e 100644 --- a/devel/development.ini.example +++ b/devel/development.ini.example @@ -71,6 +71,8 @@ test_gating.required = True waiverdb_api_url = http://bodhi_user:pass@localhost:6544/api/v1.0 greenwave_api_url = http://localhost:6545/api/v1.0 +graphiql_enabled = True + [server:main] use = egg:waitress#main host = 0.0.0.0 diff --git a/production.ini b/production.ini index 31e63384a8..b799dd3f77 100644 --- a/production.ini +++ b/production.ini @@ -316,6 +316,12 @@ use = egg:bodhi-server # you are using the dummy acl_system. # acl_dummy_committer = +## +## GraphiQL +## +# graphiql_url = http://localhost:6543/graphql +# graphiql_enabled = False + ## ## Pagure ## diff --git a/requirements.txt b/requirements.txt index 7e6ac13202..9b15f4fa74 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,8 @@ dogpile.cache pyasn1-modules # Due to an unfortunate dash in its name, installs break if pyasn1 is installed first fedora_messaging feedgen>=0.7.0 +graphene +graphene-sqlalchemy jinja2 markdown psycopg2 @@ -24,3 +26,4 @@ PyYAML simplemediawiki sqlalchemy waitress +WebOb-GraphQL