4 Request = collections.namedtuple(
11 _Response = collections.namedtuple(
21 class Response(_Response):
22 def __new__(cls, content, **kwargs):
23 status = kwargs.pop('status', 200)
24 assert isinstance(status, int)
26 content_type = kwargs.pop('content_type')
27 assert isinstance(content_type, str)
29 extra_headers = kwargs.pop('extra_headers', ())
30 assert isinstance(extra_headers, tuple)
32 assert len(kwargs) == 0
34 return super().__new__(
37 content_type=content_type,
38 extra_headers=extra_headers,
45 ('Content-Type', self.content_type),
48 class HTMLResponse(Response):
49 def __new__(cls, content, **kwargs):
50 assert 'content_type' not in kwargs
52 return super().__new__(
55 content_type='text/html',
59 class JSONResponse(Response):
60 def __new__(cls, content_json, **kwargs):
61 assert 'content_type' not in kwargs
62 assert 'content' not in kwargs
64 self = super().__new__(
66 content=json.dumps(content_json),
67 content_type='application/json',
70 self.content_json = content_json
73 class TextResponse(Response):
74 def __new__(cls, content, **kwargs):
75 assert 'content_type' not in kwargs
77 return super().__new__(
80 content_type='text/plain',
84 _RedirectResponse = collections.namedtuple(
92 class RedirectResponse(_RedirectResponse):
93 def __new__(cls, location, **kwargs):
94 assert isinstance(location, str)
96 permanent = kwargs.pop('permanent', True)
97 assert isinstance(permanent, bool)
98 assert len(kwargs) == 0
100 return super().__new__(
108 return 308 if self.permanent else 307
112 return (('Location', self.location),)
118 def _get_status(response):
121 307: '307 Temporary Redirect',
122 308: '308 Permanent Redirect',
125 def _get_headers(response):
126 return list(response.headers)
128 def _get_content(response):
129 content = response.content
131 if isinstance(content, bytes):
134 if isinstance(content, str):
135 return (content.encode('utf-8'),)
140 def app(environ, start_fn):
141 response = handler(Request(environ))
143 start_fn(_get_status(response), _get_headers(response))
144 return _get_content(response)