Default the root view in cherrypy
Asked Answered
S

3

11

In some source code I am writing, I am able to make a request such as:

http://proxy.metaperl.org/index/bitgold-rw1

And have it redirect successfully.

However, I want to remove index from the URL and have it still redirect by using the index() method. I tried renaming index() to default() after reading about Dispatching, but it still does not allow me to have a URL like this:

http://proxy.metaperl.org/bitgold-rw1

It tries to find a method named bitgold-rw1 instead of using the default method to resolve the request, gving me the error:

NotFound: (404, "The path '/bitgold-rw1' was not found.")

The WSGI startup file looks like this:

# -*- python -*-

# core
import os
import sys

# 3rd party
import cherrypy

# local
def full_path(*extra):
    return os.path.join(os.path.dirname(__file__), *extra)

sys.path.insert(0, full_path())
import config
import myapp

application = cherrypy.Application(
    myapp.Root(),
    "/",
    config.config)
Sixfooter answered 3/9, 2015 at 6:31 Comment(3)
I don't do a lot in cherrypy, but isn't index supposed to be mapping to the site with no subs? i.e. stackoverflow.com as opposed to `stackoverflow.com/questions'?Petro
I think the issue is that CherryPy thinks I am looking for a route http://proxy.metaperl.org/bitgold-rw1 and it can't find it. I think index can have optional parms.Sixfooter
Interesting. I might have an idea of what's going on here. Can you show us the Root class? In particular anything to do with the related methods? That would like help us get an answer.Petro
I
3

Renaming to default is not enough. It needs to be callable at least with variadic arguments, *args, to receive path segments. Like this:

#!/usr/bin/env python3


import cherrypy


config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  }
}


class Root:

  @cherrypy.expose
  def default(self, *args, **kwargs):
    cherrypy.log('{0}, {1}'.format(args, kwargs))
    return 'OK'


if __name__ == '__main__':
  cherrypy.quickstart(Root(), '/', config)

Then it will catch things like http://127.0.0.1:8080/bitgold-rw1/ and also like http://127.0.0.1:8080/bitgold-rw1/foo/bar.

And btw, if it's about MVC it's a controller, not a view.

Insignificancy answered 7/9, 2015 at 12:4 Comment(0)
A
3

As mentioned by @ralhei @saaj default method is the key if you do not want to deal with dispatchers in cherrypy. I tried the code below and working as you want

class Root(object):

    @cherrypy.expose
    def index(self, tag):
        redirect_url = db.urls[tag]
        ip = cherrypy.request.headers['Remote-Addr']
        request_url = 'http://ipinfo.io/{0}/country'.format(ip)
        r = requests.get(request_url)
        country = r.text.strip()
        raise cherrypy.HTTPRedirect(redirect_url)

    @cherrypy.expose
    def default(self,tag):
        return self.index(tag)
Archery answered 9/9, 2015 at 7:18 Comment(0)
G
1

if you rename your index method to 'default' in your Root class this should work.

Add the line

cherrypy.quickstart(Root())

at the bottom of myapp.py and run it with 'python myapp.py' your server should startup and listen on port 8080. Making a request to http://localhost:8080/bitgold-rw1 works for me, it complains that I'm not a US citizen which I guess is fine ;-)

Gerber answered 6/9, 2015 at 13:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.