示例#1
0
def api_request(uri, method="GET", data=None, params=None, timeout=4):
    """
    Invoke an API request to the given URI, returning JSON data from the response as a dict.

    :param uri: The request URI.
    :type uri: string
    :param method: The HTTP method, defaults to "GET".
    :type method: string, optional
    :param data: The request body.
    :type data: dict, optional
    :param params: The URL parameters.
    :type params: list, optional
    :param timeout: The request timeout, in seconds.
    :type timeout: float, optional
    :return: The response from the request.
    :rtype: dict
    """
    if params is None:
        params = []

    data = json.dumps(data).encode("utf-8") if data else None

    if params:
        uri += "?{}".format(urlencode([(x, params[x]) for x in params]))

    request = Request(uri, method=method.upper())
    request.add_header("Content-Type", "application/json")

    logger.debug("Making {} request to {} with data: {}".format(
        method, uri, data))

    try:
        response = urlopen(request, data, timeout)
        response_data = response.read().decode("utf-8")

        status_code = response.getcode()
        logger.debug("Response status code: {}".format(status_code))
        logger.debug("Response: {}".format(response_data))

        if str(status_code)[0] != "2":
            raise PyngrokNgrokHTTPError(
                "ngrok client API returned {}: {}".format(
                    status_code, response_data), uri, status_code, None,
                request.headers, response_data)
        elif status_code == 204:
            return None

        return json.loads(response_data)
    except socket.timeout:
        raise PyngrokNgrokURLError(
            "ngrok client exception, URLError: timed out", "timed out")
    except HTTPError as e:
        response_data = e.read().decode("utf-8")

        status_code = e.getcode()
        logger.debug("Response status code: {}".format(status_code))
        logger.debug("Response: {}".format(response_data))

        raise PyngrokNgrokHTTPError(
            "ngrok client exception, API returned {}: {}".format(
                status_code, response_data), e.url, status_code, e.msg, e.hdrs,
            response_data)
    except URLError as e:
        raise PyngrokNgrokURLError(
            "ngrok client exception, URLError: {}".format(e.reason), e.reason)
示例#2
0
def api_request(url, method="GET", data=None, params=None, timeout=4):
    """
    Invoke an API request to the given URL, returning JSON data from the response.

    One use for this method is making requests to ``ngrok`` tunnels:

    .. code-block:: python

        from pyngrok import ngrok

        public_url = ngrok.connect()
        response = ngrok.api_request("{}/some-route".format(public_url),
                                     method="POST", data={"foo": "bar"})

    Another is making requests to the ``ngrok`` API itself:

    .. code-block:: python

        from pyngrok import ngrok

        api_url = ngrok.get_ngrok_process().api_url
        response = ngrok.api_request("{}/api/requests/http".format(api_url),
                                     params={"tunnel_name": "foo"})

    :param url: The request URL.
    :type url: str
    :param method: The HTTP method.
    :type method: str, optional
    :param data: The request body.
    :type data: dict, optional
    :param params: The URL parameters.
    :type params: dict, optional
    :param timeout: The request timeout, in seconds.
    :type timeout: float, optional
    :return: The response from the request.
    :rtype: dict
    """
    if params is None:
        params = []

    if not url.lower().startswith("http"):
        raise PyngrokSecurityError(
            "URL must start with \"http\": {}".format(url))

    data = json.dumps(data).encode("utf-8") if data else None

    if params:
        url += "?{}".format(urlencode([(x, params[x]) for x in params]))

    request = Request(url, method=method.upper())
    request.add_header("Content-Type", "application/json")

    logger.debug("Making {} request to {} with data: {}".format(
        method, url, data))

    try:
        response = urlopen(request, data, timeout)
        response_data = response.read().decode("utf-8")

        status_code = response.getcode()
        logger.debug("Response {}: {}".format(status_code,
                                              response_data.strip()))

        if str(status_code)[0] != "2":
            raise PyngrokNgrokHTTPError(
                "ngrok client API returned {}: {}".format(
                    status_code, response_data), url, status_code, None,
                request.headers, response_data)
        elif status_code == HTTPStatus.NO_CONTENT:
            return None

        return json.loads(response_data)
    except socket.timeout:
        raise PyngrokNgrokURLError(
            "ngrok client exception, URLError: timed out", "timed out")
    except HTTPError as e:
        response_data = e.read().decode("utf-8")

        status_code = e.getcode()
        logger.debug("Response {}: {}".format(status_code,
                                              response_data.strip()))

        raise PyngrokNgrokHTTPError(
            "ngrok client exception, API returned {}: {}".format(
                status_code, response_data), e.url, status_code, e.msg, e.hdrs,
            response_data)
    except URLError as e:
        raise PyngrokNgrokURLError(
            "ngrok client exception, URLError: {}".format(e.reason), e.reason)