Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
supermeter / supermeter / data / http_data.py
Size: Mime:
try:
    from typing import Any, Dict, Optional, Union


except ImportError:
    pass

import sys

from supertenant import consts
from supertenant.supermeter.data.base import BaseData


def any_to_str(value):
    # type: (Any) -> str
    if isinstance(value, str):
        return value
    elif isinstance(value, bytes):
        if sys.version_info[0] >= 3:
            return value.decode("utf-8", "ignore")
        else:
            return str(value)
    elif type(value).__name__ == "unicode":
        return str(value.encode("utf-8", "ignore"))
    else:
        raise ValueError("Can't convert %s to str" % type(value))


class HTTPData(BaseData):
    def __init__(self, resource_type, integration_module):
        # type: (str, str) -> None
        super(HTTPData, self).__init__(resource_type, integration_module)

    def set_path(self, path):
        # type: (str) -> None
        self.set_tag(consts.LABEL_HTTP_PATH, path)

    def set_method(self, method):
        # type: (str) -> None
        self.set_tag(consts.LABEL_HTTP_METHOD, method)

    def set_host(self, host):
        # type: (str) -> None
        self.set_tag(consts.LABEL_HTTP_HOST, host)

    def get_host(self):
        # type: () -> Optional[str]
        return self.get_tag(consts.LABEL_HTTP_HOST)

    def set_params(self, params):
        # type: (str) -> None
        self.set_tag(consts.LABEL_HTTP_PARAMS, params)

    def set_status(self, status):
        # type: (Union[str, int]) -> None
        try:
            intstatus = int(status)
            if 400 <= intstatus <= 511:
                self.mark_error()
            if not isinstance(status, str):
                status = str(status)
        except Exception:
            self.mark_error()

        self.set_tag(consts.LABEL_HTTP_STATUS, str(status))

    def set_user_agent(self, user_agent):
        # type: (str) -> None
        self.set_tag(consts.LABEL_HTTP_USER_AGENT, user_agent)

    def add_header(self, header, value):
        # type: (str, str) -> None
        # Note that we currently don't support multiple values for the same header,
        # although it's a valid HTTP feature.
        self.set_tag(HTTPData.get_header_label(header), str(value))

    def set_headers_from_wsgi_env(self, env):
        # type: (Dict[Any, Any]) -> None
        for header, value in env.items():
            try:
                headerstr = any_to_str(header)
                valuestr = any_to_str(value)
            except Exception:
                continue

            if header.startswith("HTTP_"):
                self.add_header(headerstr[5:], valuestr)

        if "CONTENT_LENGTH" in env:
            self.add_header("content-length", env["CONTENT_LENGTH"])
        if "CONTENT_TYPE" in env:
            self.add_header("content-type", env["CONTENT_TYPE"])

    @staticmethod
    def get_header_label(header):
        # type: (str) -> str
        return "%s.%s" % (consts.LABEL_HTTP_HEADER_PREFIX, header.lower())


class HTTPClientData(HTTPData):
    def __init__(self, integration_module):
        # type: (str) -> None
        super(HTTPClientData, self).__init__(consts.RESOURCE_TYPE_HTTP_CLIENT, integration_module)
        self.set_span_type(consts.SPAN_TYPE_CLIENT_REQUEST)


class HTTPServerData(HTTPData):
    def __init__(self, integration_module):
        # type: (str) -> None
        super(HTTPServerData, self).__init__(consts.RESOURCE_TYPE_HTTP_SERVER, integration_module)
        self.set_span_type(consts.SPAN_TYPE_SERVER_REQUEST)