WhakerPy 1.3

https://sourceforge.net/projects/whakerpy/

Module whakerpy.webapp

Class WSGIApplication

Description

Create the default application for an UWSGI server.

WSGI response is created from given "environ" parameters and communicated with start_response.

Constructor

Initialize the WSGIApplication instance.

Parameters
  • default_path: (str) Default root path for static or dynamic pages
  • default_filename: (str) Default filename to serve if none is provided
  • webpagemaker: (callable) A callable used to generate dynamic pages
  • defaultwebjson: (str) Path to the JSON file for dynamic page definitions
View Source
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()

Public functions

add_page

Add a page to the list of available pages.

False is returned if the page already exists or the response has a wrong type.

Parameters
  • page_name: (str) the name of the page
  • response: (BaseResponseRecipe) the response object of the page (has to inherited of BaseResponseRecipe)
Returns
  • (bool) True if we successfully added the page
View Source
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

Protected functions

__create_dynamic_page

Create page dynamically from the json config file.

Parameters
  • page_name: (str) Name of the page to bake
View Source
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)

__serve_dynamic_content

Handle requests for dynamic content or return a 404 if not found.

Parameters
  • page_name
  • filepath
  • environ
  • handler_utils
View Source
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)

Overloads

__call__

Handle WSGI requests.

Process the incoming "environ" dictionary and respond using the given start_response callable.

Parameters
  • environ: (dict) WSGI environment dictionary with request data
  • start_response: (callable) Function to start the HTTP response
Returns
  • (bytes|iterable) Response content to send back to the client
View Source
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]

__contains__

Check if a page name exists in the application.

Parameters
  • page_name: (str) Name of the page to check
Returns
  • (bool) True if the page exists, False otherwise
View Source
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