Search code examples
pythonpython-2.7cherrypy

How to organize a multiple apps server with CherryPy?


I'm developping multiple webservices with CherryPy. Some of them have to use the same code parts, so I'd want to avoid code duplication.

I'd want the CherryPy WebServer to serve all the applications, mounted on different urls.

This is how I organized my file hierarchy (it's a simplified version of course):

apps/
    server.py  -- runs the WSGI Server
    app1/
        api/
        lib/
        ext/
        app.py  -- provides a function get_wsgi_app(name, config)
    app2/
        api/
        lib/
        ext/
        app.py
    common/  -- All common classes and modules

Consider that server.py is the entry point. It imports each app.py and get a WSGI application from it. Then it mounts them to be served.

I'd want to be able to import some classes from common/ but without altering multiple times sys.path. So I tought I may be able to import the needed modules in ext. And when I need them in an app I'd just have to make an import like :

from ext.share_module import class

1 - Do you think the file hierarchy is fine?

2 - I'd want each app to be independent from the server and the other apps. So, for the import I'd want to be able to simply consider that app1/ is the root folder and not apps/ . But because server.py is the entry point, I can't import the modules like I want.

3 - Any suggestion, consideration or advice ? :)


Solution

  • OK here's the solution I ended up with. It is almost the same that in the question.

    apps/
        server.py  -- runs the WSGI Server
        app1/
            api/  -- contains the business logic
            controller/  -- makes the interface between HTTP and the API
            lib/
            model/
            app.py  -- provides a function get_wsgi_app(name, config, app_instance_name)
            url.py  -- like django, makes a binding between urls and controller
        app2/
            -- same as app1
        common/  -- All common classes and modules. Folders are the same that apps. 
            api/
            controller/
            lib/   
            model/
    configs/
        app1.cfg
        app2.cfg 
        server.cfg
    

    How does it works :

    server.py is the entry point. His role is to start the WSGI Server and mount the WSGI Applications. app.py instanciates the application and loads it's config. (you can have multiple instance of app1)

    urls.py contains the application's URLs.

    When I need to import a module, I just use an absolute import starting from the app folder.

    Ex :

    from app1.api.my_module import API
    from common.api.login_api import LoginAPI
    
    class Foo():
        ...
    

    I never tried to use relative imports because I prefer when it is explicit, especially in that case where the folders are often named the same.