Search code examples
pythonhttpclienttornado

How to write a common API client for Tornado and non-Tornado services


I have a web-service that exposes some API. I want to use this API in two applications, one is a command-line tool, and another is a web-server itself.

For the web-server, I am using Python tornado, so I am able to use AyncHttpClient, gen.coroutine, etc. But for the CLI, I can not use tornado since it needs an IOLoop to be running for async to work.

I am looking to create a kind of library that talks to the API, and re-use this library in CLI as well as web-service. This means that I should be able to write (possibly tornado gen) code on top of its functions to make it async.


Solution

  • Why not use an IOLoop in your CLI tool?

    @gen.coroutine
    def main():
        client = AsyncHTTPClient()
        response = yield client.fetch('http://www.google.com')
    
    if __name__ == '__main__':
        IOLoop.instance().run_sync(main)
    

    There's also the synchronous tornado.httpclient.HTTPClient which uses the same request and response objects as AsyncHTTPClient.

    If you want to be HTTP-client-agnostic then you'll need to follow the example of oauthlib. Provide a base client that speaks in terms of HTTP headers and response bodies, and separately provide bindings from that client to various implementations like requests-oauthlib. (or just release the base client and expect your callers to figure out the mapping to their own HTTP implementation)