|
1 | | -import inspect |
| 1 | +import sys |
| 2 | +import types |
2 | 3 | from logging import getLogger |
3 | 4 | from typing import Any, Literal, Union |
4 | 5 |
|
|
32 | 33 | platform_wait_strategy, |
33 | 34 | ) |
34 | 35 |
|
| 36 | +_THIS_FILE = __file__ |
| 37 | +_MAX_CALLER_FRAMES = 5 |
| 38 | + |
| 39 | + |
| 40 | +def _get_caller_component() -> str: |
| 41 | + try: |
| 42 | + current: types.FrameType | None = sys._getframe(1) |
| 43 | + for _ in range(_MAX_CALLER_FRAMES): |
| 44 | + if current is None: |
| 45 | + break |
| 46 | + code = current.f_code |
| 47 | + if code.co_filename == _THIS_FILE: |
| 48 | + current = current.f_back |
| 49 | + continue |
| 50 | + # Skip frames from third-party libraries (e.g. tenacity) |
| 51 | + if "site-packages" in code.co_filename: |
| 52 | + current = current.f_back |
| 53 | + continue |
| 54 | + qualname = code.co_qualname |
| 55 | + if "." in qualname: |
| 56 | + parts = qualname.rsplit(".", 2) |
| 57 | + return f"{parts[-2]}.{parts[-1]}" |
| 58 | + current = current.f_back |
| 59 | + except Exception: |
| 60 | + pass |
| 61 | + return "" |
| 62 | + |
35 | 63 |
|
36 | 64 | class BaseService: |
37 | 65 | def __init__( |
@@ -78,26 +106,7 @@ def request( |
78 | 106 | self._logger.debug(f"Request: {method} {url}") |
79 | 107 | self._logger.debug(f"HEADERS: {kwargs.get('headers', self._client.headers)}") |
80 | 108 |
|
81 | | - try: |
82 | | - stack = inspect.stack() |
83 | | - |
84 | | - # use the third frame because of the retry decorator |
85 | | - caller_frame = stack[3].frame |
86 | | - function_name = caller_frame.f_code.co_name |
87 | | - |
88 | | - if "self" in caller_frame.f_locals: |
89 | | - module_name = type(caller_frame.f_locals["self"]).__name__ |
90 | | - elif "cls" in caller_frame.f_locals: |
91 | | - module_name = caller_frame.f_locals["cls"].__name__ |
92 | | - else: |
93 | | - module_name = "" |
94 | | - except Exception: |
95 | | - function_name = "" |
96 | | - module_name = "" |
97 | | - |
98 | | - specific_component = ( |
99 | | - f"{module_name}.{function_name}" if module_name and function_name else "" |
100 | | - ) |
| 109 | + specific_component = _get_caller_component() |
101 | 110 |
|
102 | 111 | kwargs.setdefault("headers", {}) |
103 | 112 | kwargs["headers"][HEADER_USER_AGENT] = user_agent_value(specific_component) |
@@ -181,24 +190,4 @@ def custom_headers(self) -> dict[str, str]: |
181 | 190 |
|
182 | 191 | @property |
183 | 192 | def _specific_component(self) -> str: |
184 | | - try: |
185 | | - stack = inspect.stack() |
186 | | - |
187 | | - caller_frame = stack[4].frame |
188 | | - function_name = caller_frame.f_code.co_name |
189 | | - |
190 | | - if "self" in caller_frame.f_locals: |
191 | | - module_name = type(caller_frame.f_locals["self"]).__name__ |
192 | | - elif "cls" in caller_frame.f_locals: |
193 | | - module_name = caller_frame.f_locals["cls"].__name__ |
194 | | - else: |
195 | | - module_name = "" |
196 | | - except Exception: |
197 | | - function_name = "" |
198 | | - module_name = "" |
199 | | - |
200 | | - specific_component = ( |
201 | | - f"{module_name}.{function_name}" if module_name and function_name else "" |
202 | | - ) |
203 | | - |
204 | | - return specific_component |
| 193 | + return _get_caller_component() |
0 commit comments