From 251fdf116f5f1b0c1ecfb74bef94ba08f7921dca Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 17 Sep 2025 00:29:09 +0000
Subject: [PATCH 01/10] feat(api): manual updates
---
.stats.yml | 4 +-
README.md | 41 +-
api.md | 46 +
src/supermemory/_client.py | 18 +-
src/supermemory/_files.py | 2 +-
src/supermemory/resources/__init__.py | 28 +
src/supermemory/resources/documents.py | 894 ++++++++++++++++++
src/supermemory/resources/memories.py | 894 ++++++++++++++++++
src/supermemory/types/__init__.py | 18 +
src/supermemory/types/document_add_params.py | 69 ++
.../types/document_add_response.py | 11 +
.../types/document_get_response.py | 104 ++
src/supermemory/types/document_list_params.py | 41 +
.../types/document_list_response.py | 95 ++
.../types/document_update_params.py | 69 ++
.../types/document_update_response.py | 11 +
.../types/document_upload_file_params.py | 36 +
.../types/document_upload_file_response.py | 11 +
src/supermemory/types/memory_add_params.py | 69 ++
src/supermemory/types/memory_add_response.py | 11 +
src/supermemory/types/memory_get_response.py | 104 ++
src/supermemory/types/memory_list_params.py | 41 +
src/supermemory/types/memory_list_response.py | 95 ++
src/supermemory/types/memory_update_params.py | 69 ++
.../types/memory_update_response.py | 11 +
.../types/memory_upload_file_params.py | 36 +
.../types/memory_upload_file_response.py | 11 +
tests/api_resources/test_documents.py | 610 ++++++++++++
tests/api_resources/test_memories.py | 610 ++++++++++++
tests/test_client.py | 48 +-
30 files changed, 4065 insertions(+), 42 deletions(-)
create mode 100644 src/supermemory/resources/documents.py
create mode 100644 src/supermemory/resources/memories.py
create mode 100644 src/supermemory/types/document_add_params.py
create mode 100644 src/supermemory/types/document_add_response.py
create mode 100644 src/supermemory/types/document_get_response.py
create mode 100644 src/supermemory/types/document_list_params.py
create mode 100644 src/supermemory/types/document_list_response.py
create mode 100644 src/supermemory/types/document_update_params.py
create mode 100644 src/supermemory/types/document_update_response.py
create mode 100644 src/supermemory/types/document_upload_file_params.py
create mode 100644 src/supermemory/types/document_upload_file_response.py
create mode 100644 src/supermemory/types/memory_add_params.py
create mode 100644 src/supermemory/types/memory_add_response.py
create mode 100644 src/supermemory/types/memory_get_response.py
create mode 100644 src/supermemory/types/memory_list_params.py
create mode 100644 src/supermemory/types/memory_list_response.py
create mode 100644 src/supermemory/types/memory_update_params.py
create mode 100644 src/supermemory/types/memory_update_response.py
create mode 100644 src/supermemory/types/memory_upload_file_params.py
create mode 100644 src/supermemory/types/memory_upload_file_response.py
create mode 100644 tests/api_resources/test_documents.py
create mode 100644 tests/api_resources/test_memories.py
diff --git a/.stats.yml b/.stats.yml
index cac7cf67..9074c3a5 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 12
+configured_endpoints: 18
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-f181eaeb22a42d197dbd9c45fa61bf9a9b78a91d3334fc0f841494dc73d1a203.yml
openapi_spec_hash: bb8262ebcdea53979cf1cafbc2c68dc8
-config_hash: 9b9291a6c872b063900a46386729ba3c
+config_hash: 2737bce9823a13e0263c0fa2701821fa
diff --git a/README.md b/README.md
index 05e12990..7d5a5197 100644
--- a/README.md
+++ b/README.md
@@ -127,6 +127,23 @@ response = client.search.memories(
print(response.include)
```
+## File uploads
+
+Request parameters that correspond to file uploads can be passed as `bytes`, or a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`.
+
+```python
+from pathlib import Path
+from supermemory import Supermemory
+
+client = Supermemory()
+
+client.memories.upload_file(
+ file=Path("/path/to/file"),
+)
+```
+
+The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically.
+
## Handling errors
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `supermemory.APIConnectionError` is raised.
@@ -143,8 +160,8 @@ from supermemory import Supermemory
client = Supermemory()
try:
- client.search.documents(
- q="machine learning concepts",
+ client.memories.update(
+ id="id",
)
except supermemory.APIConnectionError as e:
print("The server could not be reached")
@@ -188,8 +205,8 @@ client = Supermemory(
)
# Or, configure per-request:
-client.with_options(max_retries=5).search.documents(
- q="machine learning concepts",
+client.with_options(max_retries=5).memories.update(
+ id="id",
)
```
@@ -213,8 +230,8 @@ client = Supermemory(
)
# Override per-request:
-client.with_options(timeout=5.0).search.documents(
- q="machine learning concepts",
+client.with_options(timeout=5.0).memories.update(
+ id="id",
)
```
@@ -256,13 +273,13 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
from supermemory import Supermemory
client = Supermemory()
-response = client.search.with_raw_response.documents(
- q="machine learning concepts",
+response = client.memories.with_raw_response.update(
+ id="id",
)
print(response.headers.get('X-My-Header'))
-search = response.parse() # get the object that `search.documents()` would have returned
-print(search.results)
+memory = response.parse() # get the object that `memories.update()` would have returned
+print(memory.id)
```
These methods return an [`APIResponse`](https://github.com/supermemoryai/python-sdk/tree/main/src/supermemory/_response.py) object.
@@ -276,8 +293,8 @@ The above interface eagerly reads the full response body when you make the reque
To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.
```python
-with client.search.with_streaming_response.documents(
- q="machine learning concepts",
+with client.memories.with_streaming_response.update(
+ id="id",
) as response:
print(response.headers.get("X-My-Header"))
diff --git a/api.md b/api.md
index 083ba491..7aa6afa9 100644
--- a/api.md
+++ b/api.md
@@ -1,3 +1,49 @@
+# Memories
+
+Types:
+
+```python
+from supermemory.types import (
+ MemoryUpdateResponse,
+ MemoryListResponse,
+ MemoryAddResponse,
+ MemoryGetResponse,
+ MemoryUploadFileResponse,
+)
+```
+
+Methods:
+
+- client.memories.update(id, \*\*params) -> MemoryUpdateResponse
+- client.memories.list(\*\*params) -> MemoryListResponse
+- client.memories.delete(id) -> None
+- client.memories.add(\*\*params) -> MemoryAddResponse
+- client.memories.get(id) -> MemoryGetResponse
+- client.memories.upload_file(\*\*params) -> MemoryUploadFileResponse
+
+# Documents
+
+Types:
+
+```python
+from supermemory.types import (
+ DocumentUpdateResponse,
+ DocumentListResponse,
+ DocumentAddResponse,
+ DocumentGetResponse,
+ DocumentUploadFileResponse,
+)
+```
+
+Methods:
+
+- client.documents.update(id, \*\*params) -> DocumentUpdateResponse
+- client.documents.list(\*\*params) -> DocumentListResponse
+- client.documents.delete(id) -> None
+- client.documents.add(\*\*params) -> DocumentAddResponse
+- client.documents.get(id) -> DocumentGetResponse
+- client.documents.upload_file(\*\*params) -> DocumentUploadFileResponse
+
# Search
Types:
diff --git a/src/supermemory/_client.py b/src/supermemory/_client.py
index 222d8fa6..c27fc11a 100644
--- a/src/supermemory/_client.py
+++ b/src/supermemory/_client.py
@@ -21,7 +21,7 @@
)
from ._utils import is_given, get_async_library
from ._version import __version__
-from .resources import search, settings, connections
+from .resources import search, memories, settings, documents, connections
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
from ._exceptions import APIStatusError, SupermemoryError
from ._base_client import (
@@ -43,6 +43,8 @@
class Supermemory(SyncAPIClient):
+ memories: memories.MemoriesResource
+ documents: documents.DocumentsResource
search: search.SearchResource
settings: settings.SettingsResource
connections: connections.ConnectionsResource
@@ -103,6 +105,8 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
+ self.memories = memories.MemoriesResource(self)
+ self.documents = documents.DocumentsResource(self)
self.search = search.SearchResource(self)
self.settings = settings.SettingsResource(self)
self.connections = connections.ConnectionsResource(self)
@@ -215,6 +219,8 @@ def _make_status_error(
class AsyncSupermemory(AsyncAPIClient):
+ memories: memories.AsyncMemoriesResource
+ documents: documents.AsyncDocumentsResource
search: search.AsyncSearchResource
settings: settings.AsyncSettingsResource
connections: connections.AsyncConnectionsResource
@@ -275,6 +281,8 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
+ self.memories = memories.AsyncMemoriesResource(self)
+ self.documents = documents.AsyncDocumentsResource(self)
self.search = search.AsyncSearchResource(self)
self.settings = settings.AsyncSettingsResource(self)
self.connections = connections.AsyncConnectionsResource(self)
@@ -388,6 +396,8 @@ def _make_status_error(
class SupermemoryWithRawResponse:
def __init__(self, client: Supermemory) -> None:
+ self.memories = memories.MemoriesResourceWithRawResponse(client.memories)
+ self.documents = documents.DocumentsResourceWithRawResponse(client.documents)
self.search = search.SearchResourceWithRawResponse(client.search)
self.settings = settings.SettingsResourceWithRawResponse(client.settings)
self.connections = connections.ConnectionsResourceWithRawResponse(client.connections)
@@ -395,6 +405,8 @@ def __init__(self, client: Supermemory) -> None:
class AsyncSupermemoryWithRawResponse:
def __init__(self, client: AsyncSupermemory) -> None:
+ self.memories = memories.AsyncMemoriesResourceWithRawResponse(client.memories)
+ self.documents = documents.AsyncDocumentsResourceWithRawResponse(client.documents)
self.search = search.AsyncSearchResourceWithRawResponse(client.search)
self.settings = settings.AsyncSettingsResourceWithRawResponse(client.settings)
self.connections = connections.AsyncConnectionsResourceWithRawResponse(client.connections)
@@ -402,6 +414,8 @@ def __init__(self, client: AsyncSupermemory) -> None:
class SupermemoryWithStreamedResponse:
def __init__(self, client: Supermemory) -> None:
+ self.memories = memories.MemoriesResourceWithStreamingResponse(client.memories)
+ self.documents = documents.DocumentsResourceWithStreamingResponse(client.documents)
self.search = search.SearchResourceWithStreamingResponse(client.search)
self.settings = settings.SettingsResourceWithStreamingResponse(client.settings)
self.connections = connections.ConnectionsResourceWithStreamingResponse(client.connections)
@@ -409,6 +423,8 @@ def __init__(self, client: Supermemory) -> None:
class AsyncSupermemoryWithStreamedResponse:
def __init__(self, client: AsyncSupermemory) -> None:
+ self.memories = memories.AsyncMemoriesResourceWithStreamingResponse(client.memories)
+ self.documents = documents.AsyncDocumentsResourceWithStreamingResponse(client.documents)
self.search = search.AsyncSearchResourceWithStreamingResponse(client.search)
self.settings = settings.AsyncSettingsResourceWithStreamingResponse(client.settings)
self.connections = connections.AsyncConnectionsResourceWithStreamingResponse(client.connections)
diff --git a/src/supermemory/_files.py b/src/supermemory/_files.py
index cc14c14f..ae7c4650 100644
--- a/src/supermemory/_files.py
+++ b/src/supermemory/_files.py
@@ -34,7 +34,7 @@ def assert_is_file_content(obj: object, *, key: str | None = None) -> None:
if not is_file_content(obj):
prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`"
raise RuntimeError(
- f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead."
+ f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead. See https://github.com/supermemoryai/python-sdk/tree/main#file-uploads"
) from None
diff --git a/src/supermemory/resources/__init__.py b/src/supermemory/resources/__init__.py
index de24910f..ca24f73f 100644
--- a/src/supermemory/resources/__init__.py
+++ b/src/supermemory/resources/__init__.py
@@ -8,6 +8,14 @@
SearchResourceWithStreamingResponse,
AsyncSearchResourceWithStreamingResponse,
)
+from .memories import (
+ MemoriesResource,
+ AsyncMemoriesResource,
+ MemoriesResourceWithRawResponse,
+ AsyncMemoriesResourceWithRawResponse,
+ MemoriesResourceWithStreamingResponse,
+ AsyncMemoriesResourceWithStreamingResponse,
+)
from .settings import (
SettingsResource,
AsyncSettingsResource,
@@ -16,6 +24,14 @@
SettingsResourceWithStreamingResponse,
AsyncSettingsResourceWithStreamingResponse,
)
+from .documents import (
+ DocumentsResource,
+ AsyncDocumentsResource,
+ DocumentsResourceWithRawResponse,
+ AsyncDocumentsResourceWithRawResponse,
+ DocumentsResourceWithStreamingResponse,
+ AsyncDocumentsResourceWithStreamingResponse,
+)
from .connections import (
ConnectionsResource,
AsyncConnectionsResource,
@@ -26,6 +42,18 @@
)
__all__ = [
+ "MemoriesResource",
+ "AsyncMemoriesResource",
+ "MemoriesResourceWithRawResponse",
+ "AsyncMemoriesResourceWithRawResponse",
+ "MemoriesResourceWithStreamingResponse",
+ "AsyncMemoriesResourceWithStreamingResponse",
+ "DocumentsResource",
+ "AsyncDocumentsResource",
+ "DocumentsResourceWithRawResponse",
+ "AsyncDocumentsResourceWithRawResponse",
+ "DocumentsResourceWithStreamingResponse",
+ "AsyncDocumentsResourceWithStreamingResponse",
"SearchResource",
"AsyncSearchResource",
"SearchResourceWithRawResponse",
diff --git a/src/supermemory/resources/documents.py b/src/supermemory/resources/documents.py
new file mode 100644
index 00000000..afd4ff33
--- /dev/null
+++ b/src/supermemory/resources/documents.py
@@ -0,0 +1,894 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Mapping, cast
+from typing_extensions import Literal
+
+import httpx
+
+from ..types import document_add_params, document_list_params, document_update_params, document_upload_file_params
+from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven, FileTypes, SequenceNotStr
+from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.document_add_response import DocumentAddResponse
+from ..types.document_get_response import DocumentGetResponse
+from ..types.document_list_response import DocumentListResponse
+from ..types.document_update_response import DocumentUpdateResponse
+from ..types.document_upload_file_response import DocumentUploadFileResponse
+
+__all__ = ["DocumentsResource", "AsyncDocumentsResource"]
+
+
+class DocumentsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> DocumentsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return DocumentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DocumentsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#with_streaming_response
+ """
+ return DocumentsResourceWithStreamingResponse(self)
+
+ def update(
+ self,
+ id: str,
+ *,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ content: str | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentUpdateResponse:
+ """
+ Update a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._patch(
+ f"/v3/documents/{id}",
+ body=maybe_transform(
+ {
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "content": content,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ document_update_params.DocumentUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentUpdateResponse,
+ )
+
+ def list(
+ self,
+ *,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ filters: str | NotGiven = NOT_GIVEN,
+ include_content: bool | NotGiven = NOT_GIVEN,
+ limit: Union[str, float] | NotGiven = NOT_GIVEN,
+ order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ page: Union[str, float] | NotGiven = NOT_GIVEN,
+ sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentListResponse:
+ """
+ Retrieves a paginated list of documents with their metadata and workflow status
+
+ Args:
+ container_tags: Optional tags this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ filters: Optional filters to apply to the search
+
+ include_content: Whether to include the content field in the response. Warning: This can make
+ responses significantly larger.
+
+ limit: Number of items per page
+
+ order: Sort order
+
+ page: Page number to fetch
+
+ sort: Field to sort by
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/v3/documents/list",
+ body=maybe_transform(
+ {
+ "container_tags": container_tags,
+ "filters": filters,
+ "include_content": include_content,
+ "limit": limit,
+ "order": order,
+ "page": page,
+ "sort": sort,
+ },
+ document_list_params.DocumentListParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentListResponse,
+ )
+
+ def delete(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Delete a document by ID or customId
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ def add(
+ self,
+ *,
+ content: str,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentAddResponse:
+ """
+ Add a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/v3/documents",
+ body=maybe_transform(
+ {
+ "content": content,
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ document_add_params.DocumentAddParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentAddResponse,
+ )
+
+ def get(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentGetResponse:
+ """
+ Get a document by ID
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentGetResponse,
+ )
+
+ def upload_file(
+ self,
+ *,
+ file: FileTypes,
+ container_tags: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentUploadFileResponse:
+ """
+ Upload a file to be processed
+
+ Args:
+ file: File to upload and process
+
+ container_tags: Optional JSON string of container tags array. This can be an ID for your user, a
+ project ID, or any other identifier you wish to use to group documents.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ body = deepcopy_minimal(
+ {
+ "file": file,
+ "container_tags": container_tags,
+ "file_type": file_type,
+ "mime_type": mime_type,
+ }
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return self._post(
+ "/v3/documents/file",
+ body=maybe_transform(body, document_upload_file_params.DocumentUploadFileParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentUploadFileResponse,
+ )
+
+
+class AsyncDocumentsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncDocumentsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return AsyncDocumentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDocumentsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#with_streaming_response
+ """
+ return AsyncDocumentsResourceWithStreamingResponse(self)
+
+ async def update(
+ self,
+ id: str,
+ *,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ content: str | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentUpdateResponse:
+ """
+ Update a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._patch(
+ f"/v3/documents/{id}",
+ body=await async_maybe_transform(
+ {
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "content": content,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ document_update_params.DocumentUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentUpdateResponse,
+ )
+
+ async def list(
+ self,
+ *,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ filters: str | NotGiven = NOT_GIVEN,
+ include_content: bool | NotGiven = NOT_GIVEN,
+ limit: Union[str, float] | NotGiven = NOT_GIVEN,
+ order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ page: Union[str, float] | NotGiven = NOT_GIVEN,
+ sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentListResponse:
+ """
+ Retrieves a paginated list of documents with their metadata and workflow status
+
+ Args:
+ container_tags: Optional tags this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ filters: Optional filters to apply to the search
+
+ include_content: Whether to include the content field in the response. Warning: This can make
+ responses significantly larger.
+
+ limit: Number of items per page
+
+ order: Sort order
+
+ page: Page number to fetch
+
+ sort: Field to sort by
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/v3/documents/list",
+ body=await async_maybe_transform(
+ {
+ "container_tags": container_tags,
+ "filters": filters,
+ "include_content": include_content,
+ "limit": limit,
+ "order": order,
+ "page": page,
+ "sort": sort,
+ },
+ document_list_params.DocumentListParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentListResponse,
+ )
+
+ async def delete(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Delete a document by ID or customId
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ async def add(
+ self,
+ *,
+ content: str,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentAddResponse:
+ """
+ Add a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/v3/documents",
+ body=await async_maybe_transform(
+ {
+ "content": content,
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ document_add_params.DocumentAddParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentAddResponse,
+ )
+
+ async def get(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentGetResponse:
+ """
+ Get a document by ID
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentGetResponse,
+ )
+
+ async def upload_file(
+ self,
+ *,
+ file: FileTypes,
+ container_tags: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> DocumentUploadFileResponse:
+ """
+ Upload a file to be processed
+
+ Args:
+ file: File to upload and process
+
+ container_tags: Optional JSON string of container tags array. This can be an ID for your user, a
+ project ID, or any other identifier you wish to use to group documents.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ body = deepcopy_minimal(
+ {
+ "file": file,
+ "container_tags": container_tags,
+ "file_type": file_type,
+ "mime_type": mime_type,
+ }
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return await self._post(
+ "/v3/documents/file",
+ body=await async_maybe_transform(body, document_upload_file_params.DocumentUploadFileParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DocumentUploadFileResponse,
+ )
+
+
+class DocumentsResourceWithRawResponse:
+ def __init__(self, documents: DocumentsResource) -> None:
+ self._documents = documents
+
+ self.update = to_raw_response_wrapper(
+ documents.update,
+ )
+ self.list = to_raw_response_wrapper(
+ documents.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ documents.delete,
+ )
+ self.add = to_raw_response_wrapper(
+ documents.add,
+ )
+ self.get = to_raw_response_wrapper(
+ documents.get,
+ )
+ self.upload_file = to_raw_response_wrapper(
+ documents.upload_file,
+ )
+
+
+class AsyncDocumentsResourceWithRawResponse:
+ def __init__(self, documents: AsyncDocumentsResource) -> None:
+ self._documents = documents
+
+ self.update = async_to_raw_response_wrapper(
+ documents.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ documents.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ documents.delete,
+ )
+ self.add = async_to_raw_response_wrapper(
+ documents.add,
+ )
+ self.get = async_to_raw_response_wrapper(
+ documents.get,
+ )
+ self.upload_file = async_to_raw_response_wrapper(
+ documents.upload_file,
+ )
+
+
+class DocumentsResourceWithStreamingResponse:
+ def __init__(self, documents: DocumentsResource) -> None:
+ self._documents = documents
+
+ self.update = to_streamed_response_wrapper(
+ documents.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ documents.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ documents.delete,
+ )
+ self.add = to_streamed_response_wrapper(
+ documents.add,
+ )
+ self.get = to_streamed_response_wrapper(
+ documents.get,
+ )
+ self.upload_file = to_streamed_response_wrapper(
+ documents.upload_file,
+ )
+
+
+class AsyncDocumentsResourceWithStreamingResponse:
+ def __init__(self, documents: AsyncDocumentsResource) -> None:
+ self._documents = documents
+
+ self.update = async_to_streamed_response_wrapper(
+ documents.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ documents.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ documents.delete,
+ )
+ self.add = async_to_streamed_response_wrapper(
+ documents.add,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ documents.get,
+ )
+ self.upload_file = async_to_streamed_response_wrapper(
+ documents.upload_file,
+ )
diff --git a/src/supermemory/resources/memories.py b/src/supermemory/resources/memories.py
new file mode 100644
index 00000000..42a6348c
--- /dev/null
+++ b/src/supermemory/resources/memories.py
@@ -0,0 +1,894 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Mapping, cast
+from typing_extensions import Literal
+
+import httpx
+
+from ..types import memory_add_params, memory_list_params, memory_update_params, memory_upload_file_params
+from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven, FileTypes, SequenceNotStr
+from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .._base_client import make_request_options
+from ..types.memory_add_response import MemoryAddResponse
+from ..types.memory_get_response import MemoryGetResponse
+from ..types.memory_list_response import MemoryListResponse
+from ..types.memory_update_response import MemoryUpdateResponse
+from ..types.memory_upload_file_response import MemoryUploadFileResponse
+
+__all__ = ["MemoriesResource", "AsyncMemoriesResource"]
+
+
+class MemoriesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> MemoriesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return MemoriesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> MemoriesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#with_streaming_response
+ """
+ return MemoriesResourceWithStreamingResponse(self)
+
+ def update(
+ self,
+ id: str,
+ *,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ content: str | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryUpdateResponse:
+ """
+ Update a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._patch(
+ f"/v3/documents/{id}",
+ body=maybe_transform(
+ {
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "content": content,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ memory_update_params.MemoryUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryUpdateResponse,
+ )
+
+ def list(
+ self,
+ *,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ filters: str | NotGiven = NOT_GIVEN,
+ include_content: bool | NotGiven = NOT_GIVEN,
+ limit: Union[str, float] | NotGiven = NOT_GIVEN,
+ order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ page: Union[str, float] | NotGiven = NOT_GIVEN,
+ sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryListResponse:
+ """
+ Retrieves a paginated list of documents with their metadata and workflow status
+
+ Args:
+ container_tags: Optional tags this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ filters: Optional filters to apply to the search
+
+ include_content: Whether to include the content field in the response. Warning: This can make
+ responses significantly larger.
+
+ limit: Number of items per page
+
+ order: Sort order
+
+ page: Page number to fetch
+
+ sort: Field to sort by
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/v3/documents/list",
+ body=maybe_transform(
+ {
+ "container_tags": container_tags,
+ "filters": filters,
+ "include_content": include_content,
+ "limit": limit,
+ "order": order,
+ "page": page,
+ "sort": sort,
+ },
+ memory_list_params.MemoryListParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryListResponse,
+ )
+
+ def delete(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Delete a document by ID or customId
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ def add(
+ self,
+ *,
+ content: str,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryAddResponse:
+ """
+ Add a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/v3/documents",
+ body=maybe_transform(
+ {
+ "content": content,
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ memory_add_params.MemoryAddParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryAddResponse,
+ )
+
+ def get(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryGetResponse:
+ """
+ Get a document by ID
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryGetResponse,
+ )
+
+ def upload_file(
+ self,
+ *,
+ file: FileTypes,
+ container_tags: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryUploadFileResponse:
+ """
+ Upload a file to be processed
+
+ Args:
+ file: File to upload and process
+
+ container_tags: Optional JSON string of container tags array. This can be an ID for your user, a
+ project ID, or any other identifier you wish to use to group documents.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ body = deepcopy_minimal(
+ {
+ "file": file,
+ "container_tags": container_tags,
+ "file_type": file_type,
+ "mime_type": mime_type,
+ }
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return self._post(
+ "/v3/documents/file",
+ body=maybe_transform(body, memory_upload_file_params.MemoryUploadFileParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryUploadFileResponse,
+ )
+
+
+class AsyncMemoriesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncMemoriesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return AsyncMemoriesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncMemoriesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/supermemoryai/python-sdk#with_streaming_response
+ """
+ return AsyncMemoriesResourceWithStreamingResponse(self)
+
+ async def update(
+ self,
+ id: str,
+ *,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ content: str | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryUpdateResponse:
+ """
+ Update a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._patch(
+ f"/v3/documents/{id}",
+ body=await async_maybe_transform(
+ {
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "content": content,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ memory_update_params.MemoryUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryUpdateResponse,
+ )
+
+ async def list(
+ self,
+ *,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ filters: str | NotGiven = NOT_GIVEN,
+ include_content: bool | NotGiven = NOT_GIVEN,
+ limit: Union[str, float] | NotGiven = NOT_GIVEN,
+ order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
+ page: Union[str, float] | NotGiven = NOT_GIVEN,
+ sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryListResponse:
+ """
+ Retrieves a paginated list of documents with their metadata and workflow status
+
+ Args:
+ container_tags: Optional tags this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ filters: Optional filters to apply to the search
+
+ include_content: Whether to include the content field in the response. Warning: This can make
+ responses significantly larger.
+
+ limit: Number of items per page
+
+ order: Sort order
+
+ page: Page number to fetch
+
+ sort: Field to sort by
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/v3/documents/list",
+ body=await async_maybe_transform(
+ {
+ "container_tags": container_tags,
+ "filters": filters,
+ "include_content": include_content,
+ "limit": limit,
+ "order": order,
+ "page": page,
+ "sort": sort,
+ },
+ memory_list_params.MemoryListParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryListResponse,
+ )
+
+ async def delete(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Delete a document by ID or customId
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ async def add(
+ self,
+ *,
+ content: str,
+ container_tag: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ custom_id: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryAddResponse:
+ """
+ Add a document with any content type (text, url, file, etc.) and metadata
+
+ Args:
+ content: The content to extract and process into a document. This can be a URL to a
+ website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+
+ container_tag: Optional tag this document should be containerized by. This can be an ID for
+ your user, a project ID, or any other identifier you wish to use to group
+ documents.
+
+ container_tags: (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+
+ custom_id: Optional custom ID of the document. This could be an ID from your database that
+ will uniquely identify this document.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ metadata: Optional metadata for the document. This is used to store additional information
+ about the document. You can use this to store any additional information you
+ need about the document. Metadata can be filtered through. Keys must be strings
+ and are case sensitive. Values can be strings, numbers, or booleans. You cannot
+ nest objects.
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/v3/documents",
+ body=await async_maybe_transform(
+ {
+ "content": content,
+ "container_tag": container_tag,
+ "container_tags": container_tags,
+ "custom_id": custom_id,
+ "file_type": file_type,
+ "metadata": metadata,
+ "mime_type": mime_type,
+ },
+ memory_add_params.MemoryAddParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryAddResponse,
+ )
+
+ async def get(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryGetResponse:
+ """
+ Get a document by ID
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ f"/v3/documents/{id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryGetResponse,
+ )
+
+ async def upload_file(
+ self,
+ *,
+ file: FileTypes,
+ container_tags: str | NotGiven = NOT_GIVEN,
+ file_type: str | NotGiven = NOT_GIVEN,
+ mime_type: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MemoryUploadFileResponse:
+ """
+ Upload a file to be processed
+
+ Args:
+ file: File to upload and process
+
+ container_tags: Optional JSON string of container tags array. This can be an ID for your user, a
+ project ID, or any other identifier you wish to use to group documents.
+
+ file_type:
+ Optional file type override to force specific processing behavior. Valid values:
+ text, pdf, tweet, google_doc, google_slide, google_sheet, image, video,
+ notion_doc, webpage, onedrive
+
+ mime_type: Required when fileType is 'image' or 'video'. Specifies the exact MIME type to
+ use (e.g., 'image/png', 'image/jpeg', 'video/mp4', 'video/webm')
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ body = deepcopy_minimal(
+ {
+ "file": file,
+ "container_tags": container_tags,
+ "file_type": file_type,
+ "mime_type": mime_type,
+ }
+ )
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
+ # It should be noted that the actual Content-Type header that will be
+ # sent to the server will contain a `boundary` parameter, e.g.
+ # multipart/form-data; boundary=---abc--
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
+ return await self._post(
+ "/v3/documents/file",
+ body=await async_maybe_transform(body, memory_upload_file_params.MemoryUploadFileParams),
+ files=files,
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MemoryUploadFileResponse,
+ )
+
+
+class MemoriesResourceWithRawResponse:
+ def __init__(self, memories: MemoriesResource) -> None:
+ self._memories = memories
+
+ self.update = to_raw_response_wrapper(
+ memories.update,
+ )
+ self.list = to_raw_response_wrapper(
+ memories.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ memories.delete,
+ )
+ self.add = to_raw_response_wrapper(
+ memories.add,
+ )
+ self.get = to_raw_response_wrapper(
+ memories.get,
+ )
+ self.upload_file = to_raw_response_wrapper(
+ memories.upload_file,
+ )
+
+
+class AsyncMemoriesResourceWithRawResponse:
+ def __init__(self, memories: AsyncMemoriesResource) -> None:
+ self._memories = memories
+
+ self.update = async_to_raw_response_wrapper(
+ memories.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ memories.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ memories.delete,
+ )
+ self.add = async_to_raw_response_wrapper(
+ memories.add,
+ )
+ self.get = async_to_raw_response_wrapper(
+ memories.get,
+ )
+ self.upload_file = async_to_raw_response_wrapper(
+ memories.upload_file,
+ )
+
+
+class MemoriesResourceWithStreamingResponse:
+ def __init__(self, memories: MemoriesResource) -> None:
+ self._memories = memories
+
+ self.update = to_streamed_response_wrapper(
+ memories.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ memories.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ memories.delete,
+ )
+ self.add = to_streamed_response_wrapper(
+ memories.add,
+ )
+ self.get = to_streamed_response_wrapper(
+ memories.get,
+ )
+ self.upload_file = to_streamed_response_wrapper(
+ memories.upload_file,
+ )
+
+
+class AsyncMemoriesResourceWithStreamingResponse:
+ def __init__(self, memories: AsyncMemoriesResource) -> None:
+ self._memories = memories
+
+ self.update = async_to_streamed_response_wrapper(
+ memories.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ memories.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ memories.delete,
+ )
+ self.add = async_to_streamed_response_wrapper(
+ memories.add,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ memories.get,
+ )
+ self.upload_file = async_to_streamed_response_wrapper(
+ memories.upload_file,
+ )
diff --git a/src/supermemory/types/__init__.py b/src/supermemory/types/__init__.py
index 6a34d7ba..beace710 100644
--- a/src/supermemory/types/__init__.py
+++ b/src/supermemory/types/__init__.py
@@ -2,10 +2,23 @@
from __future__ import annotations
+from .memory_add_params import MemoryAddParams as MemoryAddParams
+from .memory_list_params import MemoryListParams as MemoryListParams
+from .document_add_params import DocumentAddParams as DocumentAddParams
+from .memory_add_response import MemoryAddResponse as MemoryAddResponse
+from .memory_get_response import MemoryGetResponse as MemoryGetResponse
+from .document_list_params import DocumentListParams as DocumentListParams
+from .memory_list_response import MemoryListResponse as MemoryListResponse
+from .memory_update_params import MemoryUpdateParams as MemoryUpdateParams
from .setting_get_response import SettingGetResponse as SettingGetResponse
+from .document_add_response import DocumentAddResponse as DocumentAddResponse
+from .document_get_response import DocumentGetResponse as DocumentGetResponse
from .search_execute_params import SearchExecuteParams as SearchExecuteParams
from .setting_update_params import SettingUpdateParams as SettingUpdateParams
from .connection_list_params import ConnectionListParams as ConnectionListParams
+from .document_list_response import DocumentListResponse as DocumentListResponse
+from .document_update_params import DocumentUpdateParams as DocumentUpdateParams
+from .memory_update_response import MemoryUpdateResponse as MemoryUpdateResponse
from .search_memories_params import SearchMemoriesParams as SearchMemoriesParams
from .search_documents_params import SearchDocumentsParams as SearchDocumentsParams
from .search_execute_response import SearchExecuteResponse as SearchExecuteResponse
@@ -13,12 +26,17 @@
from .connection_create_params import ConnectionCreateParams as ConnectionCreateParams
from .connection_import_params import ConnectionImportParams as ConnectionImportParams
from .connection_list_response import ConnectionListResponse as ConnectionListResponse
+from .document_update_response import DocumentUpdateResponse as DocumentUpdateResponse
from .search_memories_response import SearchMemoriesResponse as SearchMemoriesResponse
+from .memory_upload_file_params import MemoryUploadFileParams as MemoryUploadFileParams
from .search_documents_response import SearchDocumentsResponse as SearchDocumentsResponse
from .connection_create_response import ConnectionCreateResponse as ConnectionCreateResponse
from .connection_import_response import ConnectionImportResponse as ConnectionImportResponse
+from .document_upload_file_params import DocumentUploadFileParams as DocumentUploadFileParams
+from .memory_upload_file_response import MemoryUploadFileResponse as MemoryUploadFileResponse
from .connection_get_by_id_response import ConnectionGetByIDResponse as ConnectionGetByIDResponse
from .connection_get_by_tags_params import ConnectionGetByTagsParams as ConnectionGetByTagsParams
+from .document_upload_file_response import DocumentUploadFileResponse as DocumentUploadFileResponse
from .connection_get_by_tags_response import ConnectionGetByTagsResponse as ConnectionGetByTagsResponse
from .connection_delete_by_id_response import ConnectionDeleteByIDResponse as ConnectionDeleteByIDResponse
from .connection_list_documents_params import ConnectionListDocumentsParams as ConnectionListDocumentsParams
diff --git a/src/supermemory/types/document_add_params.py b/src/supermemory/types/document_add_params.py
new file mode 100644
index 00000000..c07a50f5
--- /dev/null
+++ b/src/supermemory/types/document_add_params.py
@@ -0,0 +1,69 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union
+from typing_extensions import Required, Annotated, TypedDict
+
+from .._types import SequenceNotStr
+from .._utils import PropertyInfo
+
+__all__ = ["DocumentAddParams"]
+
+
+class DocumentAddParams(TypedDict, total=False):
+ content: Required[str]
+ """The content to extract and process into a document.
+
+ This can be a URL to a website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+ """
+
+ container_tag: Annotated[str, PropertyInfo(alias="containerTag")]
+ """Optional tag this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]
+ """
+ (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+ """
+
+ custom_id: Annotated[str, PropertyInfo(alias="customId")]
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ file_type: Annotated[str, PropertyInfo(alias="fileType")]
+ """Optional file type override to force specific processing behavior.
+
+ Valid values: text, pdf, tweet, google_doc, google_slide, google_sheet, image,
+ video, notion_doc, webpage, onedrive
+ """
+
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]]
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ mime_type: Annotated[str, PropertyInfo(alias="mimeType")]
+ """Required when fileType is 'image' or 'video'.
+
+ Specifies the exact MIME type to use (e.g., 'image/png', 'image/jpeg',
+ 'video/mp4', 'video/webm')
+ """
diff --git a/src/supermemory/types/document_add_response.py b/src/supermemory/types/document_add_response.py
new file mode 100644
index 00000000..5a123794
--- /dev/null
+++ b/src/supermemory/types/document_add_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["DocumentAddResponse"]
+
+
+class DocumentAddResponse(BaseModel):
+ id: str
+
+ status: str
diff --git a/src/supermemory/types/document_get_response.py b/src/supermemory/types/document_get_response.py
new file mode 100644
index 00000000..f812b5a8
--- /dev/null
+++ b/src/supermemory/types/document_get_response.py
@@ -0,0 +1,104 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["DocumentGetResponse"]
+
+
+class DocumentGetResponse(BaseModel):
+ id: str
+ """Unique identifier of the document."""
+
+ connection_id: Optional[str] = FieldInfo(alias="connectionId", default=None)
+ """Optional ID of connection the document was created from.
+
+ This is useful for identifying the source of the document.
+ """
+
+ content: Optional[str] = None
+ """The content to extract and process into a document.
+
+ This can be a URL to a website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+ """
+
+ created_at: datetime = FieldInfo(alias="createdAt")
+ """Creation timestamp"""
+
+ custom_id: Optional[str] = FieldInfo(alias="customId", default=None)
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ metadata: Union[str, float, bool, Dict[str, object], List[object], None] = None
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ og_image: Optional[str] = FieldInfo(alias="ogImage", default=None)
+
+ source: Optional[str] = None
+ """Source of the document"""
+
+ status: Literal["unknown", "queued", "extracting", "chunking", "embedding", "indexing", "done", "failed"]
+ """Status of the document"""
+
+ summary: Optional[str] = None
+ """Summary of the document content"""
+
+ summary_embedding_model: Optional[str] = FieldInfo(alias="summaryEmbeddingModel", default=None)
+
+ summary_embedding_model_new: Optional[str] = FieldInfo(alias="summaryEmbeddingModelNew", default=None)
+
+ summary_embedding_new: Optional[List[float]] = FieldInfo(alias="summaryEmbeddingNew", default=None)
+
+ title: Optional[str] = None
+ """Title of the document"""
+
+ type: Literal[
+ "text",
+ "pdf",
+ "tweet",
+ "google_doc",
+ "google_slide",
+ "google_sheet",
+ "image",
+ "video",
+ "notion_doc",
+ "webpage",
+ "onedrive",
+ ]
+ """Type of the document"""
+
+ updated_at: datetime = FieldInfo(alias="updatedAt")
+ """Last update timestamp"""
+
+ container_tags: Optional[List[str]] = FieldInfo(alias="containerTags", default=None)
+ """Optional tags this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ raw: None = None
+ """Raw content of the document"""
+
+ url: Optional[str] = None
+ """URL of the document"""
diff --git a/src/supermemory/types/document_list_params.py b/src/supermemory/types/document_list_params.py
new file mode 100644
index 00000000..d4915ef0
--- /dev/null
+++ b/src/supermemory/types/document_list_params.py
@@ -0,0 +1,41 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from typing_extensions import Literal, Annotated, TypedDict
+
+from .._types import SequenceNotStr
+from .._utils import PropertyInfo
+
+__all__ = ["DocumentListParams"]
+
+
+class DocumentListParams(TypedDict, total=False):
+ container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]
+ """Optional tags this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ filters: str
+ """Optional filters to apply to the search"""
+
+ include_content: Annotated[bool, PropertyInfo(alias="includeContent")]
+ """Whether to include the content field in the response.
+
+ Warning: This can make responses significantly larger.
+ """
+
+ limit: Union[str, float]
+ """Number of items per page"""
+
+ order: Literal["asc", "desc"]
+ """Sort order"""
+
+ page: Union[str, float]
+ """Page number to fetch"""
+
+ sort: Literal["createdAt", "updatedAt"]
+ """Field to sort by"""
diff --git a/src/supermemory/types/document_list_response.py b/src/supermemory/types/document_list_response.py
new file mode 100644
index 00000000..afb58f49
--- /dev/null
+++ b/src/supermemory/types/document_list_response.py
@@ -0,0 +1,95 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["DocumentListResponse", "Memory", "Pagination"]
+
+
+class Memory(BaseModel):
+ id: str
+ """Unique identifier of the document."""
+
+ connection_id: Optional[str] = FieldInfo(alias="connectionId", default=None)
+ """Optional ID of connection the document was created from.
+
+ This is useful for identifying the source of the document.
+ """
+
+ created_at: datetime = FieldInfo(alias="createdAt")
+ """Creation timestamp"""
+
+ custom_id: Optional[str] = FieldInfo(alias="customId", default=None)
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ metadata: Union[str, float, bool, Dict[str, object], List[object], None] = None
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ status: Literal["unknown", "queued", "extracting", "chunking", "embedding", "indexing", "done", "failed"]
+ """Status of the document"""
+
+ summary: Optional[str] = None
+ """Summary of the document content"""
+
+ title: Optional[str] = None
+ """Title of the document"""
+
+ type: Literal[
+ "text",
+ "pdf",
+ "tweet",
+ "google_doc",
+ "google_slide",
+ "google_sheet",
+ "image",
+ "video",
+ "notion_doc",
+ "webpage",
+ "onedrive",
+ ]
+ """Type of the document"""
+
+ updated_at: datetime = FieldInfo(alias="updatedAt")
+ """Last update timestamp"""
+
+ container_tags: Optional[List[str]] = FieldInfo(alias="containerTags", default=None)
+ """Optional tags this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ content: Optional[str] = None
+ """Content of the document (only included when includeContent=true)"""
+
+
+class Pagination(BaseModel):
+ current_page: float = FieldInfo(alias="currentPage")
+
+ limit: float
+
+ total_items: float = FieldInfo(alias="totalItems")
+
+ total_pages: float = FieldInfo(alias="totalPages")
+
+
+class DocumentListResponse(BaseModel):
+ memories: List[Memory]
+
+ pagination: Pagination
+ """Pagination metadata"""
diff --git a/src/supermemory/types/document_update_params.py b/src/supermemory/types/document_update_params.py
new file mode 100644
index 00000000..4b4b1218
--- /dev/null
+++ b/src/supermemory/types/document_update_params.py
@@ -0,0 +1,69 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union
+from typing_extensions import Annotated, TypedDict
+
+from .._types import SequenceNotStr
+from .._utils import PropertyInfo
+
+__all__ = ["DocumentUpdateParams"]
+
+
+class DocumentUpdateParams(TypedDict, total=False):
+ container_tag: Annotated[str, PropertyInfo(alias="containerTag")]
+ """Optional tag this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]
+ """
+ (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+ """
+
+ content: str
+ """The content to extract and process into a document.
+
+ This can be a URL to a website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+ """
+
+ custom_id: Annotated[str, PropertyInfo(alias="customId")]
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ file_type: Annotated[str, PropertyInfo(alias="fileType")]
+ """Optional file type override to force specific processing behavior.
+
+ Valid values: text, pdf, tweet, google_doc, google_slide, google_sheet, image,
+ video, notion_doc, webpage, onedrive
+ """
+
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]]
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ mime_type: Annotated[str, PropertyInfo(alias="mimeType")]
+ """Required when fileType is 'image' or 'video'.
+
+ Specifies the exact MIME type to use (e.g., 'image/png', 'image/jpeg',
+ 'video/mp4', 'video/webm')
+ """
diff --git a/src/supermemory/types/document_update_response.py b/src/supermemory/types/document_update_response.py
new file mode 100644
index 00000000..3b27289e
--- /dev/null
+++ b/src/supermemory/types/document_update_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["DocumentUpdateResponse"]
+
+
+class DocumentUpdateResponse(BaseModel):
+ id: str
+
+ status: str
diff --git a/src/supermemory/types/document_upload_file_params.py b/src/supermemory/types/document_upload_file_params.py
new file mode 100644
index 00000000..95c97d2d
--- /dev/null
+++ b/src/supermemory/types/document_upload_file_params.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, Annotated, TypedDict
+
+from .._types import FileTypes
+from .._utils import PropertyInfo
+
+__all__ = ["DocumentUploadFileParams"]
+
+
+class DocumentUploadFileParams(TypedDict, total=False):
+ file: Required[FileTypes]
+ """File to upload and process"""
+
+ container_tags: Annotated[str, PropertyInfo(alias="containerTags")]
+ """Optional JSON string of container tags array.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ file_type: Annotated[str, PropertyInfo(alias="fileType")]
+ """Optional file type override to force specific processing behavior.
+
+ Valid values: text, pdf, tweet, google_doc, google_slide, google_sheet, image,
+ video, notion_doc, webpage, onedrive
+ """
+
+ mime_type: Annotated[str, PropertyInfo(alias="mimeType")]
+ """Required when fileType is 'image' or 'video'.
+
+ Specifies the exact MIME type to use (e.g., 'image/png', 'image/jpeg',
+ 'video/mp4', 'video/webm')
+ """
diff --git a/src/supermemory/types/document_upload_file_response.py b/src/supermemory/types/document_upload_file_response.py
new file mode 100644
index 00000000..5801bcab
--- /dev/null
+++ b/src/supermemory/types/document_upload_file_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["DocumentUploadFileResponse"]
+
+
+class DocumentUploadFileResponse(BaseModel):
+ id: str
+
+ status: str
diff --git a/src/supermemory/types/memory_add_params.py b/src/supermemory/types/memory_add_params.py
new file mode 100644
index 00000000..21ed5bb4
--- /dev/null
+++ b/src/supermemory/types/memory_add_params.py
@@ -0,0 +1,69 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union
+from typing_extensions import Required, Annotated, TypedDict
+
+from .._types import SequenceNotStr
+from .._utils import PropertyInfo
+
+__all__ = ["MemoryAddParams"]
+
+
+class MemoryAddParams(TypedDict, total=False):
+ content: Required[str]
+ """The content to extract and process into a document.
+
+ This can be a URL to a website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+ """
+
+ container_tag: Annotated[str, PropertyInfo(alias="containerTag")]
+ """Optional tag this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]
+ """
+ (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+ """
+
+ custom_id: Annotated[str, PropertyInfo(alias="customId")]
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ file_type: Annotated[str, PropertyInfo(alias="fileType")]
+ """Optional file type override to force specific processing behavior.
+
+ Valid values: text, pdf, tweet, google_doc, google_slide, google_sheet, image,
+ video, notion_doc, webpage, onedrive
+ """
+
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]]
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ mime_type: Annotated[str, PropertyInfo(alias="mimeType")]
+ """Required when fileType is 'image' or 'video'.
+
+ Specifies the exact MIME type to use (e.g., 'image/png', 'image/jpeg',
+ 'video/mp4', 'video/webm')
+ """
diff --git a/src/supermemory/types/memory_add_response.py b/src/supermemory/types/memory_add_response.py
new file mode 100644
index 00000000..704918e4
--- /dev/null
+++ b/src/supermemory/types/memory_add_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["MemoryAddResponse"]
+
+
+class MemoryAddResponse(BaseModel):
+ id: str
+
+ status: str
diff --git a/src/supermemory/types/memory_get_response.py b/src/supermemory/types/memory_get_response.py
new file mode 100644
index 00000000..a495ade9
--- /dev/null
+++ b/src/supermemory/types/memory_get_response.py
@@ -0,0 +1,104 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["MemoryGetResponse"]
+
+
+class MemoryGetResponse(BaseModel):
+ id: str
+ """Unique identifier of the document."""
+
+ connection_id: Optional[str] = FieldInfo(alias="connectionId", default=None)
+ """Optional ID of connection the document was created from.
+
+ This is useful for identifying the source of the document.
+ """
+
+ content: Optional[str] = None
+ """The content to extract and process into a document.
+
+ This can be a URL to a website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+ """
+
+ created_at: datetime = FieldInfo(alias="createdAt")
+ """Creation timestamp"""
+
+ custom_id: Optional[str] = FieldInfo(alias="customId", default=None)
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ metadata: Union[str, float, bool, Dict[str, object], List[object], None] = None
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ og_image: Optional[str] = FieldInfo(alias="ogImage", default=None)
+
+ source: Optional[str] = None
+ """Source of the document"""
+
+ status: Literal["unknown", "queued", "extracting", "chunking", "embedding", "indexing", "done", "failed"]
+ """Status of the document"""
+
+ summary: Optional[str] = None
+ """Summary of the document content"""
+
+ summary_embedding_model: Optional[str] = FieldInfo(alias="summaryEmbeddingModel", default=None)
+
+ summary_embedding_model_new: Optional[str] = FieldInfo(alias="summaryEmbeddingModelNew", default=None)
+
+ summary_embedding_new: Optional[List[float]] = FieldInfo(alias="summaryEmbeddingNew", default=None)
+
+ title: Optional[str] = None
+ """Title of the document"""
+
+ type: Literal[
+ "text",
+ "pdf",
+ "tweet",
+ "google_doc",
+ "google_slide",
+ "google_sheet",
+ "image",
+ "video",
+ "notion_doc",
+ "webpage",
+ "onedrive",
+ ]
+ """Type of the document"""
+
+ updated_at: datetime = FieldInfo(alias="updatedAt")
+ """Last update timestamp"""
+
+ container_tags: Optional[List[str]] = FieldInfo(alias="containerTags", default=None)
+ """Optional tags this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ raw: None = None
+ """Raw content of the document"""
+
+ url: Optional[str] = None
+ """URL of the document"""
diff --git a/src/supermemory/types/memory_list_params.py b/src/supermemory/types/memory_list_params.py
new file mode 100644
index 00000000..c876faa6
--- /dev/null
+++ b/src/supermemory/types/memory_list_params.py
@@ -0,0 +1,41 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from typing_extensions import Literal, Annotated, TypedDict
+
+from .._types import SequenceNotStr
+from .._utils import PropertyInfo
+
+__all__ = ["MemoryListParams"]
+
+
+class MemoryListParams(TypedDict, total=False):
+ container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]
+ """Optional tags this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ filters: str
+ """Optional filters to apply to the search"""
+
+ include_content: Annotated[bool, PropertyInfo(alias="includeContent")]
+ """Whether to include the content field in the response.
+
+ Warning: This can make responses significantly larger.
+ """
+
+ limit: Union[str, float]
+ """Number of items per page"""
+
+ order: Literal["asc", "desc"]
+ """Sort order"""
+
+ page: Union[str, float]
+ """Page number to fetch"""
+
+ sort: Literal["createdAt", "updatedAt"]
+ """Field to sort by"""
diff --git a/src/supermemory/types/memory_list_response.py b/src/supermemory/types/memory_list_response.py
new file mode 100644
index 00000000..5eead3af
--- /dev/null
+++ b/src/supermemory/types/memory_list_response.py
@@ -0,0 +1,95 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["MemoryListResponse", "Memory", "Pagination"]
+
+
+class Memory(BaseModel):
+ id: str
+ """Unique identifier of the document."""
+
+ connection_id: Optional[str] = FieldInfo(alias="connectionId", default=None)
+ """Optional ID of connection the document was created from.
+
+ This is useful for identifying the source of the document.
+ """
+
+ created_at: datetime = FieldInfo(alias="createdAt")
+ """Creation timestamp"""
+
+ custom_id: Optional[str] = FieldInfo(alias="customId", default=None)
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ metadata: Union[str, float, bool, Dict[str, object], List[object], None] = None
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ status: Literal["unknown", "queued", "extracting", "chunking", "embedding", "indexing", "done", "failed"]
+ """Status of the document"""
+
+ summary: Optional[str] = None
+ """Summary of the document content"""
+
+ title: Optional[str] = None
+ """Title of the document"""
+
+ type: Literal[
+ "text",
+ "pdf",
+ "tweet",
+ "google_doc",
+ "google_slide",
+ "google_sheet",
+ "image",
+ "video",
+ "notion_doc",
+ "webpage",
+ "onedrive",
+ ]
+ """Type of the document"""
+
+ updated_at: datetime = FieldInfo(alias="updatedAt")
+ """Last update timestamp"""
+
+ container_tags: Optional[List[str]] = FieldInfo(alias="containerTags", default=None)
+ """Optional tags this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ content: Optional[str] = None
+ """Content of the document (only included when includeContent=true)"""
+
+
+class Pagination(BaseModel):
+ current_page: float = FieldInfo(alias="currentPage")
+
+ limit: float
+
+ total_items: float = FieldInfo(alias="totalItems")
+
+ total_pages: float = FieldInfo(alias="totalPages")
+
+
+class MemoryListResponse(BaseModel):
+ memories: List[Memory]
+
+ pagination: Pagination
+ """Pagination metadata"""
diff --git a/src/supermemory/types/memory_update_params.py b/src/supermemory/types/memory_update_params.py
new file mode 100644
index 00000000..1a1308a1
--- /dev/null
+++ b/src/supermemory/types/memory_update_params.py
@@ -0,0 +1,69 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union
+from typing_extensions import Annotated, TypedDict
+
+from .._types import SequenceNotStr
+from .._utils import PropertyInfo
+
+__all__ = ["MemoryUpdateParams"]
+
+
+class MemoryUpdateParams(TypedDict, total=False):
+ container_tag: Annotated[str, PropertyInfo(alias="containerTag")]
+ """Optional tag this document should be containerized by.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]
+ """
+ (DEPRECATED: Use containerTag instead) Optional tags this document should be
+ containerized by. This can be an ID for your user, a project ID, or any other
+ identifier you wish to use to group documents.
+ """
+
+ content: str
+ """The content to extract and process into a document.
+
+ This can be a URL to a website, a PDF, an image, or a video.
+
+ Plaintext: Any plaintext format
+
+ URL: A URL to a website, PDF, image, or video
+
+ We automatically detect the content type from the url's response format.
+ """
+
+ custom_id: Annotated[str, PropertyInfo(alias="customId")]
+ """Optional custom ID of the document.
+
+ This could be an ID from your database that will uniquely identify this
+ document.
+ """
+
+ file_type: Annotated[str, PropertyInfo(alias="fileType")]
+ """Optional file type override to force specific processing behavior.
+
+ Valid values: text, pdf, tweet, google_doc, google_slide, google_sheet, image,
+ video, notion_doc, webpage, onedrive
+ """
+
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]]
+ """Optional metadata for the document.
+
+ This is used to store additional information about the document. You can use
+ this to store any additional information you need about the document. Metadata
+ can be filtered through. Keys must be strings and are case sensitive. Values can
+ be strings, numbers, or booleans. You cannot nest objects.
+ """
+
+ mime_type: Annotated[str, PropertyInfo(alias="mimeType")]
+ """Required when fileType is 'image' or 'video'.
+
+ Specifies the exact MIME type to use (e.g., 'image/png', 'image/jpeg',
+ 'video/mp4', 'video/webm')
+ """
diff --git a/src/supermemory/types/memory_update_response.py b/src/supermemory/types/memory_update_response.py
new file mode 100644
index 00000000..132b8cf9
--- /dev/null
+++ b/src/supermemory/types/memory_update_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["MemoryUpdateResponse"]
+
+
+class MemoryUpdateResponse(BaseModel):
+ id: str
+
+ status: str
diff --git a/src/supermemory/types/memory_upload_file_params.py b/src/supermemory/types/memory_upload_file_params.py
new file mode 100644
index 00000000..6e8a07aa
--- /dev/null
+++ b/src/supermemory/types/memory_upload_file_params.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, Annotated, TypedDict
+
+from .._types import FileTypes
+from .._utils import PropertyInfo
+
+__all__ = ["MemoryUploadFileParams"]
+
+
+class MemoryUploadFileParams(TypedDict, total=False):
+ file: Required[FileTypes]
+ """File to upload and process"""
+
+ container_tags: Annotated[str, PropertyInfo(alias="containerTags")]
+ """Optional JSON string of container tags array.
+
+ This can be an ID for your user, a project ID, or any other identifier you wish
+ to use to group documents.
+ """
+
+ file_type: Annotated[str, PropertyInfo(alias="fileType")]
+ """Optional file type override to force specific processing behavior.
+
+ Valid values: text, pdf, tweet, google_doc, google_slide, google_sheet, image,
+ video, notion_doc, webpage, onedrive
+ """
+
+ mime_type: Annotated[str, PropertyInfo(alias="mimeType")]
+ """Required when fileType is 'image' or 'video'.
+
+ Specifies the exact MIME type to use (e.g., 'image/png', 'image/jpeg',
+ 'video/mp4', 'video/webm')
+ """
diff --git a/src/supermemory/types/memory_upload_file_response.py b/src/supermemory/types/memory_upload_file_response.py
new file mode 100644
index 00000000..f67b958f
--- /dev/null
+++ b/src/supermemory/types/memory_upload_file_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["MemoryUploadFileResponse"]
+
+
+class MemoryUploadFileResponse(BaseModel):
+ id: str
+
+ status: str
diff --git a/tests/api_resources/test_documents.py b/tests/api_resources/test_documents.py
new file mode 100644
index 00000000..7cf1bd4b
--- /dev/null
+++ b/tests/api_resources/test_documents.py
@@ -0,0 +1,610 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from supermemory import Supermemory, AsyncSupermemory
+from tests.utils import assert_matches_type
+from supermemory.types import (
+ DocumentAddResponse,
+ DocumentGetResponse,
+ DocumentListResponse,
+ DocumentUpdateResponse,
+ DocumentUploadFileResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestDocuments:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_update(self, client: Supermemory) -> None:
+ document = client.documents.update(
+ id="id",
+ )
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_update_with_all_params(self, client: Supermemory) -> None:
+ document = client.documents.update(
+ id="id",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ content="This is a detailed article about machine learning concepts...",
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_update(self, client: Supermemory) -> None:
+ response = client.documents.with_raw_response.update(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = response.parse()
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_update(self, client: Supermemory) -> None:
+ with client.documents.with_streaming_response.update(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = response.parse()
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_update(self, client: Supermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.documents.with_raw_response.update(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Supermemory) -> None:
+ document = client.documents.list()
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Supermemory) -> None:
+ document = client.documents.list(
+ container_tags=["user_123", "project_123"],
+ filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ include_content=False,
+ limit=10,
+ order="desc",
+ page=1,
+ sort="createdAt",
+ )
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Supermemory) -> None:
+ response = client.documents.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = response.parse()
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Supermemory) -> None:
+ with client.documents.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = response.parse()
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_delete(self, client: Supermemory) -> None:
+ document = client.documents.delete(
+ "id",
+ )
+ assert document is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_delete(self, client: Supermemory) -> None:
+ response = client.documents.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = response.parse()
+ assert document is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_delete(self, client: Supermemory) -> None:
+ with client.documents.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = response.parse()
+ assert document is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_delete(self, client: Supermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.documents.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_add(self, client: Supermemory) -> None:
+ document = client.documents.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_add_with_all_params(self, client: Supermemory) -> None:
+ document = client.documents.add(
+ content="This is a detailed article about machine learning concepts...",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_add(self, client: Supermemory) -> None:
+ response = client.documents.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = response.parse()
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_add(self, client: Supermemory) -> None:
+ with client.documents.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = response.parse()
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_get(self, client: Supermemory) -> None:
+ document = client.documents.get(
+ "id",
+ )
+ assert_matches_type(DocumentGetResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_get(self, client: Supermemory) -> None:
+ response = client.documents.with_raw_response.get(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = response.parse()
+ assert_matches_type(DocumentGetResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_get(self, client: Supermemory) -> None:
+ with client.documents.with_streaming_response.get(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = response.parse()
+ assert_matches_type(DocumentGetResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_get(self, client: Supermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.documents.with_raw_response.get(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_upload_file(self, client: Supermemory) -> None:
+ document = client.documents.upload_file(
+ file=b"raw file contents",
+ )
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_upload_file_with_all_params(self, client: Supermemory) -> None:
+ document = client.documents.upload_file(
+ file=b"raw file contents",
+ container_tags='["user_123", "project_123"]',
+ file_type="image",
+ mime_type="image/png",
+ )
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_upload_file(self, client: Supermemory) -> None:
+ response = client.documents.with_raw_response.upload_file(
+ file=b"raw file contents",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = response.parse()
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_upload_file(self, client: Supermemory) -> None:
+ with client.documents.with_streaming_response.upload_file(
+ file=b"raw file contents",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = response.parse()
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncDocuments:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_update(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.update(
+ id="id",
+ )
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.update(
+ id="id",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ content="This is a detailed article about machine learning concepts...",
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.documents.with_raw_response.update(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = await response.parse()
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.documents.with_streaming_response.update(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = await response.parse()
+ assert_matches_type(DocumentUpdateResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_update(self, async_client: AsyncSupermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.documents.with_raw_response.update(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.list()
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.list(
+ container_tags=["user_123", "project_123"],
+ filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ include_content=False,
+ limit=10,
+ order="desc",
+ page=1,
+ sort="createdAt",
+ )
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.documents.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = await response.parse()
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.documents.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = await response.parse()
+ assert_matches_type(DocumentListResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.delete(
+ "id",
+ )
+ assert document is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.documents.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = await response.parse()
+ assert document is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.documents.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = await response.parse()
+ assert document is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncSupermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.documents.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_add(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_add_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.add(
+ content="This is a detailed article about machine learning concepts...",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_add(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.documents.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = await response.parse()
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_add(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.documents.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = await response.parse()
+ assert_matches_type(DocumentAddResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_get(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.get(
+ "id",
+ )
+ assert_matches_type(DocumentGetResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.documents.with_raw_response.get(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = await response.parse()
+ assert_matches_type(DocumentGetResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.documents.with_streaming_response.get(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = await response.parse()
+ assert_matches_type(DocumentGetResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncSupermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.documents.with_raw_response.get(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_upload_file(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.upload_file(
+ file=b"raw file contents",
+ )
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_upload_file_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ document = await async_client.documents.upload_file(
+ file=b"raw file contents",
+ container_tags='["user_123", "project_123"]',
+ file_type="image",
+ mime_type="image/png",
+ )
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_upload_file(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.documents.with_raw_response.upload_file(
+ file=b"raw file contents",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ document = await response.parse()
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_upload_file(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.documents.with_streaming_response.upload_file(
+ file=b"raw file contents",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ document = await response.parse()
+ assert_matches_type(DocumentUploadFileResponse, document, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_memories.py b/tests/api_resources/test_memories.py
new file mode 100644
index 00000000..9d5c5d21
--- /dev/null
+++ b/tests/api_resources/test_memories.py
@@ -0,0 +1,610 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from supermemory import Supermemory, AsyncSupermemory
+from tests.utils import assert_matches_type
+from supermemory.types import (
+ MemoryAddResponse,
+ MemoryGetResponse,
+ MemoryListResponse,
+ MemoryUpdateResponse,
+ MemoryUploadFileResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestMemories:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_update(self, client: Supermemory) -> None:
+ memory = client.memories.update(
+ id="id",
+ )
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_update_with_all_params(self, client: Supermemory) -> None:
+ memory = client.memories.update(
+ id="id",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ content="This is a detailed article about machine learning concepts...",
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_update(self, client: Supermemory) -> None:
+ response = client.memories.with_raw_response.update(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = response.parse()
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_update(self, client: Supermemory) -> None:
+ with client.memories.with_streaming_response.update(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = response.parse()
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_update(self, client: Supermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.memories.with_raw_response.update(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Supermemory) -> None:
+ memory = client.memories.list()
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Supermemory) -> None:
+ memory = client.memories.list(
+ container_tags=["user_123", "project_123"],
+ filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ include_content=False,
+ limit=10,
+ order="desc",
+ page=1,
+ sort="createdAt",
+ )
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Supermemory) -> None:
+ response = client.memories.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = response.parse()
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Supermemory) -> None:
+ with client.memories.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = response.parse()
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_delete(self, client: Supermemory) -> None:
+ memory = client.memories.delete(
+ "id",
+ )
+ assert memory is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_delete(self, client: Supermemory) -> None:
+ response = client.memories.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = response.parse()
+ assert memory is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_delete(self, client: Supermemory) -> None:
+ with client.memories.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = response.parse()
+ assert memory is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_delete(self, client: Supermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.memories.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_add(self, client: Supermemory) -> None:
+ memory = client.memories.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_add_with_all_params(self, client: Supermemory) -> None:
+ memory = client.memories.add(
+ content="This is a detailed article about machine learning concepts...",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_add(self, client: Supermemory) -> None:
+ response = client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = response.parse()
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_add(self, client: Supermemory) -> None:
+ with client.memories.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = response.parse()
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_get(self, client: Supermemory) -> None:
+ memory = client.memories.get(
+ "id",
+ )
+ assert_matches_type(MemoryGetResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_get(self, client: Supermemory) -> None:
+ response = client.memories.with_raw_response.get(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = response.parse()
+ assert_matches_type(MemoryGetResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_get(self, client: Supermemory) -> None:
+ with client.memories.with_streaming_response.get(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = response.parse()
+ assert_matches_type(MemoryGetResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_get(self, client: Supermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.memories.with_raw_response.get(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_upload_file(self, client: Supermemory) -> None:
+ memory = client.memories.upload_file(
+ file=b"raw file contents",
+ )
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_upload_file_with_all_params(self, client: Supermemory) -> None:
+ memory = client.memories.upload_file(
+ file=b"raw file contents",
+ container_tags='["user_123", "project_123"]',
+ file_type="image",
+ mime_type="image/png",
+ )
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_upload_file(self, client: Supermemory) -> None:
+ response = client.memories.with_raw_response.upload_file(
+ file=b"raw file contents",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = response.parse()
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_upload_file(self, client: Supermemory) -> None:
+ with client.memories.with_streaming_response.upload_file(
+ file=b"raw file contents",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = response.parse()
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncMemories:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_update(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.update(
+ id="id",
+ )
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.update(
+ id="id",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ content="This is a detailed article about machine learning concepts...",
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.memories.with_raw_response.update(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = await response.parse()
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.memories.with_streaming_response.update(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = await response.parse()
+ assert_matches_type(MemoryUpdateResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_update(self, async_client: AsyncSupermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.memories.with_raw_response.update(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.list()
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.list(
+ container_tags=["user_123", "project_123"],
+ filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ include_content=False,
+ limit=10,
+ order="desc",
+ page=1,
+ sort="createdAt",
+ )
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.memories.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = await response.parse()
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.memories.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = await response.parse()
+ assert_matches_type(MemoryListResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.delete(
+ "id",
+ )
+ assert memory is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.memories.with_raw_response.delete(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = await response.parse()
+ assert memory is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.memories.with_streaming_response.delete(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = await response.parse()
+ assert memory is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncSupermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.memories.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_add(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_add_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.add(
+ content="This is a detailed article about machine learning concepts...",
+ container_tag="user_123",
+ container_tags=["user_123", "project_123"],
+ custom_id="mem_abc123",
+ file_type="pdf",
+ metadata={
+ "category": "technology",
+ "isPublic": True,
+ "readingTime": 5,
+ "source": "web",
+ "tag_1": "ai",
+ "tag_2": "machine-learning",
+ },
+ mime_type="image/png",
+ )
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_add(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = await response.parse()
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_add(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.memories.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = await response.parse()
+ assert_matches_type(MemoryAddResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_get(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.get(
+ "id",
+ )
+ assert_matches_type(MemoryGetResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.memories.with_raw_response.get(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = await response.parse()
+ assert_matches_type(MemoryGetResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.memories.with_streaming_response.get(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = await response.parse()
+ assert_matches_type(MemoryGetResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncSupermemory) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.memories.with_raw_response.get(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_upload_file(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.upload_file(
+ file=b"raw file contents",
+ )
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_upload_file_with_all_params(self, async_client: AsyncSupermemory) -> None:
+ memory = await async_client.memories.upload_file(
+ file=b"raw file contents",
+ container_tags='["user_123", "project_123"]',
+ file_type="image",
+ mime_type="image/png",
+ )
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_upload_file(self, async_client: AsyncSupermemory) -> None:
+ response = await async_client.memories.with_raw_response.upload_file(
+ file=b"raw file contents",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ memory = await response.parse()
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_upload_file(self, async_client: AsyncSupermemory) -> None:
+ async with async_client.memories.with_streaming_response.upload_file(
+ file=b"raw file contents",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ memory = await response.parse()
+ assert_matches_type(MemoryUploadFileResponse, memory, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/test_client.py b/tests/test_client.py
index 0f948871..f66d20fc 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -724,20 +724,20 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str
@mock.patch("supermemory._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: Supermemory) -> None:
- respx_mock.post("/v3/search").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.patch("/v3/documents/id").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.search.with_streaming_response.documents(q="machine learning concepts").__enter__()
+ client.memories.with_streaming_response.update(id="id").__enter__()
assert _get_open_connections(self.client) == 0
@mock.patch("supermemory._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: Supermemory) -> None:
- respx_mock.post("/v3/search").mock(return_value=httpx.Response(500))
+ respx_mock.patch("/v3/documents/id").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.search.with_streaming_response.documents(q="machine learning concepts").__enter__()
+ client.memories.with_streaming_response.update(id="id").__enter__()
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -764,9 +764,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/v3/search").mock(side_effect=retry_handler)
+ respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
- response = client.search.with_raw_response.documents(q="machine learning concepts")
+ response = client.memories.with_raw_response.update(id="id")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -788,11 +788,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/v3/search").mock(side_effect=retry_handler)
+ respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
- response = client.search.with_raw_response.documents(
- q="machine learning concepts", extra_headers={"x-stainless-retry-count": Omit()}
- )
+ response = client.memories.with_raw_response.update(id="id", extra_headers={"x-stainless-retry-count": Omit()})
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -813,11 +811,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/v3/search").mock(side_effect=retry_handler)
+ respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
- response = client.search.with_raw_response.documents(
- q="machine learning concepts", extra_headers={"x-stainless-retry-count": "42"}
- )
+ response = client.memories.with_raw_response.update(id="id", extra_headers={"x-stainless-retry-count": "42"})
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1545,10 +1541,10 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte
async def test_retrying_timeout_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncSupermemory
) -> None:
- respx_mock.post("/v3/search").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.patch("/v3/documents/id").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.search.with_streaming_response.documents(q="machine learning concepts").__aenter__()
+ await async_client.memories.with_streaming_response.update(id="id").__aenter__()
assert _get_open_connections(self.client) == 0
@@ -1557,10 +1553,10 @@ async def test_retrying_timeout_errors_doesnt_leak(
async def test_retrying_status_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncSupermemory
) -> None:
- respx_mock.post("/v3/search").mock(return_value=httpx.Response(500))
+ respx_mock.patch("/v3/documents/id").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.search.with_streaming_response.documents(q="machine learning concepts").__aenter__()
+ await async_client.memories.with_streaming_response.update(id="id").__aenter__()
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1588,9 +1584,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/v3/search").mock(side_effect=retry_handler)
+ respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
- response = await client.search.with_raw_response.documents(q="machine learning concepts")
+ response = await client.memories.with_raw_response.update(id="id")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1613,10 +1609,10 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/v3/search").mock(side_effect=retry_handler)
+ respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
- response = await client.search.with_raw_response.documents(
- q="machine learning concepts", extra_headers={"x-stainless-retry-count": Omit()}
+ response = await client.memories.with_raw_response.update(
+ id="id", extra_headers={"x-stainless-retry-count": Omit()}
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1639,10 +1635,10 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/v3/search").mock(side_effect=retry_handler)
+ respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
- response = await client.search.with_raw_response.documents(
- q="machine learning concepts", extra_headers={"x-stainless-retry-count": "42"}
+ response = await client.memories.with_raw_response.update(
+ id="id", extra_headers={"x-stainless-retry-count": "42"}
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
From 8c480f70cf3d0e55c4c5bc3b77d83bd6b21c4fdf Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 17 Sep 2025 02:09:30 +0000
Subject: [PATCH 02/10] chore(internal): update pydantic dependency
---
requirements-dev.lock | 7 +++++--
requirements.lock | 7 +++++--
src/supermemory/_models.py | 14 ++++++++++----
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/requirements-dev.lock b/requirements-dev.lock
index b46f0c64..38e12e51 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -88,9 +88,9 @@ pluggy==1.5.0
propcache==0.3.1
# via aiohttp
# via yarl
-pydantic==2.10.3
+pydantic==2.11.9
# via supermemory
-pydantic-core==2.27.1
+pydantic-core==2.33.2
# via pydantic
pygments==2.18.0
# via rich
@@ -126,6 +126,9 @@ typing-extensions==4.12.2
# via pydantic-core
# via pyright
# via supermemory
+ # via typing-inspection
+typing-inspection==0.4.1
+ # via pydantic
virtualenv==20.24.5
# via nox
yarl==1.20.0
diff --git a/requirements.lock b/requirements.lock
index 22670ed7..de2de686 100644
--- a/requirements.lock
+++ b/requirements.lock
@@ -55,9 +55,9 @@ multidict==6.4.4
propcache==0.3.1
# via aiohttp
# via yarl
-pydantic==2.10.3
+pydantic==2.11.9
# via supermemory
-pydantic-core==2.27.1
+pydantic-core==2.33.2
# via pydantic
sniffio==1.3.0
# via anyio
@@ -68,5 +68,8 @@ typing-extensions==4.12.2
# via pydantic
# via pydantic-core
# via supermemory
+ # via typing-inspection
+typing-inspection==0.4.1
+ # via pydantic
yarl==1.20.0
# via aiohttp
diff --git a/src/supermemory/_models.py b/src/supermemory/_models.py
index 3a6017ef..6a3cd1d2 100644
--- a/src/supermemory/_models.py
+++ b/src/supermemory/_models.py
@@ -256,7 +256,7 @@ def model_dump(
mode: Literal["json", "python"] | str = "python",
include: IncEx | None = None,
exclude: IncEx | None = None,
- by_alias: bool = False,
+ by_alias: bool | None = None,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
@@ -264,6 +264,7 @@ def model_dump(
warnings: bool | Literal["none", "warn", "error"] = True,
context: dict[str, Any] | None = None,
serialize_as_any: bool = False,
+ fallback: Callable[[Any], Any] | None = None,
) -> dict[str, Any]:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump
@@ -295,10 +296,12 @@ def model_dump(
raise ValueError("context is only supported in Pydantic v2")
if serialize_as_any != False:
raise ValueError("serialize_as_any is only supported in Pydantic v2")
+ if fallback is not None:
+ raise ValueError("fallback is only supported in Pydantic v2")
dumped = super().dict( # pyright: ignore[reportDeprecated]
include=include,
exclude=exclude,
- by_alias=by_alias,
+ by_alias=by_alias if by_alias is not None else False,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
@@ -313,13 +316,14 @@ def model_dump_json(
indent: int | None = None,
include: IncEx | None = None,
exclude: IncEx | None = None,
- by_alias: bool = False,
+ by_alias: bool | None = None,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
round_trip: bool = False,
warnings: bool | Literal["none", "warn", "error"] = True,
context: dict[str, Any] | None = None,
+ fallback: Callable[[Any], Any] | None = None,
serialize_as_any: bool = False,
) -> str:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump_json
@@ -348,11 +352,13 @@ def model_dump_json(
raise ValueError("context is only supported in Pydantic v2")
if serialize_as_any != False:
raise ValueError("serialize_as_any is only supported in Pydantic v2")
+ if fallback is not None:
+ raise ValueError("fallback is only supported in Pydantic v2")
return super().json( # type: ignore[reportDeprecated]
indent=indent,
include=include,
exclude=exclude,
- by_alias=by_alias,
+ by_alias=by_alias if by_alias is not None else False,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
From 30824814233753584a89c56a2efb69d72995be02 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 17 Sep 2025 20:14:03 +0000
Subject: [PATCH 03/10] feat(api): api update
---
.stats.yml | 4 ++--
src/supermemory/types/search_memories_params.py | 7 +++++++
tests/api_resources/test_search.py | 2 ++
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 9074c3a5..43ae048d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-f181eaeb22a42d197dbd9c45fa61bf9a9b78a91d3334fc0f841494dc73d1a203.yml
-openapi_spec_hash: bb8262ebcdea53979cf1cafbc2c68dc8
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-5aeca69d1004a718af7a0d19bde90a4b8f2e8af4ac133e6a4caed202f57dce32.yml
+openapi_spec_hash: a590ba1fcf0a35c96ef800f933151c89
config_hash: 2737bce9823a13e0263c0fa2701821fa
diff --git a/src/supermemory/types/search_memories_params.py b/src/supermemory/types/search_memories_params.py
index 060184d1..20602ee9 100644
--- a/src/supermemory/types/search_memories_params.py
+++ b/src/supermemory/types/search_memories_params.py
@@ -61,6 +61,13 @@ class FiltersUnionMember0(TypedDict, total=False):
class Include(TypedDict, total=False):
documents: bool
+ forgotten_memories: Annotated[bool, PropertyInfo(alias="forgottenMemories")]
+ """If true, include forgotten memories in search results.
+
+ Forgotten memories are memories that have been explicitly forgotten or have
+ passed their expiration date.
+ """
+
related_memories: Annotated[bool, PropertyInfo(alias="relatedMemories")]
summaries: bool
diff --git a/tests/api_resources/test_search.py b/tests/api_resources/test_search.py
index fc79884f..4fae417c 100644
--- a/tests/api_resources/test_search.py
+++ b/tests/api_resources/test_search.py
@@ -194,6 +194,7 @@ def test_method_memories_with_all_params(self, client: Supermemory) -> None:
},
include={
"documents": True,
+ "forgotten_memories": False,
"related_memories": True,
"summaries": True,
},
@@ -409,6 +410,7 @@ async def test_method_memories_with_all_params(self, async_client: AsyncSupermem
},
include={
"documents": True,
+ "forgotten_memories": False,
"related_memories": True,
"summaries": True,
},
From 95a3da0521742939ffe7881d75d213ad81b797bc Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 18 Sep 2025 19:14:03 +0000
Subject: [PATCH 04/10] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 43ae048d..6660bb78 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-5aeca69d1004a718af7a0d19bde90a4b8f2e8af4ac133e6a4caed202f57dce32.yml
-openapi_spec_hash: a590ba1fcf0a35c96ef800f933151c89
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-0dc5f10179855bda1aabcad789449ca1e5b84cb5c619ccdd2227cec5b384af43.yml
+openapi_spec_hash: 847c9b8bf6a9a67f2b061243e2024b16
config_hash: 2737bce9823a13e0263c0fa2701821fa
From 30317810d7089dbdf59f5e143bd66b1a0495b2b6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 19 Sep 2025 02:11:06 +0000
Subject: [PATCH 05/10] chore(types): change optional parameter type from
NotGiven to Omit
---
src/supermemory/__init__.py | 4 +-
src/supermemory/_base_client.py | 18 +--
src/supermemory/_client.py | 16 +--
src/supermemory/_qs.py | 14 +--
src/supermemory/_types.py | 29 +++--
src/supermemory/_utils/_transform.py | 4 +-
src/supermemory/_utils/_utils.py | 8 +-
src/supermemory/resources/connections.py | 62 +++++-----
src/supermemory/resources/documents.py | 118 +++++++++----------
src/supermemory/resources/memories.py | 118 +++++++++----------
src/supermemory/resources/search.py | 138 +++++++++++------------
src/supermemory/resources/settings.py | 62 +++++-----
tests/test_transform.py | 11 +-
13 files changed, 309 insertions(+), 293 deletions(-)
diff --git a/src/supermemory/__init__.py b/src/supermemory/__init__.py
index bb87a0cf..78f13680 100644
--- a/src/supermemory/__init__.py
+++ b/src/supermemory/__init__.py
@@ -3,7 +3,7 @@
import typing as _t
from . import types
-from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
+from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes, omit, not_given
from ._utils import file_from_path
from ._client import (
Client,
@@ -48,7 +48,9 @@
"ProxiesTypes",
"NotGiven",
"NOT_GIVEN",
+ "not_given",
"Omit",
+ "omit",
"SupermemoryError",
"APIError",
"APIStatusError",
diff --git a/src/supermemory/_base_client.py b/src/supermemory/_base_client.py
index fbcaf523..4c1fceb0 100644
--- a/src/supermemory/_base_client.py
+++ b/src/supermemory/_base_client.py
@@ -42,7 +42,6 @@
from ._qs import Querystring
from ._files import to_httpx_files, async_to_httpx_files
from ._types import (
- NOT_GIVEN,
Body,
Omit,
Query,
@@ -57,6 +56,7 @@
RequestOptions,
HttpxRequestFiles,
ModelBuilderProtocol,
+ not_given,
)
from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping
from ._compat import PYDANTIC_V1, model_copy, model_dump
@@ -145,9 +145,9 @@ def __init__(
def __init__(
self,
*,
- url: URL | NotGiven = NOT_GIVEN,
- json: Body | NotGiven = NOT_GIVEN,
- params: Query | NotGiven = NOT_GIVEN,
+ url: URL | NotGiven = not_given,
+ json: Body | NotGiven = not_given,
+ params: Query | NotGiven = not_given,
) -> None:
self.url = url
self.json = json
@@ -595,7 +595,7 @@ def _maybe_override_cast_to(self, cast_to: type[ResponseT], options: FinalReques
# we internally support defining a temporary header to override the
# default `cast_to` type for use with `.with_raw_response` and `.with_streaming_response`
# see _response.py for implementation details
- override_cast_to = headers.pop(OVERRIDE_CAST_TO_HEADER, NOT_GIVEN)
+ override_cast_to = headers.pop(OVERRIDE_CAST_TO_HEADER, not_given)
if is_given(override_cast_to):
options.headers = headers
return cast(Type[ResponseT], override_cast_to)
@@ -825,7 +825,7 @@ def __init__(
version: str,
base_url: str | URL,
max_retries: int = DEFAULT_MAX_RETRIES,
- timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.Client | None = None,
custom_headers: Mapping[str, str] | None = None,
custom_query: Mapping[str, object] | None = None,
@@ -1356,7 +1356,7 @@ def __init__(
base_url: str | URL,
_strict_response_validation: bool,
max_retries: int = DEFAULT_MAX_RETRIES,
- timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.AsyncClient | None = None,
custom_headers: Mapping[str, str] | None = None,
custom_query: Mapping[str, object] | None = None,
@@ -1818,8 +1818,8 @@ def make_request_options(
extra_query: Query | None = None,
extra_body: Body | None = None,
idempotency_key: str | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- post_parser: PostParser | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ post_parser: PostParser | NotGiven = not_given,
) -> RequestOptions:
"""Create a dict of type RequestOptions without keys of NotGiven values."""
options: RequestOptions = {}
diff --git a/src/supermemory/_client.py b/src/supermemory/_client.py
index c27fc11a..0de41593 100644
--- a/src/supermemory/_client.py
+++ b/src/supermemory/_client.py
@@ -3,7 +3,7 @@
from __future__ import annotations
import os
-from typing import Any, Union, Mapping
+from typing import Any, Mapping
from typing_extensions import Self, override
import httpx
@@ -11,13 +11,13 @@
from . import _exceptions
from ._qs import Querystring
from ._types import (
- NOT_GIVEN,
Omit,
Timeout,
NotGiven,
Transport,
ProxiesTypes,
RequestOptions,
+ not_given,
)
from ._utils import is_given, get_async_library
from ._version import __version__
@@ -59,7 +59,7 @@ def __init__(
*,
api_key: str | None = None,
base_url: str | httpx.URL | None = None,
- timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
+ timeout: float | Timeout | None | NotGiven = not_given,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
default_query: Mapping[str, object] | None = None,
@@ -138,9 +138,9 @@ def copy(
*,
api_key: str | None = None,
base_url: str | httpx.URL | None = None,
- timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.Client | None = None,
- max_retries: int | NotGiven = NOT_GIVEN,
+ max_retries: int | NotGiven = not_given,
default_headers: Mapping[str, str] | None = None,
set_default_headers: Mapping[str, str] | None = None,
default_query: Mapping[str, object] | None = None,
@@ -235,7 +235,7 @@ def __init__(
*,
api_key: str | None = None,
base_url: str | httpx.URL | None = None,
- timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
+ timeout: float | Timeout | None | NotGiven = not_given,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
default_query: Mapping[str, object] | None = None,
@@ -314,9 +314,9 @@ def copy(
*,
api_key: str | None = None,
base_url: str | httpx.URL | None = None,
- timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.AsyncClient | None = None,
- max_retries: int | NotGiven = NOT_GIVEN,
+ max_retries: int | NotGiven = not_given,
default_headers: Mapping[str, str] | None = None,
set_default_headers: Mapping[str, str] | None = None,
default_query: Mapping[str, object] | None = None,
diff --git a/src/supermemory/_qs.py b/src/supermemory/_qs.py
index 274320ca..ada6fd3f 100644
--- a/src/supermemory/_qs.py
+++ b/src/supermemory/_qs.py
@@ -4,7 +4,7 @@
from urllib.parse import parse_qs, urlencode
from typing_extensions import Literal, get_args
-from ._types import NOT_GIVEN, NotGiven, NotGivenOr
+from ._types import NotGiven, not_given
from ._utils import flatten
_T = TypeVar("_T")
@@ -41,8 +41,8 @@ def stringify(
self,
params: Params,
*,
- array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN,
- nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN,
+ array_format: ArrayFormat | NotGiven = not_given,
+ nested_format: NestedFormat | NotGiven = not_given,
) -> str:
return urlencode(
self.stringify_items(
@@ -56,8 +56,8 @@ def stringify_items(
self,
params: Params,
*,
- array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN,
- nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN,
+ array_format: ArrayFormat | NotGiven = not_given,
+ nested_format: NestedFormat | NotGiven = not_given,
) -> list[tuple[str, str]]:
opts = Options(
qs=self,
@@ -143,8 +143,8 @@ def __init__(
self,
qs: Querystring = _qs,
*,
- array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN,
- nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN,
+ array_format: ArrayFormat | NotGiven = not_given,
+ nested_format: NestedFormat | NotGiven = not_given,
) -> None:
self.array_format = qs.array_format if isinstance(array_format, NotGiven) else array_format
self.nested_format = qs.nested_format if isinstance(nested_format, NotGiven) else nested_format
diff --git a/src/supermemory/_types.py b/src/supermemory/_types.py
index 24417563..9a02d83d 100644
--- a/src/supermemory/_types.py
+++ b/src/supermemory/_types.py
@@ -117,18 +117,21 @@ class RequestOptions(TypedDict, total=False):
# Sentinel class used until PEP 0661 is accepted
class NotGiven:
"""
- A sentinel singleton class used to distinguish omitted keyword arguments
- from those passed in with the value None (which may have different behavior).
+ For parameters with a meaningful None value, we need to distinguish between
+ the user explicitly passing None, and the user not passing the parameter at
+ all.
+
+ User code shouldn't need to use not_given directly.
For example:
```py
- def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response: ...
+ def create(timeout: Timeout | None | NotGiven = not_given): ...
- get(timeout=1) # 1s timeout
- get(timeout=None) # No timeout
- get() # Default timeout behavior, which may not be statically known at the method definition.
+ create(timeout=1) # 1s timeout
+ create(timeout=None) # No timeout
+ create() # Default timeout behavior
```
"""
@@ -140,13 +143,14 @@ def __repr__(self) -> str:
return "NOT_GIVEN"
-NotGivenOr = Union[_T, NotGiven]
+not_given = NotGiven()
+# for backwards compatibility:
NOT_GIVEN = NotGiven()
class Omit:
- """In certain situations you need to be able to represent a case where a default value has
- to be explicitly removed and `None` is not an appropriate substitute, for example:
+ """
+ To explicitly omit something from being sent in a request, use `omit`.
```py
# as the default `Content-Type` header is `application/json` that will be sent
@@ -156,8 +160,8 @@ class Omit:
# to look something like: 'multipart/form-data; boundary=0d8382fcf5f8c3be01ca2e11002d2983'
client.post(..., headers={"Content-Type": "multipart/form-data"})
- # instead you can remove the default `application/json` header by passing Omit
- client.post(..., headers={"Content-Type": Omit()})
+ # instead you can remove the default `application/json` header by passing omit
+ client.post(..., headers={"Content-Type": omit})
```
"""
@@ -165,6 +169,9 @@ def __bool__(self) -> Literal[False]:
return False
+omit = Omit()
+
+
@runtime_checkable
class ModelBuilderProtocol(Protocol):
@classmethod
diff --git a/src/supermemory/_utils/_transform.py b/src/supermemory/_utils/_transform.py
index c19124f0..52075492 100644
--- a/src/supermemory/_utils/_transform.py
+++ b/src/supermemory/_utils/_transform.py
@@ -268,7 +268,7 @@ def _transform_typeddict(
annotations = get_type_hints(expected_type, include_extras=True)
for key, value in data.items():
if not is_given(value):
- # we don't need to include `NotGiven` values here as they'll
+ # we don't need to include omitted values here as they'll
# be stripped out before the request is sent anyway
continue
@@ -434,7 +434,7 @@ async def _async_transform_typeddict(
annotations = get_type_hints(expected_type, include_extras=True)
for key, value in data.items():
if not is_given(value):
- # we don't need to include `NotGiven` values here as they'll
+ # we don't need to include omitted values here as they'll
# be stripped out before the request is sent anyway
continue
diff --git a/src/supermemory/_utils/_utils.py b/src/supermemory/_utils/_utils.py
index f0818595..50d59269 100644
--- a/src/supermemory/_utils/_utils.py
+++ b/src/supermemory/_utils/_utils.py
@@ -21,7 +21,7 @@
import sniffio
-from .._types import NotGiven, FileTypes, NotGivenOr, HeadersLike
+from .._types import Omit, NotGiven, FileTypes, HeadersLike
_T = TypeVar("_T")
_TupleT = TypeVar("_TupleT", bound=Tuple[object, ...])
@@ -63,7 +63,7 @@ def _extract_items(
try:
key = path[index]
except IndexError:
- if isinstance(obj, NotGiven):
+ if not is_given(obj):
# no value was provided - we can safely ignore
return []
@@ -126,8 +126,8 @@ def _extract_items(
return []
-def is_given(obj: NotGivenOr[_T]) -> TypeGuard[_T]:
- return not isinstance(obj, NotGiven)
+def is_given(obj: _T | NotGiven | Omit) -> TypeGuard[_T]:
+ return not isinstance(obj, NotGiven) and not isinstance(obj, Omit)
# Type safe methods for narrowing types with TypeVars.
diff --git a/src/supermemory/resources/connections.py b/src/supermemory/resources/connections.py
index dfd73a81..f56c31da 100644
--- a/src/supermemory/resources/connections.py
+++ b/src/supermemory/resources/connections.py
@@ -15,7 +15,7 @@
connection_list_documents_params,
connection_delete_by_provider_params,
)
-from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven, SequenceNotStr
+from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -61,16 +61,16 @@ def create(
self,
provider: Literal["notion", "google-drive", "onedrive"],
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- document_limit: int | NotGiven = NOT_GIVEN,
- metadata: Optional[Dict[str, Union[str, float, bool]]] | NotGiven = NOT_GIVEN,
- redirect_url: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ document_limit: int | Omit = omit,
+ metadata: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
+ redirect_url: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionCreateResponse:
"""
Initialize connection and get authorization URL
@@ -106,13 +106,13 @@ def create(
def list(
self,
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionListResponse:
"""
List all connections
@@ -146,7 +146,7 @@ def delete_by_id(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionDeleteByIDResponse:
"""
Delete a specific connection by ID
@@ -180,7 +180,7 @@ def delete_by_provider(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionDeleteByProviderResponse:
"""
Delete connection for a specific provider and container tags
@@ -219,7 +219,7 @@ def get_by_id(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionGetByIDResponse:
"""
Get connection details with id
@@ -253,7 +253,7 @@ def get_by_tags(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionGetByTagsResponse:
"""
Get connection details with provider and container tags
@@ -286,13 +286,13 @@ def import_(
self,
provider: Literal["notion", "google-drive", "onedrive"],
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> str:
"""
Initiate a manual sync of connections
@@ -324,13 +324,13 @@ def list_documents(
self,
provider: Literal["notion", "google-drive", "onedrive"],
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionListDocumentsResponse:
"""
List documents indexed for a provider and container tags
@@ -384,16 +384,16 @@ async def create(
self,
provider: Literal["notion", "google-drive", "onedrive"],
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- document_limit: int | NotGiven = NOT_GIVEN,
- metadata: Optional[Dict[str, Union[str, float, bool]]] | NotGiven = NOT_GIVEN,
- redirect_url: str | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ document_limit: int | Omit = omit,
+ metadata: Optional[Dict[str, Union[str, float, bool]]] | Omit = omit,
+ redirect_url: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionCreateResponse:
"""
Initialize connection and get authorization URL
@@ -429,13 +429,13 @@ async def create(
async def list(
self,
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionListResponse:
"""
List all connections
@@ -471,7 +471,7 @@ async def delete_by_id(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionDeleteByIDResponse:
"""
Delete a specific connection by ID
@@ -505,7 +505,7 @@ async def delete_by_provider(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionDeleteByProviderResponse:
"""
Delete connection for a specific provider and container tags
@@ -544,7 +544,7 @@ async def get_by_id(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionGetByIDResponse:
"""
Get connection details with id
@@ -578,7 +578,7 @@ async def get_by_tags(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionGetByTagsResponse:
"""
Get connection details with provider and container tags
@@ -611,13 +611,13 @@ async def import_(
self,
provider: Literal["notion", "google-drive", "onedrive"],
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> str:
"""
Initiate a manual sync of connections
@@ -651,13 +651,13 @@ async def list_documents(
self,
provider: Literal["notion", "google-drive", "onedrive"],
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ConnectionListDocumentsResponse:
"""
List documents indexed for a provider and container tags
diff --git a/src/supermemory/resources/documents.py b/src/supermemory/resources/documents.py
index afd4ff33..b2e08e8e 100644
--- a/src/supermemory/resources/documents.py
+++ b/src/supermemory/resources/documents.py
@@ -8,7 +8,7 @@
import httpx
from ..types import document_add_params, document_list_params, document_update_params, document_upload_file_params
-from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven, FileTypes, SequenceNotStr
+from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, FileTypes, SequenceNotStr, omit, not_given
from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -52,19 +52,19 @@ def update(
self,
id: str,
*,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- content: str | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ content: str | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentUpdateResponse:
"""
Update a document with any content type (text, url, file, etc.) and metadata
@@ -137,19 +137,19 @@ def update(
def list(
self,
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- filters: str | NotGiven = NOT_GIVEN,
- include_content: bool | NotGiven = NOT_GIVEN,
- limit: Union[str, float] | NotGiven = NOT_GIVEN,
- order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
- page: Union[str, float] | NotGiven = NOT_GIVEN,
- sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ filters: str | Omit = omit,
+ include_content: bool | Omit = omit,
+ limit: Union[str, float] | Omit = omit,
+ order: Literal["asc", "desc"] | Omit = omit,
+ page: Union[str, float] | Omit = omit,
+ sort: Literal["createdAt", "updatedAt"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentListResponse:
"""
Retrieves a paginated list of documents with their metadata and workflow status
@@ -209,7 +209,7 @@ def delete(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
Delete a document by ID or customId
@@ -238,18 +238,18 @@ def add(
self,
*,
content: str,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentAddResponse:
"""
Add a document with any content type (text, url, file, etc.) and metadata
@@ -326,7 +326,7 @@ def get(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentGetResponse:
"""
Get a document by ID
@@ -354,15 +354,15 @@ def upload_file(
self,
*,
file: FileTypes,
- container_tags: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tags: str | Omit = omit,
+ file_type: str | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentUploadFileResponse:
"""
Upload a file to be processed
@@ -437,19 +437,19 @@ async def update(
self,
id: str,
*,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- content: str | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ content: str | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentUpdateResponse:
"""
Update a document with any content type (text, url, file, etc.) and metadata
@@ -522,19 +522,19 @@ async def update(
async def list(
self,
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- filters: str | NotGiven = NOT_GIVEN,
- include_content: bool | NotGiven = NOT_GIVEN,
- limit: Union[str, float] | NotGiven = NOT_GIVEN,
- order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
- page: Union[str, float] | NotGiven = NOT_GIVEN,
- sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ filters: str | Omit = omit,
+ include_content: bool | Omit = omit,
+ limit: Union[str, float] | Omit = omit,
+ order: Literal["asc", "desc"] | Omit = omit,
+ page: Union[str, float] | Omit = omit,
+ sort: Literal["createdAt", "updatedAt"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentListResponse:
"""
Retrieves a paginated list of documents with their metadata and workflow status
@@ -594,7 +594,7 @@ async def delete(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
Delete a document by ID or customId
@@ -623,18 +623,18 @@ async def add(
self,
*,
content: str,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentAddResponse:
"""
Add a document with any content type (text, url, file, etc.) and metadata
@@ -711,7 +711,7 @@ async def get(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentGetResponse:
"""
Get a document by ID
@@ -739,15 +739,15 @@ async def upload_file(
self,
*,
file: FileTypes,
- container_tags: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tags: str | Omit = omit,
+ file_type: str | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> DocumentUploadFileResponse:
"""
Upload a file to be processed
diff --git a/src/supermemory/resources/memories.py b/src/supermemory/resources/memories.py
index 42a6348c..30850259 100644
--- a/src/supermemory/resources/memories.py
+++ b/src/supermemory/resources/memories.py
@@ -8,7 +8,7 @@
import httpx
from ..types import memory_add_params, memory_list_params, memory_update_params, memory_upload_file_params
-from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven, FileTypes, SequenceNotStr
+from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, FileTypes, SequenceNotStr, omit, not_given
from .._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -52,19 +52,19 @@ def update(
self,
id: str,
*,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- content: str | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ content: str | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryUpdateResponse:
"""
Update a document with any content type (text, url, file, etc.) and metadata
@@ -137,19 +137,19 @@ def update(
def list(
self,
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- filters: str | NotGiven = NOT_GIVEN,
- include_content: bool | NotGiven = NOT_GIVEN,
- limit: Union[str, float] | NotGiven = NOT_GIVEN,
- order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
- page: Union[str, float] | NotGiven = NOT_GIVEN,
- sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ filters: str | Omit = omit,
+ include_content: bool | Omit = omit,
+ limit: Union[str, float] | Omit = omit,
+ order: Literal["asc", "desc"] | Omit = omit,
+ page: Union[str, float] | Omit = omit,
+ sort: Literal["createdAt", "updatedAt"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryListResponse:
"""
Retrieves a paginated list of documents with their metadata and workflow status
@@ -209,7 +209,7 @@ def delete(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
Delete a document by ID or customId
@@ -238,18 +238,18 @@ def add(
self,
*,
content: str,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryAddResponse:
"""
Add a document with any content type (text, url, file, etc.) and metadata
@@ -326,7 +326,7 @@ def get(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryGetResponse:
"""
Get a document by ID
@@ -354,15 +354,15 @@ def upload_file(
self,
*,
file: FileTypes,
- container_tags: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tags: str | Omit = omit,
+ file_type: str | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryUploadFileResponse:
"""
Upload a file to be processed
@@ -437,19 +437,19 @@ async def update(
self,
id: str,
*,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- content: str | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ content: str | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryUpdateResponse:
"""
Update a document with any content type (text, url, file, etc.) and metadata
@@ -522,19 +522,19 @@ async def update(
async def list(
self,
*,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- filters: str | NotGiven = NOT_GIVEN,
- include_content: bool | NotGiven = NOT_GIVEN,
- limit: Union[str, float] | NotGiven = NOT_GIVEN,
- order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
- page: Union[str, float] | NotGiven = NOT_GIVEN,
- sort: Literal["createdAt", "updatedAt"] | NotGiven = NOT_GIVEN,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ filters: str | Omit = omit,
+ include_content: bool | Omit = omit,
+ limit: Union[str, float] | Omit = omit,
+ order: Literal["asc", "desc"] | Omit = omit,
+ page: Union[str, float] | Omit = omit,
+ sort: Literal["createdAt", "updatedAt"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryListResponse:
"""
Retrieves a paginated list of documents with their metadata and workflow status
@@ -594,7 +594,7 @@ async def delete(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
Delete a document by ID or customId
@@ -623,18 +623,18 @@ async def add(
self,
*,
content: str,
- container_tag: str | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- custom_id: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ custom_id: str | Omit = omit,
+ file_type: str | Omit = omit,
+ metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryAddResponse:
"""
Add a document with any content type (text, url, file, etc.) and metadata
@@ -711,7 +711,7 @@ async def get(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryGetResponse:
"""
Get a document by ID
@@ -739,15 +739,15 @@ async def upload_file(
self,
*,
file: FileTypes,
- container_tags: str | NotGiven = NOT_GIVEN,
- file_type: str | NotGiven = NOT_GIVEN,
- mime_type: str | NotGiven = NOT_GIVEN,
+ container_tags: str | Omit = omit,
+ file_type: str | Omit = omit,
+ mime_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MemoryUploadFileResponse:
"""
Upload a file to be processed
diff --git a/src/supermemory/resources/search.py b/src/supermemory/resources/search.py
index 6d9eecb4..54eee0f7 100644
--- a/src/supermemory/resources/search.py
+++ b/src/supermemory/resources/search.py
@@ -8,7 +8,7 @@
import httpx
from ..types import search_execute_params, search_memories_params, search_documents_params
-from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven, SequenceNotStr
+from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -50,24 +50,24 @@ def documents(
self,
*,
q: str,
- categories_filter: List[Literal["technology", "science", "business", "health"]] | NotGiven = NOT_GIVEN,
- chunk_threshold: float | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- doc_id: str | NotGiven = NOT_GIVEN,
- document_threshold: float | NotGiven = NOT_GIVEN,
- filters: search_documents_params.Filters | NotGiven = NOT_GIVEN,
- include_full_docs: bool | NotGiven = NOT_GIVEN,
- include_summary: bool | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- only_matching_chunks: bool | NotGiven = NOT_GIVEN,
- rerank: bool | NotGiven = NOT_GIVEN,
- rewrite_query: bool | NotGiven = NOT_GIVEN,
+ categories_filter: List[Literal["technology", "science", "business", "health"]] | Omit = omit,
+ chunk_threshold: float | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ doc_id: str | Omit = omit,
+ document_threshold: float | Omit = omit,
+ filters: search_documents_params.Filters | Omit = omit,
+ include_full_docs: bool | Omit = omit,
+ include_summary: bool | Omit = omit,
+ limit: int | Omit = omit,
+ only_matching_chunks: bool | Omit = omit,
+ rerank: bool | Omit = omit,
+ rewrite_query: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SearchDocumentsResponse:
"""
Search memories with advanced filtering
@@ -149,24 +149,24 @@ def execute(
self,
*,
q: str,
- categories_filter: List[Literal["technology", "science", "business", "health"]] | NotGiven = NOT_GIVEN,
- chunk_threshold: float | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- doc_id: str | NotGiven = NOT_GIVEN,
- document_threshold: float | NotGiven = NOT_GIVEN,
- filters: search_execute_params.Filters | NotGiven = NOT_GIVEN,
- include_full_docs: bool | NotGiven = NOT_GIVEN,
- include_summary: bool | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- only_matching_chunks: bool | NotGiven = NOT_GIVEN,
- rerank: bool | NotGiven = NOT_GIVEN,
- rewrite_query: bool | NotGiven = NOT_GIVEN,
+ categories_filter: List[Literal["technology", "science", "business", "health"]] | Omit = omit,
+ chunk_threshold: float | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ doc_id: str | Omit = omit,
+ document_threshold: float | Omit = omit,
+ filters: search_execute_params.Filters | Omit = omit,
+ include_full_docs: bool | Omit = omit,
+ include_summary: bool | Omit = omit,
+ limit: int | Omit = omit,
+ only_matching_chunks: bool | Omit = omit,
+ rerank: bool | Omit = omit,
+ rewrite_query: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SearchExecuteResponse:
"""
Search memories with advanced filtering
@@ -248,19 +248,19 @@ def memories(
self,
*,
q: str,
- container_tag: str | NotGiven = NOT_GIVEN,
- filters: search_memories_params.Filters | NotGiven = NOT_GIVEN,
- include: search_memories_params.Include | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- rerank: bool | NotGiven = NOT_GIVEN,
- rewrite_query: bool | NotGiven = NOT_GIVEN,
- threshold: float | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ filters: search_memories_params.Filters | Omit = omit,
+ include: search_memories_params.Include | Omit = omit,
+ limit: int | Omit = omit,
+ rerank: bool | Omit = omit,
+ rewrite_query: bool | Omit = omit,
+ threshold: float | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SearchMemoriesResponse:
"""
Search memory entries - Low latency for conversational
@@ -339,24 +339,24 @@ async def documents(
self,
*,
q: str,
- categories_filter: List[Literal["technology", "science", "business", "health"]] | NotGiven = NOT_GIVEN,
- chunk_threshold: float | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- doc_id: str | NotGiven = NOT_GIVEN,
- document_threshold: float | NotGiven = NOT_GIVEN,
- filters: search_documents_params.Filters | NotGiven = NOT_GIVEN,
- include_full_docs: bool | NotGiven = NOT_GIVEN,
- include_summary: bool | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- only_matching_chunks: bool | NotGiven = NOT_GIVEN,
- rerank: bool | NotGiven = NOT_GIVEN,
- rewrite_query: bool | NotGiven = NOT_GIVEN,
+ categories_filter: List[Literal["technology", "science", "business", "health"]] | Omit = omit,
+ chunk_threshold: float | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ doc_id: str | Omit = omit,
+ document_threshold: float | Omit = omit,
+ filters: search_documents_params.Filters | Omit = omit,
+ include_full_docs: bool | Omit = omit,
+ include_summary: bool | Omit = omit,
+ limit: int | Omit = omit,
+ only_matching_chunks: bool | Omit = omit,
+ rerank: bool | Omit = omit,
+ rewrite_query: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SearchDocumentsResponse:
"""
Search memories with advanced filtering
@@ -438,24 +438,24 @@ async def execute(
self,
*,
q: str,
- categories_filter: List[Literal["technology", "science", "business", "health"]] | NotGiven = NOT_GIVEN,
- chunk_threshold: float | NotGiven = NOT_GIVEN,
- container_tags: SequenceNotStr[str] | NotGiven = NOT_GIVEN,
- doc_id: str | NotGiven = NOT_GIVEN,
- document_threshold: float | NotGiven = NOT_GIVEN,
- filters: search_execute_params.Filters | NotGiven = NOT_GIVEN,
- include_full_docs: bool | NotGiven = NOT_GIVEN,
- include_summary: bool | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- only_matching_chunks: bool | NotGiven = NOT_GIVEN,
- rerank: bool | NotGiven = NOT_GIVEN,
- rewrite_query: bool | NotGiven = NOT_GIVEN,
+ categories_filter: List[Literal["technology", "science", "business", "health"]] | Omit = omit,
+ chunk_threshold: float | Omit = omit,
+ container_tags: SequenceNotStr[str] | Omit = omit,
+ doc_id: str | Omit = omit,
+ document_threshold: float | Omit = omit,
+ filters: search_execute_params.Filters | Omit = omit,
+ include_full_docs: bool | Omit = omit,
+ include_summary: bool | Omit = omit,
+ limit: int | Omit = omit,
+ only_matching_chunks: bool | Omit = omit,
+ rerank: bool | Omit = omit,
+ rewrite_query: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SearchExecuteResponse:
"""
Search memories with advanced filtering
@@ -537,19 +537,19 @@ async def memories(
self,
*,
q: str,
- container_tag: str | NotGiven = NOT_GIVEN,
- filters: search_memories_params.Filters | NotGiven = NOT_GIVEN,
- include: search_memories_params.Include | NotGiven = NOT_GIVEN,
- limit: int | NotGiven = NOT_GIVEN,
- rerank: bool | NotGiven = NOT_GIVEN,
- rewrite_query: bool | NotGiven = NOT_GIVEN,
- threshold: float | NotGiven = NOT_GIVEN,
+ container_tag: str | Omit = omit,
+ filters: search_memories_params.Filters | Omit = omit,
+ include: search_memories_params.Include | Omit = omit,
+ limit: int | Omit = omit,
+ rerank: bool | Omit = omit,
+ rewrite_query: bool | Omit = omit,
+ threshold: float | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SearchMemoriesResponse:
"""
Search memory entries - Low latency for conversational
diff --git a/src/supermemory/resources/settings.py b/src/supermemory/resources/settings.py
index 26db07d7..ff223f03 100644
--- a/src/supermemory/resources/settings.py
+++ b/src/supermemory/resources/settings.py
@@ -7,7 +7,7 @@
import httpx
from ..types import setting_update_params
-from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -47,25 +47,25 @@ def with_streaming_response(self) -> SettingsResourceWithStreamingResponse:
def update(
self,
*,
- exclude_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | NotGiven = NOT_GIVEN,
- filter_prompt: Optional[str] | NotGiven = NOT_GIVEN,
- google_drive_client_id: Optional[str] | NotGiven = NOT_GIVEN,
- google_drive_client_secret: Optional[str] | NotGiven = NOT_GIVEN,
- google_drive_custom_key_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
- include_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | NotGiven = NOT_GIVEN,
- notion_client_id: Optional[str] | NotGiven = NOT_GIVEN,
- notion_client_secret: Optional[str] | NotGiven = NOT_GIVEN,
- notion_custom_key_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
- onedrive_client_id: Optional[str] | NotGiven = NOT_GIVEN,
- onedrive_client_secret: Optional[str] | NotGiven = NOT_GIVEN,
- onedrive_custom_key_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
- should_llm_filter: Optional[bool] | NotGiven = NOT_GIVEN,
+ exclude_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | Omit = omit,
+ filter_prompt: Optional[str] | Omit = omit,
+ google_drive_client_id: Optional[str] | Omit = omit,
+ google_drive_client_secret: Optional[str] | Omit = omit,
+ google_drive_custom_key_enabled: Optional[bool] | Omit = omit,
+ include_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | Omit = omit,
+ notion_client_id: Optional[str] | Omit = omit,
+ notion_client_secret: Optional[str] | Omit = omit,
+ notion_custom_key_enabled: Optional[bool] | Omit = omit,
+ onedrive_client_id: Optional[str] | Omit = omit,
+ onedrive_client_secret: Optional[str] | Omit = omit,
+ onedrive_custom_key_enabled: Optional[bool] | Omit = omit,
+ should_llm_filter: Optional[bool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SettingUpdateResponse:
"""
Update settings for an organization
@@ -113,7 +113,7 @@ def get(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SettingGetResponse:
"""Get settings for an organization"""
return self._get(
@@ -148,25 +148,25 @@ def with_streaming_response(self) -> AsyncSettingsResourceWithStreamingResponse:
async def update(
self,
*,
- exclude_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | NotGiven = NOT_GIVEN,
- filter_prompt: Optional[str] | NotGiven = NOT_GIVEN,
- google_drive_client_id: Optional[str] | NotGiven = NOT_GIVEN,
- google_drive_client_secret: Optional[str] | NotGiven = NOT_GIVEN,
- google_drive_custom_key_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
- include_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | NotGiven = NOT_GIVEN,
- notion_client_id: Optional[str] | NotGiven = NOT_GIVEN,
- notion_client_secret: Optional[str] | NotGiven = NOT_GIVEN,
- notion_custom_key_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
- onedrive_client_id: Optional[str] | NotGiven = NOT_GIVEN,
- onedrive_client_secret: Optional[str] | NotGiven = NOT_GIVEN,
- onedrive_custom_key_enabled: Optional[bool] | NotGiven = NOT_GIVEN,
- should_llm_filter: Optional[bool] | NotGiven = NOT_GIVEN,
+ exclude_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | Omit = omit,
+ filter_prompt: Optional[str] | Omit = omit,
+ google_drive_client_id: Optional[str] | Omit = omit,
+ google_drive_client_secret: Optional[str] | Omit = omit,
+ google_drive_custom_key_enabled: Optional[bool] | Omit = omit,
+ include_items: Union[str, float, bool, Dict[str, object], Iterable[object], None] | Omit = omit,
+ notion_client_id: Optional[str] | Omit = omit,
+ notion_client_secret: Optional[str] | Omit = omit,
+ notion_custom_key_enabled: Optional[bool] | Omit = omit,
+ onedrive_client_id: Optional[str] | Omit = omit,
+ onedrive_client_secret: Optional[str] | Omit = omit,
+ onedrive_custom_key_enabled: Optional[bool] | Omit = omit,
+ should_llm_filter: Optional[bool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SettingUpdateResponse:
"""
Update settings for an organization
@@ -214,7 +214,7 @@ async def get(
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SettingGetResponse:
"""Get settings for an organization"""
return await self._get(
diff --git a/tests/test_transform.py b/tests/test_transform.py
index b4c46e41..ab0bf040 100644
--- a/tests/test_transform.py
+++ b/tests/test_transform.py
@@ -8,7 +8,7 @@
import pytest
-from supermemory._types import NOT_GIVEN, Base64FileInput
+from supermemory._types import Base64FileInput, omit, not_given
from supermemory._utils import (
PropertyInfo,
transform as _transform,
@@ -450,4 +450,11 @@ async def test_transform_skipping(use_async: bool) -> None:
@pytest.mark.asyncio
async def test_strips_notgiven(use_async: bool) -> None:
assert await transform({"foo_bar": "bar"}, Foo1, use_async) == {"fooBar": "bar"}
- assert await transform({"foo_bar": NOT_GIVEN}, Foo1, use_async) == {}
+ assert await transform({"foo_bar": not_given}, Foo1, use_async) == {}
+
+
+@parametrize
+@pytest.mark.asyncio
+async def test_strips_omit(use_async: bool) -> None:
+ assert await transform({"foo_bar": "bar"}, Foo1, use_async) == {"fooBar": "bar"}
+ assert await transform({"foo_bar": omit}, Foo1, use_async) == {}
From 19c5dd364b496d9a7858e1764000aba6d71613c6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 19 Sep 2025 23:13:53 +0000
Subject: [PATCH 06/10] feat(api): api update
---
.stats.yml | 4 +-
src/supermemory/resources/documents.py | 8 +-
src/supermemory/resources/memories.py | 8 +-
src/supermemory/resources/search.py | 12 +--
src/supermemory/types/document_list_params.py | 80 +++++++++++++++++--
src/supermemory/types/memory_list_params.py | 80 +++++++++++++++++--
.../types/search_documents_params.py | 75 +++++++++++++++--
.../types/search_execute_params.py | 75 +++++++++++++++--
.../types/search_memories_params.py | 78 ++++++++++++++++--
tests/api_resources/test_documents.py | 38 ++++++++-
tests/api_resources/test_memories.py | 38 ++++++++-
tests/api_resources/test_search.py | 78 +++++++++---------
12 files changed, 486 insertions(+), 88 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 6660bb78..ce6f5a0e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-0dc5f10179855bda1aabcad789449ca1e5b84cb5c619ccdd2227cec5b384af43.yml
-openapi_spec_hash: 847c9b8bf6a9a67f2b061243e2024b16
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-6453f22c5b02f00d5656b9fbef9a4c70999ed890c95ddbfd363c7ddba2cef59f.yml
+openapi_spec_hash: bb200bfe2a4fa307beaa119b54efeeb2
config_hash: 2737bce9823a13e0263c0fa2701821fa
diff --git a/src/supermemory/resources/documents.py b/src/supermemory/resources/documents.py
index b2e08e8e..ac9c4ad0 100644
--- a/src/supermemory/resources/documents.py
+++ b/src/supermemory/resources/documents.py
@@ -138,7 +138,7 @@ def list(
self,
*,
container_tags: SequenceNotStr[str] | Omit = omit,
- filters: str | Omit = omit,
+ filters: document_list_params.Filters | Omit = omit,
include_content: bool | Omit = omit,
limit: Union[str, float] | Omit = omit,
order: Literal["asc", "desc"] | Omit = omit,
@@ -159,7 +159,7 @@ def list(
your user, a project ID, or any other identifier you wish to use to group
documents.
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_content: Whether to include the content field in the response. Warning: This can make
responses significantly larger.
@@ -523,7 +523,7 @@ async def list(
self,
*,
container_tags: SequenceNotStr[str] | Omit = omit,
- filters: str | Omit = omit,
+ filters: document_list_params.Filters | Omit = omit,
include_content: bool | Omit = omit,
limit: Union[str, float] | Omit = omit,
order: Literal["asc", "desc"] | Omit = omit,
@@ -544,7 +544,7 @@ async def list(
your user, a project ID, or any other identifier you wish to use to group
documents.
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_content: Whether to include the content field in the response. Warning: This can make
responses significantly larger.
diff --git a/src/supermemory/resources/memories.py b/src/supermemory/resources/memories.py
index 30850259..36689baf 100644
--- a/src/supermemory/resources/memories.py
+++ b/src/supermemory/resources/memories.py
@@ -138,7 +138,7 @@ def list(
self,
*,
container_tags: SequenceNotStr[str] | Omit = omit,
- filters: str | Omit = omit,
+ filters: memory_list_params.Filters | Omit = omit,
include_content: bool | Omit = omit,
limit: Union[str, float] | Omit = omit,
order: Literal["asc", "desc"] | Omit = omit,
@@ -159,7 +159,7 @@ def list(
your user, a project ID, or any other identifier you wish to use to group
documents.
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_content: Whether to include the content field in the response. Warning: This can make
responses significantly larger.
@@ -523,7 +523,7 @@ async def list(
self,
*,
container_tags: SequenceNotStr[str] | Omit = omit,
- filters: str | Omit = omit,
+ filters: memory_list_params.Filters | Omit = omit,
include_content: bool | Omit = omit,
limit: Union[str, float] | Omit = omit,
order: Literal["asc", "desc"] | Omit = omit,
@@ -544,7 +544,7 @@ async def list(
your user, a project ID, or any other identifier you wish to use to group
documents.
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_content: Whether to include the content field in the response. Warning: This can make
responses significantly larger.
diff --git a/src/supermemory/resources/search.py b/src/supermemory/resources/search.py
index 54eee0f7..15867142 100644
--- a/src/supermemory/resources/search.py
+++ b/src/supermemory/resources/search.py
@@ -91,7 +91,7 @@ def documents(
most documents, more results), 1 is most sensitive (returns lesser documents,
accurate results)
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_full_docs: If true, include full document in the response. This is helpful if you want a
chatbot to know the full context of the document.
@@ -190,7 +190,7 @@ def execute(
most documents, more results), 1 is most sensitive (returns lesser documents,
accurate results)
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_full_docs: If true, include full document in the response. This is helpful if you want a
chatbot to know the full context of the document.
@@ -271,7 +271,7 @@ def memories(
container_tag: Optional tag this search should be containerized by. This can be an ID for your
user, a project ID, or any other identifier you wish to use to filter memories.
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
limit: Maximum number of results to return
@@ -380,7 +380,7 @@ async def documents(
most documents, more results), 1 is most sensitive (returns lesser documents,
accurate results)
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_full_docs: If true, include full document in the response. This is helpful if you want a
chatbot to know the full context of the document.
@@ -479,7 +479,7 @@ async def execute(
most documents, more results), 1 is most sensitive (returns lesser documents,
accurate results)
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
include_full_docs: If true, include full document in the response. This is helpful if you want a
chatbot to know the full context of the document.
@@ -560,7 +560,7 @@ async def memories(
container_tag: Optional tag this search should be containerized by. This can be an ID for your
user, a project ID, or any other identifier you wish to use to filter memories.
- filters: Optional filters to apply to the search
+ filters: Optional filters to apply to the search. Can be a JSON string or Query object.
limit: Maximum number of results to return
diff --git a/src/supermemory/types/document_list_params.py b/src/supermemory/types/document_list_params.py
index d4915ef0..4ce7914e 100644
--- a/src/supermemory/types/document_list_params.py
+++ b/src/supermemory/types/document_list_params.py
@@ -2,13 +2,26 @@
from __future__ import annotations
-from typing import Union
-from typing_extensions import Literal, Annotated, TypedDict
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
from .._types import SequenceNotStr
from .._utils import PropertyInfo
-__all__ = ["DocumentListParams"]
+__all__ = [
+ "DocumentListParams",
+ "Filters",
+ "FiltersOr",
+ "FiltersOrOr",
+ "FiltersOrOrUnionMember0",
+ "FiltersOrOrOr",
+ "FiltersOrOrAnd",
+ "FiltersAnd",
+ "FiltersAndAnd",
+ "FiltersAndAndUnionMember0",
+ "FiltersAndAndOr",
+ "FiltersAndAndAnd",
+]
class DocumentListParams(TypedDict, total=False):
@@ -19,8 +32,8 @@ class DocumentListParams(TypedDict, total=False):
to use to group documents.
"""
- filters: str
- """Optional filters to apply to the search"""
+ filters: Filters
+ """Optional filters to apply to the search. Can be a JSON string or Query object."""
include_content: Annotated[bool, PropertyInfo(alias="includeContent")]
"""Whether to include the content field in the response.
@@ -39,3 +52,60 @@ class DocumentListParams(TypedDict, total=False):
sort: Literal["createdAt", "updatedAt"]
"""Field to sort by"""
+
+
+class FiltersOrOrUnionMember0(TypedDict, total=False):
+ key: Required[str]
+
+ value: Required[str]
+
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
+
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersOrOrOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersOrOrAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersOrOr: TypeAlias = Union[FiltersOrOrUnionMember0, FiltersOrOrOr, FiltersOrOrAnd]
+
+
+class FiltersOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[FiltersOrOr], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndUnionMember0(TypedDict, total=False):
+ key: Required[str]
+
+ value: Required[str]
+
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
+
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersAndAndOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersAndAnd: TypeAlias = Union[FiltersAndAndUnionMember0, FiltersAndAndOr, FiltersAndAndAnd]
+
+
+class FiltersAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[FiltersAndAnd], PropertyInfo(alias="AND")]]
+
+
+Filters: TypeAlias = Union[FiltersOr, FiltersAnd]
diff --git a/src/supermemory/types/memory_list_params.py b/src/supermemory/types/memory_list_params.py
index c876faa6..636663ff 100644
--- a/src/supermemory/types/memory_list_params.py
+++ b/src/supermemory/types/memory_list_params.py
@@ -2,13 +2,26 @@
from __future__ import annotations
-from typing import Union
-from typing_extensions import Literal, Annotated, TypedDict
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
from .._types import SequenceNotStr
from .._utils import PropertyInfo
-__all__ = ["MemoryListParams"]
+__all__ = [
+ "MemoryListParams",
+ "Filters",
+ "FiltersOr",
+ "FiltersOrOr",
+ "FiltersOrOrUnionMember0",
+ "FiltersOrOrOr",
+ "FiltersOrOrAnd",
+ "FiltersAnd",
+ "FiltersAndAnd",
+ "FiltersAndAndUnionMember0",
+ "FiltersAndAndOr",
+ "FiltersAndAndAnd",
+]
class MemoryListParams(TypedDict, total=False):
@@ -19,8 +32,8 @@ class MemoryListParams(TypedDict, total=False):
to use to group documents.
"""
- filters: str
- """Optional filters to apply to the search"""
+ filters: Filters
+ """Optional filters to apply to the search. Can be a JSON string or Query object."""
include_content: Annotated[bool, PropertyInfo(alias="includeContent")]
"""Whether to include the content field in the response.
@@ -39,3 +52,60 @@ class MemoryListParams(TypedDict, total=False):
sort: Literal["createdAt", "updatedAt"]
"""Field to sort by"""
+
+
+class FiltersOrOrUnionMember0(TypedDict, total=False):
+ key: Required[str]
+
+ value: Required[str]
+
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
+
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersOrOrOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersOrOrAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersOrOr: TypeAlias = Union[FiltersOrOrUnionMember0, FiltersOrOrOr, FiltersOrOrAnd]
+
+
+class FiltersOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[FiltersOrOr], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndUnionMember0(TypedDict, total=False):
+ key: Required[str]
+
+ value: Required[str]
+
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
+
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersAndAndOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersAndAnd: TypeAlias = Union[FiltersAndAndUnionMember0, FiltersAndAndOr, FiltersAndAndAnd]
+
+
+class FiltersAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[FiltersAndAnd], PropertyInfo(alias="AND")]]
+
+
+Filters: TypeAlias = Union[FiltersOr, FiltersAnd]
diff --git a/src/supermemory/types/search_documents_params.py b/src/supermemory/types/search_documents_params.py
index 13e0a642..a621bdaa 100644
--- a/src/supermemory/types/search_documents_params.py
+++ b/src/supermemory/types/search_documents_params.py
@@ -2,13 +2,26 @@
from __future__ import annotations
-from typing import Dict, List, Union, Iterable
+from typing import List, Union, Iterable
from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
from .._types import SequenceNotStr
from .._utils import PropertyInfo
-__all__ = ["SearchDocumentsParams", "Filters", "FiltersUnionMember0"]
+__all__ = [
+ "SearchDocumentsParams",
+ "Filters",
+ "FiltersOr",
+ "FiltersOrOr",
+ "FiltersOrOrUnionMember0",
+ "FiltersOrOrOr",
+ "FiltersOrOrAnd",
+ "FiltersAnd",
+ "FiltersAndAnd",
+ "FiltersAndAndUnionMember0",
+ "FiltersAndAndOr",
+ "FiltersAndAndAnd",
+]
class SearchDocumentsParams(TypedDict, total=False):
@@ -48,7 +61,7 @@ class SearchDocumentsParams(TypedDict, total=False):
"""
filters: Filters
- """Optional filters to apply to the search"""
+ """Optional filters to apply to the search. Can be a JSON string or Query object."""
include_full_docs: Annotated[bool, PropertyInfo(alias="includeFullDocs")]
"""If true, include full document in the response.
@@ -85,10 +98,58 @@ class SearchDocumentsParams(TypedDict, total=False):
"""
-class FiltersUnionMember0(TypedDict, total=False):
- and_: Annotated[Iterable[object], PropertyInfo(alias="AND")]
+class FiltersOrOrUnionMember0(TypedDict, total=False):
+ key: Required[str]
- or_: Annotated[Iterable[object], PropertyInfo(alias="OR")]
+ value: Required[str]
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
-Filters: TypeAlias = Union[FiltersUnionMember0, Dict[str, object]]
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersOrOrOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersOrOrAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersOrOr: TypeAlias = Union[FiltersOrOrUnionMember0, FiltersOrOrOr, FiltersOrOrAnd]
+
+
+class FiltersOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[FiltersOrOr], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndUnionMember0(TypedDict, total=False):
+ key: Required[str]
+
+ value: Required[str]
+
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
+
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersAndAndOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersAndAnd: TypeAlias = Union[FiltersAndAndUnionMember0, FiltersAndAndOr, FiltersAndAndAnd]
+
+
+class FiltersAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[FiltersAndAnd], PropertyInfo(alias="AND")]]
+
+
+Filters: TypeAlias = Union[FiltersOr, FiltersAnd]
diff --git a/src/supermemory/types/search_execute_params.py b/src/supermemory/types/search_execute_params.py
index 48032181..67d9d87b 100644
--- a/src/supermemory/types/search_execute_params.py
+++ b/src/supermemory/types/search_execute_params.py
@@ -2,13 +2,26 @@
from __future__ import annotations
-from typing import Dict, List, Union, Iterable
+from typing import List, Union, Iterable
from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
from .._types import SequenceNotStr
from .._utils import PropertyInfo
-__all__ = ["SearchExecuteParams", "Filters", "FiltersUnionMember0"]
+__all__ = [
+ "SearchExecuteParams",
+ "Filters",
+ "FiltersOr",
+ "FiltersOrOr",
+ "FiltersOrOrUnionMember0",
+ "FiltersOrOrOr",
+ "FiltersOrOrAnd",
+ "FiltersAnd",
+ "FiltersAndAnd",
+ "FiltersAndAndUnionMember0",
+ "FiltersAndAndOr",
+ "FiltersAndAndAnd",
+]
class SearchExecuteParams(TypedDict, total=False):
@@ -48,7 +61,7 @@ class SearchExecuteParams(TypedDict, total=False):
"""
filters: Filters
- """Optional filters to apply to the search"""
+ """Optional filters to apply to the search. Can be a JSON string or Query object."""
include_full_docs: Annotated[bool, PropertyInfo(alias="includeFullDocs")]
"""If true, include full document in the response.
@@ -85,10 +98,58 @@ class SearchExecuteParams(TypedDict, total=False):
"""
-class FiltersUnionMember0(TypedDict, total=False):
- and_: Annotated[Iterable[object], PropertyInfo(alias="AND")]
+class FiltersOrOrUnionMember0(TypedDict, total=False):
+ key: Required[str]
- or_: Annotated[Iterable[object], PropertyInfo(alias="OR")]
+ value: Required[str]
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
-Filters: TypeAlias = Union[FiltersUnionMember0, Dict[str, object]]
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersOrOrOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersOrOrAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersOrOr: TypeAlias = Union[FiltersOrOrUnionMember0, FiltersOrOrOr, FiltersOrOrAnd]
+
+
+class FiltersOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[FiltersOrOr], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndUnionMember0(TypedDict, total=False):
+ key: Required[str]
+
+ value: Required[str]
+
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
+
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersAndAndOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersAndAnd: TypeAlias = Union[FiltersAndAndUnionMember0, FiltersAndAndOr, FiltersAndAndAnd]
+
+
+class FiltersAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[FiltersAndAnd], PropertyInfo(alias="AND")]]
+
+
+Filters: TypeAlias = Union[FiltersOr, FiltersAnd]
diff --git a/src/supermemory/types/search_memories_params.py b/src/supermemory/types/search_memories_params.py
index 20602ee9..5751cd34 100644
--- a/src/supermemory/types/search_memories_params.py
+++ b/src/supermemory/types/search_memories_params.py
@@ -2,12 +2,26 @@
from __future__ import annotations
-from typing import Dict, Union, Iterable
-from typing_extensions import Required, Annotated, TypeAlias, TypedDict
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
from .._utils import PropertyInfo
-__all__ = ["SearchMemoriesParams", "Filters", "FiltersUnionMember0", "Include"]
+__all__ = [
+ "SearchMemoriesParams",
+ "Filters",
+ "FiltersOr",
+ "FiltersOrOr",
+ "FiltersOrOrUnionMember0",
+ "FiltersOrOrOr",
+ "FiltersOrOrAnd",
+ "FiltersAnd",
+ "FiltersAndAnd",
+ "FiltersAndAndUnionMember0",
+ "FiltersAndAndOr",
+ "FiltersAndAndAnd",
+ "Include",
+]
class SearchMemoriesParams(TypedDict, total=False):
@@ -22,7 +36,7 @@ class SearchMemoriesParams(TypedDict, total=False):
"""
filters: Filters
- """Optional filters to apply to the search"""
+ """Optional filters to apply to the search. Can be a JSON string or Query object."""
include: Include
@@ -49,13 +63,61 @@ class SearchMemoriesParams(TypedDict, total=False):
"""
-class FiltersUnionMember0(TypedDict, total=False):
- and_: Annotated[Iterable[object], PropertyInfo(alias="AND")]
+class FiltersOrOrUnionMember0(TypedDict, total=False):
+ key: Required[str]
- or_: Annotated[Iterable[object], PropertyInfo(alias="OR")]
+ value: Required[str]
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
-Filters: TypeAlias = Union[FiltersUnionMember0, Dict[str, object]]
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersOrOrOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersOrOrAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersOrOr: TypeAlias = Union[FiltersOrOrUnionMember0, FiltersOrOrOr, FiltersOrOrAnd]
+
+
+class FiltersOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[FiltersOrOr], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndUnionMember0(TypedDict, total=False):
+ key: Required[str]
+
+ value: Required[str]
+
+ filter_type: Annotated[Literal["metadata", "numeric", "array_contains"], PropertyInfo(alias="filterType")]
+
+ negate: Union[bool, Literal["true", "false"]]
+
+ numeric_operator: Annotated[Literal[">", "<", ">=", "<=", "="], PropertyInfo(alias="numericOperator")]
+
+
+class FiltersAndAndOr(TypedDict, total=False):
+ or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]]
+
+
+class FiltersAndAndAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]]
+
+
+FiltersAndAnd: TypeAlias = Union[FiltersAndAndUnionMember0, FiltersAndAndOr, FiltersAndAndAnd]
+
+
+class FiltersAnd(TypedDict, total=False):
+ and_: Required[Annotated[Iterable[FiltersAndAnd], PropertyInfo(alias="AND")]]
+
+
+Filters: TypeAlias = Union[FiltersOr, FiltersAnd]
class Include(TypedDict, total=False):
diff --git a/tests/api_resources/test_documents.py b/tests/api_resources/test_documents.py
index 7cf1bd4b..c192d7e2 100644
--- a/tests/api_resources/test_documents.py
+++ b/tests/api_resources/test_documents.py
@@ -98,7 +98,24 @@ def test_method_list(self, client: Supermemory) -> None:
def test_method_list_with_all_params(self, client: Supermemory) -> None:
document = client.documents.list(
container_tags=["user_123", "project_123"],
- filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ filters={
+ "and_": [
+ {
+ "key": "group",
+ "value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ {
+ "key": "timestamp",
+ "value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ ]
+ },
include_content=False,
limit=10,
order="desc",
@@ -394,7 +411,24 @@ async def test_method_list(self, async_client: AsyncSupermemory) -> None:
async def test_method_list_with_all_params(self, async_client: AsyncSupermemory) -> None:
document = await async_client.documents.list(
container_tags=["user_123", "project_123"],
- filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ filters={
+ "and_": [
+ {
+ "key": "group",
+ "value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ {
+ "key": "timestamp",
+ "value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ ]
+ },
include_content=False,
limit=10,
order="desc",
diff --git a/tests/api_resources/test_memories.py b/tests/api_resources/test_memories.py
index 9d5c5d21..2effb9a2 100644
--- a/tests/api_resources/test_memories.py
+++ b/tests/api_resources/test_memories.py
@@ -98,7 +98,24 @@ def test_method_list(self, client: Supermemory) -> None:
def test_method_list_with_all_params(self, client: Supermemory) -> None:
memory = client.memories.list(
container_tags=["user_123", "project_123"],
- filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ filters={
+ "and_": [
+ {
+ "key": "group",
+ "value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ {
+ "key": "timestamp",
+ "value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ ]
+ },
include_content=False,
limit=10,
order="desc",
@@ -394,7 +411,24 @@ async def test_method_list(self, async_client: AsyncSupermemory) -> None:
async def test_method_list_with_all_params(self, async_client: AsyncSupermemory) -> None:
memory = await async_client.memories.list(
container_tags=["user_123", "project_123"],
- filters='{"AND":[{"key":"group","negate":false,"value":"jira_users"},{"filterType":"numeric","key":"timestamp","negate":false,"numericOperator":">","value":"1742745777"}]}',
+ filters={
+ "and_": [
+ {
+ "key": "group",
+ "value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ {
+ "key": "timestamp",
+ "value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
+ },
+ ]
+ },
include_content=False,
limit=10,
order="desc",
diff --git a/tests/api_resources/test_search.py b/tests/api_resources/test_search.py
index 4fae417c..810511c6 100644
--- a/tests/api_resources/test_search.py
+++ b/tests/api_resources/test_search.py
@@ -43,18 +43,19 @@ def test_method_documents_with_all_params(self, client: Supermemory) -> None:
"and_": [
{
"key": "group",
- "negate": False,
"value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
},
{
- "filterType": "numeric",
"key": "timestamp",
- "negate": False,
- "numericOperator": ">",
"value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
},
- ],
- "or_": [{}],
+ ]
},
include_full_docs=False,
include_summary=False,
@@ -113,18 +114,19 @@ def test_method_execute_with_all_params(self, client: Supermemory) -> None:
"and_": [
{
"key": "group",
- "negate": False,
"value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
},
{
- "filterType": "numeric",
"key": "timestamp",
- "negate": False,
- "numericOperator": ">",
"value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
},
- ],
- "or_": [{}],
+ ]
},
include_full_docs=False,
include_summary=False,
@@ -179,18 +181,19 @@ def test_method_memories_with_all_params(self, client: Supermemory) -> None:
"and_": [
{
"key": "group",
- "negate": False,
"value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
},
{
- "filterType": "numeric",
"key": "timestamp",
- "negate": False,
- "numericOperator": ">",
"value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
},
- ],
- "or_": [{}],
+ ]
},
include={
"documents": True,
@@ -259,18 +262,19 @@ async def test_method_documents_with_all_params(self, async_client: AsyncSuperme
"and_": [
{
"key": "group",
- "negate": False,
"value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
},
{
- "filterType": "numeric",
"key": "timestamp",
- "negate": False,
- "numericOperator": ">",
"value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
},
- ],
- "or_": [{}],
+ ]
},
include_full_docs=False,
include_summary=False,
@@ -329,18 +333,19 @@ async def test_method_execute_with_all_params(self, async_client: AsyncSupermemo
"and_": [
{
"key": "group",
- "negate": False,
"value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
},
{
- "filterType": "numeric",
"key": "timestamp",
- "negate": False,
- "numericOperator": ">",
"value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
},
- ],
- "or_": [{}],
+ ]
},
include_full_docs=False,
include_summary=False,
@@ -395,18 +400,19 @@ async def test_method_memories_with_all_params(self, async_client: AsyncSupermem
"and_": [
{
"key": "group",
- "negate": False,
"value": "jira_users",
+ "filter_type": "metadata",
+ "negate": False,
+ "numeric_operator": ">",
},
{
- "filterType": "numeric",
"key": "timestamp",
- "negate": False,
- "numericOperator": ">",
"value": "1742745777",
+ "filter_type": "numeric",
+ "negate": False,
+ "numeric_operator": ">",
},
- ],
- "or_": [{}],
+ ]
},
include={
"documents": True,
From fb748cf2375b1ce1eddd2584503e81d3b8386443 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 20 Sep 2025 02:13:15 +0000
Subject: [PATCH 07/10] chore: do not install brew dependencies in
./scripts/bootstrap by default
---
scripts/bootstrap | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/scripts/bootstrap b/scripts/bootstrap
index e84fe62c..b430fee3 100755
--- a/scripts/bootstrap
+++ b/scripts/bootstrap
@@ -4,10 +4,18 @@ set -e
cd "$(dirname "$0")/.."
-if ! command -v rye >/dev/null 2>&1 && [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then
+if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then
brew bundle check >/dev/null 2>&1 || {
- echo "==> Installing Homebrew dependencies…"
- brew bundle
+ echo -n "==> Install Homebrew dependencies? (y/N): "
+ read -r response
+ case "$response" in
+ [yY][eE][sS]|[yY])
+ brew bundle
+ ;;
+ *)
+ ;;
+ esac
+ echo
}
fi
From 85c6969827e057f821a44fdc18b7699f06c2f175 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 20 Sep 2025 03:14:01 +0000
Subject: [PATCH 08/10] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index ce6f5a0e..32448b4a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-6453f22c5b02f00d5656b9fbef9a4c70999ed890c95ddbfd363c7ddba2cef59f.yml
-openapi_spec_hash: bb200bfe2a4fa307beaa119b54efeeb2
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-b7bf8402df5372a3fac3cb55e083d7c09867328639cb7e2ceb7826de125ccff7.yml
+openapi_spec_hash: a91c06034ad9e8a7315927d6f2e18521
config_hash: 2737bce9823a13e0263c0fa2701821fa
From e92cb27550c2190a6804a2865ae359ff79fa1866 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 20 Sep 2025 21:09:26 +0000
Subject: [PATCH 09/10] feat(api): manual updates
---
.stats.yml | 2 +-
README.md | 22 +++++++--------
tests/test_client.py | 64 +++++++++++++++++++++++++++++---------------
3 files changed, 54 insertions(+), 34 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 32448b4a..ebe1bcee 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 18
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-b7bf8402df5372a3fac3cb55e083d7c09867328639cb7e2ceb7826de125ccff7.yml
openapi_spec_hash: a91c06034ad9e8a7315927d6f2e18521
-config_hash: 2737bce9823a13e0263c0fa2701821fa
+config_hash: 5deef1e3a49e3a7816348fbf7ba259bf
diff --git a/README.md b/README.md
index 7d5a5197..4b1036fa 100644
--- a/README.md
+++ b/README.md
@@ -160,8 +160,8 @@ from supermemory import Supermemory
client = Supermemory()
try:
- client.memories.update(
- id="id",
+ client.memories.add(
+ content="This is a detailed article about machine learning concepts...",
)
except supermemory.APIConnectionError as e:
print("The server could not be reached")
@@ -205,8 +205,8 @@ client = Supermemory(
)
# Or, configure per-request:
-client.with_options(max_retries=5).memories.update(
- id="id",
+client.with_options(max_retries=5).memories.add(
+ content="This is a detailed article about machine learning concepts...",
)
```
@@ -230,8 +230,8 @@ client = Supermemory(
)
# Override per-request:
-client.with_options(timeout=5.0).memories.update(
- id="id",
+client.with_options(timeout=5.0).memories.add(
+ content="This is a detailed article about machine learning concepts...",
)
```
@@ -273,12 +273,12 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
from supermemory import Supermemory
client = Supermemory()
-response = client.memories.with_raw_response.update(
- id="id",
+response = client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
)
print(response.headers.get('X-My-Header'))
-memory = response.parse() # get the object that `memories.update()` would have returned
+memory = response.parse() # get the object that `memories.add()` would have returned
print(memory.id)
```
@@ -293,8 +293,8 @@ The above interface eagerly reads the full response body when you make the reque
To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.
```python
-with client.memories.with_streaming_response.update(
- id="id",
+with client.memories.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts...",
) as response:
print(response.headers.get("X-My-Header"))
diff --git a/tests/test_client.py b/tests/test_client.py
index f66d20fc..4e97c388 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -724,20 +724,24 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str
@mock.patch("supermemory._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: Supermemory) -> None:
- respx_mock.patch("/v3/documents/id").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.post("/v3/documents").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.memories.with_streaming_response.update(id="id").__enter__()
+ client.memories.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts..."
+ ).__enter__()
assert _get_open_connections(self.client) == 0
@mock.patch("supermemory._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: Supermemory) -> None:
- respx_mock.patch("/v3/documents/id").mock(return_value=httpx.Response(500))
+ respx_mock.post("/v3/documents").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.memories.with_streaming_response.update(id="id").__enter__()
+ client.memories.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts..."
+ ).__enter__()
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -764,9 +768,11 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
+ respx_mock.post("/v3/documents").mock(side_effect=retry_handler)
- response = client.memories.with_raw_response.update(id="id")
+ response = client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts..."
+ )
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -788,9 +794,12 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
+ respx_mock.post("/v3/documents").mock(side_effect=retry_handler)
- response = client.memories.with_raw_response.update(id="id", extra_headers={"x-stainless-retry-count": Omit()})
+ response = client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ extra_headers={"x-stainless-retry-count": Omit()},
+ )
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -811,9 +820,12 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
+ respx_mock.post("/v3/documents").mock(side_effect=retry_handler)
- response = client.memories.with_raw_response.update(id="id", extra_headers={"x-stainless-retry-count": "42"})
+ response = client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ extra_headers={"x-stainless-retry-count": "42"},
+ )
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1541,10 +1553,12 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte
async def test_retrying_timeout_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncSupermemory
) -> None:
- respx_mock.patch("/v3/documents/id").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.post("/v3/documents").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.memories.with_streaming_response.update(id="id").__aenter__()
+ await async_client.memories.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts..."
+ ).__aenter__()
assert _get_open_connections(self.client) == 0
@@ -1553,10 +1567,12 @@ async def test_retrying_timeout_errors_doesnt_leak(
async def test_retrying_status_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncSupermemory
) -> None:
- respx_mock.patch("/v3/documents/id").mock(return_value=httpx.Response(500))
+ respx_mock.post("/v3/documents").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.memories.with_streaming_response.update(id="id").__aenter__()
+ await async_client.memories.with_streaming_response.add(
+ content="This is a detailed article about machine learning concepts..."
+ ).__aenter__()
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1584,9 +1600,11 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
+ respx_mock.post("/v3/documents").mock(side_effect=retry_handler)
- response = await client.memories.with_raw_response.update(id="id")
+ response = await client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts..."
+ )
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1609,10 +1627,11 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
+ respx_mock.post("/v3/documents").mock(side_effect=retry_handler)
- response = await client.memories.with_raw_response.update(
- id="id", extra_headers={"x-stainless-retry-count": Omit()}
+ response = await client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ extra_headers={"x-stainless-retry-count": Omit()},
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1635,10 +1654,11 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.patch("/v3/documents/id").mock(side_effect=retry_handler)
+ respx_mock.post("/v3/documents").mock(side_effect=retry_handler)
- response = await client.memories.with_raw_response.update(
- id="id", extra_headers={"x-stainless-retry-count": "42"}
+ response = await client.memories.with_raw_response.add(
+ content="This is a detailed article about machine learning concepts...",
+ extra_headers={"x-stainless-retry-count": "42"},
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
From c213dbcff4dfb27162afd04265256f27bcfbf102 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 20 Sep 2025 21:10:58 +0000
Subject: [PATCH 10/10] release: 3.1.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 18 ++++++++++++++++++
README.md | 4 ++--
pyproject.toml | 2 +-
src/supermemory/_version.py | 2 +-
5 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index e36acabe..e0dc5001 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "3.0.0-alpha.30"
+ ".": "3.1.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 87bd87cc..065277d1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## 3.1.0 (2025-09-20)
+
+Full Changelog: [v3.0.0-alpha.30...v3.1.0](https://github.com/supermemoryai/python-sdk/compare/v3.0.0-alpha.30...v3.1.0)
+
+### Features
+
+* **api:** api update ([19c5dd3](https://github.com/supermemoryai/python-sdk/commit/19c5dd364b496d9a7858e1764000aba6d71613c6))
+* **api:** api update ([3082481](https://github.com/supermemoryai/python-sdk/commit/30824814233753584a89c56a2efb69d72995be02))
+* **api:** manual updates ([e92cb27](https://github.com/supermemoryai/python-sdk/commit/e92cb27550c2190a6804a2865ae359ff79fa1866))
+* **api:** manual updates ([251fdf1](https://github.com/supermemoryai/python-sdk/commit/251fdf116f5f1b0c1ecfb74bef94ba08f7921dca))
+
+
+### Chores
+
+* do not install brew dependencies in ./scripts/bootstrap by default ([fb748cf](https://github.com/supermemoryai/python-sdk/commit/fb748cf2375b1ce1eddd2584503e81d3b8386443))
+* **internal:** update pydantic dependency ([8c480f7](https://github.com/supermemoryai/python-sdk/commit/8c480f70cf3d0e55c4c5bc3b77d83bd6b21c4fdf))
+* **types:** change optional parameter type from NotGiven to Omit ([3031781](https://github.com/supermemoryai/python-sdk/commit/30317810d7089dbdf59f5e143bd66b1a0495b2b6))
+
## 3.0.0-alpha.30 (2025-09-15)
Full Changelog: [v3.0.0-alpha.29...v3.0.0-alpha.30](https://github.com/supermemoryai/python-sdk/compare/v3.0.0-alpha.29...v3.0.0-alpha.30)
diff --git a/README.md b/README.md
index 4b1036fa..113af8d0 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ The REST API documentation can be found on [docs.supermemory.ai](https://docs.su
```sh
# install from PyPI
-pip install --pre supermemory
+pip install supermemory
```
## Usage
@@ -77,7 +77,7 @@ You can enable this by installing `aiohttp`:
```sh
# install from PyPI
-pip install --pre supermemory[aiohttp]
+pip install supermemory[aiohttp]
```
Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
diff --git a/pyproject.toml b/pyproject.toml
index b941471b..46943a25 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "supermemory"
-version = "3.0.0-alpha.30"
+version = "3.1.0"
description = "The official Python library for the supermemory API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/supermemory/_version.py b/src/supermemory/_version.py
index 0e7aa74e..941e3486 100644
--- a/src/supermemory/_version.py
+++ b/src/supermemory/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "supermemory"
-__version__ = "3.0.0-alpha.30" # x-release-please-version
+__version__ = "3.1.0" # x-release-please-version