Module 15Watt_Wsgi.Response
Expand source code
from .Request import Request
from .Exceptions import NotAllowedHttpResponseCode
from .Cookie import Cookie
class ResponseCodeToText(object):
"""
Translates the web servers numeric response code to its
string representation:
200 -> 200 OK
401 -> Unauthorized
...
"""
__numToTxt = {
100: 'Continue',
101: 'Switching Protocols',
102: 'Processing',
103: 'Early Hints',
200: 'OK',
201: 'Created',
202: 'Accepted',
203: 'Non - Authoritative Information',
204: 'No Content',
205: 'Reset Content',
206: 'Partial Content',
207: 'Multi - Status',
208: 'Already Reported',
226: 'IM Used',
300: 'Multiple Choices',
301: 'Moved Permanently',
302: 'Found',
303: 'See Other',
304: 'Not Modified',
307: 'Temporary Redirect',
308: 'Permanent Redirect',
400: 'Bad Request',
401: 'Unauthorized',
402: 'Payment Required',
403: 'Forbidden',
404: 'Not Found',
405: 'Method Not Allowed',
406: 'Not Acceptable',
407: 'Proxy Authentication Required',
408: 'Request Timeout',
409: 'Conflict',
410: 'Gone',
411: 'Length Required',
412: 'Precondition Failed',
413: 'Payload Too Large',
414: 'URI Too Long',
415: 'Unsupported Media Type',
416: 'Range Not Satisfiable',
417: 'Expectation Failed',
418: 'I\'m a teapot',
421: 'Misdirected Request',
422: 'Unprocessable Entity',
423: 'Locked',
424: 'Failed Dependency',
425: 'Too Early',
426: 'Upgrade Required',
428: 'Precondition Required',
429: 'Too Many Requests',
431: 'Request Header Fields Too Large',
451: 'Unavailable For Legal Reasons',
500: 'Internal Server Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Timeout',
505: 'HTTP Version Not Supported',
506: 'Variant Also Negotiates',
507: 'Insufficient Storage',
508: 'Loop Detected',
510: 'Not Extended',
511: 'Network Authentication Required',
513: 'The Server Is In A Bad Mood'
}
def __init__(self, respCode: int):
if respCode not in self.__numToTxt:
raise NotAllowedHttpResponseCode(respCode)
self.__responseCode = respCode
def asText(self) -> str:
"""
Returns the string representation of the response code
:return:
"""
return '{responseCode} {responseText}'.format(
responseCode=self.__responseCode,
responseText=self.__numToTxt[self.__responseCode]
)
def __str__(self) -> str:
return self.asText()
class Response(object):
"""
Representation of the response, that is sent back to the web server
"""
def __init__(self, request: Request, startResponse):
self.__request = request
self.__startResponse = startResponse
self.contentType = 'text/plain'
self.charset = 'utf-8'
self.returnCode = 200
self.__arrHeaders = {}
self.__arrCookies = {}
# The content to send as a byte array
self.__byteContent = None
# The content to send as a string
self.__stringContent = ''
# Getters for the private properties
@property
def request(self) -> Request:
return self.__request
@property
def stringContent(self) -> str:
return self.__stringContent
@stringContent.setter
def stringContent(self, strCont: str) -> None:
self.__byteContent = None
self.__stringContent = strCont
@property
def byteContent(self) -> bytes:
return self.__byteContent
@byteContent.setter
def byteContent(self, byteCont: bytes) -> None:
self.__stringContent = ''
self.__byteContent = byteCont
def addHeader(self, key: str, value: str):
"""
Adds a header line to the response.
An already added header is overwritten
"""
self.__arrHeaders[key] = value
return self
def addCookie(self, cookie: Cookie):
"""
Adds a cookie to the response.
A already added cookie is overwritten
"""
self.__arrCookies[cookie.key] = cookie
return self
def getContent(self) -> list[bytes]:
"""
Returns the rendered content.
startResponse has been called before.
:return:
"""
# Run startResponse to the web server
self.__startResponse(
ResponseCodeToText(respCode=self.returnCode).asText(),
self.__buildHeader()
)
if self.__byteContent is None:
# Byte content has not been created yet
self.__byteContent = bytes(self.__stringContent, self.charset)
# Return the byte content
return [self.__byteContent]
def redirect(self, url: str, code: int = 303) -> None:
"""
Redirects the user to the given url
"""
self.returnCode = code
self.addHeader('Location', url)
def __buildHeader(self) -> list[tuple]:
arrHeader = [
('Content-type', '{contType}; charset={charSet}'.format(contType=self.contentType, charSet=self.charset)),
('Access-Control-Allow-Origin', '*')
]
for key in self.__arrHeaders:
arrHeader.append((key, self.__arrHeaders[key]))
for key in self.__arrCookies:
arrHeader.append(('Set-Cookie', str(self.__arrCookies[key])))
return arrHeader
Classes
class Response (request: 15Watt_Wsgi.Request.Request, startResponse)
-
Representation of the response, that is sent back to the web server
Expand source code
class Response(object): """ Representation of the response, that is sent back to the web server """ def __init__(self, request: Request, startResponse): self.__request = request self.__startResponse = startResponse self.contentType = 'text/plain' self.charset = 'utf-8' self.returnCode = 200 self.__arrHeaders = {} self.__arrCookies = {} # The content to send as a byte array self.__byteContent = None # The content to send as a string self.__stringContent = '' # Getters for the private properties @property def request(self) -> Request: return self.__request @property def stringContent(self) -> str: return self.__stringContent @stringContent.setter def stringContent(self, strCont: str) -> None: self.__byteContent = None self.__stringContent = strCont @property def byteContent(self) -> bytes: return self.__byteContent @byteContent.setter def byteContent(self, byteCont: bytes) -> None: self.__stringContent = '' self.__byteContent = byteCont def addHeader(self, key: str, value: str): """ Adds a header line to the response. An already added header is overwritten """ self.__arrHeaders[key] = value return self def addCookie(self, cookie: Cookie): """ Adds a cookie to the response. A already added cookie is overwritten """ self.__arrCookies[cookie.key] = cookie return self def getContent(self) -> list[bytes]: """ Returns the rendered content. startResponse has been called before. :return: """ # Run startResponse to the web server self.__startResponse( ResponseCodeToText(respCode=self.returnCode).asText(), self.__buildHeader() ) if self.__byteContent is None: # Byte content has not been created yet self.__byteContent = bytes(self.__stringContent, self.charset) # Return the byte content return [self.__byteContent] def redirect(self, url: str, code: int = 303) -> None: """ Redirects the user to the given url """ self.returnCode = code self.addHeader('Location', url) def __buildHeader(self) -> list[tuple]: arrHeader = [ ('Content-type', '{contType}; charset={charSet}'.format(contType=self.contentType, charSet=self.charset)), ('Access-Control-Allow-Origin', '*') ] for key in self.__arrHeaders: arrHeader.append((key, self.__arrHeaders[key])) for key in self.__arrCookies: arrHeader.append(('Set-Cookie', str(self.__arrCookies[key]))) return arrHeader
Instance variables
var byteContent : bytes
-
Expand source code
@property def byteContent(self) -> bytes: return self.__byteContent
var request : 15Watt_Wsgi.Request.Request
-
Expand source code
@property def request(self) -> Request: return self.__request
var stringContent : str
-
Expand source code
@property def stringContent(self) -> str: return self.__stringContent
Methods
def addCookie(self, cookie: 15Watt_Wsgi.Cookie.Cookie)
-
Adds a cookie to the response. A already added cookie is overwritten
Expand source code
def addCookie(self, cookie: Cookie): """ Adds a cookie to the response. A already added cookie is overwritten """ self.__arrCookies[cookie.key] = cookie return self
def addHeader(self, key: str, value: str)
-
Adds a header line to the response. An already added header is overwritten
Expand source code
def addHeader(self, key: str, value: str): """ Adds a header line to the response. An already added header is overwritten """ self.__arrHeaders[key] = value return self
def getContent(self) ‑> list[bytes]
-
Returns the rendered content. startResponse has been called before. :return:
Expand source code
def getContent(self) -> list[bytes]: """ Returns the rendered content. startResponse has been called before. :return: """ # Run startResponse to the web server self.__startResponse( ResponseCodeToText(respCode=self.returnCode).asText(), self.__buildHeader() ) if self.__byteContent is None: # Byte content has not been created yet self.__byteContent = bytes(self.__stringContent, self.charset) # Return the byte content return [self.__byteContent]
def redirect(self, url: str, code: int = 303) ‑> None
-
Redirects the user to the given url
Expand source code
def redirect(self, url: str, code: int = 303) -> None: """ Redirects the user to the given url """ self.returnCode = code self.addHeader('Location', url)
class ResponseCodeToText (respCode: int)
-
Translates the web servers numeric response code to its string representation:
200 -> 200 OK
401 -> Unauthorized
…
Expand source code
class ResponseCodeToText(object): """ Translates the web servers numeric response code to its string representation: 200 -> 200 OK 401 -> Unauthorized ... """ __numToTxt = { 100: 'Continue', 101: 'Switching Protocols', 102: 'Processing', 103: 'Early Hints', 200: 'OK', 201: 'Created', 202: 'Accepted', 203: 'Non - Authoritative Information', 204: 'No Content', 205: 'Reset Content', 206: 'Partial Content', 207: 'Multi - Status', 208: 'Already Reported', 226: 'IM Used', 300: 'Multiple Choices', 301: 'Moved Permanently', 302: 'Found', 303: 'See Other', 304: 'Not Modified', 307: 'Temporary Redirect', 308: 'Permanent Redirect', 400: 'Bad Request', 401: 'Unauthorized', 402: 'Payment Required', 403: 'Forbidden', 404: 'Not Found', 405: 'Method Not Allowed', 406: 'Not Acceptable', 407: 'Proxy Authentication Required', 408: 'Request Timeout', 409: 'Conflict', 410: 'Gone', 411: 'Length Required', 412: 'Precondition Failed', 413: 'Payload Too Large', 414: 'URI Too Long', 415: 'Unsupported Media Type', 416: 'Range Not Satisfiable', 417: 'Expectation Failed', 418: 'I\'m a teapot', 421: 'Misdirected Request', 422: 'Unprocessable Entity', 423: 'Locked', 424: 'Failed Dependency', 425: 'Too Early', 426: 'Upgrade Required', 428: 'Precondition Required', 429: 'Too Many Requests', 431: 'Request Header Fields Too Large', 451: 'Unavailable For Legal Reasons', 500: 'Internal Server Error', 501: 'Not Implemented', 502: 'Bad Gateway', 503: 'Service Unavailable', 504: 'Gateway Timeout', 505: 'HTTP Version Not Supported', 506: 'Variant Also Negotiates', 507: 'Insufficient Storage', 508: 'Loop Detected', 510: 'Not Extended', 511: 'Network Authentication Required', 513: 'The Server Is In A Bad Mood' } def __init__(self, respCode: int): if respCode not in self.__numToTxt: raise NotAllowedHttpResponseCode(respCode) self.__responseCode = respCode def asText(self) -> str: """ Returns the string representation of the response code :return: """ return '{responseCode} {responseText}'.format( responseCode=self.__responseCode, responseText=self.__numToTxt[self.__responseCode] ) def __str__(self) -> str: return self.asText()
Methods
def asText(self) ‑> str
-
Returns the string representation of the response code :return:
Expand source code
def asText(self) -> str: """ Returns the string representation of the response code :return: """ return '{responseCode} {responseText}'.format( responseCode=self.__responseCode, responseText=self.__numToTxt[self.__responseCode] )