Search code examples
pythonhttp-status-code-404cherrypy

How to custom 404 error page load subfolders using cherrypy


I would like to override 404 error page showed in cherrypy to my custom error page. The challenge is to read all subfolders inside the directory that contain my index.html. These subfolders are img, css, js...

According to cherrypy documentation I found that I can custom a 404 error page overriding this function and doing a cherrypy.config.update in the following form:

  _cp_config = {
       'error_page.404': os.path.join(localDir, "static/index.html")
   }

I customised the page with success and cherrypy load my html with success.

Here is my code that loads the html (but not the subdirectories inside that folder).

import cherrypy
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
application = get_wsgi_application()
WEBAPP = "/app-web/"
CONF_WEBAPP = {'/':
           {'tools.staticdir.on': True,
            'tools.staticdir.dir': WEBAPP,
            'tools.staticdir.index': 'index.html'}}
WEB_ROOT = '/webclient/'

class ServeWebApp(object):
    @cherrypy.expose
    def index(self):
        pass

if __name__ == '__main__':
    cherrypy.tree.graft(application, '/')
    cherrypy.tree.mount(ServeWebApp(), '/webapp', config=CONF_WEBAPP)
    cherrypy.config.update({'error_page.404': os.path.join(WEB_ROOT, "index.html")})
    cherrypy.server.socket_host = "0.0.0.0"
    cherrypy.server.socket_port = 8000
    cherrypy.server.thread_pool = 100

    cherrypy.engine.start()
    cherrypy.engine.block()

I am serving a static web site fully functional with css and js declaring CONF_WEBAPP and loading in the line:

cherrypy.tree.mount(ServeWebApp(), '/webapp', config=CONF_WEBAPP)

inside my folder WEB_ROOT I have an index.html file, and a set of folders {css, js, fonts, img}. I would like to load the index file and all subdirectories inside that folder. Is it possible? Are there another way to get the same result? I can not use another tool to show custom page (like Nginx, apache).

Another method to customize but I could not follow that way because it uses functions


Solution

  • Here is how I solved my problem.

    First I installed lib requests in my virtualenv.

    import requests
    from ConfigParser import RawConfigParser
    config = RawConfigParser()
    #file with my urls I would like to use in my app.
    config.read('myparams.ini')
    
    
    class PlatformAndroid(object):
        android_url = config.get('links', 'android')#static url to play store
        redir = requests.get(android_url)
        if redir.status_code < 400: #case my app is published in play store
            raise cherrypy.HTTPRedirect(android_url)
        #unpublished app
        raise cherrypy.HTTPRedirect(config.get('links','webapp')) #fallback to webapp version of my platform specific app.
    
    if __name__ == '__main__':
    
        cherrypy.tree.mount(PlatformAndroid(), '/android')
    
        cherrypy.engine.start()
        cherrypy.engine.block()
    

    myparams.ini

    [links]
    
    android : http://play.google.com/store/apps/
    ios : http://itunes.apple.com/us/app/
    webapp : http://mysite.example.com/webapp/