Welcome, guest | Sign In | My Account | Store | Cart

You want to create a simple browser-based desktop application with minimal fuss.

Python, 28 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import cherrypy

class Root(object):
    @cherrypy.expose
    def index(self):
        return "Hello, world! <br /><a href='stop'>Stop</a>"
    # index.exposed = True # for python < 2.4

    @cherrypy.expose
    def stop(self):
        raise SystemExit
    # stop.exposed = True

if __name__ == '__main__':

    import webbrowser

    cherrypy.root = Root()

    cherrypy.config.update({
            'server.environment':'production',
            'server.socketHost':'127.0.0.1',
            })

    cherrypy.server.start_with_callback(
            webbrowser.open,
            ('http://localhost:8080',),
            )

The browser is an attractive UI target for an application for many reasons. This recipe shows you how to use CherryPy and the standard library module 'webbrowser' to create a simple 'Hello, World' browser-based application.

First, we create a class that exposes index() and stop() methods. Second, we bind an instance of our Root class to cherrypy.root and configure our server to run in production mode and only accept connections on the loopback interface. Third, and finally, we start cherrypy with start_with_callback() and specify 'webbrowser.open' as the callback function. This launches the application server and then the browser as the user interface.

Though not fleshed out here, persistence can be added with ease using the standard module shelve, a database, CSV files, etc. Even though CherryPy uses a threaded server by default, synchronization of the datasource shouldn't be much of a concern as we are dealing with a single-user desktop application. To be on the safe side, you can set 'server.threadPool':1 to have a single request handler thread.

This recipe should be cross platform, as both CherryPy and the webbrowser module run in Windows and Unix environments. For Windows platforms, it should also be possible to bundle the application as an 'exe' file using Py2exe.

For more information on CherryPy, see http://www.cherrypy.org

4 comments

Terry Brown 16 years, 5 months ago  # | flag

Update for CherryPy 3.0.2. Here's a version that works for me with CherryPy 3.0.2, the above doesn't work in 3.0.2, but was very helpful.

import cherrypy

class Root(object):
    @cherrypy.expose
    def index(self):
        return "Hello, world!
Stop"

    @cherrypy.expose
    def stop(self):
        raise SystemExit

if __name__ == '__main__':

    import webbrowser

    cherrypy.config.update({'server.socket_port':8888})

    cherrypy.tree.mount(Root(), '/')

    cherrypy.server.quickstart()

    cherrypy.engine.start_with_callback(
            webbrowser.open,
            ('http://131.212.123.122:8888/',),
            )
    cherrypy.engine.block()
Terry Brown 16 years, 5 months ago  # | flag

whoops, mangled markup, here's the code again.

import cherrypy

class Root(object):
    @cherrypy.expose
    def index(self):
        return "Hello, world! &lt;br />&lt;a href='stop'>Stop&lt;/a>"

    @cherrypy.expose
    def stop(self):
        raise SystemExit

if __name__ == '__main__':

    import webbrowser

    cherrypy.config.update({'server.socket_port':8888})

    cherrypy.tree.mount(Root(), '/')

    cherrypy.server.quickstart()

    cherrypy.engine.start_with_callback(
            webbrowser.open,
            ('http://131.212.123.122:8888/',),
            )
    cherrypy.engine.block()
Terry Brown 16 years, 4 months ago  # | flag

A more graceful exit. Here's another idea:

@cherrypy.expose">class="prettyprint">@cherrypy.expose
def stop(self):
    cherrypy.response.headers['Content-Type'] = 'text/plain'
    def content():
        yield 'App. has closed'
        raise SystemExit
    return content()
stop._cp_config = {'response.stream': True}

This defines stop as a streaming method as described here: http://www.cherrypy.org/wiki/ReturnVsYield This gives you a chance to tell the user the application's ended, rather than just a "can't access page" error as provided by the original.

f.occhipinti 12 years, 2 months ago  # | flag

This works for me on cherrypy 3.2.2. cherrypy.server.quickstart is not accepted, config.update is not needed, and the ip address for the browser should be localhost. However, this is a very useful receipe. This should be on cherrypy official docs.

import cherrypy
class Root(object):
    def index(self):
        return 'Hello'
    index.exposed = True

def start():
    import webbrowser
    cherrypy.tree.mount(Root(), '/')
    cherrypy.engine.start_with_callback(
        webbrowser.open,
        ('http://localhost:8080/',),
        )
    cherrypy.engine.block()

if __name__=='__main__':
    start()