Skip to content

Commit

Permalink
integrate ariadne, modularity and injection
Browse files Browse the repository at this point in the history
  • Loading branch information
philtweir committed Jun 30, 2020
1 parent 9f719b6 commit 2f0686f
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 45 deletions.
79 changes: 34 additions & 45 deletions 022-burette/magnum_opus_iii/magnumopus/graph.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,46 @@
from quart import request, jsonify
from graphql import GraphQLSchema
from ariadne import ObjectType, make_executable_schema, graphql
from ariadne.constants import PLAYGROUND_HTML
from .schemas import init_graph as init_graph_schemas
from .resources import init_graph as init_graph_resources

from .repositories import PANTRY_STORES

PANTRY = PANTRY_STORES['list']

type_defs = """
TYPE_DEFS = """
type Query {
substances(nature: String!): [Substance]
}
type Substance {
nature: String!,
state: [String]!
}
"""

query = ObjectType('Query')
substance = ObjectType('Substance')

@query.field('substances')
def resolve_substances(obj, *_, nature='Unknown'):
return PANTRY.find_substances_by_nature(nature)


@substance.field('nature')
def resolve_nature(obj, *_):
return obj.nature

@substance.field('state')
def resolve_state(obj, *_):
return obj.state

schema = make_executable_schema(type_defs, query, substance)

async def graphql_server():
data = await request.get_json()
success, result = await graphql(
schema,
data,
context_value=request
)

return jsonify(result), (200 if success else 400)
class InjectorObjectType(ObjectType):
def __init__(self, *args, app=None, **kwargs):
super(InjectorObjectType, self).__init__(*args, **kwargs)
self._app = app

def get_injector(self):
return self._app.extensions['injector']

def field(self, name: str):
g = super(InjectorObjectType, self).field(name)
def injected_resolver(f):
def _inject_resolver(*args, **kwargs):
self._app.logger.error(name)
inj = self.get_injector()
return inj.call_with_injection(
f, args=args, kwargs=kwargs
)
return g(_inject_resolver)
return injected_resolver

def init_app(app):
app.route('/graphql', methods=['GET'], endpoint='graphql_playground')(
lambda: (PLAYGROUND_HTML, 200)
)
query = InjectorObjectType('Query', app=app)

type_defs = [TYPE_DEFS] + init_graph_schemas(query)
resolvers = [query] + init_graph_resources(query)

app.route('/graphql', methods=['POST'], endpoint='graphql_server')(
graphql_server
)
schema = make_executable_schema(type_defs, resolvers)

return []
return [
lambda binder: binder.bind(
GraphQLSchema,
to=schema
)
]
7 changes: 7 additions & 0 deletions 022-burette/magnum_opus_iii/magnumopus/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from . import substance
from . import alembic_instruction
from . import graph

def init_app(app):
substance.init_app(app)
alembic_instruction.init_app(app)
graph.init_app(app)
return []

def init_graph(graph):
resolvers = []
resolvers += substance.init_graph(graph)
return resolvers
39 changes: 39 additions & 0 deletions 022-burette/magnum_opus_iii/magnumopus/resources/graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from quart import request, jsonify
from quart_openapi import Resource
from injector import inject
from typing import Dict
from ariadne import graphql
from ariadne.constants import PLAYGROUND_HTML
from graphql.type import GraphQLSchema
from ..injection import ViewInjectorMeta
from ..repositories.pantry import Pantry
from ..models import db

class GraphResource(Resource):
@inject
def __init__(self, schema: GraphQLSchema):
super(GraphResource, self).__init__()

self._schema = schema

async def get(self):
return (PLAYGROUND_HTML, 200)

async def post(self):
data = await request.get_json()
success, result = await graphql(
self._schema,
data,
context_value=request
)

return jsonify(result), (200 if success else 400)


def init_app(app):
class AppGraphResource(GraphResource, metaclass=ViewInjectorMeta):
get_app = lambda: app

app.route('/graphql', endpoint='graphql')(AppGraphResource)

return []
20 changes: 20 additions & 0 deletions 022-burette/magnum_opus_iii/magnumopus/resources/substance.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from quart_openapi import Resource
from injector import inject
from typing import Dict
from ariadne import ObjectType
from ..injection import ViewInjectorMeta
from ..repositories.pantry import Pantry
from ..models import db
Expand Down Expand Up @@ -47,3 +48,22 @@ class AppSubstanceResource(SubstanceResource, metaclass=ViewInjectorMeta):
get_app = lambda: app

app.route('/substance', endpoint='SubstanceResource')(AppSubstanceResource)

def init_graph(query):
substance = ObjectType('Substance')

@query.field('substances')
@inject
def resolve_substances(obj, info, pantry: Pantry, *_, nature='Unknown'):
substances = pantry.find_substances_by_nature(nature)
return substances

@substance.field('nature')
def resolve_nature(obj, *_):
return obj.nature

@substance.field('state')
def resolve_state(obj, *_):
return obj.state

return [substance]
7 changes: 7 additions & 0 deletions 022-burette/magnum_opus_iii/magnumopus/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ def configure_injector(binder):
'many': SubstanceSchema(many=True)
}
)

def init_graph(query):
from .substance_schema import init_graph as init_graph_substance

return [
init_graph_substance(query)
]
10 changes: 10 additions & 0 deletions 022-burette/magnum_opus_iii/magnumopus/schemas/substance_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
from ..models.substance import Substance
from ..services.assessor import assess_whether_substance_is_philosophers_stone

SUBSTANCE_GRAPH_SCHEMA = """
type Substance {
nature: String!,
state: [String]!
}
"""

class SubstanceSchema(ma.SQLAlchemySchema):
is_philosophers_stone = fields.Function(
assess_whether_substance_is_philosophers_stone
Expand All @@ -17,3 +24,6 @@ class Meta:
id = fields.Integer()
nature = fields.String()
state = fields.Function(lambda model: model.state or [])

def init_graph(query):
return SUBSTANCE_GRAPH_SCHEMA

0 comments on commit 2f0686f

Please sign in to comment.