3 Request = collections.namedtuple(
10 _Response = collections.namedtuple(
20 class Response(_Response):
21 def __new__(cls, content, **kwargs):
22 status = kwargs.pop('status', 200)
23 assert isinstance(status, int)
25 content_type = kwargs.pop('content_type')
26 assert isinstance(content_type, str)
28 extra_headers = kwargs.pop('extra_headers', ())
29 assert isinstance(extra_headers, tuple)
31 assert len(kwargs) == 0
33 return super().__new__(
36 content_type=content_type,
37 extra_headers=extra_headers,
44 ('Content-Type', self.content_type),
47 class TextResponse(Response):
48 def __new__(cls, content, **kwargs):
49 assert 'content_type' not in kwargs
50 return super().__new__(
53 content_type='text/plain',
57 def _get_status(response):
62 def _get_headers(response):
63 return list(response.headers)
65 def _get_content(response):
66 content = response.content
68 if isinstance(content, bytes):
71 if isinstance(content, str):
72 return (content.encode('utf-8'),)
77 def app(environ, start_fn):
78 response = handler(Request(environ))
80 start_fn(_get_status(response), _get_headers(response))
81 return _get_content(response)