cherrypy handle all request with one function or class
Asked Answered
F

3

5

i'd like to use cherrypy but i don't want to use the normal dispatcher, i'd like to have a function that catch all the requests and then perform my code. I think that i have to implement my own dispatcher but i can't find any valid example. Can you help me by posting some code or link ?

Thanks

Foxtrot answered 11/7, 2011 at 23:22 Comment(0)
T
13

make a default function:

import cherrypy

class server(object):
        @cherrypy.expose
        def default(self,*args,**kwargs):
                return "It works!"

cherrypy.quickstart(server())
Tynes answered 13/9, 2011 at 21:32 Comment(1)
Works fine! and helped me too.Restricted
T
2

What you ask can be done with routes and defining a custom dispatcher

http://tools.cherrypy.org/wiki/RoutesUrlGeneration

Something like the following. Note the class instantiation assigned to a variable that is used as the controller for all routes, otherwise you will get multiple instances of your class. This differs from the example in the link, but I think is more what you want.

class Root:
    def index(self):
        <cherrpy stuff>
        return some_variable

dispatcher = None
root = Root()

def setup_routes():
    d = cherrypy.dispatch.RoutesDispatcher()
    d.connect('blog', 'myblog/:entry_id/:action', controller=root)
    d.connect('main', ':action', controller=root)
    dispatcher = d
    return dispatcher

conf = {'/': {'request.dispatch': setup_routes()}}

Hope that helps : )

Torture answered 12/7, 2011 at 1:34 Comment(2)
am i wrong or this solution assume that i already know all the available path when cherrypy start ? this is not my case, i have to query the database every time to find if a particular url is valid and what to displayFoxtrot
Yes it does assume that you already know the paths that you are serving from. If you have those paths in a database you could construct the paths at app startup in the dispatch function. Its hard to give you a full solution without knowing more but you should be able to loop through a cursor and point all paths to your instantiated class. Hopefully your paths are not dynamic. This solution would require an app restart for every path change.Torture
H
1

Here's a quick example for CherryPy 3.2:

from cherrypy._cpdispatch import LateParamPageHandler

class SingletonDispatcher(object):

    def __init__(self, func):
        self.func = func

    def set_config(self, path_info):
        # Get config for the root object/path.
        request = cherrypy.serving.request
        request.config = base = cherrypy.config.copy()
        curpath = ""

        def merge(nodeconf):
            if 'tools.staticdir.dir' in nodeconf:
                nodeconf['tools.staticdir.section'] = curpath or "/"
            base.update(nodeconf)

        # Mix in values from app.config.
        app = request.app
        if "/" in app.config:
            merge(app.config["/"])

        for segment in path_info.split("/")[:-1]:
            curpath = "/".join((curpath, segment))
            if curpath in app.config:
                merge(app.config[curpath])

    def __call__(self, path_info):
        """Set handler and config for the current request."""
        self.set_config(path_info)

        # Decode any leftover %2F in the virtual_path atoms.
        vpath = [x.replace("%2F", "/") for x in path_info.split("/") if x]
        cherrypy.request.handler = LateParamPageHandler(self.func, *vpath)

Then just set it in config for the paths you intend:

[/single]
request.dispatch = myapp.SingletonDispatcher(myapp.dispatch_func)

...where "dispatch_func" is your "function that catches all the requests". It will be passed any path segments as positional arguments, and any querystring as keyword arguments.

Hime answered 12/7, 2011 at 6:12 Comment(4)
Hm, but that won't collect config for you from the Application per URI. I'll see if I can improve the above tomorrow.Hime
uh maybe i'm too newbie but i can't get your example working, see this gist.github.com/1086473 if i call 127.0.0.1:8080 i get the "hello world" message but what i want is handle other urls that i can't determine at startup and the test() function never get called. Is it possible to catch 404 exceptions to handle all the paths ?Foxtrot
Sorry about that. I got the vpath messed up. I've fixed the above.Hime
i've replaced the code in the gist with the new version of your class but it acts exactly like beforeFoxtrot

© 2022 - 2024 — McMap. All rights reserved.