memwal 0.1.9.dev1__tar.gz → 0.1.9.dev2__tar.gz
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-0.1.9.dev1 → memwal-0.1.9.dev2}/CHANGELOG.md +1 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/PKG-INFO +1 -1
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/memwal/__init__.py +1 -1
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/memwal/client.py +18 -1
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/pyproject.toml +1 -1
- memwal-0.1.9.dev2/tests/test_auth_rejected_message.py +30 -0
- memwal-0.1.9.dev1/tests/test_auth_rejected_message.py +0 -9
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/.gitignore +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/README.md +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/examples/.env.example +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/examples/.gitignore +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/examples/async_remember_demo.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/examples/interactive_demo.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/examples/verify_credentials.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/memwal/compatibility.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/memwal/middleware.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/memwal/mock.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/memwal/types.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/memwal/utils.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/notebooks/walrus_memory_python_sdk.ipynb +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/run_tests.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/tests/__init__.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/tests/test_client.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/tests/test_env_presets.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/tests/test_integration.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/tests/test_middleware.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/tests/test_mock.py +0 -0
- {memwal-0.1.9.dev1 → memwal-0.1.9.dev2}/tests/test_signing.py +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
### Fixed
|
|
6
6
|
|
|
7
|
+
- HTTP 503 with `x-auth-error: AUTH_UPSTREAM_UNAVAILABLE` is reported as a retryable credential-verification outage, not a sign-in failure. Other 503s keep the generic sanitized body.
|
|
7
8
|
- `remember_bulk_async` rejects an empty `items` list before the request and raises when the relayer returns a `job_ids` length that does not match the batch.
|
|
8
9
|
- restore `truncated` docs now match WALM-431 retryable semantics.
|
|
9
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: memwal
|
|
3
|
-
Version: 0.1.9.
|
|
3
|
+
Version: 0.1.9.dev2
|
|
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
|
|
@@ -97,6 +97,11 @@ AUTH_REJECTED_MESSAGE = (
|
|
|
97
97
|
"and dashboard credentials. Full troubleshooting: "
|
|
98
98
|
"https://docs.wal.app/walrus-memory/troubleshooting/overview#401-auth_rejected-errors"
|
|
99
99
|
)
|
|
100
|
+
AUTH_UPSTREAM_UNAVAILABLE = "AUTH_UPSTREAM_UNAVAILABLE"
|
|
101
|
+
UPSTREAM_UNAVAILABLE_MESSAGE = (
|
|
102
|
+
"Walrus Memory temporarily cannot verify credentials (upstream unavailable). "
|
|
103
|
+
"Retry; this is not a sign-in failure."
|
|
104
|
+
)
|
|
100
105
|
|
|
101
106
|
|
|
102
107
|
logger = logging.getLogger("memwal")
|
|
@@ -1285,6 +1290,8 @@ class MemWal:
|
|
|
1285
1290
|
raise _HttpStatusError(
|
|
1286
1291
|
status=response.status_code,
|
|
1287
1292
|
body=err_text,
|
|
1293
|
+
auth_error=response.headers.get("x-auth-error"),
|
|
1294
|
+
retry_after=response.headers.get("retry-after"),
|
|
1288
1295
|
)
|
|
1289
1296
|
|
|
1290
1297
|
return response.json()
|
|
@@ -1328,15 +1335,25 @@ class _HttpStatusError(MemWalError):
|
|
|
1328
1335
|
explicitly accepted).
|
|
1329
1336
|
"""
|
|
1330
1337
|
|
|
1331
|
-
def __init__(
|
|
1338
|
+
def __init__(
|
|
1339
|
+
self,
|
|
1340
|
+
status: int,
|
|
1341
|
+
body: str,
|
|
1342
|
+
auth_error: str | None = None,
|
|
1343
|
+
retry_after: str | None = None,
|
|
1344
|
+
) -> None:
|
|
1332
1345
|
if status == 401:
|
|
1333
1346
|
super().__init__(AUTH_REJECTED_MESSAGE)
|
|
1347
|
+
elif status == 503 and auth_error == AUTH_UPSTREAM_UNAVAILABLE:
|
|
1348
|
+
super().__init__(UPSTREAM_UNAVAILABLE_MESSAGE)
|
|
1334
1349
|
else:
|
|
1335
1350
|
super().__init__(
|
|
1336
1351
|
f"Walrus Memory API error ({status}): {_redact_internal_urls(body)}"
|
|
1337
1352
|
)
|
|
1338
1353
|
self.status = status
|
|
1339
1354
|
self.body = body
|
|
1355
|
+
self.auth_error = auth_error
|
|
1356
|
+
self.retry_after = retry_after
|
|
1340
1357
|
|
|
1341
1358
|
|
|
1342
1359
|
class MemWalRememberJobNotFound(MemWalError):
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Tests for the AUTH_REJECTED_MESSAGE shown on a 401 from the relayer."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from memwal.client import (
|
|
6
|
+
AUTH_REJECTED_MESSAGE,
|
|
7
|
+
AUTH_UPSTREAM_UNAVAILABLE,
|
|
8
|
+
UPSTREAM_UNAVAILABLE_MESSAGE,
|
|
9
|
+
_HttpStatusError,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_auth_rejected_message_points_to_troubleshooting_guide() -> None:
|
|
14
|
+
assert "docs.wal.app/walrus-memory/troubleshooting/overview" in AUTH_REJECTED_MESSAGE
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_auth_503_is_retryable_not_a_credential_failure() -> None:
|
|
18
|
+
err = _HttpStatusError(
|
|
19
|
+
503, "upstream unavailable", auth_error=AUTH_UPSTREAM_UNAVAILABLE, retry_after="5"
|
|
20
|
+
)
|
|
21
|
+
assert str(err) == UPSTREAM_UNAVAILABLE_MESSAGE
|
|
22
|
+
assert "sign-in" in str(err)
|
|
23
|
+
assert "401" not in str(err)
|
|
24
|
+
assert err.retry_after == "5"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_non_auth_503_keeps_generic_body() -> None:
|
|
28
|
+
err = _HttpStatusError(503, "Rate limiter temporarily unavailable")
|
|
29
|
+
assert "Rate limiter temporarily unavailable" in str(err)
|
|
30
|
+
assert "cannot verify credentials" not in str(err)
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"""Tests for the AUTH_REJECTED_MESSAGE shown on a 401 from the relayer."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from memwal.client import AUTH_REJECTED_MESSAGE
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def test_auth_rejected_message_points_to_troubleshooting_guide() -> None:
|
|
9
|
-
assert "docs.wal.app/walrus-memory/troubleshooting/overview" in AUTH_REJECTED_MESSAGE
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|