mirror of
https://github.com/kennethreitz/responder.git
synced 2026-06-05 23:00:17 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a2eaa5c7b5 | |||
| 175c46e68c | |||
| a58cc11079 | |||
| 218a375c27 | |||
| 567b1577c6 | |||
| 3c3687d11f | |||
| 19dfac8340 | |||
| b61feafe5a | |||
| 0c342c8b3e | |||
| dbcba8fad7 | |||
| b8053e20f2 | |||
| 1896901aa8 | |||
| 383c9132ed | |||
| 57b144c3e7 | |||
| 5d43c0418c | |||
| 87c0076e12 | |||
| 95252ac697 |
+5
-2
@@ -1,3 +1,6 @@
|
||||
# v0.1.6
|
||||
- 500 support.
|
||||
|
||||
# v0.1.5
|
||||
- Improvements to sequential media reading.
|
||||
- File upload support.
|
||||
@@ -18,7 +21,7 @@
|
||||
- Prototype of static application support.
|
||||
|
||||
# v0.0.10
|
||||
- Bufgix for async class-based views.
|
||||
- Bugfix for async class-based views.
|
||||
|
||||
# v0.0.9
|
||||
- Bugfix for async class-based views.
|
||||
@@ -39,7 +42,7 @@
|
||||
- Safe load/dump yaml.
|
||||
|
||||
# v0.0.4:
|
||||
- Asyncronous support for data uploads.
|
||||
- Asynchronous support for data uploads.
|
||||
- Bug fixes.
|
||||
|
||||
# v0.0.3:
|
||||
|
||||
@@ -86,7 +86,7 @@ class Query(graphene.ObjectType):
|
||||
hello = graphene.String(name=graphene.String(default_value="stranger"))
|
||||
|
||||
def resolve_hello(self, info, name):
|
||||
return "Hello " + name
|
||||
return f"Hello {name}"
|
||||
|
||||
api.add_route("/graph", graphene.Schema(query=Query))
|
||||
```
|
||||
|
||||
@@ -43,7 +43,7 @@ Serve a GraphQL API::
|
||||
hello = graphene.String(name=graphene.String(default_value="stranger"))
|
||||
|
||||
def resolve_hello(self, info, name):
|
||||
return "Hello " + name
|
||||
return f"Hello {name}"
|
||||
|
||||
api.add_route("/graph", graphene.Schema(query=Query))
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.1.5"
|
||||
__version__ = "0.1.6"
|
||||
|
||||
+46
-21
@@ -205,6 +205,7 @@ class API:
|
||||
if resp.session:
|
||||
data = self._signer.sign(json.dumps(resp.session).encode("utf-8"))
|
||||
resp.cookies[self.session_cookie] = data.decode("utf-8")
|
||||
|
||||
@staticmethod
|
||||
def no_response(req, resp, **params):
|
||||
pass
|
||||
@@ -228,13 +229,16 @@ class API:
|
||||
|
||||
elif route.is_function:
|
||||
try:
|
||||
# Run the view.
|
||||
r = route.endpoint(req, resp, **params)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "cr_running"):
|
||||
await r
|
||||
except TypeError as e:
|
||||
cont = True
|
||||
try:
|
||||
# Run the view.
|
||||
r = route.endpoint(req, resp, **params)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "cr_running"):
|
||||
await r
|
||||
except TypeError as e:
|
||||
cont = True
|
||||
except Exception:
|
||||
self.default_response(req, resp, error=True)
|
||||
|
||||
if route.is_class_based or cont:
|
||||
try:
|
||||
@@ -243,23 +247,37 @@ class API:
|
||||
view = route.endpoint
|
||||
|
||||
# Run on_request first.
|
||||
# Run the view.
|
||||
r = getattr(view, "on_request", self.no_response)(req, resp, **params)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "send"):
|
||||
await r
|
||||
try:
|
||||
# Run the view.
|
||||
r = getattr(view, "on_request", self.no_response)(
|
||||
req, resp, **params
|
||||
)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "send"):
|
||||
await r
|
||||
except Exception as e:
|
||||
self.default_response(req, resp, error=True)
|
||||
|
||||
# Then on_get.
|
||||
method = req.method
|
||||
|
||||
# Run the view.
|
||||
r = getattr(view, f"on_{method}", self.no_response)(req, resp, **params)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "send"):
|
||||
await r
|
||||
# Run on_request first.
|
||||
try:
|
||||
# Run the view.
|
||||
r = getattr(view, f"on_{method}", self.no_response)(
|
||||
req, resp, **params
|
||||
)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "send"):
|
||||
await r
|
||||
except Exception as e:
|
||||
|
||||
self.default_response(req, resp, error=True)
|
||||
|
||||
else:
|
||||
self.default_response(req, resp)
|
||||
self.default_response(req, resp, notfound=True)
|
||||
|
||||
self.default_response(req, resp)
|
||||
|
||||
self._prepare_session(resp)
|
||||
self._prepare_cookies(resp)
|
||||
@@ -299,12 +317,19 @@ class API:
|
||||
sorted(self.routes.items(), key=lambda item: item[1]._weight())
|
||||
)
|
||||
|
||||
def default_response(self, req, resp):
|
||||
def default_response(self, req, resp, notfound=False, error=False):
|
||||
if resp.status_code is None:
|
||||
resp.status_code = 200
|
||||
|
||||
if self.default_endpoint:
|
||||
self.default_endpoint(req, resp)
|
||||
else:
|
||||
resp.status_code = status_codes.HTTP_404
|
||||
resp.text = "Not found."
|
||||
if notfound:
|
||||
resp.status_code = status_codes.HTTP_404
|
||||
resp.text = "Not found."
|
||||
if error:
|
||||
resp.status_code = status_codes.HTTP_500
|
||||
resp.text = "Application error."
|
||||
|
||||
def static_response(self, req, resp):
|
||||
index = (self.static_dir / "index.html").resolve()
|
||||
|
||||
@@ -51,9 +51,8 @@ async def format_files(r, encode=False):
|
||||
if key == "filename":
|
||||
filename = value
|
||||
|
||||
content = part.text
|
||||
if filename:
|
||||
dump[filename] = content
|
||||
dump[filename] = part.content
|
||||
return dump
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -244,7 +244,7 @@ class Response:
|
||||
|
||||
def __init__(self, req, *, formats):
|
||||
self.req = req
|
||||
self.status_code = HTTP_200 #: The HTTP Status Code to use for the Response.
|
||||
self.status_code = None #: The HTTP Status Code to use for the Response.
|
||||
self.text = None #: A unicode representation of the response body.
|
||||
self.content = None #: A bytes representation of the response body.
|
||||
self.encoding = DEFAULT_ENCODING
|
||||
|
||||
+2
-3
@@ -33,7 +33,6 @@ class Route:
|
||||
|
||||
@property
|
||||
def endpoint_name(self):
|
||||
print(self.endpoint.__name__)
|
||||
return self.endpoint.__name__
|
||||
|
||||
@property
|
||||
@@ -66,8 +65,8 @@ class Route:
|
||||
|
||||
def _weight(self):
|
||||
params = set(self._param_pattern.findall(self.route))
|
||||
params_count = -len(params) or 0
|
||||
return params_count != 0, params_count
|
||||
params_count = len(params)
|
||||
return params_count != 0, -params_count
|
||||
|
||||
@property
|
||||
def is_graphql(self):
|
||||
|
||||
@@ -22,15 +22,3 @@ def test_bytes_encoding(api, session):
|
||||
|
||||
r = session.get(api.url_for(route), data=data)
|
||||
assert r.content == data
|
||||
|
||||
|
||||
def test_false_encoding_raises(api, session):
|
||||
data = "hi mom!"
|
||||
|
||||
@api.route("/")
|
||||
async def route(req, resp):
|
||||
req.encoding = "non-existient"
|
||||
resp.text = await req.text
|
||||
|
||||
with pytest.raises(LookupError):
|
||||
session.get(api.url_for(route), data=data)
|
||||
|
||||
+13
-2
@@ -416,9 +416,20 @@ def test_file_uploads(api, session):
|
||||
@api.route("/")
|
||||
async def upload(req, resp):
|
||||
|
||||
resp.media = {"files": await req.media("files")}
|
||||
files = await req.media("files")
|
||||
files["hello"] = files["hello"].decode("utf-8")
|
||||
resp.media = {"files": files}
|
||||
|
||||
world = io.StringIO("world")
|
||||
data = {"hello": world}
|
||||
r = session.get(api.url_for(upload), files=data)
|
||||
r = session.post(api.url_for(upload), files=data)
|
||||
assert r.json() == {"files": {"hello": "world"}}
|
||||
|
||||
|
||||
def test_500(api, session):
|
||||
@api.route("/")
|
||||
def view(rea, resp):
|
||||
raise ValueError
|
||||
|
||||
r = session.get(api.url_for(view))
|
||||
assert not r.ok
|
||||
|
||||
Reference in New Issue
Block a user