question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom Server example with Flask

See original GitHub issue

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.

from ariadne import gql, ResolverMap, make_executable_schema
from ariadne.constants import PLAYGROUND_HTML
from graphql import format_error, graphql_sync
from flask import request, jsonify
from flask.views import MethodView

type_defs = gql("""
    type Query {
        hello: String!
    }
""")


query = ResolverMap("Query")


@query.field("hello")
def resolve_hello(_, info):
    request = info.context
    print(request.headers)
    user_agent = request.headers.get("User-Agent", "Guest")
    return "Hello, %s!" % user_agent


schema = make_executable_schema(type_defs, query)


class GraphQlView(MethodView):

    def get(self):
        return PLAYGROUND_HTML, 200

    def post(self):
        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(
            schema,
            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)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:7
  • Comments:14 (13 by maintainers)

github_iconTop GitHub Comments

4reactions
jrastcommented, Apr 2, 2019

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.

2reactions
rafalpcommented, Apr 1, 2019

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():
    ...
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Deploy a Flask Web Server on Cloud Foundry
Learn how to efficiently deploy a Flash web server on Cloud Foundry without stressing yourself about the process in this tutorial!
Read more >
Deploy to Production — Flask Documentation (2.2.x)
This part of the tutorial assumes you have a server that you want to deploy your application to. It gives an overview of...
Read more >
How to build a web application using Flask and deploy it to the ...
This piece of code is stored in our main.py. Line 1: Here we are importing the Flask module and creating a Flask web...
Read more >
How To Make a Web Application Using Flask in Python 3
A local Python 3 programming environment, follow the tutorial for ... Warning Flask uses a simple web server to serve our application in...
Read more >
Creating RESTful Web APIs using Flask and Python
For this example, the statement This is executed BEFORE each request. will be printed on the server first and then the function for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found