Alex headshot

AlBlue’s Blog

Macs, Modularity and More

HTTPie

2012

I came across HTTPie today, a Python-based command line utility for executing HTTP requests in a sane way. I’m pretty sure this is going to become a regular in my day-to-day toolbox of utilities.

Installing it onto a decent operating systems is pretty easy:

```sh Installing HTTPie $ sudo easy_install pip $ sudo pip install -U httpie


Once it had downloaded the pre-requisites, it gives you a utility which
you can use to see output from HTTP requests, be able to supply parameters,
and colourise the output.

```sh Example
$ http GET https://www.googleapis.com/discovery/v1/apis/
HTTP/1.1 200 OK
Expires: Thu, 08 Mar 2012 16:56:17 GMT
Date: Thu, 08 Mar 2012 16:51:17 GMT
Cache-Control: public, max-age=300, must-revalidate, no-transform
ETag: "H6ld74DKed8AAlT0jfgIC1JiBUc/n78e9I7ZrCSK0CfSxKuC-JZ9LRI"
Content-Type: application/json; charset=UTF-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Transfer-Encoding: chunked

{
    "discoveryVersion": "v1",
    "items": [
        {
            "description": "Gives AdSense publishers access to their inventory and the ability to generate reports",
            "discoveryLink": "./apis/adsense/v1/rest",
            "discoveryRestUrl": "https://www.googleapis.com/discovery/v1/apis/adsense/v1/rest",
        ...
    ],
    "kind": "discovery#directoryList"
}

The colours won’t show up correctly here – but if you run this in a shell then you’ll notice that the output is coloured appropriately.

In the example above, I used https because the server requires it. If you’re just using it over HTTP you don’t need to specify the prefix:

```sh Accesssing with HTTP $ http GET www.googleapis.com/discovery/v1/apis/ HTTP/1.1 403 Forbidden Content-Type: application/json; charset=UTF-8 Date: Thu, 08 Mar 2012 16:59:26 GMT Expires: Thu, 08 Mar 2012 16:59:26 GMT Cache-Control: private, max-age=0 X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block Server: GSE Transfer-Encoding: chunked

{ “error”: { “code”: 403, “errors”: [ { “domain”: “global”, “message”: “SSL is required to perform this operation.”, “reason”: “sslRequired” } ], “message”: “SSL is required to perform this operation.” } }


If you want to send other data to the server, you can specify key=value pairs
which can be sent via a multi-part form encoded (`--form`) or encoded as a
JSON object.

```sh Asking DuckDuckGo about ZFS
http --form POST duckduckgo.com q=zfs format=json
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 08 Mar 2012 17:11:18 GMT
Content-Type: application/x-javascript; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Thu, 08 Mar 2012 17:11:19 GMT
Cache-Control: max-age=1
Content-Encoding: gzip

{"Definition":"ZFS A distributed file system from Sun that
was added to OpenSolaris in 2005 and Solaris 10 in 2006 ...}

If the result is a JSON type (but not declared as JavaScript) then you can use the --pretty to format the results in an indented fashion.

Finally, if you need to specify specific headers, then you can pass them in as well, by using : as a separator instead of = (enclosing in quotes if there are spaces):

sh Passing in custom headers $ http GET alblue.bandlem.com "If-Modified-Since: Thu, 08 Mar 2012 17:30:07 GMT" HTTP/1.1 304 Not Modified Date: Thu, 08 Mar 2012 17:30:18 GMT Server: Apache/2.2.9 (Debian) mod_ssl/2.2.9 OpenSSL/0.9.8g ETag: "4e10073-41b6-4baaec4d1c400" Cache-Control: max-age=172800, public, must-revalidate

This is a newly released tool but I think it’s going to gain in popularity a lot, over existing wget and curl style interfaces which are often pretty clunky.