glaip-sdk 0.1.1__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- glaip_sdk/client/base.py +72 -14
- {glaip_sdk-0.1.1.dist-info → glaip_sdk-0.1.2.dist-info}/METADATA +1 -1
- {glaip_sdk-0.1.1.dist-info → glaip_sdk-0.1.2.dist-info}/RECORD +5 -5
- {glaip_sdk-0.1.1.dist-info → glaip_sdk-0.1.2.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.1.1.dist-info → glaip_sdk-0.1.2.dist-info}/entry_points.txt +0 -0
glaip_sdk/client/base.py
CHANGED
|
@@ -7,6 +7,7 @@ Authors:
|
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
|
+
from collections.abc import Iterable, Mapping
|
|
10
11
|
from typing import Any, NoReturn, Union
|
|
11
12
|
|
|
12
13
|
import httpx
|
|
@@ -289,7 +290,7 @@ class BaseClient:
|
|
|
289
290
|
return parsed.get("data", parsed) if unwrap else parsed
|
|
290
291
|
else:
|
|
291
292
|
error_type = parsed.get("error", "UnknownError")
|
|
292
|
-
message = parsed.
|
|
293
|
+
message = self._format_error_dict({key: value for key, value in parsed.items() if key != "success"})
|
|
293
294
|
self._raise_api_error(
|
|
294
295
|
400,
|
|
295
296
|
message,
|
|
@@ -332,12 +333,58 @@ class BaseClient:
|
|
|
332
333
|
return validation_message
|
|
333
334
|
return f"Validation error: {parsed}"
|
|
334
335
|
|
|
336
|
+
formatted_details = None
|
|
337
|
+
if "details" in parsed:
|
|
338
|
+
formatted_details = self._format_error_details(parsed["details"])
|
|
339
|
+
|
|
335
340
|
message = parsed.get("message")
|
|
336
341
|
if message:
|
|
342
|
+
if formatted_details:
|
|
343
|
+
return f"{message}\n{formatted_details}"
|
|
337
344
|
return message
|
|
338
345
|
|
|
346
|
+
if formatted_details:
|
|
347
|
+
return formatted_details
|
|
348
|
+
|
|
339
349
|
return str(parsed) if parsed else DEFAULT_ERROR_MESSAGE
|
|
340
350
|
|
|
351
|
+
def _format_error_details(self, details: Any) -> str | None:
|
|
352
|
+
"""Render generic error details into a human-readable string."""
|
|
353
|
+
if details is None:
|
|
354
|
+
return None
|
|
355
|
+
|
|
356
|
+
if isinstance(details, dict):
|
|
357
|
+
return self._format_detail_mapping(details)
|
|
358
|
+
|
|
359
|
+
if isinstance(details, (list, tuple, set)):
|
|
360
|
+
return self._format_detail_iterable(details)
|
|
361
|
+
|
|
362
|
+
return f"Details: {details}"
|
|
363
|
+
|
|
364
|
+
@staticmethod
|
|
365
|
+
def _format_detail_mapping(details: Mapping[str, Any]) -> str | None:
|
|
366
|
+
"""Format details provided as a mapping."""
|
|
367
|
+
entries = [f" {key}: {value}" for key, value in details.items()]
|
|
368
|
+
if not entries:
|
|
369
|
+
return None
|
|
370
|
+
return "Details:\n" + "\n".join(entries)
|
|
371
|
+
|
|
372
|
+
@staticmethod
|
|
373
|
+
def _format_detail_iterable(details: Iterable[Any]) -> str | None:
|
|
374
|
+
"""Format details provided as an iterable collection."""
|
|
375
|
+
entries: list[str] = []
|
|
376
|
+
for item in details:
|
|
377
|
+
if isinstance(item, Mapping):
|
|
378
|
+
inner = ", ".join(f"{k}={v}" for k, v in item.items())
|
|
379
|
+
entries.append(f" - {inner if inner else '{}'}")
|
|
380
|
+
else:
|
|
381
|
+
entries.append(f" - {item}")
|
|
382
|
+
|
|
383
|
+
if not entries:
|
|
384
|
+
return None
|
|
385
|
+
|
|
386
|
+
return "Details:\n" + "\n".join(entries)
|
|
387
|
+
|
|
341
388
|
def _format_validation_errors(self, errors: list[Any]) -> str | None:
|
|
342
389
|
"""Render validation errors into a human-readable string."""
|
|
343
390
|
entries: list[str] = []
|
|
@@ -356,6 +403,22 @@ class BaseClient:
|
|
|
356
403
|
|
|
357
404
|
return "Validation errors:\n" + "\n".join(entries)
|
|
358
405
|
|
|
406
|
+
@staticmethod
|
|
407
|
+
def _is_no_content_response(response: httpx.Response) -> bool:
|
|
408
|
+
"""Return True when the response contains no content."""
|
|
409
|
+
return response.status_code == 204
|
|
410
|
+
|
|
411
|
+
@staticmethod
|
|
412
|
+
def _is_success_status(response: httpx.Response) -> bool:
|
|
413
|
+
"""Return True for successful HTTP status codes."""
|
|
414
|
+
return 200 <= response.status_code < 300
|
|
415
|
+
|
|
416
|
+
def _handle_error_response(self, response: httpx.Response) -> None:
|
|
417
|
+
"""Raise an API error for non-success responses."""
|
|
418
|
+
error_message = self._get_error_message(response)
|
|
419
|
+
parsed_content = self._parse_response_content(response)
|
|
420
|
+
self._raise_api_error(response.status_code, error_message, payload=parsed_content)
|
|
421
|
+
|
|
359
422
|
def _handle_response(
|
|
360
423
|
self,
|
|
361
424
|
response: httpx.Response,
|
|
@@ -364,22 +427,17 @@ class BaseClient:
|
|
|
364
427
|
) -> Any:
|
|
365
428
|
"""Handle HTTP response with proper error handling."""
|
|
366
429
|
# Handle no-content success before general error handling
|
|
367
|
-
if response
|
|
430
|
+
if self._is_no_content_response(response):
|
|
368
431
|
return None
|
|
369
432
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
self._raise_api_error(response.status_code, error_message, payload=parsed_content)
|
|
376
|
-
return None # Won't be reached but helps with type checking
|
|
377
|
-
|
|
378
|
-
parsed = self._parse_response_content(response)
|
|
379
|
-
if parsed is None:
|
|
380
|
-
return None
|
|
433
|
+
if self._is_success_status(response):
|
|
434
|
+
parsed = self._parse_response_content(response)
|
|
435
|
+
if parsed is None:
|
|
436
|
+
return None
|
|
437
|
+
return self._handle_success_response(parsed, unwrap=unwrap)
|
|
381
438
|
|
|
382
|
-
|
|
439
|
+
self._handle_error_response(response)
|
|
440
|
+
return None
|
|
383
441
|
|
|
384
442
|
def _raise_api_error(
|
|
385
443
|
self,
|
|
@@ -39,7 +39,7 @@ glaip_sdk/cli/validators.py,sha256=Squ2W-fMz9kfvhtTt7pCcAYnzFU28ZxxTEqH1vF9r00,5
|
|
|
39
39
|
glaip_sdk/client/__init__.py,sha256=nYLXfBVTTWwKjP0e63iumPYO4k5FifwWaELQPaPIKIg,188
|
|
40
40
|
glaip_sdk/client/_agent_payloads.py,sha256=QjaSqXZvDNX0bQVKC7Eb5nHj7KxhU0zLSfNUQiKf2J8,16269
|
|
41
41
|
glaip_sdk/client/agents.py,sha256=hRkt-D2ZRkeWamPqKsqKwl74ZjScKL4UHLbbVezGCWc,37597
|
|
42
|
-
glaip_sdk/client/base.py,sha256
|
|
42
|
+
glaip_sdk/client/base.py,sha256=ikW33raz2M6rXzo3JmhttfXXuVdMv5zBRKEZkU1F-4I,18176
|
|
43
43
|
glaip_sdk/client/main.py,sha256=tELAA36rzthnNKTgwZ6lLPb3Au8Wh1mF8Kz-9N-YtCg,8652
|
|
44
44
|
glaip_sdk/client/mcps.py,sha256=GQ1EBTSVc-WrFigyw8iocK34DT3TMW85XtnDeOawP9E,8945
|
|
45
45
|
glaip_sdk/client/run_rendering.py,sha256=T6NF3SjTWSV6IpU2TexBq8AFKU1yq98NLsTp1N4B2yk,12209
|
|
@@ -76,7 +76,7 @@ glaip_sdk/utils/resource_refs.py,sha256=OpwJxTCKq3RIqLAmKE0xspJplD4IhKqLCo0OqPaf
|
|
|
76
76
|
glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
|
|
77
77
|
glaip_sdk/utils/serialization.py,sha256=cvlPQ73y4jhsbJeQ6Bv7vaq0NV8uZ27p2vD_R-nyiRQ,12646
|
|
78
78
|
glaip_sdk/utils/validation.py,sha256=NPDexNgGUIoLkEIz6hl3K6EG7ZKSEkcNLDElqm8-Ng4,7019
|
|
79
|
-
glaip_sdk-0.1.
|
|
80
|
-
glaip_sdk-0.1.
|
|
81
|
-
glaip_sdk-0.1.
|
|
82
|
-
glaip_sdk-0.1.
|
|
79
|
+
glaip_sdk-0.1.2.dist-info/METADATA,sha256=VQWPGOU1y8-yuf8bUrODnK24DVrobD9GJ_wJxAfhybk,6023
|
|
80
|
+
glaip_sdk-0.1.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
81
|
+
glaip_sdk-0.1.2.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
|
|
82
|
+
glaip_sdk-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|