Create a redirect response type
[fwx] / phial.py
index f76a5dc..bc07b5f 100644 (file)
--- a/phial.py
+++ b/phial.py
@@ -1,4 +1,5 @@
 import collections
+import json
 
 Request = collections.namedtuple(
     'Request',
@@ -44,9 +45,35 @@ class Response(_Response):
             ('Content-Type', self.content_type),
         )
 
+class HTMLResponse(Response):
+    def __new__(cls, content, **kwargs):
+        assert 'content_type' not in kwargs
+
+        return super().__new__(
+            cls,
+            content,
+            content_type='text/html',
+            **kwargs,
+        )
+
+class JSONResponse(Response):
+    def __new__(cls, content_json, **kwargs):
+        assert 'content_type' not in kwargs
+        assert 'content' not in kwargs
+
+        self = super().__new__(
+            cls,
+            content=json.dumps(content_json),
+            content_type='application/json',
+            **kwargs,
+        )
+        self.content_json = content_json
+        return self
+
 class TextResponse(Response):
     def __new__(cls, content, **kwargs):
         assert 'content_type' not in kwargs
+
         return super().__new__(
             cls,
             content,
@@ -54,9 +81,45 @@ class TextResponse(Response):
             **kwargs,
         )
 
+_RedirectResponse = collections.namedtuple(
+    'RedirectResponse',
+    (
+        'location',
+        'permanent',
+    ),
+)
+
+class RedirectResponse(_RedirectResponse):
+    def __new__(cls, location, **kwargs):
+        assert isinstance(location, str)
+
+        permanent = kwargs.pop('permanent', True)
+        assert isinstance(permanent, bool)
+        assert len(kwargs) == 0
+
+        return super().__new__(
+            cls,
+            location=location,
+            permanent=permanent,
+        )
+
+    @property
+    def status(self):
+        return 308 if self.permanent else 307
+
+    @property
+    def headers(self):
+        return (('Location', self.location),)
+
+    @property
+    def content(self):
+        return (b'',)
+
 def _get_status(response):
     return {
         200: '200 OK',
+        307: '307 Temporary Redirect',
+        308: '308 Permanent Redirect',
     }[response.status]
 
 def _get_headers(response):