glaip-sdk 0.0.7__py3-none-any.whl → 0.0.8__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/branding.py +3 -3
- glaip_sdk/cli/commands/agents.py +119 -12
- glaip_sdk/cli/display.py +4 -3
- glaip_sdk/cli/main.py +51 -5
- glaip_sdk/cli/resolution.py +17 -9
- glaip_sdk/cli/slash/__init__.py +25 -0
- glaip_sdk/cli/slash/agent_session.py +146 -0
- glaip_sdk/cli/slash/prompt.py +198 -0
- glaip_sdk/cli/slash/session.py +665 -0
- glaip_sdk/cli/utils.py +99 -5
- glaip_sdk/utils/rendering/renderer/base.py +19 -1
- glaip_sdk/utils/serialization.py +49 -17
- {glaip_sdk-0.0.7.dist-info → glaip_sdk-0.0.8.dist-info}/METADATA +1 -1
- {glaip_sdk-0.0.7.dist-info → glaip_sdk-0.0.8.dist-info}/RECORD +16 -12
- {glaip_sdk-0.0.7.dist-info → glaip_sdk-0.0.8.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.0.7.dist-info → glaip_sdk-0.0.8.dist-info}/entry_points.txt +0 -0
glaip_sdk/cli/utils.py
CHANGED
|
@@ -8,13 +8,16 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
import io
|
|
10
10
|
import json
|
|
11
|
+
import logging
|
|
11
12
|
import os
|
|
12
13
|
import platform
|
|
13
14
|
import shlex
|
|
14
15
|
import shutil
|
|
15
16
|
import subprocess
|
|
17
|
+
import sys
|
|
16
18
|
import tempfile
|
|
17
19
|
from collections.abc import Callable
|
|
20
|
+
from contextlib import AbstractContextManager, nullcontext
|
|
18
21
|
from pathlib import Path
|
|
19
22
|
from typing import TYPE_CHECKING, Any
|
|
20
23
|
|
|
@@ -50,6 +53,7 @@ from glaip_sdk.utils.rendering.renderer import (
|
|
|
50
53
|
)
|
|
51
54
|
|
|
52
55
|
console = Console()
|
|
56
|
+
logger = logging.getLogger("glaip_sdk.cli.utils")
|
|
53
57
|
|
|
54
58
|
|
|
55
59
|
# ----------------------------- Context helpers ---------------------------- #
|
|
@@ -225,6 +229,76 @@ def _get_view(ctx: Any) -> str:
|
|
|
225
229
|
return fallback or "rich"
|
|
226
230
|
|
|
227
231
|
|
|
232
|
+
def spinner_context(
|
|
233
|
+
ctx: Any | None,
|
|
234
|
+
message: str,
|
|
235
|
+
*,
|
|
236
|
+
console_override: Console | None = None,
|
|
237
|
+
spinner: str = "dots",
|
|
238
|
+
spinner_style: str = "cyan",
|
|
239
|
+
) -> AbstractContextManager[Any]:
|
|
240
|
+
"""Return a context manager that renders a spinner when appropriate."""
|
|
241
|
+
|
|
242
|
+
active_console = console_override or console
|
|
243
|
+
if not _can_use_spinner(ctx, active_console):
|
|
244
|
+
return nullcontext()
|
|
245
|
+
|
|
246
|
+
return active_console.status(
|
|
247
|
+
message,
|
|
248
|
+
spinner=spinner,
|
|
249
|
+
spinner_style=spinner_style,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def _can_use_spinner(ctx: Any | None, active_console: Console) -> bool:
|
|
254
|
+
"""Check if spinner output is allowed in the current environment."""
|
|
255
|
+
|
|
256
|
+
if ctx is not None:
|
|
257
|
+
tty_enabled = bool(get_ctx_value(ctx, "tty", True))
|
|
258
|
+
view = (_get_view(ctx) or "rich").lower()
|
|
259
|
+
if not tty_enabled or view not in {"", "rich"}:
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
if not active_console.is_terminal:
|
|
263
|
+
return False
|
|
264
|
+
|
|
265
|
+
return _stream_supports_tty(getattr(active_console, "file", None))
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _stream_supports_tty(stream: Any) -> bool:
|
|
269
|
+
"""Return True if the provided stream can safely render a spinner."""
|
|
270
|
+
|
|
271
|
+
target = stream if hasattr(stream, "isatty") else sys.stdout
|
|
272
|
+
try:
|
|
273
|
+
return bool(target.isatty())
|
|
274
|
+
except Exception:
|
|
275
|
+
return False
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _spinner_update(status_indicator: Any | None, message: str) -> None:
|
|
279
|
+
"""Update spinner text when a status indicator is active."""
|
|
280
|
+
|
|
281
|
+
if status_indicator is None:
|
|
282
|
+
return
|
|
283
|
+
|
|
284
|
+
try:
|
|
285
|
+
status_indicator.update(message)
|
|
286
|
+
except Exception: # pragma: no cover - defensive update
|
|
287
|
+
pass
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def _spinner_stop(status_indicator: Any | None) -> None:
|
|
291
|
+
"""Stop an active spinner safely."""
|
|
292
|
+
|
|
293
|
+
if status_indicator is None:
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
try:
|
|
297
|
+
status_indicator.stop()
|
|
298
|
+
except Exception: # pragma: no cover - defensive stop
|
|
299
|
+
pass
|
|
300
|
+
|
|
301
|
+
|
|
228
302
|
# ----------------------------- Client config ----------------------------- #
|
|
229
303
|
|
|
230
304
|
|
|
@@ -507,6 +581,8 @@ def _fuzzy_pick(
|
|
|
507
581
|
)
|
|
508
582
|
except (KeyboardInterrupt, EOFError): # pragma: no cover - user cancelled input
|
|
509
583
|
return None
|
|
584
|
+
except Exception: # pragma: no cover - prompt_toolkit not available in headless env
|
|
585
|
+
return None
|
|
510
586
|
|
|
511
587
|
return _perform_fuzzy_search(answer, labels, by_label) if answer else None
|
|
512
588
|
|
|
@@ -798,11 +874,14 @@ def _handle_fuzzy_pick_selection(
|
|
|
798
874
|
rows: list[dict[str, Any]], columns: list[tuple], title: str
|
|
799
875
|
) -> bool:
|
|
800
876
|
"""Handle fuzzy picker selection, returns True if selection was made."""
|
|
801
|
-
picked =
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
877
|
+
picked = None
|
|
878
|
+
if console.is_terminal and os.isatty(1):
|
|
879
|
+
try:
|
|
880
|
+
picked = _fuzzy_pick(rows, columns, title)
|
|
881
|
+
except Exception:
|
|
882
|
+
logger.debug(
|
|
883
|
+
"Fuzzy picker failed; falling back to table output", exc_info=True
|
|
884
|
+
)
|
|
806
885
|
if picked:
|
|
807
886
|
table = _create_table(columns, title)
|
|
808
887
|
table.add_row(*[str(picked.get(key, "N/A")) for key, _, _, _ in columns])
|
|
@@ -1096,6 +1175,7 @@ def resolve_resource(
|
|
|
1096
1175
|
label: str,
|
|
1097
1176
|
select: int | None = None,
|
|
1098
1177
|
interface_preference: str = "fuzzy",
|
|
1178
|
+
status_indicator: Any | None = None,
|
|
1099
1179
|
) -> Any | None:
|
|
1100
1180
|
"""Resolve resource reference (ID or name) with ambiguity handling.
|
|
1101
1181
|
|
|
@@ -1107,32 +1187,46 @@ def resolve_resource(
|
|
|
1107
1187
|
label: Resource type label for error messages
|
|
1108
1188
|
select: Optional selection index for ambiguity resolution
|
|
1109
1189
|
interface_preference: "fuzzy" for fuzzy picker, "questionary" for up/down list
|
|
1190
|
+
status_indicator: Optional Rich status indicator for wait animations
|
|
1110
1191
|
|
|
1111
1192
|
Returns:
|
|
1112
1193
|
Resolved resource object
|
|
1113
1194
|
"""
|
|
1195
|
+
spinner = status_indicator
|
|
1196
|
+
_spinner_update(spinner, f"[bold blue]Resolving {label}…[/bold blue]")
|
|
1197
|
+
|
|
1114
1198
|
# Try to resolve by ID first
|
|
1199
|
+
_spinner_update(spinner, f"[bold blue]Fetching {label} by ID…[/bold blue]")
|
|
1115
1200
|
result = _resolve_by_id(ref, get_by_id)
|
|
1116
1201
|
if result is not None:
|
|
1202
|
+
_spinner_update(spinner, f"[bold green]{label} found[/bold green]")
|
|
1117
1203
|
return result
|
|
1118
1204
|
|
|
1119
1205
|
# If get_by_id returned None, the resource doesn't exist
|
|
1120
1206
|
if is_uuid(ref):
|
|
1207
|
+
_spinner_stop(spinner)
|
|
1121
1208
|
raise click.ClickException(f"{label} '{ref}' not found")
|
|
1122
1209
|
|
|
1123
1210
|
# Find resources by name
|
|
1211
|
+
_spinner_update(
|
|
1212
|
+
spinner, f"[bold blue]Searching {label}s matching '{ref}'…[/bold blue]"
|
|
1213
|
+
)
|
|
1124
1214
|
matches = find_by_name(name=ref)
|
|
1125
1215
|
if not matches:
|
|
1216
|
+
_spinner_stop(spinner)
|
|
1126
1217
|
raise click.ClickException(f"{label} '{ref}' not found")
|
|
1127
1218
|
|
|
1128
1219
|
if len(matches) == 1:
|
|
1220
|
+
_spinner_update(spinner, f"[bold green]{label} found[/bold green]")
|
|
1129
1221
|
return matches[0]
|
|
1130
1222
|
|
|
1131
1223
|
# Multiple matches found, handle ambiguity
|
|
1132
1224
|
if select:
|
|
1225
|
+
_spinner_stop(spinner)
|
|
1133
1226
|
return _resolve_by_name_multiple_with_select(matches, select)
|
|
1134
1227
|
|
|
1135
1228
|
# Choose interface based on preference
|
|
1229
|
+
_spinner_stop(spinner)
|
|
1136
1230
|
if interface_preference == "fuzzy":
|
|
1137
1231
|
return _resolve_by_name_multiple_fuzzy(ctx, ref, matches, label)
|
|
1138
1232
|
else:
|
|
@@ -179,7 +179,7 @@ class RichStreamRenderer:
|
|
|
179
179
|
AIPPanel(
|
|
180
180
|
Markdown(f"**Query:** {query}"),
|
|
181
181
|
title="User Request",
|
|
182
|
-
border_style="
|
|
182
|
+
border_style="#d97706",
|
|
183
183
|
padding=(0, 1),
|
|
184
184
|
)
|
|
185
185
|
)
|
|
@@ -311,6 +311,24 @@ class RichStreamRenderer:
|
|
|
311
311
|
def _ensure_live(self) -> None:
|
|
312
312
|
"""Ensure live display is updated."""
|
|
313
313
|
# Lazily create Live if needed
|
|
314
|
+
# Rich's Live expects the console to maintain a _live_stack list. When tests
|
|
315
|
+
# or callers provide a lightweight console double (e.g. unittest.mock.Mock),
|
|
316
|
+
# the attribute might be missing or replaced with another type which breaks
|
|
317
|
+
# the background refresh thread. Normal Rich consoles always expose
|
|
318
|
+
# _live_stack as a list, so we defensively initialise it if needed.
|
|
319
|
+
live_stack = getattr(self.console, "_live_stack", None)
|
|
320
|
+
if not isinstance(live_stack, list):
|
|
321
|
+
try:
|
|
322
|
+
self.console._live_stack = [] # type: ignore[attr-defined]
|
|
323
|
+
except Exception:
|
|
324
|
+
# If the console forbids attribute assignment we simply skip the
|
|
325
|
+
# live update for this cycle and fall back to buffered printing.
|
|
326
|
+
logger.debug(
|
|
327
|
+
"Console missing _live_stack; skipping live UI initialisation",
|
|
328
|
+
exc_info=True,
|
|
329
|
+
)
|
|
330
|
+
return
|
|
331
|
+
|
|
314
332
|
if self.live is None and self.cfg.live:
|
|
315
333
|
try:
|
|
316
334
|
self.live = Live(
|
glaip_sdk/utils/serialization.py
CHANGED
|
@@ -8,7 +8,7 @@ Authors:
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
import json
|
|
11
|
-
from collections.abc import Iterable
|
|
11
|
+
from collections.abc import Callable, Iterable
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import Any
|
|
14
14
|
|
|
@@ -217,13 +217,13 @@ def _coerce_resource_to_mapping(resource: Any) -> dict[str, Any] | None:
|
|
|
217
217
|
if isinstance(resource, dict):
|
|
218
218
|
return resource
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
try:
|
|
221
|
+
if hasattr(resource, "__dict__"):
|
|
222
222
|
return dict(resource.__dict__)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
except (
|
|
224
|
+
Exception
|
|
225
|
+
): # pragma: no cover - pathological objects can still defeat coercion
|
|
226
|
+
return None
|
|
227
227
|
|
|
228
228
|
return None
|
|
229
229
|
|
|
@@ -235,27 +235,59 @@ def _iter_public_attribute_names(resource: Any) -> Iterable[str]:
|
|
|
235
235
|
names: list[str] = []
|
|
236
236
|
|
|
237
237
|
def _collect(candidates: Iterable[str] | None) -> None:
|
|
238
|
-
|
|
239
|
-
return
|
|
240
|
-
for candidate in candidates:
|
|
238
|
+
for candidate in candidates or ():
|
|
241
239
|
if candidate not in seen:
|
|
242
240
|
seen.add(candidate)
|
|
243
241
|
names.append(candidate)
|
|
244
242
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
)
|
|
250
|
-
|
|
243
|
+
# Collect from __dict__
|
|
244
|
+
_collect_from_dict(resource, _collect)
|
|
245
|
+
|
|
246
|
+
# Collect from __annotations__
|
|
247
|
+
_collect_from_annotations(resource, _collect)
|
|
248
|
+
|
|
249
|
+
# Collect from __slots__
|
|
251
250
|
_collect(getattr(resource, "__slots__", ()))
|
|
252
251
|
|
|
252
|
+
# Fallback to dir() if no names found
|
|
253
253
|
if not names:
|
|
254
|
-
|
|
254
|
+
_collect_from_dir(resource, _collect)
|
|
255
255
|
|
|
256
256
|
return iter(names)
|
|
257
257
|
|
|
258
258
|
|
|
259
|
+
def _collect_from_dict(
|
|
260
|
+
resource: Any, collect_func: Callable[[Iterable[str]], None]
|
|
261
|
+
) -> None:
|
|
262
|
+
"""Safely collect attribute names from __dict__."""
|
|
263
|
+
try:
|
|
264
|
+
if hasattr(resource, "__dict__"):
|
|
265
|
+
dict_keys = getattr(resource, "__dict__", {})
|
|
266
|
+
if dict_keys:
|
|
267
|
+
collect_func(dict_keys.keys())
|
|
268
|
+
except Exception: # pragma: no cover - defensive programming
|
|
269
|
+
pass
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def _collect_from_annotations(
|
|
273
|
+
resource: Any, collect_func: Callable[[Iterable[str]], None]
|
|
274
|
+
) -> None:
|
|
275
|
+
"""Safely collect attribute names from __annotations__."""
|
|
276
|
+
annotations = getattr(resource, "__annotations__", {})
|
|
277
|
+
if annotations:
|
|
278
|
+
collect_func(annotations.keys())
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def _collect_from_dir(
|
|
282
|
+
resource: Any, collect_func: Callable[[Iterable[str]], None]
|
|
283
|
+
) -> None:
|
|
284
|
+
"""Safely collect attribute names from dir()."""
|
|
285
|
+
try:
|
|
286
|
+
collect_func(name for name in dir(resource) if not name.startswith("__"))
|
|
287
|
+
except Exception: # pragma: no cover - defensive programming
|
|
288
|
+
pass
|
|
289
|
+
|
|
290
|
+
|
|
259
291
|
def _safe_getattr(resource: Any, name: str) -> Any:
|
|
260
292
|
try:
|
|
261
293
|
return getattr(resource, name)
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
glaip_sdk/__init__.py,sha256=FD-oTyFUKsTB9xTuGiqvkhuFXfeZ-TspjkeXERglha8,370
|
|
2
2
|
glaip_sdk/_version.py,sha256=tGkFWAVu2ry4Hy7j-u7ophGbPRX8y-ngBbXDhN1VBIQ,2007
|
|
3
|
-
glaip_sdk/branding.py,sha256=
|
|
3
|
+
glaip_sdk/branding.py,sha256=_TiQtiwH3ZSWaQhooWPHioriL0goTiYANeN6DT8lQX8,5398
|
|
4
4
|
glaip_sdk/cli/__init__.py,sha256=xCCfuF1Yc7mpCDcfhHZTX0vizvtrDSLeT8MJ3V7m5A0,156
|
|
5
5
|
glaip_sdk/cli/agent_config.py,sha256=VHjebw68wAdhGUzYdPH8qz10oADZPRgUQcPW6F7iHIU,2421
|
|
6
6
|
glaip_sdk/cli/commands/__init__.py,sha256=x0CZlZbZHoHvuzfoTWIyEch6WmNnbPzxajrox6riYp0,173
|
|
7
|
-
glaip_sdk/cli/commands/agents.py,sha256=
|
|
7
|
+
glaip_sdk/cli/commands/agents.py,sha256=1xGSoH6C9hSaGglXf4pnloqX5gJQIPsgHhkliiWQQcY,39988
|
|
8
8
|
glaip_sdk/cli/commands/configure.py,sha256=eRDzsaKV4fl2lJt8ieS4g2-xRnaa02eAAPW8xBf-tqA,7507
|
|
9
9
|
glaip_sdk/cli/commands/mcps.py,sha256=ZfmFkisXHHqgFH6WU7W5qPvfdt5Dxd5ZFZb_Ml3POoQ,12794
|
|
10
10
|
glaip_sdk/cli/commands/models.py,sha256=lHEVuXT8Sq239C_2LneV8PimVZSm9DXJKajdSVO-N50,1496
|
|
11
11
|
glaip_sdk/cli/commands/tools.py,sha256=Xm_qCe0h2EqhbqNuKTBvow1HMc7MbLYx6j92A6rLwu0,16743
|
|
12
|
-
glaip_sdk/cli/display.py,sha256=
|
|
12
|
+
glaip_sdk/cli/display.py,sha256=jE20swoRKzpYUmc0jgbeonaXKeE9x95hfjWAEdnBYRc,8727
|
|
13
13
|
glaip_sdk/cli/io.py,sha256=GPkw3pQMLBGoD5GH-KlbKpNRlVWFZOXHE17F7V3kQsI,3343
|
|
14
|
-
glaip_sdk/cli/main.py,sha256=
|
|
15
|
-
glaip_sdk/cli/resolution.py,sha256=
|
|
16
|
-
glaip_sdk/cli/
|
|
14
|
+
glaip_sdk/cli/main.py,sha256=1RSR3YmJECnpErD_y9NXqCHjyho3JkYkVc26J6NAbzE,12694
|
|
15
|
+
glaip_sdk/cli/resolution.py,sha256=BOw2NchReLKewAwBAZLWw_3_bI7u3tfzQEO7kQbIiGE,2067
|
|
16
|
+
glaip_sdk/cli/slash/__init__.py,sha256=Vdv6Y8bu-pA8dxDlyP4XrhudBPivztUozhLAz9vaLig,682
|
|
17
|
+
glaip_sdk/cli/slash/agent_session.py,sha256=JFIFBxB4xzigqHtpLGbl2fgg7RHNwy3e-kUMPMK9MdM,5006
|
|
18
|
+
glaip_sdk/cli/slash/prompt.py,sha256=QFWYgNt5AhBRYGGyUkH30ToZE7B6LS-eZGzoyibYrK8,6064
|
|
19
|
+
glaip_sdk/cli/slash/session.py,sha256=GtnnBqV79KtFJHeLfCKKnCXJ6SU1AmeXquPjy72T20E,24215
|
|
20
|
+
glaip_sdk/cli/utils.py,sha256=Jhjv9ggwZGQ8oJZGIPIpOc29LqSZAks9FLVWtTpklYU,40629
|
|
17
21
|
glaip_sdk/cli/validators.py,sha256=USbBgY86AwuDHO-Q_g8g7hu-ot4NgITBsWjTWIl62ms,5569
|
|
18
22
|
glaip_sdk/client/__init__.py,sha256=nYLXfBVTTWwKjP0e63iumPYO4k5FifwWaELQPaPIKIg,188
|
|
19
23
|
glaip_sdk/client/agents.py,sha256=FSKubF40wptMNIheC3_iawiX2CRbhTcNLFiz4qkPC6k,34659
|
|
@@ -36,7 +40,7 @@ glaip_sdk/utils/rendering/__init__.py,sha256=vXjwk5rPhhfPyD8S0DnV4GFFEtPJp4HCCg1
|
|
|
36
40
|
glaip_sdk/utils/rendering/formatting.py,sha256=_k8tkcobctmHvdygMljZF7-ALGXpD9-hHF1CNtM2KMU,7201
|
|
37
41
|
glaip_sdk/utils/rendering/models.py,sha256=SS34_00FaoGuSYn-viBkAtIbq7cJNwwPjpxnvyeUmxI,1567
|
|
38
42
|
glaip_sdk/utils/rendering/renderer/__init__.py,sha256=EXwVBmGkSYcype4ocAXo69Z1kXu0gpNXmhH5LW0_B7A,2939
|
|
39
|
-
glaip_sdk/utils/rendering/renderer/base.py,sha256=
|
|
43
|
+
glaip_sdk/utils/rendering/renderer/base.py,sha256=OqRBfdE1cwYhaB-1wXwc4pyGaagnX2duistDOIaVsD0,40969
|
|
40
44
|
glaip_sdk/utils/rendering/renderer/config.py,sha256=E4ER8TJJbqr1hcWjkwG7XROqLuccQy4EL99CbuLvSXE,783
|
|
41
45
|
glaip_sdk/utils/rendering/renderer/console.py,sha256=4cLOw4Q1fkHkApuj6dWW8eYpeYdcT0t2SO5MbVt5UTc,1844
|
|
42
46
|
glaip_sdk/utils/rendering/renderer/debug.py,sha256=FEYxAu4ZB0CjrJKevqQ2TKDgElA2cf6GqZXCNm12sNQ,3721
|
|
@@ -47,9 +51,9 @@ glaip_sdk/utils/rendering/steps.py,sha256=4zdeyKxMbUzCal4-yv8yf18144cs5wwXaxhe6m
|
|
|
47
51
|
glaip_sdk/utils/resource_refs.py,sha256=0YzblJNfRhz9xhpaKE9aE68XEV-6_ssr0fIkiMVOka0,5489
|
|
48
52
|
glaip_sdk/utils/rich_utils.py,sha256=-Ij-1bIJvnVAi6DrfftchIlMcvOTjVmSE0Qqax0EY_s,763
|
|
49
53
|
glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
|
|
50
|
-
glaip_sdk/utils/serialization.py,sha256=
|
|
54
|
+
glaip_sdk/utils/serialization.py,sha256=cUE6PxqTsfJuEEmsk_Li3QmaDavTIPotEA-BQ-v5exY,9043
|
|
51
55
|
glaip_sdk/utils/validation.py,sha256=QNORcdyvuliEs4EH2_mkDgmoyT9utgl7YNhaf45SEf8,6992
|
|
52
|
-
glaip_sdk-0.0.
|
|
53
|
-
glaip_sdk-0.0.
|
|
54
|
-
glaip_sdk-0.0.
|
|
55
|
-
glaip_sdk-0.0.
|
|
56
|
+
glaip_sdk-0.0.8.dist-info/METADATA,sha256=yWuZjBH9LvHlgsGZ8NP8GsUpsAM2X2ScE9uNCDnRPls,4942
|
|
57
|
+
glaip_sdk-0.0.8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
58
|
+
glaip_sdk-0.0.8.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
|
|
59
|
+
glaip_sdk-0.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|