def xJson(id=None):
    if id is None:
        url = 'http://xkcd.com/info.0.json'
    else:
        url = 'http://xkcd.com/' + str(id) + '/info.0.json'

    try:
        request = urllib.request.Request(url, headers={"User-Agent":
                                                       "Sublime Xkcd"})
        #opener = urllib.request.build_opener()
        global opener
        f = opener.open(request)
        result = json.loads(f.read().decode("utf-8"))

        return result

    except urllib.error.HTTPError as e:
        sublime.error_message(
            'Xkcd: %s: HTTP error %s contacting API' % (__name__, str(e.code)))
    except urllib.error.URLError as e:
        sublime.error_message(
            'Xkcd: %s: URL error %s contacting API' % (__name__, str(e.reason)))
Test Porter service request response of echo non blocking
dataset/ETHPy150Open eivind88/xkcd/xkcd.py/xJson--crossover with--dataset/ETHPy150Open ioflo/ioflo/ioflo/aio/http/test/test_serving.py/BasicTestCase.testPorterServiceEcho