Search code examples
pythonpython-2.7openshiftcherrypy

Importing CherryPy fails on openshift


I'm running a cherrypy based app on an openshift gear. Recently I've been getting a "503 service temporarily unavailable" error whenever I try to go to the site. Inspecting the logs, I see I'm getting an ImportError where I try to import CherryPy. This is strange - CherryPy is listed as a dependency in my requirements.txt and used to be imported just fine. I double checked to make sure I'm getting the right path to the openshift activate_this.py and it seems to be correct. I'm not quite sure where to look next; any help would be appreciated. Thanks!

The failed import is at line 14 of app.py:

import os
import files


virtenv = os.path.join(os.environ['OPENSHIFT_PYTHON_DIR'], 'virtenv')
virtualenv = os.path.join(virtenv, 'bin', 'activate_this.py')
conf = os.path.join(files.get_root(), "conf", "server.conf")
try:
    execfile(virtualenv, dict(__file__=virtualenv))
    print virtualenv
except IOError:
    pass

import cherrypy
import wsgi


def mount():
    def CORS():
        cherrypy.response.headers["Access-Control-Allow-Origin"] = os.environ['OPENSHIFT_APP_DNS']

    cherrypy.config.update({"tools.staticdir.root": files.get_root()})
    cherrypy.tools.CORS = cherrypy.Tool('before_handler', CORS)
    cherrypy.tree.mount(wsgi.application(), "/", conf)


def start():
    cherrypy.engine.start()


def end():
    cherrypy.engine.exit()

if __name__ == "__main__":
    mount()
    start()

UPDATE

I eventually saw (when pushing to the openshift repo using git bash CLI) that the dependency installation from requirements.txt was failing with some exceptions I haven't bothered to look into yet. It then goes on to try to install dependencies in setup.py, and that works just fine.

Regarding the port in use issue...I have no idea. I changed my startup from tree.mount and engine.start to quickstart, and everything worked when I pushed to openshift. Just for kicks (and because I need it to run my tests), I switched back to cherrypy.tree.mount, pushed it, and it worked just fine.

Go figure.


Solution

  • I use the app.py entry point for Openshift. Here are several examples on how I start my server using the pyramid framework on Openshift. I use waitress as the server but I have also used the cherrypy wsgi server. Just comment out the code you don't want.

    app.py

    #Openshift entry point
    
    import os
    
    from pyramid.paster import get_app
    from pyramid.paster import get_appsettings
    
    
    if __name__ == '__main__':
        here = os.path.dirname(os.path.abspath(__file__))
    
        if 'OPENSHIFT_APP_NAME' in os.environ:                                          #are we on OPENSHIFT?
            ip = os.environ['OPENSHIFT_PYTHON_IP']
            port = int(os.environ['OPENSHIFT_PYTHON_PORT'])
            config = os.path.join(here, 'production.ini')
        else:
            ip = '0.0.0.0'                                                              #localhost
            port = 6543
            config = os.path.join(here, 'development.ini')
    
        app = get_app(config, 'main')                                                   #find 'main' method in __init__.py.  That is our wsgi app
        settings = get_appsettings(config, 'main')                                      #don't really need this but is an example on how to get settings from the '.ini' files
    
    # Waitress (remember to include the waitress server in "install_requires" in the setup.py)
        from waitress import serve
        print("Starting Waitress.")
        serve(app, host=ip, port=port, threads=50)
    
    # Cherrypy server (remember to include the cherrypy server in "install_requires" in the setup.py)
    #     from cherrypy import wsgiserver
    #     print("Starting Cherrypy Server on http://{0}:{1}".format(ip, port))
    #     server = wsgiserver.CherryPyWSGIServer((ip, port), app, server_name='Server')
    #     server.start()
    
    
    #Simple Server
        # from wsgiref.simple_server import make_server
        # print("Starting Simple Server on http://{0}:{1}".format(ip, port))
        # server = make_server(ip, port, app)
        # server.serve_forever()
    
    #Running 'production.ini' method manually.  I find this method the least compatible with Openshift since you can't
    #easily start/stop/restart your app with the 'rhc' commands. Mabye somebody can suggest a better way :)
    
    # #Don't forget to set the Host IP in 'production.ini'.  Use 8080 for the port for Openshift
    # You will need to use the 'pre_build' action hook(pkill python) so it stops the existing running instance of the server on OS
    # You also will have to set up another custom action hook so rhc app-restart, stop works.
    # See Openshifts Origin User's Guide  ( I have not tried this yet)
    
    #Method #1
        # print('Running pserve production.ini')
        # os.system("pserve production.ini &")
    
    #Method #2
        #import subprocess
        #subprocess.Popen(['pserve', 'production.ini &'])