Home:ALL Converter>Cherrypy routing with WSGI

Cherrypy routing with WSGI

Ask Time:2015-07-01T01:13:31         Author:hyprnick

Json Formatter

I'm trying to route certain URLs to a grafted WSGI app and also route sub URLs to a normal cherrypy page handler.

I need the following routes to work. All the other routes should return 404.

  • /api -> WSGI
  • /api?wsdl -> WSGI
  • /api/goodurl -> Page Handler
  • /api/badurl -> 404 Error

The WSGI app mounted at /api is a legacy SOAP based application. It needs to accept ?wsdl parameters but that is all.

I'm writing a new RESTful api at /api/some_resource.

The issue I'm having is that if the resource doesn't exist, it ends up sending the bad request to the legacy soap application. The final example "/api/badurl" ends up going to the WSGI app.

Is there a way to tell cherrypy to only send the first two routes to the WSGI app?

I wrote up a simple example of my issue:

import cherrypy

globalConf = {
    'server.socket_host': '0.0.0.0',
    'server.socket_port': 8080,
}
cherrypy.config.update(globalConf)

class HelloApiWsgi(object):
    def __call__(self, environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return ['Hello World from WSGI']

class HelloApi(object):
    @cherrypy.expose
    def index(self):
        return "Hello from api"

cherrypy.tree.graft(HelloApiWsgi(), '/api')
cherrypy.tree.mount(HelloApi(), '/api/hello')

cherrypy.engine.start()
cherrypy.engine.block()

Here's some unit tests:

import unittest
import requests

server = 'localhost:8080'

class TestRestApi(unittest.TestCase):

    def testWsgi(self):
        r = requests.get('http://%s/api?wsdl'%(server))
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.text, 'Hello World from WSGI')

        r = requests.get('http://%s/api'%(server))
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.text, 'Hello World from WSGI')

    def testGoodUrl(self):
        r = requests.get('http://%s/api/hello'%(server))
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.text, 'Hello from api')

    def testBadUrl(self):
        r = requests.get('http://%s/api/badurl'%(server))
        self.assertEqual(r.status_code, 404)

Outputs:

nosetests test_rest_api.py
F..
======================================================================
FAIL: testBadUrl (webserver.test_rest_api.TestRestApi)
----------------------------------------------------------------------
Traceback (most recent call last):
  File line 25, in testBadUrl
    self.assertEqual(r.status_code, 404)
AssertionError: 200 != 404
-------------------- >> begin captured stdout << ---------------------
Hello World from WSGI

Author:hyprnick,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/31144371/cherrypy-routing-with-wsgi
yy