mirror of
https://github.com/kennethreitz/responder.git
synced 2026-06-05 23:00:17 +00:00
working order
This commit is contained in:
Generated
+6
@@ -57,6 +57,12 @@
|
||||
],
|
||||
"version": "==0.4.5"
|
||||
},
|
||||
"graphql-server-core": {
|
||||
"hashes": [
|
||||
"sha256:e5f82add4b3d5580aa1f1e7d9f00e944ad3abe1b65eb337e611d6a77cc20f231"
|
||||
],
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
|
||||
@@ -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(
|
||||
|
||||
+31
-15
@@ -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)
|
||||
|
||||
@@ -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 = """<!--
|
||||
The request to this GraphQL server provided the header "Accept: text/html"
|
||||
and as a result has been presented GraphiQL - an in-browser IDE for
|
||||
exploring GraphQL.
|
||||
If you wish to receive JSON, provide the header "Accept: application/json" or
|
||||
add "&raw" to the end of the URL within a browser.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{graphiql_html_title|default("GraphiQL", true)}}</title>
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<link href="//cdn.jsdelivr.net/npm/graphiql@{{graphiql_version}}/graphiql.css" rel="stylesheet" />
|
||||
<script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/react/15.0.0/react.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/react/15.0.0/react-dom.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/graphiql@{{graphiql_version}}/graphiql.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
// Collect the URL parameters
|
||||
var parameters = {};
|
||||
window.location.search.substr(1).split('&').forEach(function (entry) {
|
||||
var eq = entry.indexOf('=');
|
||||
if (eq >= 0) {
|
||||
parameters[decodeURIComponent(entry.slice(0, eq))] =
|
||||
decodeURIComponent(entry.slice(eq + 1));
|
||||
}
|
||||
});
|
||||
|
||||
// Produce a Location query string from a parameter object.
|
||||
function locationQuery(params) {
|
||||
return '?' + Object.keys(params).map(function (key) {
|
||||
return encodeURIComponent(key) + '=' +
|
||||
encodeURIComponent(params[key]);
|
||||
}).join('&');
|
||||
}
|
||||
|
||||
// Derive a fetch URL from the current URL, sans the GraphQL parameters.
|
||||
var graphqlParamNames = {
|
||||
query: true,
|
||||
variables: true,
|
||||
operationName: true
|
||||
};
|
||||
|
||||
var otherParams = {};
|
||||
for (var k in parameters) {
|
||||
if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
|
||||
otherParams[k] = parameters[k];
|
||||
}
|
||||
}
|
||||
var fetchURL = locationQuery(otherParams);
|
||||
|
||||
// Defines a GraphQL fetcher using the fetch API.
|
||||
function graphQLFetcher(graphQLParams) {
|
||||
return fetch(fetchURL, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(graphQLParams),
|
||||
credentials: 'include',
|
||||
}).then(function (response) {
|
||||
return response.text();
|
||||
}).then(function (responseBody) {
|
||||
try {
|
||||
return JSON.parse(responseBody);
|
||||
} catch (error) {
|
||||
return responseBody;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// When the query and variables string is edited, update the URL bar so
|
||||
// that it can be easily shared.
|
||||
function onEditQuery(newQuery) {
|
||||
parameters.query = newQuery;
|
||||
updateURL();
|
||||
}
|
||||
|
||||
function onEditVariables(newVariables) {
|
||||
parameters.variables = newVariables;
|
||||
updateURL();
|
||||
}
|
||||
|
||||
function onEditOperationName(newOperationName) {
|
||||
parameters.operationName = newOperationName;
|
||||
updateURL();
|
||||
}
|
||||
|
||||
function updateURL() {
|
||||
history.replaceState(null, null, locationQuery(parameters));
|
||||
}
|
||||
|
||||
// Render <GraphiQL /> into the body.
|
||||
ReactDOM.render(
|
||||
React.createElement(GraphiQL, {
|
||||
fetcher: graphQLFetcher,
|
||||
onEditQuery: onEditQuery,
|
||||
onEditVariables: onEditVariables,
|
||||
onEditOperationName: onEditOperationName,
|
||||
query: {{ params.query|tojson }},
|
||||
response: {{ result|tojson }},
|
||||
variables: {{ params.variables|tojson }},
|
||||
operationName: {{ params.operation_name|tojson }},
|
||||
}),
|
||||
document.body
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
|
||||
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,
|
||||
)
|
||||
+17
-7
@@ -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,
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from jinja2 import Template
|
||||
|
||||
def load_template(app)
|
||||
@@ -28,6 +28,7 @@ required = [
|
||||
"requests",
|
||||
"requests-wsgi-adapter",
|
||||
"graphene",
|
||||
"graphql-server-core>=1.1",
|
||||
"whitenoise",
|
||||
"jinja2",
|
||||
]
|
||||
|
||||
+94
-1
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user