memwal 0.2.2.dev0__py3-none-any.whl → 0.2.2.dev1__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.
memwal/__init__.py CHANGED
@@ -128,4 +128,4 @@ __all__ = [
128
128
  "RecallManualResult",
129
129
  ]
130
130
 
131
- __version__ = "0.2.2.dev0"
131
+ __version__ = "0.2.2.dev1"
memwal/client.py CHANGED
@@ -142,6 +142,24 @@ def _reject_blank_text(text: object, message: str = "Text cannot be empty") -> N
142
142
  raise ValueError(message)
143
143
 
144
144
 
145
+ def _require(data: object, field: str, endpoint: str) -> Any:
146
+ """``data[field]`` from a parsed 2xx body, or a ``MemWalError`` naming both.
147
+
148
+ A bare ``KeyError`` is not a ``MemWalError``, carries only the field name,
149
+ and is raised far from the response that caused it (#1250). Optional
150
+ fields keep using ``.get()`` with a documented default.
151
+ """
152
+
153
+ if not isinstance(data, dict):
154
+ raise MemWalError(
155
+ f"{endpoint} response was {type(data).__name__}, expected an object "
156
+ f"with {field!r}"
157
+ )
158
+ if field not in data:
159
+ raise MemWalError(f"{endpoint} response missing {field!r}")
160
+ return data[field]
161
+
162
+
145
163
  IDEMPOTENCY_BUCKET_MS = 30 * 60 * 1000
146
164
 
147
165
 
@@ -1189,9 +1207,9 @@ class MemWal:
1189
1207
  data = await self._signed_request("POST", "/api/recall", body)
1190
1208
  memories = [
1191
1209
  RecallMemory(
1192
- blob_id=m["blob_id"],
1193
- text=m["text"],
1194
- distance=m["distance"],
1210
+ blob_id=_require(m, "blob_id", "POST /api/recall"),
1211
+ text=_require(m, "text", "POST /api/recall"),
1212
+ distance=_require(m, "distance", "POST /api/recall"),
1195
1213
  score=m.get("score"),
1196
1214
  created_at=m.get("created_at"),
1197
1215
  )
@@ -1359,12 +1377,16 @@ class MemWal:
1359
1377
  "namespace": self._resolve_namespace(namespace),
1360
1378
  })
1361
1379
  memories = [
1362
- AskMemory(blob_id=m["blob_id"], text=m["text"], distance=m["distance"])
1380
+ AskMemory(
1381
+ blob_id=_require(m, "blob_id", "POST /api/ask"),
1382
+ text=_require(m, "text", "POST /api/ask"),
1383
+ distance=_require(m, "distance", "POST /api/ask"),
1384
+ )
1363
1385
  for m in data.get("memories", [])
1364
1386
  ]
1365
1387
  return AskResult(
1366
- answer=data["answer"],
1367
- memories_used=data["memories_used"],
1388
+ answer=_require(data, "answer", "POST /api/ask"),
1389
+ memories_used=_require(data, "memories_used", "POST /api/ask"),
1368
1390
  memories=memories,
1369
1391
  )
1370
1392
 
@@ -1424,12 +1446,13 @@ class MemWal:
1424
1446
  "namespace": namespace,
1425
1447
  "limit": limit,
1426
1448
  })
1449
+ endpoint = "POST /api/restore"
1427
1450
  return RestoreResult(
1428
- restored=data["restored"],
1429
- skipped=data["skipped"],
1430
- total=data["total"],
1431
- namespace=data["namespace"],
1432
- owner=data["owner"],
1451
+ restored=_require(data, "restored", endpoint),
1452
+ skipped=_require(data, "skipped", endpoint),
1453
+ total=_require(data, "total", endpoint),
1454
+ namespace=_require(data, "namespace", endpoint),
1455
+ owner=_require(data, "owner", endpoint),
1433
1456
  # Relayers older than WALM-319 omit `truncated` entirely --
1434
1457
  # treat "not present" as "not known to be truncated" rather
1435
1458
  # than require every relayer version to send it.
@@ -1492,20 +1515,21 @@ class MemWal:
1492
1515
  # against `path_and_query`, not `path`.
1493
1516
  path = f"/v1/owners/{owner}/namespaces" + (f"?{query}" if query else "")
1494
1517
  data = await self._signed_request("GET", path, {}, include_seal_session=False)
1518
+ endpoint = "GET /v1/owners/{owner}/namespaces"
1495
1519
  return NamespacesResult(
1496
1520
  namespaces=[
1497
1521
  NamespaceSummary(
1498
- id=ns["id"],
1499
- name=ns["name"],
1500
- memory_count=ns["memory_count"],
1501
- storage_used=ns["storage_used"],
1502
- updated_at=ns["updated_at"],
1522
+ id=_require(ns, "id", endpoint),
1523
+ name=_require(ns, "name", endpoint),
1524
+ memory_count=_require(ns, "memory_count", endpoint),
1525
+ storage_used=_require(ns, "storage_used", endpoint),
1526
+ updated_at=_require(ns, "updated_at", endpoint),
1503
1527
  )
1504
- for ns in data["namespaces"]
1528
+ for ns in _require(data, "namespaces", endpoint)
1505
1529
  ],
1506
1530
  next_cursor=data.get("next_cursor"),
1507
- has_more=data["has_more"],
1508
- snapshot_version=data["snapshot_version"],
1531
+ has_more=_require(data, "has_more", endpoint),
1532
+ snapshot_version=_require(data, "snapshot_version", endpoint),
1509
1533
  )
1510
1534
 
1511
1535
  async def health(self) -> HealthResult:
@@ -1523,8 +1547,8 @@ class MemWal:
1523
1547
  raise MemWalError(f"Health check failed: {response.status_code}")
1524
1548
  data = response.json()
1525
1549
  return HealthResult(
1526
- status=data["status"],
1527
- version=data["version"],
1550
+ status=_require(data, "status", "GET /health"),
1551
+ version=_require(data, "version", "GET /health"),
1528
1552
  relayer_version=data.get("relayerVersion"),
1529
1553
  api_version=data.get("apiVersion"),
1530
1554
  min_supported_sdk=data.get("minSupportedSdk"),
@@ -1569,11 +1593,12 @@ class MemWal:
1569
1593
  },
1570
1594
  include_seal_session=False,
1571
1595
  )
1596
+ endpoint = "POST /api/remember/manual"
1572
1597
  return RememberManualResult(
1573
- id=data["id"],
1574
- blob_id=data["blob_id"],
1575
- owner=data["owner"],
1576
- namespace=data["namespace"],
1598
+ id=_require(data, "id", endpoint),
1599
+ blob_id=_require(data, "blob_id", endpoint),
1600
+ owner=_require(data, "owner", endpoint),
1601
+ namespace=_require(data, "namespace", endpoint),
1577
1602
  )
1578
1603
 
1579
1604
  async def recall_manual(self, opts: RecallManualOptions) -> RecallManualResult:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: memwal
3
- Version: 0.2.2.dev0
3
+ Version: 0.2.2.dev1
4
4
  Summary: Python SDK for Walrus Memory — Privacy-first AI memory with Ed25519 signing
5
5
  Project-URL: Homepage, https://memory.walrus.xyz
6
6
  Project-URL: Documentation, https://memory.walrus.xyz
@@ -1,10 +1,10 @@
1
- memwal/__init__.py,sha256=G_2AYOMiAWMZ_G89OKlHPYV63KXxp--oMGC0cYV9r1c,3142
2
- memwal/client.py,sha256=l_V6fcUyXq9r1qV8sHw8xlSc8-Q50ebTtDuP4rscq8c,95076
1
+ memwal/__init__.py,sha256=MGoDtX1cNKJndeJGln3gaFCfk3ueuHt0Mfs-CF2JyyE,3142
2
+ memwal/client.py,sha256=6YExSuMZ9RGeIShakk8UxSXgVY8pKwDexExPgnqhH4I,96563
3
3
  memwal/compatibility.py,sha256=FsKApCcHOFZeIeNOph3YydWVnZtMJdT0KCt0e6jylho,2799
4
4
  memwal/middleware.py,sha256=z2xdbvaobBg4byJXnrX7amWdVYE4jfeO4t31DoDBv_o,38413
5
5
  memwal/mock.py,sha256=cB-mu2yqycvMCVMmgqTTsIj_pGSkHufCyLNbfkPdHEE,24262
6
6
  memwal/types.py,sha256=fPvxU4k14qmj577sMtGZyVaGhwXxORtyXL-TxD0P6LI,14002
7
7
  memwal/utils.py,sha256=YyLuxPjKB0RksL1ZGPORpW7QrSID0vQQABq3L_64zKw,12596
8
- memwal-0.2.2.dev0.dist-info/METADATA,sha256=11TlxEsj6VTIT3FxMNJBr9UqstdqvYlIp8jduI83LV4,11923
9
- memwal-0.2.2.dev0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
10
- memwal-0.2.2.dev0.dist-info/RECORD,,
8
+ memwal-0.2.2.dev1.dist-info/METADATA,sha256=XLsl3x9kG7nJN5MyuQ_hg7te9FZbu59qLwlbUyyQQEM,11923
9
+ memwal-0.2.2.dev1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
10
+ memwal-0.2.2.dev1.dist-info/RECORD,,