Skip to content

Commit aa4b941

Browse files
authored
Improvements to console logging (#43780)
1 parent f812d87 commit aa4b941

File tree

3 files changed

+71
-66
lines changed

3 files changed

+71
-66
lines changed

sdk/ai/azure-ai-projects/azure/ai/projects/_patch.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,6 @@
2121

2222
logger = logging.getLogger(__name__)
2323

24-
_console_logging_enabled: bool = os.environ.get("AZURE_AI_PROJECTS_CONSOLE_LOGGING", "False").lower() in (
25-
"true",
26-
"1",
27-
"yes",
28-
)
29-
if _console_logging_enabled:
30-
import sys
31-
32-
# Enable detailed console logs across Azure libraries
33-
azure_logger = logging.getLogger("azure")
34-
azure_logger.setLevel(logging.DEBUG)
35-
azure_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
36-
# Exclude detailed logs for network calls associated with getting Entra ID token.
37-
identity_logger = logging.getLogger("azure.identity")
38-
identity_logger.setLevel(logging.ERROR)
39-
# Make sure regular (redacted) detailed azure.core logs are not shown, as we are about to
40-
# turn on non-redacted logs by passing 'logging_enable=True' to the client constructor
41-
# (which are implemented as a separate logging policy)
42-
logger = logging.getLogger("azure.core.pipeline.policies.http_logging_policy")
43-
logger.setLevel(logging.ERROR)
44-
4524

4625
def _patch_user_agent(user_agent: Optional[str]) -> str:
4726
# All authenticated external clients exposed by this client will have this application id
@@ -104,7 +83,27 @@ class AIProjectClient(AIProjectClientGenerated): # pylint: disable=too-many-ins
10483

10584
def __init__(self, endpoint: str, credential: TokenCredential, **kwargs: Any) -> None:
10685

107-
kwargs.setdefault("logging_enable", _console_logging_enabled)
86+
self._console_logging_enabled: bool = (
87+
os.environ.get("AZURE_AI_PROJECTS_CONSOLE_LOGGING", "false").lower() == "true"
88+
)
89+
90+
if self._console_logging_enabled:
91+
import sys
92+
93+
# Enable detailed console logs across Azure libraries
94+
azure_logger = logging.getLogger("azure")
95+
azure_logger.setLevel(logging.DEBUG)
96+
azure_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
97+
# Exclude detailed logs for network calls associated with getting Entra ID token.
98+
identity_logger = logging.getLogger("azure.identity")
99+
identity_logger.setLevel(logging.ERROR)
100+
# Make sure regular (redacted) detailed azure.core logs are not shown, as we are about to
101+
# turn on non-redacted logs by passing 'logging_enable=True' to the client constructor
102+
# (which are implemented as a separate logging policy)
103+
logger = logging.getLogger("azure.core.pipeline.policies.http_logging_policy")
104+
logger.setLevel(logging.ERROR)
105+
106+
kwargs.setdefault("logging_enable", self._console_logging_enabled)
108107

109108
self._kwargs = kwargs.copy()
110109
self._patched_user_agent = _patch_user_agent(self._kwargs.pop("user_agent", None))
@@ -149,7 +148,6 @@ def get_openai_client(self, **kwargs) -> "OpenAI": # type: ignore[name-defined]
149148
"azure.identity package not installed. Please install it using 'pip install azure.identity'"
150149
) from e
151150

152-
# TODO: Test the case where input endpoint URL has "/" at the end
153151
openai_base_url = self._config.endpoint + "/openai" # pylint: disable=protected-access
154152

155153
if "default_query" not in kwargs:
@@ -162,7 +160,7 @@ def get_openai_client(self, **kwargs) -> "OpenAI": # type: ignore[name-defined]
162160

163161
http_client = None
164162

165-
if _console_logging_enabled:
163+
if self._console_logging_enabled:
166164
try:
167165
import httpx
168166
except ModuleNotFoundError as e:
@@ -200,7 +198,7 @@ def handle_request(self, request: httpx.Request) -> httpx.Response:
200198
headers = dict(request.headers)
201199
self._sanitize_auth_header(headers)
202200
print("Headers:")
203-
for key, value in headers.items():
201+
for key, value in sorted(headers.items()):
204202
print(f" {key}: {value}")
205203

206204
self._log_request_body(request)
@@ -209,12 +207,17 @@ def handle_request(self, request: httpx.Request) -> httpx.Response:
209207

210208
print(f"\n<== Response:\n{response.status_code} {response.reason_phrase}")
211209
print("Headers:")
212-
for key, value in dict(response.headers).items():
210+
for key, value in sorted(dict(response.headers).items()):
213211
print(f" {key}: {value}")
214-
try:
215-
print(f"Body:\n {response.read().decode('utf-8')}")
216-
except Exception: # pylint: disable=broad-exception-caught
217-
print("Body:\n [non-text content]")
212+
213+
content = response.read()
214+
if content is None or content == b"":
215+
print("Body: [No content]")
216+
else:
217+
try:
218+
print(f"Body:\n {content.decode('utf-8')}")
219+
except Exception: # pylint: disable=broad-exception-caught
220+
print(f"Body (raw):\n {content!r}")
218221
print("\n")
219222

220223
return response
@@ -244,8 +247,7 @@ def _log_request_body(self, request: httpx.Request) -> None:
244247
print(f"Body: [Cannot access content: {access_error}]")
245248
return
246249

247-
# Check if content is None or empty
248-
if content is None:
250+
if content is None or content == b"":
249251
print("Body: [No content]")
250252
return
251253

sdk/ai/azure-ai-projects/azure/ai/projects/aio/_patch.py

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,6 @@
2222

2323
logger = logging.getLogger(__name__)
2424

25-
_console_logging_enabled: bool = os.environ.get("AZURE_AI_PROJECTS_CONSOLE_LOGGING", "False").lower() in (
26-
"true",
27-
"1",
28-
"yes",
29-
)
30-
if _console_logging_enabled:
31-
import sys
32-
33-
# Enable detailed console logs across Azure libraries
34-
azure_logger = logging.getLogger("azure")
35-
azure_logger.setLevel(logging.DEBUG)
36-
azure_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
37-
# Exclude detailed logs for network calls associated with getting Entra ID token.
38-
identity_logger = logging.getLogger("azure.identity")
39-
identity_logger.setLevel(logging.ERROR)
40-
# Make sure regular (redacted) detailed azure.core logs are not shown, as we are about to
41-
# turn on non-redacted logs by passing 'logging_enable=True' to the client constructor
42-
# (which are implemented as a separate logging policy)
43-
logger = logging.getLogger("azure.core.pipeline.policies.http_logging_policy")
44-
logger.setLevel(logging.ERROR)
45-
4625

4726
class AIProjectClient(AIProjectClientGenerated): # pylint: disable=too-many-instance-attributes
4827
"""AIProjectClient.
@@ -89,7 +68,27 @@ class AIProjectClient(AIProjectClientGenerated): # pylint: disable=too-many-ins
8968

9069
def __init__(self, endpoint: str, credential: AsyncTokenCredential, **kwargs: Any) -> None:
9170

92-
kwargs.setdefault("logging_enable", _console_logging_enabled)
71+
self._console_logging_enabled: bool = (
72+
os.environ.get("AZURE_AI_PROJECTS_CONSOLE_LOGGING", "false").lower() == "true"
73+
)
74+
75+
if self._console_logging_enabled:
76+
import sys
77+
78+
# Enable detailed console logs across Azure libraries
79+
azure_logger = logging.getLogger("azure")
80+
azure_logger.setLevel(logging.DEBUG)
81+
azure_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
82+
# Exclude detailed logs for network calls associated with getting Entra ID token.
83+
identity_logger = logging.getLogger("azure.identity")
84+
identity_logger.setLevel(logging.ERROR)
85+
# Make sure regular (redacted) detailed azure.core logs are not shown, as we are about to
86+
# turn on non-redacted logs by passing 'logging_enable=True' to the client constructor
87+
# (which are implemented as a separate logging policy)
88+
logger = logging.getLogger("azure.core.pipeline.policies.http_logging_policy")
89+
logger.setLevel(logging.ERROR)
90+
91+
kwargs.setdefault("logging_enable", self._console_logging_enabled)
9392

9493
self._kwargs = kwargs.copy()
9594
self._patched_user_agent = _patch_user_agent(self._kwargs.pop("user_agent", None))
@@ -134,7 +133,6 @@ async def get_openai_client(self, **kwargs) -> "AsyncOpenAI": # type: ignore[na
134133
"azure.identity package not installed. Please install it using 'pip install azure.identity'"
135134
) from e
136135

137-
# TODO: Test the case where input endpoint URL has "/" at the end
138136
base_url = self._config.endpoint + "/openai" # pylint: disable=protected-access
139137

140138
if "default_query" not in kwargs:
@@ -147,7 +145,7 @@ async def get_openai_client(self, **kwargs) -> "AsyncOpenAI": # type: ignore[na
147145

148146
http_client = None
149147

150-
if _console_logging_enabled:
148+
if self._console_logging_enabled:
151149
try:
152150
import httpx
153151
except ModuleNotFoundError as e:
@@ -185,7 +183,7 @@ async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
185183
headers = dict(request.headers)
186184
self._sanitize_auth_header(headers)
187185
print("Headers:")
188-
for key, value in headers.items():
186+
for key, value in sorted(headers.items()):
189187
print(f" {key}: {value}")
190188

191189
self._log_request_body(request)
@@ -194,13 +192,17 @@ async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
194192

195193
print(f"\n<== Response:\n{response.status_code} {response.reason_phrase}")
196194
print("Headers:")
197-
for key, value in dict(response.headers).items():
195+
for key, value in sorted(dict(response.headers).items()):
198196
print(f" {key}: {value}")
199-
try:
200-
content = await response.aread()
201-
print(f"Body:\n {content.decode('utf-8')}")
202-
except Exception: # pylint: disable=broad-exception-caught
203-
print("Body:\n [non-text content]")
197+
198+
content = await response.aread()
199+
if content is None or content == b"":
200+
print("Body: [No content]")
201+
else:
202+
try:
203+
print(f"Body:\n {content.decode('utf-8')}")
204+
except Exception: # pylint: disable=broad-exception-caught
205+
print(f"Body (raw):\n {content!r}")
204206
print("\n")
205207

206208
return response
@@ -230,8 +232,7 @@ def _log_request_body(self, request: httpx.Request) -> None:
230232
print(f"Body: [Cannot access content: {access_error}]")
231233
return
232234

233-
# Check if content is None or empty
234-
if content is None:
235+
if content is None or content == b"":
235236
print("Body: [No content]")
236237
return
237238

sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5671,7 +5671,9 @@ class FileSearchTool(Tool, discriminator="file_search"):
56715671
visibility=["read", "create", "update", "delete", "query"]
56725672
)
56735673
"""Ranking options for search."""
5674-
filters: Optional[Union["_models.ComparisonFilter", "_models.CompoundFilter"]] = rest_field(visibility=["read", "create", "update", "delete", "query"])
5674+
filters: Optional[Union["_models.ComparisonFilter", "_models.CompoundFilter"]] = rest_field(
5675+
visibility=["read", "create", "update", "delete", "query"]
5676+
)
56755677
"""A filter to apply. Is either a ComparisonFilter type or a CompoundFilter type."""
56765678

56775679
@overload

0 commit comments

Comments
 (0)