cloudant-labs / cloudant-python

Asynchronous Cloudant / CouchDB interface for Python
http://cloudant-labs.github.io/cloudant-python/
37 stars 17 forks source link

AuthSession not cached (was 'Q: best practice for caching AuthSession') #51

Open snowch opened 9 years ago

snowch commented 9 years ago

Currently I am working with a codebase that calls login for each API request. However, it would be more efficient if a login call was made only when necessary.

What is the best practice for caching the AuthSession cookie when using cloudant-python library so that a login call does not need to be made unless the cached AuthSessoin cookie does not exist, or has expired or an API call results in 401 - Unauthorized?

Many thanks.

snowch commented 9 years ago

One option is to use nginx to manage the session, e.g. https://github.com/greenmangaming/cloudant-nginx

snowch commented 9 years ago

I've shifted focus from reusing the session to reusing the http connection with basic authentication.

I've done a little bit of digging around and I'm thinking that a requests.adapters.HTTPAdapter could be shared between request executions. This seems to work. Is it safe?


#!/usr/bin/env python

import cloudant
import logging
from requests.adapters import HTTPAdapter

logging.basicConfig()
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

httpAdapter = HTTPAdapter(pool_connections=10, pool_maxsize=100)

auth=tuple(open('./PASSWORD').read().rstrip().split(':'))

def make_request(share_http_adapter):

    account = cloudant.Account('someaccount', async=False)

    if share_http_adapter == 'true':
        account._session.adapters['https://'] = httpAdapter

    aaccount._session.auth = auth

    db = account.database('somedb')

    response = db.get('/someurl...')
    response.raise_for_status()

print "shared http adapter = true"
make_request(share_http_adapter='false')
make_request(share_http_adapter='false')
print 
print "shared http adapter = false"    
make_request(share_http_adapter='true')
make_request(share_http_adapter='true')

The above outputs:

shared http adapter = true
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): someaccount.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET /someurl ...
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): someaccount.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET someurl ...

shared http adapter = false
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): someaccount.cloudant.com
DEBUG:requests.packages.urllib3.connectionpool:"GET someurl ...
DEBUG:requests.packages.urllib3.connectionpool:"GET someurl ...

Notice that the first output block shows two HTTPS connections being opened and only one in the second block.