memorysync 1.8.0__tar.gz → 1.9.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.8.0 → memorysync-1.9.0}/PKG-INFO +1 -1
- memorysync-1.9.0/src/memorysync/_version.py +1 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/src/memorysync/client.py +130 -0
- memorysync-1.8.0/src/memorysync/_version.py +0 -1
- {memorysync-1.8.0 → memorysync-1.9.0}/.gitignore +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/LICENSE +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/README.md +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/pyproject.toml +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/src/memorysync/__init__.py +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/src/memorysync/connections.py +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/src/memorysync/control_plane.py +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/src/memorysync/control_plane_types.py +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/src/memorysync/errors.py +0 -0
- {memorysync-1.8.0 → memorysync-1.9.0}/src/memorysync/types.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.9.0"
|
|
@@ -612,6 +612,81 @@ class MemorySyncClient:
|
|
|
612
612
|
return skipped
|
|
613
613
|
return Memory.from_dict(raw)
|
|
614
614
|
|
|
615
|
+
# ── Bulk import ──────────────────────────────────────────────────
|
|
616
|
+
|
|
617
|
+
def create_import(
|
|
618
|
+
self,
|
|
619
|
+
file: Union[bytes, "IO[bytes]"],
|
|
620
|
+
*,
|
|
621
|
+
filename: str,
|
|
622
|
+
end_user_id: Optional[str] = None,
|
|
623
|
+
resume: bool = False,
|
|
624
|
+
continue_on_error: bool = False,
|
|
625
|
+
) -> Dict[str, Any]:
|
|
626
|
+
"""Upload a payload and get an import job back, without waiting for it.
|
|
627
|
+
|
|
628
|
+
``bulk_add`` accepts fifty records per call because each one runs the
|
|
629
|
+
extraction pipeline. For a migration out of another system, upload the
|
|
630
|
+
whole file here and poll :meth:`get_import`.
|
|
631
|
+
|
|
632
|
+
``resume`` requires ``client_ref`` on every record and is what makes
|
|
633
|
+
re-running the same file safe: records a previous run already stored come
|
|
634
|
+
back counted as ``already_imported`` rather than stored again.
|
|
635
|
+
|
|
636
|
+
The payload is JSONL, or JSON when ``filename`` ends in ``.json``. The
|
|
637
|
+
extension is how the server picks the reader, so it is required.
|
|
638
|
+
"""
|
|
639
|
+
if not filename or not filename.strip():
|
|
640
|
+
raise ValidationError("filename is required so the server can pick a reader")
|
|
641
|
+
form = _strip_none(
|
|
642
|
+
{
|
|
643
|
+
"end_user_id": end_user_id,
|
|
644
|
+
"resume": "true" if resume else "false",
|
|
645
|
+
"continue_on_error": "true" if continue_on_error else "false",
|
|
646
|
+
}
|
|
647
|
+
)
|
|
648
|
+
return (
|
|
649
|
+
self._request(
|
|
650
|
+
"POST",
|
|
651
|
+
"/imports",
|
|
652
|
+
files={"file": (filename, file)},
|
|
653
|
+
data=form,
|
|
654
|
+
end_user_override=end_user_id,
|
|
655
|
+
)
|
|
656
|
+
or {}
|
|
657
|
+
)
|
|
658
|
+
|
|
659
|
+
def get_import(self, job_id: str) -> Dict[str, Any]:
|
|
660
|
+
"""One import job's status, progress and per-outcome counters.
|
|
661
|
+
|
|
662
|
+
``progress_percentage`` stays below 100 until the job is genuinely
|
|
663
|
+
finished, so reaching 100 means done.
|
|
664
|
+
"""
|
|
665
|
+
if not job_id or not str(job_id).strip():
|
|
666
|
+
raise ValidationError("job_id is required")
|
|
667
|
+
return self._request("GET", f"/imports/{job_id}") or {}
|
|
668
|
+
|
|
669
|
+
def list_imports(
|
|
670
|
+
self, *, status: Optional[str] = None, limit: Optional[int] = None
|
|
671
|
+
) -> Dict[str, Any]:
|
|
672
|
+
"""Recent import jobs, newest first."""
|
|
673
|
+
return (
|
|
674
|
+
self._request(
|
|
675
|
+
"GET", "/imports", params={"status": status, "limit": limit}
|
|
676
|
+
)
|
|
677
|
+
or {}
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
def cancel_import(self, job_id: str) -> Dict[str, Any]:
|
|
681
|
+
"""Ask the worker to stop between batches.
|
|
682
|
+
|
|
683
|
+
Records already imported stay imported, and the counters report how far it
|
|
684
|
+
reached. Cancelling a finished job is a no-op rather than an error.
|
|
685
|
+
"""
|
|
686
|
+
if not job_id or not str(job_id).strip():
|
|
687
|
+
raise ValidationError("job_id is required")
|
|
688
|
+
return self._request("POST", f"/imports/{job_id}/cancel") or {}
|
|
689
|
+
|
|
615
690
|
# ── Bulk edit ────────────────────────────────────────────────────
|
|
616
691
|
|
|
617
692
|
def batch_update(
|
|
@@ -1296,6 +1371,61 @@ class AsyncMemorySyncClient:
|
|
|
1296
1371
|
|
|
1297
1372
|
# ── Bulk edit ────────────────────────────────────────────────────
|
|
1298
1373
|
|
|
1374
|
+
# ── Bulk import ──────────────────────────────────────────────────
|
|
1375
|
+
|
|
1376
|
+
async def create_import(
|
|
1377
|
+
self,
|
|
1378
|
+
file: Union[bytes, "IO[bytes]"],
|
|
1379
|
+
*,
|
|
1380
|
+
filename: str,
|
|
1381
|
+
end_user_id: Optional[str] = None,
|
|
1382
|
+
resume: bool = False,
|
|
1383
|
+
continue_on_error: bool = False,
|
|
1384
|
+
) -> Dict[str, Any]:
|
|
1385
|
+
"""Async twin of :meth:`MemorySyncClient.create_import`."""
|
|
1386
|
+
if not filename or not filename.strip():
|
|
1387
|
+
raise ValidationError("filename is required so the server can pick a reader")
|
|
1388
|
+
form = _strip_none(
|
|
1389
|
+
{
|
|
1390
|
+
"end_user_id": end_user_id,
|
|
1391
|
+
"resume": "true" if resume else "false",
|
|
1392
|
+
"continue_on_error": "true" if continue_on_error else "false",
|
|
1393
|
+
}
|
|
1394
|
+
)
|
|
1395
|
+
return (
|
|
1396
|
+
await self._request(
|
|
1397
|
+
"POST",
|
|
1398
|
+
"/imports",
|
|
1399
|
+
files={"file": (filename, file)},
|
|
1400
|
+
data=form,
|
|
1401
|
+
end_user_override=end_user_id,
|
|
1402
|
+
)
|
|
1403
|
+
or {}
|
|
1404
|
+
)
|
|
1405
|
+
|
|
1406
|
+
async def get_import(self, job_id: str) -> Dict[str, Any]:
|
|
1407
|
+
"""Async twin of :meth:`MemorySyncClient.get_import`."""
|
|
1408
|
+
if not job_id or not str(job_id).strip():
|
|
1409
|
+
raise ValidationError("job_id is required")
|
|
1410
|
+
return await self._request("GET", f"/imports/{job_id}") or {}
|
|
1411
|
+
|
|
1412
|
+
async def list_imports(
|
|
1413
|
+
self, *, status: Optional[str] = None, limit: Optional[int] = None
|
|
1414
|
+
) -> Dict[str, Any]:
|
|
1415
|
+
"""Async twin of :meth:`MemorySyncClient.list_imports`."""
|
|
1416
|
+
return (
|
|
1417
|
+
await self._request(
|
|
1418
|
+
"GET", "/imports", params={"status": status, "limit": limit}
|
|
1419
|
+
)
|
|
1420
|
+
or {}
|
|
1421
|
+
)
|
|
1422
|
+
|
|
1423
|
+
async def cancel_import(self, job_id: str) -> Dict[str, Any]:
|
|
1424
|
+
"""Async twin of :meth:`MemorySyncClient.cancel_import`."""
|
|
1425
|
+
if not job_id or not str(job_id).strip():
|
|
1426
|
+
raise ValidationError("job_id is required")
|
|
1427
|
+
return await self._request("POST", f"/imports/{job_id}/cancel") or {}
|
|
1428
|
+
|
|
1299
1429
|
async def batch_update(
|
|
1300
1430
|
self,
|
|
1301
1431
|
items: Sequence[Union[BatchUpdateItem, Dict[str, Any]]],
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.8.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
|
|
File without changes
|