Generate smart defaults for some values at some places
authorDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 22 Oct 2019 18:23:44 +0000 (14:23 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Tue, 22 Oct 2019 18:23:44 +0000 (14:23 -0400)
main.py
phial.py

diff --git a/main.py b/main.py
index 2fa7191..d7ea725 100644 (file)
--- a/main.py
+++ b/main.py
@@ -2,9 +2,8 @@ import phial
 
 def handler(request):
     return phial.Response(
-        status='200 OK',
-        headers=[('Content-Type', 'text/plain')],
-        content=[b'Hello, world\n'],
+        content_type='text/plain',
+        content='Hello, world\n',
     )
 
 app = phial.App(handler)
index 3447057..bce8979 100644 (file)
--- a/phial.py
+++ b/phial.py
@@ -7,19 +7,68 @@ Request = collections.namedtuple(
     )
 )
 
-Response = collections.namedtuple(
+_Response = collections.namedtuple(
     'Response',
     (
         'status',
-        'headers',
+        'content_type',
+        'extra_headers',
         'content',
     ),
 )
 
+class Response(_Response):
+    def __new__(cls, **kwargs):
+        status = kwargs.pop('status', 200)
+        assert isinstance(status, int)
+
+        content_type = kwargs.pop('content_type')
+        assert isinstance(content_type, str)
+
+        extra_headers = kwargs.pop('extra_headers', ())
+        assert isinstance(extra_headers, tuple)
+
+        content = kwargs.pop('content')
+
+        assert len(kwargs) == 0
+
+        return super().__new__(
+            cls,
+            status=status,
+            content_type=content_type,
+            extra_headers=extra_headers,
+            content=content,
+        )
+
+    @property
+    def headers(self):
+        return (
+            ('Content-Type', self.content_type),
+        )
+
+def _get_status(response):
+    return {
+        200: '200 OK',
+    }[response.status]
+
+def _get_headers(response):
+    return list(response.headers)
+
+def _get_content(response):
+    content = response.content
+
+    if isinstance(content, bytes):
+        return (content,)
+
+    if isinstance(content, str):
+        return (content.encode('utf-8'),)
+
+    return content
+
 def App(handler):
     def app(environ, start_fn):
         response = handler(Request(environ))
 
-        start_fn(response.status, response.headers)
-        return response.content
+        start_fn(_get_status(response), _get_headers(response))
+        return _get_content(response)
     return app