Dynamic URL with CherryPY MethodDispatcher
Asked Answered
P

2

12

I need to configure a RESTful style URL that support the following URL scheme:

  • /parent/
  • /parent/1
  • /parent/1/children
  • /parent/1/chidren/1

I want to use the MethodDispatcher so that each of the above can have GET/POST/PUT/DELETE functions. I have it working for the first and second, but can't figure out how to configure the dispatcher for the children portion. I have the book, but it barely covers this and I can't find any sample online.

Here is how I have the MethodDispatcher configured currently.

root = Root()
conf = {'/' : {'request.dispatch': cherrypy.dispatch.MethodDispatcher()}}    

cherrypy.quickstart(root, '/parent', config=conf)

Any help would be appreciated.

Panta answered 17/10, 2009 at 14:19 Comment(0)
D
9

http://tools.cherrypy.org/wiki/RestfulDispatch might be what you're looking for.

In CherryPy 3.2 (just now coming out of beta), there will be a new _cp_dispatch method you can use in your object tree to do the same thing, or even alter traversal as it happens, somewhat along the lines of Quixote's _q_lookup and _q_resolve. See https://bitbucket.org/cherrypy/cherrypy/wiki/WhatsNewIn32#!dynamic-dispatch-by-controllers

Darcydarda answered 17/10, 2009 at 15:27 Comment(3)
Perfect. This is exactly what I need, but I couldn't find it because I was focused on MethodDispatcher in my Googling. Thanks.Panta
The link to the Dynamic Dispatch by Controllers link has changed. You can find it here, bitbucket.org/cherrypy/cherrypy/wiki/WhatsNewIn32Royceroyd
Thank you for pointing out the _cp_dispatch method! I found this to be an elegant solution to a similar problem in the structure of my application.Triturable
P
2
#!/usr/bin/env python
import cherrypy

class Items(object):
    exposed = True
    def __init__(self):
        pass

    # this line will map the first argument after / to the 'id' parameter
    # for example, a GET request to the url:
    # http://localhost:8000/items/
    # will call GET with id=None
    # and a GET request like this one: http://localhost:8000/items/1
    # will call GET with id=1
    # you can map several arguments using:
    # @cherrypy.propargs('arg1', 'arg2', 'argn')
    # def GET(self, arg1, arg2, argn)
    @cherrypy.popargs('id')
    def GET(self, id=None):
        print "id: ", id
        if not id:
            # return all items
        else:
            # return only the item with id = id

    # HTML5 
    def OPTIONS(self):                                                      
        cherrypy.response.headers['Access-Control-Allow-Credentials'] = True
        cherrypy.response.headers['Access-Control-Allow-Origin'] = cherrypy.request.headers['ORIGIN']
        cherrypy.response.headers['Access-Control-Allow-Methods'] = 'GET, PUT, DELETE'                                     
        cherrypy.response.headers['Access-Control-Allow-Headers'] = cherrypy.request.headers['ACCESS-CONTROL-REQUEST-HEADERS']

class Root(object):
    pass

root = Root()
root.items = Items()

conf = {
    'global': {
        'server.socket_host': '0.0.0.0',
        'server.socket_port': 8000,
    },
    '/': {
        'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
    },
}
cherrypy.quickstart(root, '/', conf)
Posterity answered 23/4, 2013 at 23:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.