memside 0.1.0__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.
- memside-0.1.0/LICENSE.md +11 -0
- memside-0.1.0/PKG-INFO +80 -0
- memside-0.1.0/README.md +46 -0
- memside-0.1.0/pyproject.toml +33 -0
- memside-0.1.0/setup.cfg +4 -0
- memside-0.1.0/src/memside/__init__.py +3 -0
- memside-0.1.0/src/memside/client.py +155 -0
- memside-0.1.0/src/memside.egg-info/PKG-INFO +80 -0
- memside-0.1.0/src/memside.egg-info/SOURCES.txt +10 -0
- memside-0.1.0/src/memside.egg-info/dependency_links.txt +1 -0
- memside-0.1.0/src/memside.egg-info/top_level.txt +1 -0
- memside-0.1.0/tests/test_client.py +69 -0
memside-0.1.0/LICENSE.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Memside Python SDK License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Memside. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This package is provided to help developers connect applications, scripts, and tools to the public Memside API.
|
|
6
|
+
|
|
7
|
+
You may use this package to integrate with Memside. You may not use this package, its documentation, or its structure to build or market a competing product or service.
|
|
8
|
+
|
|
9
|
+
This package does not grant rights to private Memside application source code, backend services, APIs outside the public API contract, infrastructure, trademarks, product designs, databases, private documentation, or proprietary systems.
|
|
10
|
+
|
|
11
|
+
This package is provided without warranties or guarantees of any kind.
|
memside-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memside
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lightweight Python client for the public Memside API.
|
|
5
|
+
Author-email: Memside <support@memside.com>
|
|
6
|
+
License: # Memside Python SDK License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Memside. All rights reserved.
|
|
9
|
+
|
|
10
|
+
This package is provided to help developers connect applications, scripts, and tools to the public Memside API.
|
|
11
|
+
|
|
12
|
+
You may use this package to integrate with Memside. You may not use this package, its documentation, or its structure to build or market a competing product or service.
|
|
13
|
+
|
|
14
|
+
This package does not grant rights to private Memside application source code, backend services, APIs outside the public API contract, infrastructure, trademarks, product designs, databases, private documentation, or proprietary systems.
|
|
15
|
+
|
|
16
|
+
This package is provided without warranties or guarantees of any kind.
|
|
17
|
+
|
|
18
|
+
Project-URL: Homepage, https://github.com/memside/memside
|
|
19
|
+
Project-URL: Repository, https://github.com/memside/memside
|
|
20
|
+
Project-URL: Issues, https://github.com/memside/memside/issues
|
|
21
|
+
Keywords: memside,ai,memory,mcp,sdk
|
|
22
|
+
Classifier: Development Status :: 3 - Alpha
|
|
23
|
+
Classifier: Intended Audience :: Developers
|
|
24
|
+
Classifier: Programming Language :: Python :: 3
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
30
|
+
Requires-Python: >=3.9
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE.md
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# Memside Python SDK
|
|
36
|
+
|
|
37
|
+
Lightweight Python client for the public Memside API.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install memside
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from memside import MemsideClient
|
|
49
|
+
|
|
50
|
+
client = MemsideClient(api_key="mem_sk_your_key_here")
|
|
51
|
+
|
|
52
|
+
startup = client.context_startup()
|
|
53
|
+
print(startup)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
You can also set the API key through the environment:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
MEMSIDE_API_KEY=mem_sk_your_key_here
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Supported API Areas
|
|
63
|
+
|
|
64
|
+
This package wraps public Memside API-key routes:
|
|
65
|
+
|
|
66
|
+
- startup context
|
|
67
|
+
- resume context
|
|
68
|
+
- workspace profile
|
|
69
|
+
- memory listing
|
|
70
|
+
- memory search
|
|
71
|
+
- memory fetch
|
|
72
|
+
- memory create
|
|
73
|
+
- memory update
|
|
74
|
+
- memory delete, when allowed by the API
|
|
75
|
+
|
|
76
|
+
This package does not include private Memside application source, account/session internals, billing internals, admin routes, database details, or MCP server implementation.
|
|
77
|
+
|
|
78
|
+
## Requirements
|
|
79
|
+
|
|
80
|
+
Python 3.9 or newer.
|
memside-0.1.0/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Memside Python SDK
|
|
2
|
+
|
|
3
|
+
Lightweight Python client for the public Memside API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install memside
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from memside import MemsideClient
|
|
15
|
+
|
|
16
|
+
client = MemsideClient(api_key="mem_sk_your_key_here")
|
|
17
|
+
|
|
18
|
+
startup = client.context_startup()
|
|
19
|
+
print(startup)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
You can also set the API key through the environment:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
MEMSIDE_API_KEY=mem_sk_your_key_here
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Supported API Areas
|
|
29
|
+
|
|
30
|
+
This package wraps public Memside API-key routes:
|
|
31
|
+
|
|
32
|
+
- startup context
|
|
33
|
+
- resume context
|
|
34
|
+
- workspace profile
|
|
35
|
+
- memory listing
|
|
36
|
+
- memory search
|
|
37
|
+
- memory fetch
|
|
38
|
+
- memory create
|
|
39
|
+
- memory update
|
|
40
|
+
- memory delete, when allowed by the API
|
|
41
|
+
|
|
42
|
+
This package does not include private Memside application source, account/session internals, billing internals, admin routes, database details, or MCP server implementation.
|
|
43
|
+
|
|
44
|
+
## Requirements
|
|
45
|
+
|
|
46
|
+
Python 3.9 or newer.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "memside"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Lightweight Python client for the public Memside API."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { file = "LICENSE.md" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Memside", email = "support@memside.com" }
|
|
14
|
+
]
|
|
15
|
+
keywords = ["memside", "ai", "memory", "mcp", "sdk"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13"
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/memside/memside"
|
|
29
|
+
Repository = "https://github.com/memside/memside"
|
|
30
|
+
Issues = "https://github.com/memside/memside/issues"
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.packages.find]
|
|
33
|
+
where = ["src"]
|
memside-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
from urllib.error import HTTPError
|
|
4
|
+
from urllib.parse import urlencode
|
|
5
|
+
from urllib.request import Request, urlopen
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
DEFAULT_BASE_URL = "https://api.memside.com"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MemsideError(Exception):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
message,
|
|
15
|
+
*,
|
|
16
|
+
status=None,
|
|
17
|
+
code=None,
|
|
18
|
+
retryable=None,
|
|
19
|
+
request_id=None,
|
|
20
|
+
details=None,
|
|
21
|
+
):
|
|
22
|
+
super().__init__(message)
|
|
23
|
+
self.status = status
|
|
24
|
+
self.code = code
|
|
25
|
+
self.retryable = retryable
|
|
26
|
+
self.request_id = request_id
|
|
27
|
+
self.details = details
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class MemsideClient:
|
|
31
|
+
def __init__(self, api_key=None, base_url=DEFAULT_BASE_URL, timeout=30, transport=None):
|
|
32
|
+
self.api_key = api_key or os.getenv("MEMSIDE_API_KEY")
|
|
33
|
+
if not self.api_key:
|
|
34
|
+
raise MemsideError(
|
|
35
|
+
"Missing Memside API key",
|
|
36
|
+
status=401,
|
|
37
|
+
code="missing_api_key",
|
|
38
|
+
retryable=False,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
self.base_url = base_url.rstrip("/")
|
|
42
|
+
self.timeout = timeout
|
|
43
|
+
self.transport = transport
|
|
44
|
+
|
|
45
|
+
def context_startup(self, **params):
|
|
46
|
+
return self.request("GET", "/context/startup", params=params)
|
|
47
|
+
|
|
48
|
+
def context_resume(self, **params):
|
|
49
|
+
return self.request("GET", "/context/resume", params=params)
|
|
50
|
+
|
|
51
|
+
def context_workspace_profile(self, **params):
|
|
52
|
+
return self.request("GET", "/context/workspace-profile", params=params)
|
|
53
|
+
|
|
54
|
+
def memories_list(self, **params):
|
|
55
|
+
return self.request("GET", "/memories", params=params)
|
|
56
|
+
|
|
57
|
+
def memories_search(self, **params):
|
|
58
|
+
return self.request("GET", "/memories/search", params=params)
|
|
59
|
+
|
|
60
|
+
def memories_get(self, memory_id):
|
|
61
|
+
return self.request("GET", f"/memories/{memory_id}")
|
|
62
|
+
|
|
63
|
+
def memories_create(self, memory):
|
|
64
|
+
return self.request("POST", "/memories", json_body=memory)
|
|
65
|
+
|
|
66
|
+
def memories_update(self, memory_id, patch):
|
|
67
|
+
return self.request("PATCH", f"/memories/{memory_id}", json_body=patch)
|
|
68
|
+
|
|
69
|
+
def memories_delete(self, memory_id):
|
|
70
|
+
return self.request("DELETE", f"/memories/{memory_id}")
|
|
71
|
+
|
|
72
|
+
def request(self, method, path, *, params=None, json_body=None, headers=None):
|
|
73
|
+
url = self._build_url(path, params)
|
|
74
|
+
request_headers = {
|
|
75
|
+
"Accept": "application/json",
|
|
76
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
77
|
+
**(headers or {}),
|
|
78
|
+
}
|
|
79
|
+
body = None
|
|
80
|
+
|
|
81
|
+
if json_body is not None:
|
|
82
|
+
body = json.dumps(json_body).encode("utf-8")
|
|
83
|
+
request_headers["Content-Type"] = "application/json"
|
|
84
|
+
|
|
85
|
+
if self.transport:
|
|
86
|
+
status, response_headers, response_body = self.transport(
|
|
87
|
+
method,
|
|
88
|
+
url,
|
|
89
|
+
request_headers,
|
|
90
|
+
body,
|
|
91
|
+
self.timeout,
|
|
92
|
+
)
|
|
93
|
+
payload = _read_payload(response_body)
|
|
94
|
+
if status >= 400:
|
|
95
|
+
raise _to_memside_error(status, payload)
|
|
96
|
+
return payload
|
|
97
|
+
|
|
98
|
+
request = Request(url, data=body, headers=request_headers, method=method)
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
with urlopen(request, timeout=self.timeout) as response:
|
|
102
|
+
payload = _read_payload(response.read())
|
|
103
|
+
return payload
|
|
104
|
+
except HTTPError as error:
|
|
105
|
+
payload = _read_payload(error.read())
|
|
106
|
+
raise _to_memside_error(error.code, payload) from error
|
|
107
|
+
|
|
108
|
+
def _build_url(self, path, params=None):
|
|
109
|
+
clean_params = {
|
|
110
|
+
key: value
|
|
111
|
+
for key, value in (params or {}).items()
|
|
112
|
+
if value is not None
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
query = urlencode(clean_params, doseq=True)
|
|
116
|
+
url = f"{self.base_url}{path}"
|
|
117
|
+
return f"{url}?{query}" if query else url
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _read_payload(body):
|
|
121
|
+
if body is None or body == b"":
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
if isinstance(body, bytes):
|
|
125
|
+
body = body.decode("utf-8")
|
|
126
|
+
|
|
127
|
+
if body == "":
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
return json.loads(body)
|
|
132
|
+
except json.JSONDecodeError:
|
|
133
|
+
return body
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _to_memside_error(status, payload):
|
|
137
|
+
error = payload.get("error") if isinstance(payload, dict) else None
|
|
138
|
+
message = None
|
|
139
|
+
code = "request_failed"
|
|
140
|
+
retryable = False
|
|
141
|
+
|
|
142
|
+
if isinstance(error, dict):
|
|
143
|
+
message = error.get("message")
|
|
144
|
+
code = error.get("code") or code
|
|
145
|
+
status = error.get("status") or status
|
|
146
|
+
retryable = bool(error.get("retryable"))
|
|
147
|
+
|
|
148
|
+
return MemsideError(
|
|
149
|
+
message or "Memside API request failed",
|
|
150
|
+
status=status,
|
|
151
|
+
code=code,
|
|
152
|
+
retryable=retryable,
|
|
153
|
+
request_id=payload.get("request_id") if isinstance(payload, dict) else None,
|
|
154
|
+
details=payload,
|
|
155
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memside
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lightweight Python client for the public Memside API.
|
|
5
|
+
Author-email: Memside <support@memside.com>
|
|
6
|
+
License: # Memside Python SDK License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Memside. All rights reserved.
|
|
9
|
+
|
|
10
|
+
This package is provided to help developers connect applications, scripts, and tools to the public Memside API.
|
|
11
|
+
|
|
12
|
+
You may use this package to integrate with Memside. You may not use this package, its documentation, or its structure to build or market a competing product or service.
|
|
13
|
+
|
|
14
|
+
This package does not grant rights to private Memside application source code, backend services, APIs outside the public API contract, infrastructure, trademarks, product designs, databases, private documentation, or proprietary systems.
|
|
15
|
+
|
|
16
|
+
This package is provided without warranties or guarantees of any kind.
|
|
17
|
+
|
|
18
|
+
Project-URL: Homepage, https://github.com/memside/memside
|
|
19
|
+
Project-URL: Repository, https://github.com/memside/memside
|
|
20
|
+
Project-URL: Issues, https://github.com/memside/memside/issues
|
|
21
|
+
Keywords: memside,ai,memory,mcp,sdk
|
|
22
|
+
Classifier: Development Status :: 3 - Alpha
|
|
23
|
+
Classifier: Intended Audience :: Developers
|
|
24
|
+
Classifier: Programming Language :: Python :: 3
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
30
|
+
Requires-Python: >=3.9
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE.md
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# Memside Python SDK
|
|
36
|
+
|
|
37
|
+
Lightweight Python client for the public Memside API.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install memside
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from memside import MemsideClient
|
|
49
|
+
|
|
50
|
+
client = MemsideClient(api_key="mem_sk_your_key_here")
|
|
51
|
+
|
|
52
|
+
startup = client.context_startup()
|
|
53
|
+
print(startup)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
You can also set the API key through the environment:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
MEMSIDE_API_KEY=mem_sk_your_key_here
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Supported API Areas
|
|
63
|
+
|
|
64
|
+
This package wraps public Memside API-key routes:
|
|
65
|
+
|
|
66
|
+
- startup context
|
|
67
|
+
- resume context
|
|
68
|
+
- workspace profile
|
|
69
|
+
- memory listing
|
|
70
|
+
- memory search
|
|
71
|
+
- memory fetch
|
|
72
|
+
- memory create
|
|
73
|
+
- memory update
|
|
74
|
+
- memory delete, when allowed by the API
|
|
75
|
+
|
|
76
|
+
This package does not include private Memside application source, account/session internals, billing internals, admin routes, database details, or MCP server implementation.
|
|
77
|
+
|
|
78
|
+
## Requirements
|
|
79
|
+
|
|
80
|
+
Python 3.9 or newer.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE.md
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/memside/__init__.py
|
|
5
|
+
src/memside/client.py
|
|
6
|
+
src/memside.egg-info/PKG-INFO
|
|
7
|
+
src/memside.egg-info/SOURCES.txt
|
|
8
|
+
src/memside.egg-info/dependency_links.txt
|
|
9
|
+
src/memside.egg-info/top_level.txt
|
|
10
|
+
tests/test_client.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
memside
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from memside import MemsideClient, MemsideError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MemsideClientTests(unittest.TestCase):
|
|
7
|
+
def test_startup_sends_bearer_auth(self):
|
|
8
|
+
calls = []
|
|
9
|
+
|
|
10
|
+
def transport(method, url, headers, body, timeout):
|
|
11
|
+
calls.append((method, url, headers, body, timeout))
|
|
12
|
+
return 200, {}, b'{"ok": true}'
|
|
13
|
+
|
|
14
|
+
client = MemsideClient(api_key="mem_sk_test_key", transport=transport)
|
|
15
|
+
|
|
16
|
+
self.assertEqual(client.context_startup(), {"ok": True})
|
|
17
|
+
self.assertEqual(calls[0][0], "GET")
|
|
18
|
+
self.assertEqual(calls[0][1], "https://api.memside.com/context/startup")
|
|
19
|
+
self.assertEqual(calls[0][2]["Authorization"], "Bearer mem_sk_test_key")
|
|
20
|
+
|
|
21
|
+
def test_search_serializes_query_params(self):
|
|
22
|
+
calls = []
|
|
23
|
+
|
|
24
|
+
def transport(method, url, headers, body, timeout):
|
|
25
|
+
calls.append((method, url, headers, body, timeout))
|
|
26
|
+
return 200, {}, b'{"matches": []}'
|
|
27
|
+
|
|
28
|
+
client = MemsideClient(api_key="mem_sk_test_key", transport=transport)
|
|
29
|
+
|
|
30
|
+
self.assertEqual(client.memories_search(q="launch", limit=5), {"matches": []})
|
|
31
|
+
self.assertEqual(
|
|
32
|
+
calls[0][1],
|
|
33
|
+
"https://api.memside.com/memories/search?q=launch&limit=5",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def test_create_sends_json_body(self):
|
|
37
|
+
calls = []
|
|
38
|
+
|
|
39
|
+
def transport(method, url, headers, body, timeout):
|
|
40
|
+
calls.append((method, url, headers, body, timeout))
|
|
41
|
+
return 201, {}, b'{"id": "mem_123"}'
|
|
42
|
+
|
|
43
|
+
client = MemsideClient(api_key="mem_sk_test_key", transport=transport)
|
|
44
|
+
|
|
45
|
+
self.assertEqual(client.memories_create({"content": "Remember this"}), {"id": "mem_123"})
|
|
46
|
+
self.assertEqual(calls[0][0], "POST")
|
|
47
|
+
self.assertEqual(calls[0][2]["Content-Type"], "application/json")
|
|
48
|
+
self.assertEqual(calls[0][3], b'{"content": "Remember this"}')
|
|
49
|
+
|
|
50
|
+
def test_failed_requests_raise_memside_error(self):
|
|
51
|
+
def transport(method, url, headers, body, timeout):
|
|
52
|
+
return (
|
|
53
|
+
401,
|
|
54
|
+
{},
|
|
55
|
+
b'{"ok": false, "request_id": "req_test", "error": {"code": "unauthorized", "message": "Invalid API key", "status": 401, "retryable": false}}',
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
client = MemsideClient(api_key="mem_sk_test_key", transport=transport)
|
|
59
|
+
|
|
60
|
+
with self.assertRaises(MemsideError) as raised:
|
|
61
|
+
client.context_startup()
|
|
62
|
+
|
|
63
|
+
self.assertEqual(raised.exception.status, 401)
|
|
64
|
+
self.assertEqual(raised.exception.code, "unauthorized")
|
|
65
|
+
self.assertEqual(raised.exception.request_id, "req_test")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if __name__ == "__main__":
|
|
69
|
+
unittest.main()
|