Create the default application for an UWSGI server.
WSGI response is created from given "environ" parameters and communicated with start_response.
Create the default application for an UWSGI server.
WSGI response is created from given "environ" parameters and communicated with start_response.
Initialize the WSGIApplication instance.
def __init__(self, default_path: str='', default_filename: str='index.html', web_page_maker=WebSiteResponse, default_web_json: str=None):
"""Initialize the WSGIApplication instance.
:param default_path: (str) Default root path for static or dynamic pages
:param default_filename: (str) Default filename to serve if none is provided
:param web_page_maker: (callable) A callable used to generate dynamic pages
:param default_web_json: (str) Path to the JSON file for dynamic page definitions
"""
self.__default_path = default_path
self.__default_file = default_filename
self.__dynamic_pages = (web_page_maker, os.path.join(self.__default_path, default_web_json))
self._pages = dict()
Add a page to the list of available pages.
False is returned if the page already exists or the response has a wrong type.
def add_page(self, page_name: str, response: BaseResponseRecipe) -> bool:
"""Add a page to the list of available pages.
False is returned if the page already exists or the response has a wrong type.
:param page_name: (str) the name of the page
:param response: (BaseResponseRecipe) the response object of the page (has to inherited of BaseResponseRecipe)
:return: (bool) True if we successfully added the page
"""
if page_name in self._pages.keys():
return False
if isinstance(response, BaseResponseRecipe) is False:
return False
self._pages[page_name] = response
return True
Create page dynamically from the json config file.
def __create_dynamic_page(self, page_name: str) -> None:
"""Create page dynamically from the json config file.
:param page_name: (str) Name of the page to bake
"""
web_data = self.__dynamic_pages[0]
if hasattr(web_data, 'bake_response'):
data = web_data(self.__dynamic_pages[1])
page = data.bake_response(page_name, default=self.__default_path)
if page is not None:
self._pages[page_name] = page
else:
data = WebSiteData(self.__dynamic_pages[1])
if page_name in data:
self._pages[page_name] = web_data(page_name)
Handle requests for dynamic content or return a 404 if not found.
def __serve_dynamic_content(self, page_name: str, filepath: str, environ, handler_utils) -> tuple:
"""Handle requests for dynamic content or return a 404 if not found."""
if self.__dynamic_pages[1] is not None and page_name not in self._pages:
self.__create_dynamic_page(page_name)
if page_name not in self._pages or filepath != f'{self.__default_path}/{page_name}':
status = HTTPDStatus(404)
content = status.to_html(encode=True, msg_error=f'Page not found : {filepath}')
else:
events, accept = handler_utils.process_post(environ['wsgi.input'])
content, status = HTTPDHandlerUtils.bakery(self._pages, page_name, environ['PATH_INFO'], events, HTTPDHandlerUtils.has_to_return_data(accept))
return (content, status)
Handle WSGI requests.
Process the incoming "environ" dictionary and respond using the given start_response callable.
def __call__(self, environ, start_response):
"""Handle WSGI requests.
Process the incoming "environ" dictionary and respond using the given
start_response callable.
:param environ: (dict) WSGI environment dictionary with request data
:param start_response: (callable) Function to start the HTTP response
:return: (bytes|iterable) Response content to send back to the client
"""
if 'HTTP_ACCEPT' in environ:
environ['Accept'] = environ['HTTP_ACCEPT']
handler_utils = HTTPDHandlerUtils(environ, environ['PATH_INFO'], self.__default_file)
filepath = self.__default_path + handler_utils.get_path()
filepath = filepath.replace('//', '/')
page_name = handler_utils.get_page_name()
use_cache = True
if os.path.exists(filepath) is True:
content, status = handler_utils.static_content(filepath)
elif os.path.isfile(handler_utils.get_path()[1:]) is True:
content, status = handler_utils.static_content(handler_utils.get_path()[1:])
else:
content, status = self.__serve_dynamic_content(page_name, filepath, environ, handler_utils)
use_cache = False
if isinstance(content, types.GeneratorType):
headers = HTTPDHandlerUtils.build_default_headers(filepath, content, browser_cache=use_cache, varnish=use_cache)
start_response(repr(status), headers)
return [c for c in content]
headers = HTTPDHandlerUtils.build_default_headers(filepath, content, browser_cache=use_cache, varnish=use_cache)
start_response(repr(status), headers)
return [content]
Check if a page name exists in the application.
def __contains__(self, page_name: str) -> bool:
"""Check if a page name exists in the application.
:param page_name: (str) Name of the page to check
:return: (bool) True if the page exists, False otherwise
"""
return page_name in self._pages