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
Custom Server example with Flask #125
Comments
Does this example respond to GraphQL queries on the |
Flask users would have to add a rule to their app.add_url_rule('/graphql', view_func=GraphQlView.as_view('graphql'))` That would be good to add as note in the documentation, as most Flask users don't use method views, i.e. blueprints or |
Maybe it would be better to rewrite the example using normal view functions. |
It's been a while since I've did anything with flask, but wouldn't something like this be possible and more idiomatic? @app.route('/graphql/', methods=['GET'])
def graphql_playground():
return PLAYGROUND_HTML, 200
@app.route('/graphql/', methods=['POST'])
def graphql_server():
... |
I rewrote the example as a complete flask application, which is ready to run: from ariadne import gql, ResolverMap, make_executable_schema
from ariadne.constants import PLAYGROUND_HTML
from graphql import format_error, graphql_sync
from flask import Flask, request, jsonify
type_defs = gql("""
type Query {
hello: String!
}
""")
query = ResolverMap("Query")
@query.field("hello")
def resolve_hello(_, info):
request = info.context
user_agent = request.headers.get("User-Agent", "Guest")
return "Hello, %s!" % user_agent
app = Flask(__name__)
@app.route('/graphql/', methods=['GET'])
def graphql_playgroud():
"""Serving the GraphQL Playground
Note: This endpoint is not required if you do not want to provide the playground.
But keep in mind that clients can still explore your API, for example by
using the GraphQL desktop app.
"""
return PLAYGROUND_HTML, 200
@app.route('/graphql/', methods=['POST'])
def graphql_server():
"""Serve GraphQL queries"""
data = request.get_json()
if data is None or not isinstance(data, dict):
return 'Bad Request', 400
variables = data.get('variables')
if variables and not isinstance(variables, dict):
return 'Bad Request', 400
# Note: Passing the request to the context is option. In Flask, the current
# request is allways accessible as flask.request.
result = graphql_sync(
make_executable_schema(type_defs, query),
data.get('query'),
context_value=request,
variable_values=variables,
operation_name=data.get('operationName')
)
response = {"data": result.data}
if result.errors:
response["errors"] = [format_error(e) for e in result.errors]
return jsonify(response)
if __name__ == '__main__':
app.run(debug=True) This structure is well known, even for Flask beginners. More expirienced users know how to adapt this to using Blueprints or a Method view. |
Should this use ariadne's graphql_sync? |
@tbsf Flask is not handling requests in async. If you want to use async methods, you should look for sanic or vibora. If that's the question. |
@NyanKiyoshi graphql_sync is not async https://github.com/mirumee/ariadne/blob/master/ariadne/graphql.py#L57 I think this should look something like:
|
You should keep |
This is correct. Especially given that |
I had success using middleware instead of manually declare the routes. Is there any drawback on that? Code sample: from ariadne import make_executable_schema
from ariadne.wsgi import GraphQLMiddleware, GraphQL
from myapp.graphql import type_defs, resolvers
app = Flask(__name__)
# ...
# ...
schema = make_executable_schema(type_defs, resolvers)
gql_app = GraphQL(schema)
app.wsgi_app = GraphQLMiddleware(app.wsgi_app, gql_app, '/api/v1/gql') |
@cpuldev this is possible, but I think this has some drawbacks:
Maybe this can be done somehow, I don't know |
Our docs have been updated to include Flask integration example. Thanks! |
Hey there! I ported the custom server example from django to flask.
It's quite short and it would be nice to add it to the docs.
The text was updated successfully, but these errors were encountered: