From 671499bb43a2ab3fdf780cc5d392c7025bbcfc9f Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Wed, 10 Oct 2018 11:07:11 -0400 Subject: [PATCH] working order --- Pipfile.lock | 6 ++ app.py | 4 +- responder/api.py | 46 ++++++++----- responder/graphiql.py | 145 ----------------------------------------- responder/models.py | 24 +++++-- responder/templates.py | 3 - setup.py | 1 + templates/test.html | 95 ++++++++++++++++++++++++++- 8 files changed, 151 insertions(+), 173 deletions(-) delete mode 100644 responder/graphiql.py delete mode 100644 responder/templates.py diff --git a/Pipfile.lock b/Pipfile.lock index ff2c6b4..cd39c17 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -57,6 +57,12 @@ ], "version": "==0.4.5" }, + "graphql-server-core": { + "hashes": [ + "sha256:e5f82add4b3d5580aa1f1e7d9f00e944ad3abe1b65eb337e611d6a77cc20f231" + ], + "version": "==1.1.1" + }, "idna": { "hashes": [ "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", diff --git a/app.py b/app.py index 2ead99a..26ee723 100644 --- a/app.py +++ b/app.py @@ -38,7 +38,7 @@ class Query(graphene.ObjectType): schema = graphene.Schema(query=Query) # Alerntatively, -api.add_route("/graph", schema) +api.add_route("/graph", schema, graphiql=True) print( @@ -49,7 +49,7 @@ print( # headers={"Accept": "application/x-yaml"}, # data="hello", ) - .text + .headers ) # print( diff --git a/responder/api.py b/responder/api.py index 531867d..6a31a53 100644 --- a/responder/api.py +++ b/responder/api.py @@ -1,4 +1,6 @@ import os +import json +from functools import partial from pathlib import Path import waitress @@ -8,6 +10,7 @@ from whitenoise import WhiteNoise from wsgiadapter import WSGIAdapter as RequestsWSGIAdapter from requests import Session as RequestsSession from werkzeug.wsgi import DispatcherMiddleware +from graphql_server import encode_execution_results, json_encode, default_format_error from . import models from .status import HTTP_404 @@ -90,9 +93,7 @@ class API: try: self.routes[route](req, resp) # The request is using class-based views. - except TypeError as e: - print(e) - exit() + except TypeError: try: view = self.routes[route]() except TypeError: @@ -103,10 +104,13 @@ class API: self.graphql_response(req, resp, schema=view) except AssertionError: # WSGI App. - req.dispatched = True - return view( - environ=req._environ, start_response=req._start_response - ) + try: + req.dispatched = True + return view( + environ=req._environ, start_response=req._start_response + ) + except TypeError: + pass # Run on_request first. try: @@ -131,7 +135,6 @@ class API: assert route not in self.routes # TODO: Support grpahiql. - self.routes[route] = view def default_response(self, req, resp): @@ -140,11 +143,15 @@ class API: @staticmethod def _resolve_graphql_query(req): + if "json" in req.mimetype: + return req.json()["query"] + # Support query/q in form data. - if "query" in req.data: - return req.data["query"] - if "q" in req.data: - return req.data["q"] + if not isinstance(req.data, str): + if "query" in req.data: + return req.data["query"] + if "q" in req.data: + return req.data["q"] # Support query/q in params. if "query" in req.params: @@ -159,7 +166,14 @@ class API: def graphql_response(self, req, resp, schema): query = self._resolve_graphql_query(req) result = schema.execute(query) - resp.media = dict(result.data) + result, status_code = encode_execution_results( + [result], + is_batch=False, + format_error=default_format_error, + encode=partial(json_encode, pretty=False), + ) + resp.media = json.loads(result) + return (query, result, status_code) def route(self, route, **options): def decorator(f): @@ -205,7 +219,7 @@ class API: loader=jinja2.FileSystemLoader( str(self.templates_dir), followlinks=True ), - autoescape=False, + autoescape=jinja2.select_autoescape([]), ) template = env.get_template(name) @@ -221,7 +235,9 @@ class API: autoescape=jinja2.select_autoescape(["html", "xml"]), ) else: - env = jinja2.Environment(loader=jinja2.BaseLoader, autoescape=False) + env = jinja2.Environment( + loader=jinja2.BaseLoader, autoescape=jinja2.select_autoescape([]) + ) template = env.from_string(s) return template.render(**values) diff --git a/responder/graphiql.py b/responder/graphiql.py deleted file mode 100644 index 8eafbd0..0000000 --- a/responder/graphiql.py +++ /dev/null @@ -1,145 +0,0 @@ -from flask import render_template_string - -# From https://github.com/graphql-python/flask-graphql/blob/master/flask_graphql/render_graphiql.py - -GRAPHIQL_VERSION = "0.11.11" - -TEMPLATE = """ - - - - {{graphiql_html_title|default("GraphiQL", true)}} - - - - - - - - - - - -""" - - -def render_graphiql( - params, - result, - graphiql_version=None, - graphiql_template=None, - graphiql_html_title=None, -): - graphiql_version = graphiql_version or GRAPHIQL_VERSION - template = graphiql_template or TEMPLATE - - return render_template_string( - template, - graphiql_version=graphiql_version, - graphiql_html_title=graphiql_html_title, - result=result, - params=params, - ) diff --git a/responder/models.py b/responder/models.py index ee8d012..f573abc 100644 --- a/responder/models.py +++ b/responder/models.py @@ -8,7 +8,7 @@ from requests.models import Request as RequestsRequest from requests.structures import CaseInsensitiveDict from werkzeug.wrappers import Request as WerkzeugRequest from werkzeug.wrappers import BaseResponse as WerkzeugResponse -from werkzeug.wsgi import DispatcherMiddleware + from urllib.parse import parse_qs @@ -29,14 +29,17 @@ class Request: self = kls() self._wz = WerkzeugRequest(environ) self.headers = CaseInsensitiveDict(self._wz.headers.to_list()) - self.method = self._wz.method + self.method = self._wz.method.lower() self.full_url = self._wz.url self.url = self._wz.base_url self.full_path = self._wz.full_path self.path = self._wz.path self.params = parse_qs(self._wz.query_string.decode("utf-8")) + self.query = self._wz.query_string.decode("utf-8") self.raw = self._wz.stream self.content = self._wz.get_data(cache=True, as_text=False) + self.mimetype = self._wz.mimetype + self.accepts_mimetypes = self._wz.accept_mimetypes self.text = self._wz.get_data(cache=True, as_text=True) self.data = self._wz.get_data(cache=True, as_text=True, parse_form_data=True) self.dispatched = False @@ -73,7 +76,7 @@ class Response: @property def body(self): - + print(self.__dict__) if self.content: return (self.content, self.mimetype, {}) @@ -92,13 +95,18 @@ class Response: {}, ) # Default to JSON anyway. - if self.req.accepts_json or True: + else: return (json.dumps(self.media), self.mimetype or "application/json", {}) + else: + raise ValueError @property def gzipped_body(self): body, mimetype, headers = self.body + + if isinstance(body, str): + body = body.encode("utf-8") # print(self.req.headers) if "gzip" in self.req.headers["Accept-Encoding"].lower(): gzip_buffer = io.BytesIO() @@ -108,11 +116,10 @@ class Response: new_headers = { "Content-Encoding": "gzip", - "Vary": "Accept-Encoding", + # "Vary": "Accept-Encoding", "Content-Length": str(len(body)), } headers.update(new_headers) - # print(headers) return (gzip_buffer.getvalue(), mimetype, headers) else: @@ -121,7 +128,10 @@ class Response: @property def _wz(self): body, mimetype, headers = self.body - headers.update(self.headers) + if len(self.body) > 500: + body, mimetype, headers = self.gzipped_body + if self.headers: + headers.update(self.headers) r = WerkzeugResponse( body, diff --git a/responder/templates.py b/responder/templates.py deleted file mode 100644 index 6830829..0000000 --- a/responder/templates.py +++ /dev/null @@ -1,3 +0,0 @@ -from jinja2 import Template - -def load_template(app) diff --git a/setup.py b/setup.py index 5b070ae..b7ceaaf 100644 --- a/setup.py +++ b/setup.py @@ -28,6 +28,7 @@ required = [ "requests", "requests-wsgi-adapter", "graphene", + "graphql-server-core>=1.1", "whitenoise", "jinja2", ] diff --git a/templates/test.html b/templates/test.html index 13758fb..ccd079c 100644 --- a/templates/test.html +++ b/templates/test.html @@ -1,3 +1,96 @@ this is a test -{{ api.url_for('hello') }} +Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores in, ea beatae praesentium quis enim exercitationem +voluptate repellat possimus laborum provident voluptates numquam id atque tempora. Quidem et repudiandae aliquam? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero reiciendis consequuntur deserunt iure nesciunt autem +saepe magnam quas, debitis aliquam molestias possimus necessitatibus cumque enim modi fuga tenetur hic natus? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Quia magni maxime, optio aliquid tempore dignissimos aperiam +voluptatibus, quae sunt vel iste nesciunt. Commodi saepe ipsam architecto omnis neque sequi beatae. + +Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque quam sequi quidem corporis repudiandae quo, fugiat +ullam inventore, ratione cupiditate maiores nobis autem asperiores earum dolorum praesentium quod consequuntur nostrum! + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, in? Officiis ratione veritatis distinctio quas illo +voluptatibus quia velit corrupti. Tempora ipsam perspiciatis ullam sapiente itaque esse doloribus error culpa.this is a +test + +Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores in, ea beatae praesentium quis enim exercitationem +voluptate repellat possimus laborum provident voluptates numquam id atque tempora. Quidem et repudiandae aliquam? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero reiciendis consequuntur deserunt iure nesciunt autem +saepe magnam quas, debitis aliquam molestias possimus necessitatibus cumque enim modi fuga tenetur hic natus? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Quia magni maxime, optio aliquid tempore dignissimos aperiam +voluptatibus, quae sunt vel iste nesciunt. Commodi saepe ipsam architecto omnis neque sequi beatae. + +Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque quam sequi quidem corporis repudiandae quo, fugiat +ullam inventore, ratione cupiditate maiores nobis autem asperiores earum dolorum praesentium quod consequuntur nostrum! + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, in? Officiis ratione veritatis distinctio quas illo +voluptatibus quia velit corrupti. Tempora ipsam perspiciatis ullam sapiente itaque esse doloribus error culpa.this is a +test + +Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores in, ea beatae praesentium quis enim exercitationem +voluptate repellat possimus laborum provident voluptates numquam id atque tempora. Quidem et repudiandae aliquam? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero reiciendis consequuntur deserunt iure nesciunt autem +saepe magnam quas, debitis aliquam molestias possimus necessitatibus cumque enim modi fuga tenetur hic natus? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Quia magni maxime, optio aliquid tempore dignissimos aperiam +voluptatibus, quae sunt vel iste nesciunt. Commodi saepe ipsam architecto omnis neque sequi beatae. + +Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque quam sequi quidem corporis repudiandae quo, fugiat +ullam inventore, ratione cupiditate maiores nobis autem asperiores earum dolorum praesentium quod consequuntur nostrum! + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, in? Officiis ratione veritatis distinctio quas illo +voluptatibus quia velit corrupti. Tempora ipsam perspiciatis ullam sapiente itaque esse doloribus error culpa.this is a +test + +Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores in, ea beatae praesentium quis enim exercitationem +voluptate repellat possimus laborum provident voluptates numquam id atque tempora. Quidem et repudiandae aliquam? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero reiciendis consequuntur deserunt iure nesciunt autem +saepe magnam quas, debitis aliquam molestias possimus necessitatibus cumque enim modi fuga tenetur hic natus? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Quia magni maxime, optio aliquid tempore dignissimos aperiam +voluptatibus, quae sunt vel iste nesciunt. Commodi saepe ipsam architecto omnis neque sequi beatae. + +Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque quam sequi quidem corporis repudiandae quo, fugiat +ullam inventore, ratione cupiditate maiores nobis autem asperiores earum dolorum praesentium quod consequuntur nostrum! + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, in? Officiis ratione veritatis distinctio quas illo +voluptatibus quia velit corrupti. Tempora ipsam perspiciatis ullam sapiente itaque esse doloribus error culpa.this is a +test + +Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores in, ea beatae praesentium quis enim exercitationem +voluptate repellat possimus laborum provident voluptates numquam id atque tempora. Quidem et repudiandae aliquam? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero reiciendis consequuntur deserunt iure nesciunt autem +saepe magnam quas, debitis aliquam molestias possimus necessitatibus cumque enim modi fuga tenetur hic natus? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Quia magni maxime, optio aliquid tempore dignissimos aperiam +voluptatibus, quae sunt vel iste nesciunt. Commodi saepe ipsam architecto omnis neque sequi beatae. + +Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque quam sequi quidem corporis repudiandae quo, fugiat +ullam inventore, ratione cupiditate maiores nobis autem asperiores earum dolorum praesentium quod consequuntur nostrum! + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, in? Officiis ratione veritatis distinctio quas illo +voluptatibus quia velit corrupti. Tempora ipsam perspiciatis ullam sapiente itaque esse doloribus error culpa.this is a +test + +Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores in, ea beatae praesentium quis enim exercitationem +voluptate repellat possimus laborum provident voluptates numquam id atque tempora. Quidem et repudiandae aliquam? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero reiciendis consequuntur deserunt iure nesciunt autem +saepe magnam quas, debitis aliquam molestias possimus necessitatibus cumque enim modi fuga tenetur hic natus? + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Quia magni maxime, optio aliquid tempore dignissimos aperiam +voluptatibus, quae sunt vel iste nesciunt. Commodi saepe ipsam architecto omnis neque sequi beatae. + +Lorem ipsum, dolor sit amet consectetur adipisicing elit. Neque quam sequi quidem corporis repudiandae quo, fugiat +ullam inventore, ratione cupiditate maiores nobis autem asperiores earum dolorum praesentium quod consequuntur nostrum! + +Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorum, in? Officiis ratione veritatis distinctio quas illo +voluptatibus quia velit corrupti. Tempora ipsam perspiciatis ullam sapiente itaque esse doloribus error culpa.