memorysync 1.3.0__tar.gz → 1.4.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.
- {memorysync-1.3.0 → memorysync-1.4.0}/PKG-INFO +2 -2
- {memorysync-1.3.0 → memorysync-1.4.0}/pyproject.toml +44 -44
- memorysync-1.4.0/src/memorysync/_version.py +1 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/src/memorysync/connections.py +81 -18
- memorysync-1.3.0/src/memorysync/_version.py +0 -1
- {memorysync-1.3.0 → memorysync-1.4.0}/.gitignore +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/LICENSE +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/README.md +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/src/memorysync/__init__.py +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/src/memorysync/client.py +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/src/memorysync/control_plane.py +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/src/memorysync/control_plane_types.py +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/src/memorysync/errors.py +0 -0
- {memorysync-1.3.0 → memorysync-1.4.0}/src/memorysync/types.py +0 -0
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["hatchling"]
|
|
3
|
-
build-backend = "hatchling.build"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "memorysync"
|
|
7
|
-
version = "1.
|
|
8
|
-
description = "Official Python client for the MemorySync API."
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
license = { text = "MIT" }
|
|
11
|
-
requires-python = ">=3.9"
|
|
12
|
-
authors = [{ name = "MemorySync" }]
|
|
13
|
-
keywords = ["memorysync", "memory", "sdk", "client"]
|
|
14
|
-
classifiers = [
|
|
15
|
-
"Development Status :: 5 - Production/Stable",
|
|
16
|
-
"Intended Audience :: Developers",
|
|
17
|
-
"License :: OSI Approved :: MIT License",
|
|
18
|
-
"Programming Language :: Python :: 3",
|
|
19
|
-
"Programming Language :: Python :: 3.9",
|
|
20
|
-
"Programming Language :: Python :: 3.10",
|
|
21
|
-
"Programming Language :: Python :: 3.11",
|
|
22
|
-
"Programming Language :: Python :: 3.12",
|
|
23
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
-
"Typing :: Typed",
|
|
25
|
-
]
|
|
26
|
-
dependencies = [
|
|
27
|
-
"httpx>=0.25,<1.0",
|
|
28
|
-
"typing-extensions>=4.5; python_version < '3.11'",
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
[project.urls]
|
|
32
|
-
Homepage = "https://memorysync.io"
|
|
33
|
-
Documentation = "https://docs.memorysync.io"
|
|
34
|
-
|
|
35
|
-
[tool.hatch.build.targets.wheel]
|
|
36
|
-
packages = ["src/memorysync"]
|
|
37
|
-
|
|
38
|
-
[tool.hatch.build.targets.sdist]
|
|
39
|
-
include = [
|
|
40
|
-
"src/memorysync",
|
|
41
|
-
"README.md",
|
|
42
|
-
"LICENSE",
|
|
43
|
-
"pyproject.toml",
|
|
44
|
-
]
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "memorysync"
|
|
7
|
+
version = "1.4.0"
|
|
8
|
+
description = "Official Python client for the MemorySync API."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [{ name = "MemorySync" }]
|
|
13
|
+
keywords = ["memorysync", "memory", "sdk", "client"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 5 - Production/Stable",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"httpx>=0.25,<1.0",
|
|
28
|
+
"typing-extensions>=4.5; python_version < '3.11'",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://memorysync.io"
|
|
33
|
+
Documentation = "https://docs.memorysync.io"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["src/memorysync"]
|
|
37
|
+
|
|
38
|
+
[tool.hatch.build.targets.sdist]
|
|
39
|
+
include = [
|
|
40
|
+
"src/memorysync",
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE",
|
|
43
|
+
"pyproject.toml",
|
|
44
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.0"
|
|
@@ -38,7 +38,7 @@ shapes (memories, history, feedback, ontology).
|
|
|
38
38
|
|
|
39
39
|
from __future__ import annotations
|
|
40
40
|
|
|
41
|
-
from typing import Any, Callable, Dict, Optional, Sequence
|
|
41
|
+
from typing import Any, Callable, Dict, Mapping, Optional, Sequence
|
|
42
42
|
from urllib.parse import quote
|
|
43
43
|
|
|
44
44
|
_V2 = "/api/v2/integrations"
|
|
@@ -58,6 +58,20 @@ def _seg(value: Any) -> str:
|
|
|
58
58
|
return quote(str(value), safe="")
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
def _as_item(value: Any, key: str) -> Dict[str, Any]:
|
|
62
|
+
"""Normalize one selection entry into the object the API expects.
|
|
63
|
+
|
|
64
|
+
Two of the approval endpoints take a list of objects rather than a list of
|
|
65
|
+
ids — Slack channels carry an optional name and type, S3 prefixes carry an
|
|
66
|
+
optional bucket and label. Callers almost always have just the id, so both
|
|
67
|
+
forms are accepted here and widened to the object form, rather than making
|
|
68
|
+
every caller write ``{"id": channel_id}`` and making the simple case ugly.
|
|
69
|
+
"""
|
|
70
|
+
if isinstance(value, Mapping):
|
|
71
|
+
return dict(value)
|
|
72
|
+
return {key: value}
|
|
73
|
+
|
|
74
|
+
|
|
61
75
|
class _Namespace:
|
|
62
76
|
"""Holds the bound request function. Subclasses add methods."""
|
|
63
77
|
|
|
@@ -97,11 +111,22 @@ class SlackNamespace(_Namespace):
|
|
|
97
111
|
"GET", f"{_V2}/connections/{_seg(connection_id)}/slack/channels"
|
|
98
112
|
)
|
|
99
113
|
|
|
100
|
-
def add_channels(self, connection_id: str,
|
|
101
|
-
"""Select channels for syncing.
|
|
114
|
+
def add_channels(self, connection_id: str, channels: Sequence[Any]) -> Any:
|
|
115
|
+
"""Select channels for syncing.
|
|
116
|
+
|
|
117
|
+
Accepts bare channel ids, which is the common case::
|
|
118
|
+
|
|
119
|
+
client.connections.slack.add_channels("c1", ["C0123", "C0456"])
|
|
120
|
+
|
|
121
|
+
or dicts when you want to carry the name and type across so the server
|
|
122
|
+
does not have to look them up again::
|
|
123
|
+
|
|
124
|
+
add_channels("c1", [{"id": "C0123", "name": "support",
|
|
125
|
+
"is_private": False}])
|
|
126
|
+
"""
|
|
102
127
|
return self._request(
|
|
103
128
|
"POST", f"{_V2}/connections/{_seg(connection_id)}/slack/channels",
|
|
104
|
-
json={"
|
|
129
|
+
json={"channels": [_as_item(c, "id") for c in channels]},
|
|
105
130
|
)
|
|
106
131
|
|
|
107
132
|
def remove_channel(self, connection_id: str, channel_id: str) -> Any:
|
|
@@ -195,18 +220,47 @@ class S3Namespace(_Namespace):
|
|
|
195
220
|
"GET", f"{_V2}/connections/{_seg(connection_id)}/s3/prefixes"
|
|
196
221
|
)
|
|
197
222
|
|
|
198
|
-
def add_prefixes(self, connection_id: str, prefixes: Sequence[
|
|
199
|
-
"""Select prefixes for syncing.
|
|
223
|
+
def add_prefixes(self, connection_id: str, prefixes: Sequence[Any]) -> Any:
|
|
224
|
+
"""Select prefixes for syncing.
|
|
225
|
+
|
|
226
|
+
Accepts bare prefixes, or dicts carrying ``bucket`` and ``label``::
|
|
227
|
+
|
|
228
|
+
add_prefixes("c1", ["handbook/", "policies/"])
|
|
229
|
+
add_prefixes("c1", [{"prefix": "handbook/", "label": "Handbook"}])
|
|
230
|
+
|
|
231
|
+
An empty string means the bucket root. The bucket defaults to the one the
|
|
232
|
+
connection's credentials were validated against, and the API rejects any
|
|
233
|
+
other bucket rather than indexing one nobody proved access to.
|
|
234
|
+
"""
|
|
200
235
|
return self._request(
|
|
201
236
|
"POST", f"{_V2}/connections/{_seg(connection_id)}/s3/prefixes",
|
|
202
|
-
json={"prefixes":
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
def
|
|
206
|
-
|
|
237
|
+
json={"prefixes": [_as_item(p, "prefix") for p in prefixes]},
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
def remove_prefix(
|
|
241
|
+
self,
|
|
242
|
+
connection_id: str,
|
|
243
|
+
prefix: str = "",
|
|
244
|
+
*,
|
|
245
|
+
bucket: Optional[str] = None,
|
|
246
|
+
purge: bool = False,
|
|
247
|
+
) -> Any:
|
|
248
|
+
"""Revoke one prefix approval, optionally purging what it produced.
|
|
249
|
+
|
|
250
|
+
The prefix travels as a query parameter, not in the body and not as a path
|
|
251
|
+
segment: prefixes contain slashes, which a path segment cannot carry
|
|
252
|
+
unambiguously, and this endpoint reads no body at all.
|
|
253
|
+
|
|
254
|
+
Pass ``purge=True`` to also delete the memories already derived from the
|
|
255
|
+
prefix. The default leaves them in place, so revoking an approval does not
|
|
256
|
+
silently destroy knowledge.
|
|
257
|
+
"""
|
|
258
|
+
params: Dict[str, Any] = {"prefix": prefix, "purge": purge}
|
|
259
|
+
if bucket is not None:
|
|
260
|
+
params["bucket"] = bucket
|
|
207
261
|
return self._request(
|
|
208
262
|
"DELETE", f"{_V2}/connections/{_seg(connection_id)}/s3/prefixes",
|
|
209
|
-
|
|
263
|
+
params=params,
|
|
210
264
|
)
|
|
211
265
|
|
|
212
266
|
def exclusion_policy(self, connection_id: str) -> Any:
|
|
@@ -286,10 +340,15 @@ class GranolaNamespace(_Namespace):
|
|
|
286
340
|
)
|
|
287
341
|
|
|
288
342
|
def relink_identity(self, connection_id: str, **body: Any) -> Any:
|
|
289
|
-
"""
|
|
343
|
+
"""Re-run identity matching for this connection.
|
|
344
|
+
|
|
345
|
+
Takes no arguments: the route reads no body and re-matches the whole
|
|
346
|
+
roster. ``**body`` is kept only so a forward-compatible field can be
|
|
347
|
+
passed once the route grows one.
|
|
348
|
+
"""
|
|
290
349
|
return self._request(
|
|
291
350
|
"POST", f"{_V2}/connections/{_seg(connection_id)}/granola/identities/relink",
|
|
292
|
-
json=body,
|
|
351
|
+
json=body or None,
|
|
293
352
|
)
|
|
294
353
|
|
|
295
354
|
def settings(self, connection_id: str) -> Any:
|
|
@@ -321,7 +380,7 @@ class ConnectionOAuthNamespace(_Namespace):
|
|
|
321
380
|
platform back. Poll :meth:`status` to find out how it went — the callback
|
|
322
381
|
does not come to your backend.
|
|
323
382
|
"""
|
|
324
|
-
payload = {"
|
|
383
|
+
payload = {"provider_id": provider}
|
|
325
384
|
payload.update(body)
|
|
326
385
|
return self._request("POST", f"{_V2}/oauth/initiate", json=payload)
|
|
327
386
|
|
|
@@ -361,14 +420,18 @@ class ConnectionsNamespace(_Namespace):
|
|
|
361
420
|
return self._request("GET", f"{_V2}/connections/{_seg(connection_id)}")
|
|
362
421
|
|
|
363
422
|
def create_with_api_key(self, provider: str, api_key: str, **body: Any) -> Any:
|
|
364
|
-
"""Connect a provider that authenticates with an API key or bot token.
|
|
365
|
-
|
|
423
|
+
"""Connect a provider that authenticates with an API key or bot token.
|
|
424
|
+
|
|
425
|
+
The wire field is ``provider_id``; the argument is named ``provider``
|
|
426
|
+
because that is what the rest of this namespace calls it.
|
|
427
|
+
"""
|
|
428
|
+
payload: Dict[str, Any] = {"provider_id": provider, "api_key": api_key}
|
|
366
429
|
payload.update(body)
|
|
367
430
|
return self._request("POST", f"{_V2}/connections/api-key", json=payload)
|
|
368
431
|
|
|
369
432
|
def create_with_credentials(self, provider: str, credentials: Dict[str, Any], **body: Any) -> Any:
|
|
370
433
|
"""Connect a provider that needs a credential bundle, such as S3 keys."""
|
|
371
|
-
payload: Dict[str, Any] = {"
|
|
434
|
+
payload: Dict[str, Any] = {"provider_id": provider, "credentials": credentials}
|
|
372
435
|
payload.update(body)
|
|
373
436
|
return self._request("POST", f"{_V2}/connections/credentials", json=payload)
|
|
374
437
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.3.0"
|
|
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
|