Last active
May 15, 2016 21:54
-
-
Save estebistec/b6667ecaea0ff20c4356ca6d8c5b1f58 to your computer and use it in GitHub Desktop.
morepath #70: Content negotiation: Look at accept header in request
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -* | |
import morepath | |
import reg | |
from morepath import generic | |
from webob.acceptparse import MIMEAccept | |
from webob.exc import HTTPNotAcceptable | |
class MediaTypeIndex(reg.KeyIndex): | |
@property | |
def offered_types(self): | |
return self.d.keys() | |
def permutations(self, key): | |
if isinstance(key, str): | |
key = MIMEAccept(key) | |
yield key.best_match(self.offered_types) | |
DEFAULT_RESPONSE_TYPE = 'text/html' | |
class App(morepath.App): | |
pass | |
@App.predicate(generic.view, name='accept', default=DEFAULT_RESPONSE_TYPE, | |
index=MediaTypeIndex, | |
after=morepath.LAST_VIEW_PREDICATE) | |
def accept_header_predicate(request): | |
return request.accept | |
@App.predicate_fallback(generic.view, accept_header_predicate) | |
def media_type_not_found(self, request): | |
raise HTTPNotAcceptable() | |
@App.path(path='') | |
class Root(object): | |
pass | |
@App.html(model=Root, accept='text/html') | |
def hello_world(self, request): | |
return "<p>Hello world!</p>" | |
@App.view(model=Root, accept='text/*') | |
def hello_world_any_text(self, request): | |
return self.hello_world(request) | |
@App.json(model=Root, accept='application/json') | |
def hello_world_json(self, request): | |
return {'message': "Hello world!"} | |
# Example 2: Another resource model with different media type offerings | |
# NOTE Including, not having the predicate-wide default | |
@App.path(path='/health') | |
class HealthCheck(object): | |
pass | |
@App.json(model=HealthCheck, accept="application/json") | |
def health_check(self, request): | |
return {"health_status": "GOOD"} | |
@App.json(model=HealthCheck, accept="application/hal+json") | |
def health_check_hal(self, request): | |
return {"health_status": "GOOD", "_links": {"self": {"url": request.link(self)}}} | |
if __name__ == '__main__': | |
morepath.autocommit() | |
morepath.run(App()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* Rebuilt URL to: http://127.0.0.1:5000/ | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET / HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: text/html | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 200 OK | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Type: text/html; charset=UTF-8 | |
< Content-Length: 19 | |
< | |
{ [19 bytes data] | |
100 19 100 19 0 0 9200 0 --:--:-- --:--:-- --:--:-- 19000 | |
* Closing connection 0 | |
<p>Hello world!</p>* Rebuilt URL to: http://127.0.0.1:5000/ | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET / HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/json | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 200 OK | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Type: application/json | |
< Content-Length: 27 | |
< | |
{ [27 bytes data] | |
100 27 100 27 0 0 7642 0 --:--:-- --:--:-- --:--:-- 13500 | |
* Closing connection 0 | |
{"message": "Hello world!"}* Rebuilt URL to: http://127.0.0.1:5000/ | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET / HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/something-else | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 406 Not Acceptable | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Length: 140 | |
< Content-Type: text/plain; charset=UTF-8 | |
< | |
{ [140 bytes data] | |
100 140 100 140 0 0 26007 0 --:--:-- --:--:-- --:--:-- 35000 | |
* Closing connection 0 | |
406 Not Acceptable | |
The resource could not be generated that was acceptable to your browser (content of type application/something-else. | |
* Rebuilt URL to: http://127.0.0.1:5000/ | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET / HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: */* | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 200 OK | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Type: text/html; charset=UTF-8 | |
< Content-Length: 19 | |
< | |
{ [19 bytes data] | |
100 19 100 19 0 0 9254 0 --:--:-- --:--:-- --:--:-- 19000 | |
* Closing connection 0 | |
<p>Hello world!</p>* Rebuilt URL to: http://127.0.0.1:5000/ | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET / HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/*;q=0.5, text/*;q=0.5 | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 200 OK | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Type: text/html; charset=UTF-8 | |
< Content-Length: 19 | |
< | |
{ [19 bytes data] | |
100 19 100 19 0 0 7609 0 --:--:-- --:--:-- --:--:-- 9500 | |
* Closing connection 0 | |
<p>Hello world!</p>* Rebuilt URL to: http://127.0.0.1:5000/ | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET / HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/hal+json;q=1, application/json;q=0.8 | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 406 Not Acceptable | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Length: 226 | |
< Content-Type: application/json; charset=utf-8 | |
< | |
{ [226 bytes data] | |
100 226 100 226 0 0 21705 0 --:--:-- --:--:-- --:--:-- 22600 | |
* Closing connection 0 | |
{"message": "The resource could not be generated that was acceptable to your browser\n(content of type application/hal+json;q=1, application/json;q=0.8. <br /><br />\n", "code": "406 Not Acceptable", "title": "Not Acceptable"}* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET /health HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/*;q=0.5, text/*;q=0.5 | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 406 Not Acceptable | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Length: 147 | |
< Content-Type: text/plain; charset=UTF-8 | |
< | |
{ [147 bytes data] | |
100 147 100 147 0 0 55408 0 --:--:-- --:--:-- --:--:-- 73500 | |
* Closing connection 0 | |
406 Not Acceptable | |
The resource could not be generated that was acceptable to your browser (content of type application/*;q=0.5, text/*;q=0.5. | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET /health HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/json | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 200 OK | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Type: application/json | |
< Content-Length: 25 | |
< | |
{ [25 bytes data] | |
100 25 100 25 0 0 9245 0 --:--:-- --:--:-- --:--:-- 12500 | |
* Closing connection 0 | |
{"health_status": "GOOD"}* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET /health HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/hal+json;q=1, application/json;q=0.8 | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 200 OK | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Type: application/json | |
< Content-Length: 86 | |
< | |
{ [86 bytes data] | |
100 86 100 86 0 0 27634 0 --:--:-- --:--:-- --:--:-- 43000 | |
* Closing connection 0 | |
{"_links": {"self": {"url": "http://127.0.0.1:5000/health"}}, "health_status": "GOOD"}* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET /health HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: text/html | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 406 Not Acceptable | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Length: 230 | |
< Content-Type: text/html; charset=UTF-8 | |
< | |
{ [230 bytes data] | |
100 230 100 230 0 0 70921 0 --:--:-- --:--:-- --:--:-- 76666 | |
* Closing connection 0 | |
<html> | |
<head> | |
<title>406 Not Acceptable</title> | |
</head> | |
<body> | |
<h1>406 Not Acceptable</h1> | |
The resource could not be generated that was acceptable to your browser | |
(content of type text/html. <br /><br /> | |
</body> | |
</html>* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET /health HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: application/something-else | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 406 Not Acceptable | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Length: 140 | |
< Content-Type: text/plain; charset=UTF-8 | |
< | |
{ [140 bytes data] | |
100 140 100 140 0 0 54116 0 --:--:-- --:--:-- --:--:-- 70000 | |
* Closing connection 0 | |
406 Not Acceptable | |
The resource could not be generated that was acceptable to your browser (content of type application/something-else. | |
* Trying 127.0.0.1... | |
% Total % Received % Xferd Average Speed Time Time Time Current | |
Dload Upload Total Spent Left Speed | |
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0) | |
> GET /health HTTP/1.1 | |
> Host: 127.0.0.1:5000 | |
> User-Agent: curl/7.43.0 | |
> Accept: */* | |
> | |
* HTTP 1.0, assume close after body | |
< HTTP/1.0 406 Not Acceptable | |
< Date: Sun, 15 May 2016 21:53:19 GMT | |
< Server: WSGIServer/0.2 CPython/3.5.1 | |
< Content-Length: 117 | |
< Content-Type: text/plain; charset=UTF-8 | |
< | |
{ [117 bytes data] | |
100 117 100 117 0 0 47560 0 --:--:-- --:--:-- --:--:-- 58500 | |
* Closing connection 0 | |
406 Not Acceptable | |
The resource could not be generated that was acceptable to your browser (content of type */*. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
curl http://127.0.0.1:5000 -H 'Accept: text/html' -v | |
curl http://127.0.0.1:5000 -H 'Accept: application/json' -v | |
curl http://127.0.0.1:5000 -H 'Accept: application/something-else' -v | |
curl http://127.0.0.1:5000 -H 'Accept: */*' -v | |
curl http://127.0.0.1:5000 -H 'Accept: application/*;q=0.5, text/*;q=0.5' -v | |
curl http://127.0.0.1:5000 -H 'Accept: application/hal+json;q=1, application/json;q=0.8' -v | |
curl http://127.0.0.1:5000/health -H 'Accept: application/*;q=0.5, text/*;q=0.5' -v | |
curl http://127.0.0.1:5000/health -H 'Accept: application/json' -v | |
curl http://127.0.0.1:5000/health -H 'Accept: application/hal+json;q=1, application/json;q=0.8' -v | |
curl http://127.0.0.1:5000/health -H 'Accept: text/html' -v | |
curl http://127.0.0.1:5000/health -H 'Accept: application/something-else' -v | |
curl http://127.0.0.1:5000/health -H 'Accept: */*' -v |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment