Brendel Consulting logo

Brendel Consulting

composing beautiful software solutions

Aug 3, 2010

Easy to use, flexible HTTP access method in Python

Python comes with 'batteries included' as they like to say. This means that libraries for most tasks you need to tackle are already part of a standard Python install. In order to issue HTTP requests, the most common libraries mentioned are urllib and urllib2. They offer the very convenient urlopen() function, which make it a snap to quickly retrieve online resources.

One thing that always bothered me, however, was the inflexibility of those methods. Want to use PUT instead of POST? Out of luck. Need authentication? Deal with pesky URLopener classes. Want timeouts for your requests? Use global socket options or use Python 2.6. Want to specify some custom headers? Deal with more classes. And so on.

All I want is a simple function like urlopen(), which can do all of these things for me and which also works on Python 2.5 (I'm often using Jython, which still is at 2.5). Of course, there is always the low level httplib, on top of which the two urllibs actually build. And while using that library requires a few more steps, you can use it to write yourself your powerful, simple version of urlopen().

So, for RESTx - an open source project to simply and easily create RESTful web services - I wrapped all the functionality I wanted into a convenient, compact function that uses httplib directly. Currently, it only supports HTTP's basic authentication, but hopefully that can be extended at some point in the future.

Here it is then for your enjoyment. Let me know if you think this is useful. Oh, and while you are here, please follow me on Twitter.

Update: Several people pointed out httplib2 to me, which offers a lot of the convenience I was looking for. However, it is not available in Jython, or Python 2.5 in general.

import httplib
import urllib
import socket
import urlparse

def http_access(method, url, data=None, headers=None, timeout=None, credentials=None):
"""
Access an HTTP resource with GET or POST.

@param method: The method for the HTTP request: GET, POST, etc.
@type method: string

@param url: The URL to access.
@type url: string

@param data: If present it specifies the data for a POST or PUT request.
@type data: Data to be sent or None.

@param headers: A dictionary of additional HTTP request headers or None.
@type headers: dict

@param timeout: Timeout for the request in seconds, or None. Specified as
floating point value, so you can set sub-second timeouts.
@type timeout: float

@param credentials: A username/password tuple to support basic HTTP authentication.
@type credentials: tuple

@return: Code and response data tuple.
@rtype: tuple

"""
(scheme, host_port, path, params, query, fragment) = urlparse.urlparse(url)
allpath = url[url.index(host_port)+len(host_port):]
host, port = urllib.splitport(host_port)

if not headers:
headers = dict()

if credentials:
accountname, password = credentials
headers["Authorization"] = "Basic " + base64.encodestring('%s:%s' % (accountname, password))[:-1]

if scheme == 'https':
conn = httplib.HTTPSConnection(host, port)
else:
conn = httplib.HTTPConnection(host, port)

conn.request(method, allpath, data, headers)
conn.sock.settimeout(timeout)

try:
resp = conn.getresponse()
code = resp.status
data = resp.read()
except socket.timeout, e:
return 408, httplib.responses[408]

return code, data



if __name__ == '__main__':
# Some usage example: Getting data in JSON format from a ficticious server with
# a timeout of 0.5 seconds.
status, data = http_access("GET", "http://localhost:8001", data = None,
headers = { "Accept" : "application/json" }, timeout=0.5 )

print "@@@ HTTP response code: ", status
print "@@@ Received data: ", data


Labels: , , , , , , ,

 
 

Jul 1, 2010

A new, simpler way to create RESTful resources

Lately, I have been working on a new project called RESTx. A new, simpler way to do data integration and data publishing. Fully open source and licensed under GPLv3, fully RESTful, super simple to install and use. The download is small - just over 200k - and installation is deliberately quick and straight forward; a single command sets it all up for you. So I would like to invite you to have a look and check it out. I'd love to get your feedback and opinion on it.

What is it about?
RESTx gives developers the ability to quickly write custom data access and integration logic as components. Writing those components is very simple, the API is compact to the point where you could probably explain it in just 5 minutes. At the same time it gives you all the freedom you'd get in a custom program or script. You can even chose the language for writing components (Java and Python are currently supported, more to come).

Any component parameters are exposed, so that users can post new parameter sets to the component in order to create a new RESTful resource or RESTful web service in just seconds, simply by filling out a form in a browser. The RESTful resources are then accessed via a simple URL, suitable for access by end users in a browser, sharing, building bocks for mashups, and so on. The ability to create RESTful resources without any coding allows users to quickly build their own data sources without having to wait for IT to provide them.

There are a few key ideas behind RESTx, and they mostly center around being nice and simple:

Be nice to developers
Why fiddle with 300 lines of obscure XML if you can express the same idea in just 3 lines of concise, easy to read code? This is one of the core concepts for developers: Convention over configuration and sane defaults. If you need custom integration or data access logic, it will be much quicker for you to create a new component and express this concisely in a language you know, rather than work your way through yet another XML dialect.

For component development, RESTx currently supports Java and Python, more languages to be added soon. Writing custom data integration and access code is absolutely simple. The entire API can easily be explained in 5 minutes. If you think proper frameworks are too heavy and think you're faster just with a quick adhoc hack... don't! RESTx is simpler and quicker than adhoc hacking, but gives you all the advantages of a proper platform.

Be nice to users
Allow users to create their own RESTful data resource without coding by sending a new set of parameters to components on the RESTx server. That turns into an easy to share and use URL, totally hiding the component and parameters.

Users can discover all the available components (for which they can provide parameters to create a resource) and all existing resources (which they can use), simply by following links. Components and resources explain themselves: Each of them has human readable documentation strings and all their parameters and provided services can be discovered.

Be nice to search engines, web browsers and client applications
Everything on the server (components and resources) can be discovered just by following links. You get human AND machine readable descriptions, which is great for discovery by search engines.

RESTx automatically represents data in a way that matches the client request. For example, if you access a resource via a web browser, you get the information in HTML. If you access it with another client application, you can request to see the very same data in JSON, for example. In fact, all interactions with the server take place via a simple RESTful API, which allows the usage as well as creation of resources via simple, JSON encoded requests.


A few links you might be interested in:
Please enjoy! Hopefully, you will find this project useful. I am looking forward to your feedback.

Labels: , , , , , , , ,