WhakerPy 0.9

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. The "environ" parameter is a dictionary. Here are examples of "environ" key/values:

  • 'REQUEST_METHOD': 'GET'
  • 'REQUEST_URI': '/information.html',
  • 'PATH_INFO': '/information.html',
  • 'QUERY_STRING': '',
  • 'SERVER_PROTOCOL': 'HTTP/1.1',
  • 'SCRIPT_NAME': '',
  • 'SERVER_NAME': 'macpro-1.home',
  • 'SERVER_PORT': '9090',
  • 'UWSGI_ROUTER': 'http',
  • 'REMOTE_ADDR': '127.0.0.1',
  • 'REMOTE_PORT': '26095',
  • 'HTTP_HOST': 'localhost:9090',
  • 'HTTPUSERAGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/115.0',
  • 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8',
  • 'HTTPACCEPTLANGUAGE': 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3',
  • 'HTTPACCEPTENCODING': 'gzip, deflate, br',
  • 'HTTP_REFERER': 'http://localhost:9090/contributeurs.html',
  • 'HTTPDNT': '1', 'HTTPCONNECTION': 'keep-alive',
  • 'HTTPUPGRADEINSECURE_REQUESTS': '1',
  • 'HTTPSECFETCH_DEST': 'document',
  • 'HTTPSECFETCH_MODE': 'navigate',
  • 'HTTPSECFETCH_SITE': 'same-origin',
  • 'HTTPSECFETCH_USER': '?1',

Constructor

View Source
def __init__(self, default_path: str='', default_filename: str='index.html', web_page_maker=WebSiteResponse, default_web_json: str=None):
    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_web_page

Create page dynamically from the json config file.

Parameters
  • page_name
View Source
def __create_web_page(self, page_name: str) -> None:
    """Create page dynamically from the json config file.

        """
    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)

Overloads

__call__

View Source
def __call__(self, environ, start_response):
    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()
    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:
        if self.__dynamic_pages[1] is not None and page_name not in self._pages:
            self.__create_web_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))
    headers = [('Content-Type', HTTPDHandlerUtils.get_mime_type(filepath)), ('Cache-Control', 'max-age=0')]
    start_response(repr(status), headers)
    return [content]

__contains__

View Source
def __contains__(self, item):
    return item in self._pages