Python石墨烯订阅服务器

时间:2020-03-28 10:09:18

标签: python flask graphql

我尝试使用ApolloClient从我的响应前端订阅我根据https://github.com/graphql-python/graphql-ws/blob/master/examples/flask_gevent/app.py实现的Python GraphQL服务器。

我的前端订阅看起来像这样

client.subscribe({
    query: gql`
        subscription{
            count_seconds
        }
        `
}).subscribe({
    next(data) {
        console.log("New data received from subscription");
    }
});

但是我的服务器抱怨

Traceback (most recent call last):
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\gevent\pywsgi.py", line 976, in handle_one_response
    self.run_application()
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\geventwebsocket\handler.py", line 75, in run_application
    self.run_websocket()
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\geventwebsocket\handler.py", line 52, in run_websocket
    list(self.application(self.environ, lambda s, h, e=None: []))
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\flask\app.py", line 2463, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\flask_sockets.py", line 45, in __call__
    handler(environment, **values)
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\flask_cors\decorator.py", line 128, in wrapped_function
    resp = make_response(f(*args, **kwargs))
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\flask\helpers.py", line 223, in make_response
    return current_app.make_response(args)
  File "C:\Users\Adrian\Miniconda3\lib\site-packages\flask\app.py", line 2130, in make_response
    " {rv.__class__.__name__}.".format(rv=rv)
TypeError: The view function did not return a valid response. The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a list.
2020-03-27T21:16:07Z {'REMOTE_ADDR': '::1', 'REMOTE_PORT': '55650', 'HTTP_HOST': 'localhost:5000', (hidden keys: 32)} failed with TypeError

我的服务器实现

from flask import Flask, make_response, request
from flask_sockets import Sockets
from flask_cors import CORS, cross_origin
from flask_graphql import GraphQLView
from graphql_ws.gevent import GeventSubscriptionServer
from schema import schema
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
from graphql.backend import GraphQLCoreBackend

app = Flask(__name__)
app.debug = False
cors = CORS(app, resources={r"/graphql/*": {"origins": "*"}})
app.config['CORS_HEADERS'] = 'Content-Type'
sub_server = GeventSubscriptionServer(schema)

sockets = Sockets(app)

class Server:
    def __init__(self):
        self.server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler)
        app.add_url_rule('/graphql', view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=False))

        app.app_protocol = lambda environ_path_info: 'graphql-ws'
        self.server.serve_forever()

    @sockets.route('/subscriptions')
    @cross_origin()
    def echo_socket(ws):
        sub_server.handle(ws)
        return []

我不知道这是什么根本原因,...返回的列表到底在哪里,我还应该有其他东西? 也许schema也很重要

import graphene
from rx import Observable
import random


class Query(graphene.ObjectType):
    hello = graphene.String(name=graphene.String(default_value="World"))

    def resolve_hello(self, info, name):
        print("answer query")
        return 'Hello ' + name


class RandomType(graphene.ObjectType):
    seconds = graphene.Int()
    random_int = graphene.Int()


class Subscription(graphene.ObjectType):
    count_seconds = graphene.Int(up_to=graphene.Int())

    random_int = graphene.Field(RandomType)

    def resolve_count_seconds(self, info, up_to=5):
        print("new subscription")
        return Observable.interval(1000) \
            .map(lambda i: "{0}".format(i)) \
            .take_while(lambda i: int(i) <= up_to)

    def resolve_random_int(self, info):
        return Observable.interval(1000).map(lambda i: RandomType(seconds=i, random_int=random.randint(0, 500)))


schema = graphene.Schema(query=Query, subscription=Subscription)

0 个答案:

没有答案