Last updated at Mon, 06 Nov 2017 21:05:01 GMT

REST-API---a-little-cURL-and-some-Python

Here at Logentries work has been going for sometime in bringing to our customers a powerful and flexible REST API service for interaction with their log data. This work started out with the REST Query API and will continue as we expand the API range of services. Previous articles have provided some insight into interacting with the REST APIs using JavaScript and integration testing in a Java environment. In this article I am going to add ‘cURL’ and a Python library to the options for using these APIs, in either building clients or for testing REST API endpoints.

API Keys

API Keys are available via the customer Logentries account – under the API Keys tab – where the required keys are generated. There are a number of different access levels for users of an account depending on the level of read/write access of the key they have. For further information go to the page of the API Keys tab of your account or look here at the Authentication docs page.

urllib2 and Owner Authentication

Due to the way the Owner Authentication signature is generated the use of the urllib2 standard python library is unsuitable. This is because the current date must be used to generate the signature and also needs to be passed as a header. The source code of urllib2 has a hard coded date header which prevents this.

cURL

The cURL command is a very flexible, useful tool to have. As a command line tool it is useful to be able to manually check an endpoint – which is very handy for debugging and manual verification. This is an open source, command-line tool for transferring data and can be used with different protocols. The command can be embedded in scripts or test code to send data to an endpoint and capture the returning response.

In basic form the cURL command looks like this:
curl -i -H "Content-Type: application/json" -H "x-api-key:09ba90f6-dcd0-42c0-8c13-5baa6f2377d0" -X GET https://rest.logentries.com/query/saved_queries
The response in this case looks like this:

    HTTP/1.1 200 OK
    Content-Type: application/json
    Date: Mon, 04 Jul 2016 14:05:21 GMT
    Vary: Accept-Encoding
    X-RateLimit-Limit: 1000
    X-RateLimit-Remaining: 999
    X-RateLimit-Reset: 879
    transfer-encoding: chunked
    Connection: keep-alive

    {"saved_queries":[{"id":"00000000-0001-8850-0000-000000000000","name":"test1","query"{"statement":"where(abc)"}}]}

In this example, the cURL command is being used to get a list of saved queries from an account, using an appropriate key for authentication. The option -i will provide HTTP Header information in the output; for more helpful debugging information use the -v for verbosity option. The -H specifies the addition of an extra header, in this case providing the required authentication information as well as content format. Although the default method is GET, in this example this is explicitly defined with the -X option.

(Python) The Requests Module

At a higher level of abstraction is the very handy python HTTP library ‘Requests’. This does need to be pulled into a project as it’s not a standard python module. The advantage is that a lot of the detail of setting up a HTTP request with ‘urllib3’, which this library uses, is hidden away – the request is simple to create and it returns a response object that allows easy access to the various attributes of interest (status code, headers etc). A good complete example of the use of the Requests module can be found on the Logentries ‘Get Query’ Docs page.

In the following example, to show the ease of using the library, I walk through the steps of making the request in an (iPython) interactive environment.

    $ ipython
    Python 2.7.9 (default, Apr  2 2015, 15:33:21)
    Type "copyright", "credits" or "license" for more information.

    IPython 2.3.0 -- An enhanced Interactive Python.

    In [1]: import requests
    In [2]: url = "https://rest.logentries.com/query/saved_queries"
    In [3]: print url
    https://rest.logentries.com/query/saved_queries

    In [4]: headers={'x-api-key':'09ba90f6-dcd0-42c0-8c13-5baa6f2377d0'}
    In [5]: print headers
    {'x-api-key': '09ba90f6-dcd0-42c0-8c13-5baa6f2377d0'}

    In [6]: resp = requests.get(url,headers=headers)
    In [7]: print resp.status_code
    200

    In [8]: print resp.content
    {"saved_queries":[{"id":"00000000-0001-8850-0000-000000000000","name":"test1","query":{"statement":"where(abc)"}}]}

    In [9]: print resp.
    resp.apparent_encoding  resp.cookies    resp.history               resp.iter_lines  resp.raise_for_status  resp.status_code
    resp.close              resp.elapsed    resp.is_permanent_redirect resp.json        resp.raw               resp.text     
    resp.connection         resp.encoding   resp.is_redirect           resp.links       resp.reason            resp.url
    resp.content            resp.headers    resp.iter_content          resp.ok          resp.request

As seen from the sequence above – [1] the module is imported; [2] a URL string created and [4] headers defined – as shown in the ‘print’ output for each. The [6] ‘requests.get()’ method is called, with the URL and headers passed to it. This returns a response object (resp), which can be interrogated. The print statements show how simple it is for access to the [7] ‘status_code’ and [8] ‘content’ – while in the final line [9] we see the list of attributes of the response object that are available.