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 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.get("message", DEFAULT_ERROR_MESSAGE)
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.status_code == 204:
430
+ if self._is_no_content_response(response):
368
431
  return None
369
432
 
370
- # Handle error status codes
371
- if not (200 <= response.status_code < 300):
372
- error_message = self._get_error_message(response)
373
- # Try to parse response content for payload
374
- parsed_content = self._parse_response_content(response)
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
- return self._handle_success_response(parsed, unwrap=unwrap)
439
+ self._handle_error_response(response)
440
+ return None
383
441
 
384
442
  def _raise_api_error(
385
443
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: glaip-sdk
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Python SDK for GL AIP (GDP Labs AI Agent Package) - Simplified CLI Design
5
5
  License: MIT
6
6
  Author: Raymond Christopher
@@ -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=-GC5P5fB9V5lqyCuEJoxD3KBvCT98TzlMvFFFjD6kIc,16047
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.1.dist-info/METADATA,sha256=_D9k3juoxlATe8KReWJkjTTwVf6hOH8Q82ooCyj7YMY,6023
80
- glaip_sdk-0.1.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
81
- glaip_sdk-0.1.1.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
82
- glaip_sdk-0.1.1.dist-info/RECORD,,
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,,