Source code for fdi.pns.jsonio

# -*- coding: utf-8 -*-
from ..dataset.serializable import serialize
from ..dataset.deserialize import deserialize
from ..utils.common import lls

import logging
import copy
import base64
import json

# HTTPConnection.debuglevel = 1


import sys
if sys.version_info[0] > 2:
    #from urllib.parse import urlencode
    from urllib.request import urlopen
    from urllib.parse import urlsplit
    from urllib.error import HTTPError
    import requests
    from http.client import HTTPConnection
else:
    #from urllib import urlencode
    from urllib2 import urlopen
    from urlparse import urlsplit
    from urllib2 import HTTPError
    from httplib import HTTPConnection

logger = logging.getLogger(__name__)
#logger.debug('level %d' % (logger.getEffectiveLevel()))
#print('level %d' % (logger.getEffectiveLevel()))

if 0:
    print(logger.propagate)
    print(logger.disabled)
    print(logger.filters)
    print(logger.hasHandlers())
    print(logger.handlers)
    print(logger.level)


commonheaders = {
    'Accept': 'application/json',
    'Accept-Charset': 'utf-8',
    'Accept-Encoding': 'identity',
    'SameSite': 'Strict',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    "Content-type": 'application/json'
}


[docs]def auth_headers(username=None, password=None, headers=None): """Generate HTTP header with auth. Parameters ---------- username : str user name. Default is `None`. password : str Password. Set both `username` and `password` to `None` to use the values in `pnconfig["node"]`. headers : dict key-values of HTTP headers, Default is `None` for using `jsonio.commonheaders`. Examples -------- FIXME: Add docs. """ if headers is None: headers = copy.copy(commonheaders) if username is None and password is None: return headers up = bytes((username + ':' + password).encode('ascii')) code = base64.b64encode(up).decode("ascii") headers.update({'Authorization': 'Basic %s' % (code)}) return headers
[docs]def getJsonObj(url, headers=None, usedict=True, int_key=False, **kwds): """ return object from url. url can be http or file. :int_key: translate keys from string to int if `True` Raise exception if fails. Not using requests.get() as it cannot open file:/// w/o installing https://pypi.python.org/pypi/requests-file """ logger.debug('url: %s' % (url)) stri = urlopen( url, timeout=15).read().decode('utf-8') #logger.debug('stri ' + stri) # print(url,stri) # ret = json.loads(stri, parse_float=Decimal) # ret = json.loads(stri, cls=Decoder, # object_pairs_hook=collections.OrderedDict) ret = deserialize(stri, usedict=usedict, int_key=int_key, **kwds) #logger.debug(pformat(ret, depth=6)[:] + '...') logger.debug(lls(str(ret), 160)) return ret
# def jsonREST(url, obj, headers, cmd): # """ generic RESTful command handler for POST, PUT, and DELETE. # """ # js = serialize(obj) # # %s obj %s headers %s' % (url, obj, headers)) # logger.debug(url + lls(js, 160)) # i = 1 # while True: # try: # if 0 and sys.version_info[0] > 2: # if cmd == 'POST': # r = requests.post( # url, data=js, headers=headers, timeout=15) # elif cmd == 'PUT': # r = requests.post( # url, data=js, headers=headers, timeout=15) # elif cmd == 'DELETE': # r = requests.post( # url, data=js, headers=headers, timeout=15) # else: # raise ValueError('Bad REST command ' + cmd) # stri = r.text # else: # o = urlsplit(url) # u = o.netloc # p = o.path + '?' + o.query + '#' + o.fragment # h = HTTPConnection(u, timeout=15) # h.request(cmd, p, js, headers) # r = h.getresponse() # stri = r.read() # # print('ps textx %s\nstatus %d\nheader %s' % (stri, r.status_code, r.headers)) # break # except Exception as e: # logger.debug(e) # if i >= 1: # logger.error("Give up %s %s after %d tries." % (cmd, url, i)) # return None # else: # i += 1 # # ret = json.loads(stri, parse_float=Decimal) # # ret = json.loads(stri, cls=Decoder) # ret = deserialize(stri) # logger.debug(str(ret)[:160] + '...') # return ret
[docs]def postJsonObj(url, obj, headers): """ posts object to url. Returns None if fails. """ return jsonREST(url, obj, headers, 'POST')
[docs]def putJsonObj(url, obj, headers): """ puts object to url. Returns None if fails. """ return jsonREST(url, obj, headers, 'PUT')
[docs]def deleteJsonObj(url, obj, headers): """ deletes object from url. Returns None if fails. """ return jsonREST(url, obj, headers, 'DELETE')
[docs]def writeJsonObj(o, fn): """ Write an object to file fn in json safely Return True if successful else False """ for i in range(5): try: f = open(fn, 'w') except OSError: logger.warn('unable to open %f for writing. %d' % (fn, i)) if i == 5: logger.error('unable to open %f for writing.' % (fn)) return False json.dump(o, f) f.close() return True