Get a JSON API endpoint and return the parsed data.

        :param url: str, *relative* URL (relative to pp-admin/ api endpoint)
        :param headers: dict (optional)
        :returns: deferred that when fired returns the parsed data from JSON
                  or errbacks with ProductPagesException

def _get(self, url, headers={}):
        """ Get a JSON API endpoint and return the parsed data.

        :param url: str, *relative* URL (relative to pp-admin/ api endpoint)
        :param headers: dict (optional)
        :returns: deferred that when fired returns the parsed data from JSON
                  or errbacks with ProductPagesException
        """
        # print('getting %s' % url)
        headers = headers.copy()
        headers['Accept'] = 'application/json'
        url = posixpath.join(self.url, url)
        try:
            response = yield treq.get(url, headers=headers, timeout=5)
            if response.code != 200:
                err = '%s returned %s' % (url, response.code)
                raise ProductPagesException(err)
            else:
                content = yield treq.json_content(response)
                defer.returnValue(content)
        except Exception as e:
            # For example, if treq.get() timed out, or if treq.json_content()
            # could not parse the JSON, etc.
            # TODO: better handling here for the specific errors?
            # I suspect it's not good to catch Exception with inlineCallbacks
            raise ProductPagesException('treq error: %s' % e.message)