-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathtelemetry.py
More file actions
92 lines (77 loc) · 3.38 KB
/
Copy pathtelemetry.py
File metadata and controls
92 lines (77 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import http
import json
import platform
import httpx
from kiota_http.middleware import BaseMiddleware
from urllib3.util import parse_url
from .._constants import SDK_VERSION
from .._enums import NationalClouds
from .async_graph_transport import AsyncGraphTransport
from .request_context import GraphRequestContext
class GraphRequest(httpx.Request):
context: GraphRequestContext
class GraphTelemetryHandler(BaseMiddleware):
"""Middleware component that attaches metadata to a Graph request in order to help
the SDK team improve the developer experience.
"""
async def send(self, request: GraphRequest, transport: AsyncGraphTransport):
"""Adds telemetry headers and sends the http request.
"""
if self.is_graph_url(request.url):
self._add_client_request_id_header(request)
self._append_sdk_version_header(request)
self._add_host_os_header(request)
self._add_runtime_environment_header(request)
response = await super().send(request, transport)
return response
def is_graph_url(self, url):
"""Check if the request is made to a graph endpoint. We do not add telemetry headers to
non-graph endpoints"""
endpoints = set(item.value for item in NationalClouds)
base_url = parse_url(str(url))
endpoint = f"{base_url.scheme}://{base_url.netloc}"
return endpoint in endpoints
def _add_client_request_id_header(self, request) -> None:
"""Add a client-request-id header with GUID value to request"""
request.headers.update({'client-request-id': f'{request.context.client_request_id}'})
def _append_sdk_version_header(self, request) -> None:
"""Add SdkVersion request header to each request to identify the language and
version of the client SDK library(s).
Also adds the featureUsage value.
"""
if 'sdkVersion' in request.headers:
sdk_version = request.headers.get('sdkVersion')
if not sdk_version == f'graph-python-core/{SDK_VERSION} '\
f'(featureUsage={request.context.feature_usage})':
request.headers.update(
{
'sdkVersion':
f'graph-python-core/{SDK_VERSION},{ sdk_version} '\
f'(featureUsage={request.context.feature_usage})'
}
)
else:
request.headers.update(
{
'sdkVersion':
f'graph-python-core/{SDK_VERSION} '\
f'(featureUsage={request.context.feature_usage})'
}
)
def _add_host_os_header(self, request) -> None:
"""
Add HostOS request header to each request to help identify the OS
on which our client SDK is running on
"""
system = platform.system()
version = platform.version()
host_os = f'{system} {version}'
request.headers.update({'HostOs': host_os})
def _add_runtime_environment_header(self, request) -> None:
"""
Add RuntimeEnvironment request header to capture the runtime framework
on which the client SDK is running on.
"""
python_version = platform.python_version()
runtime_environment = f'Python/{python_version}'
request.headers.update({'RuntimeEnvironment': runtime_environment})