Example – Handling Errors¶
It may be desirable to have uniform error-handling code for many routes.
We can do this with Klein.handle_errors
.
Below we have created a class that will translate NotFound
exceptions into a custom 404 response.
from klein import Klein
class NotFound(Exception):
pass
class ItemStore:
app = Klein()
@app.handle_errors(NotFound)
def notfound(self, request, failure):
request.setResponseCode(404)
return 'Not found, I say'
@app.route('/droid/<string:name>')
def droid(self, request, name):
if name in ['R2D2', 'C3P0']:
raise NotFound()
return 'Droid found'
@app.route('/bounty/<string:target>')
def bounty(self, request, target):
if target == 'Han Solo':
return '150,000'
raise NotFound()
if __name__ == '__main__':
store = ItemStore()
store.app.run('localhost', 8080)
The following cURL commands (and output) can be used to test this behaviour:
curl -L http://localhost:8080/droid/R2D2
Not found, I say
curl -L http://localhost:8080/droid/Janeway
Droid found
curl -L http://localhost:8080/bounty/things
Not found, I say
Example - Catch All Routes¶
A simple way to create a catch-all function, which serves every URL that doesn’t match a route, is to use a path
variable in the route.
from klein import Klein
class OnlyOneRoute:
app = Klein()
@app.route('/api/<path:catchall>')
def catchAll(self, request, catchall):
request.redirect('/api')
@app.route('/api')
def home(self, request):
return 'API Home'
@app.route('/api/v1')
def v1(self, request):
return 'Version 1 - Home'
if __name__ == '__main__':
oneroute = OnlyOneRoute()
oneroute.app.run('localhost', 8080)
Use cURL to verify that only /api
and /api/v1
return content, all other requests are redirected:
curl -L http://localhost:8080/api
API Home
curl -L localhost:8080/api/v1
Version 1 - Home
curl -L localhost:8080/api/another
API Home
This method can also be used on the root route, in which case it will catch every request which doesn’t match a route.