Fredrik Håård's Blaag

@fhaard
I'm a programmer, consultant, developer, occasional teacher and speaker. Among my least disliked programming languages are Python, and a majority of these posts are related to Python in one way or another.
RSS Feed

Simple REST-ful (-ish) exposure of Python APIs

After having written code to expose APIs through RESTful web services a couple of times, I've decided to do it once more, only this time I won't get paid, I won't have deadlines, I'll write it so I'll never have to write it again, and I'll make it available as open source.

Problem is, I'm a lazy, lazy person, and have not been able to muster the energy to actually get writing, which leads me to this blog post - since I've not been updating the blog as I should either, I'll kill two projects with one meeting and make the actual development process open as well, as a series of blog posts and a repository at BitBucket.

For someone else to be able to follow the work, I obviously have to nail down what the goal of this exercise is:

* Create a tool that can expose a Python API in a RESTish fashion
* The API itself must not have to know about the tool
* It must run on at least CherryPy and two other webapp frameworks TBD (no, not Django)
* It must handle HTTP errors
* It must be able to encode data into JSON before returning it
* It must run on Python 3.2+
* It must not care what the proper definition of RESTful is

In addition, some good-to-haves:

* It may make linking between resources easier (if feasible)
* It may be able to use other data formats than JSON
* It may run on Python 2.7

Because I enjoy working with CherryPy since it's very good at staying out of my way, I'll start out writing for CherryPy and then generalize from there. Just to get started, I have created a minimal CherryPy app to work from, even though I'll split the tool from the framwork (or the REST framework from the web framework?) later. The entire code looks like this

import cherrypy
def requesthandler(*pathargs, **kwargs):
    cherrypy.response.status = "500 Server Error"
    return "Not implemented"
class PyRest(object):
    def index(self, *args, **kwargs):
        return requesthandler(*args, **kwargs)
    index.exposed = True
CONF = {
    'global': {
        'server.socket_host': '0.0.0.0',
        'server.socket_port': 8888,
    }
}
if __name__ == '__main__':
    ROOT = PyRest()
    cherrypy.quickstart(ROOT, '/', CONF)
def application(environ, start_response):
  cherrypy.tree.mount(PyRest(), '/', None)
  return cherrypy.tree(environ, start_response)
Blaag created 121206 20:25
blog comments powered by Disqus


Page created using blaag and abusing docutils. RSS Feed generated using PyRSS2Gen.