Python: 获取 urllib3 请求 headers

Python: fetching urllib3 request headers

我们正在将跟踪信息注入到 API 客户端库中所有 http 请求调用的请求 headers 中,该库是基于 urllib3

实现的
def _init_jaeger_tracer():
    '''Jaeger tracer initialization'''
    config = Config(
        config={
            'sampler': {
                'type': 'const',
                'param': 1,
            },
        },
        service_name="session"
        )
    return config.new_tracer()

class APIObject(rest.APIObject):
    '''Class for injecting traces into urllib3 request headers'''
    def __init__(self, configuration):
        print("RESTClientObject child class called####")
        self._tracer = None
        super().__init__(configuration)
        self._tracer = _init_jaeger_tracer()

    # pylint: disable=W0221
    def request(self, method, url, *args, **kwargs):
        lower_method = method.lower()
        with self._tracer.start_active_span('requests.{}'.format(lower_method)) as scope:
            span = scope.span
            span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_CLIENT)
            span.set_tag(tags.COMPONENT, 'request')
            span.set_tag(tags.HTTP_METHOD, lower_method)
            span.set_tag(tags.HTTP_URL, url)
            headers = kwargs.setdefault('headers', {})
            self._tracer.inject(span.context, Format.HTTP_HEADERS, headers)
    return r

这样执行后,urllib3 请求 headers 看起来像这样,

headers = {
    'Content-Type': 'application/json', 
    'User-Agent': 'API-Generator/1.0.0/python', 
    # **
    'uber-trace-id': '30cef3e816482516:1a4fed2c4863b2f6:0:1'
    # **
}

现在我们必须从注入的请求 header.

中获取 trace-id

在 python“请求”库中,我们有 return 请求 headers

的“response.request.headers”属性

在 urllib3 中我找不到方法return 请求 headers 进行进一步处理

你们能分享一些想法吗

现在,根据此请求 headers,我们需要获取 'uber-trace-id' 及其值以进一步构建 URL。

urllib3.response.HTTPResponse 的文档说它是:

Backwards-compatible with http.client.HTTPResponse [...]

这是 stdlib class,其中 getheader 方法描述为:

Return the value of the header name, or default if there is no header matching name. If there is more than one header with the name name, return all of the values joined by ', '. If default is any iterable other than a single string, its elements are similarly returned joined by commas.

因此在你的情况下是这样的。

import urllib3

http = urllib3.PoolManager()
response = http.request('GET', 'https://python.org/')
response.getheader('uber-trace-id', 'UNKNOWN')

更新

urllib3 没有 HTTP 请求对象表示。 HTTP 请求在 RequestMethods.request 的正式参数中表示。因此,在 jaeger_client 注入后,您需要自己将跟踪标识符存储在 request 覆盖中。将其存储为响应对象的属性可能是个好主意:

from jaeger_client.constants import TRACE_ID_HEADER

class APIObject(rest.APIObject):

    def request(self, *args, **kwargs) -> urllib3.response.BaseHTTPResponse:
        ...
        r._request_tracing_id = headers[TRACE_ID_HEADER]
        return r