11# for the Labelbox Python SDK
2- import inspect
32import json
43import logging
54import os
6- import re
7- import sys
85from datetime import datetime , timezone
96from types import MappingProxyType
10- from typing import Callable , Dict , Optional , TypedDict
7+ from typing import Callable , Dict , Optional
118
129import requests
1310import requests .exceptions
1411from google .api_core import retry
15- from lbox import exceptions # type: ignore
12+ from lbox import exceptions
13+ from lbox .call_info import call_info_as_str , python_version_info # type: ignore
1614
1715logger = logging .getLogger (__name__ )
1816
1917_LABELBOX_API_KEY = "LABELBOX_API_KEY"
2018
2119
22- def python_version_info ():
23- version_info = sys .version_info
24-
25- return f"{ version_info .major } .{ version_info .minor } .{ version_info .micro } -{ version_info .releaselevel } "
26-
27-
28- LABELBOX_CALL_PATTERN = re .compile (r"/labelbox/" )
29- TEST_FILE_PATTERN = re .compile (r".*test.*\.py$" )
30-
31-
32- class _RequestInfo (TypedDict ):
33- prefix : str
34- class_name : str
35- method_name : str
36-
37-
38- def call_info ():
39- method_name = "Unknown"
40- prefix = ""
41- class_name = ""
42- skip_methods = ["wrapper" , "__init__" ]
43- skip_classes = ["PaginatedCollection" , "_CursorPagination" , "_OffsetPagination" ]
44-
45- try :
46- call_info = None
47- for stack in reversed (inspect .stack ()):
48- if LABELBOX_CALL_PATTERN .search (stack .filename ):
49- call_info = stack
50- method_name = call_info .function
51- class_name = call_info .frame .f_locals .get (
52- "self" , None
53- ).__class__ .__name__
54-
55- if method_name not in skip_methods and class_name not in skip_classes :
56- if TEST_FILE_PATTERN .search (call_info .filename ):
57- prefix = "test:"
58- else :
59- if class_name == "NoneType" :
60- class_name = ""
61- break
62-
63- except Exception :
64- pass
65- return _RequestInfo (prefix = prefix , class_name = class_name , method_name = method_name )
66-
67-
68- def call_info_as_str ():
69- info = call_info ()
70- return f"{ info ['prefix' ]} { info ['class_name' ]} :{ info ['method_name' ]} "
71-
72-
7320class RequestClient :
7421 """A Labelbox request client.
7522
@@ -114,6 +61,7 @@ def __init__(
11461 self .endpoint = endpoint
11562 self .rest_endpoint = rest_endpoint
11663 self .sdk_version = sdk_version
64+ self ._sdk_method = None
11765 self ._connection : requests .Session = self ._init_connection ()
11866
11967 def _init_connection (self ) -> requests .Session :
@@ -126,6 +74,14 @@ def _init_connection(self) -> requests.Session:
12674 def headers (self ) -> MappingProxyType :
12775 return self ._connection .headers
12876
77+ @property
78+ def sdk_method (self ):
79+ return self ._sdk_method
80+
81+ @sdk_method .setter
82+ def sdk_method (self , value ):
83+ self ._sdk_method = value
84+
12985 def _default_headers (self ):
13086 return {
13187 "Authorization" : "Bearer %s" % self .api_key ,
@@ -234,7 +190,9 @@ def convert_value(value):
234190 if files :
235191 del headers ["Content-Type" ]
236192 del headers ["Accept" ]
237- headers ["X-SDK-Method" ] = call_info_as_str ()
193+ headers ["X-SDK-Method" ] = (
194+ self .sdk_method if self .sdk_method else call_info_as_str ()
195+ )
238196
239197 request = requests .Request (
240198 "POST" ,
0 commit comments