From 8680e723f9bd9cdc930ed33914557dc60d5242c0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 23:44:46 +0000 Subject: [PATCH 1/7] feat(api): manual updates --- .stats.yml | 4 +- api.md | 2 +- src/supermemory/_client.py | 6 +- src/supermemory/resources/shared.py | 187 ++++++++++++++++++ src/supermemory/types/__init__.py | 2 +- src/supermemory/types/shared/__init__.py | 1 + .../types/shared/profile_response.py | 35 ++++ .../types/shared/profile_response1.py | 35 ++++ .../types/shared/shared_profile_params.py | 21 ++ tests/api_resources/test_shared.py | 110 +++++++++++ 10 files changed, 398 insertions(+), 5 deletions(-) create mode 100644 src/supermemory/resources/shared.py create mode 100644 src/supermemory/types/shared/profile_response.py create mode 100644 src/supermemory/types/shared/profile_response1.py create mode 100644 src/supermemory/types/shared/shared_profile_params.py create mode 100644 tests/api_resources/test_shared.py diff --git a/.stats.yml b/.stats.yml index 0b389cd6..842960e6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 18 +configured_endpoints: 19 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-ebd5e757d0e76cb83013e01a1e0bb3dba62beb83b2a2ffa28d148ea032e96fd0.yml openapi_spec_hash: f930474a6ad230545154244045cc602e -config_hash: 5bc39292a7e2f871b35cdebbecd9f022 +config_hash: 73c4fae15631e979e9bf690ec9aea665 diff --git a/api.md b/api.md index 4451d8b1..c772f1b1 100644 --- a/api.md +++ b/api.md @@ -1,7 +1,7 @@ # Shared Types ```python -from supermemory.types import And, Or +from supermemory.types import And, Or, ProfileResponse ``` # Memories diff --git a/src/supermemory/_client.py b/src/supermemory/_client.py index 0de41593..7403db31 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, memories, settings, documents, connections +from .resources import search, shared, memories, settings, documents, connections from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import APIStatusError, SupermemoryError from ._base_client import ( @@ -396,6 +396,7 @@ def _make_status_error( class SupermemoryWithRawResponse: def __init__(self, client: Supermemory) -> None: + self.shared = shared.SharedResourceWithRawResponse(client.shared) self.memories = memories.MemoriesResourceWithRawResponse(client.memories) self.documents = documents.DocumentsResourceWithRawResponse(client.documents) self.search = search.SearchResourceWithRawResponse(client.search) @@ -405,6 +406,7 @@ def __init__(self, client: Supermemory) -> None: class AsyncSupermemoryWithRawResponse: def __init__(self, client: AsyncSupermemory) -> None: + self.shared = shared.AsyncSharedResourceWithRawResponse(client.shared) self.memories = memories.AsyncMemoriesResourceWithRawResponse(client.memories) self.documents = documents.AsyncDocumentsResourceWithRawResponse(client.documents) self.search = search.AsyncSearchResourceWithRawResponse(client.search) @@ -414,6 +416,7 @@ def __init__(self, client: AsyncSupermemory) -> None: class SupermemoryWithStreamedResponse: def __init__(self, client: Supermemory) -> None: + self.shared = shared.SharedResourceWithStreamingResponse(client.shared) self.memories = memories.MemoriesResourceWithStreamingResponse(client.memories) self.documents = documents.DocumentsResourceWithStreamingResponse(client.documents) self.search = search.SearchResourceWithStreamingResponse(client.search) @@ -423,6 +426,7 @@ def __init__(self, client: Supermemory) -> None: class AsyncSupermemoryWithStreamedResponse: def __init__(self, client: AsyncSupermemory) -> None: + self.shared = shared.AsyncSharedResourceWithStreamingResponse(client.shared) self.memories = memories.AsyncMemoriesResourceWithStreamingResponse(client.memories) self.documents = documents.AsyncDocumentsResourceWithStreamingResponse(client.documents) self.search = search.AsyncSearchResourceWithStreamingResponse(client.search) diff --git a/src/supermemory/resources/shared.py b/src/supermemory/resources/shared.py new file mode 100644 index 00000000..3eed258e --- /dev/null +++ b/src/supermemory/resources/shared.py @@ -0,0 +1,187 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +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 +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.shared import shared_profile_params +from ..types.shared.profile_response import ProfileResponse + +__all__ = ["SharedResource", "AsyncSharedResource"] + + +class SharedResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> SharedResourceWithRawResponse: + """ + 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 SharedResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SharedResourceWithStreamingResponse: + """ + 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 SharedResourceWithStreamingResponse(self) + + def profile( + self, + *, + container_tag: str, + q: 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, + ) -> ProfileResponse: + """ + Get user profile with optional search results + + Args: + container_tag: Tag to filter the profile by. This can be an ID for your user, a project ID, or + any other identifier you wish to use to filter memories. + + q: Optional search query to include search results in the response + + 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( + "/v4/profile", + body=maybe_transform( + { + "container_tag": container_tag, + "q": q, + }, + shared_profile_params.SharedProfileParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProfileResponse, + ) + + +class AsyncSharedResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncSharedResourceWithRawResponse: + """ + 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 AsyncSharedResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSharedResourceWithStreamingResponse: + """ + 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 AsyncSharedResourceWithStreamingResponse(self) + + async def profile( + self, + *, + container_tag: str, + q: 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, + ) -> ProfileResponse: + """ + Get user profile with optional search results + + Args: + container_tag: Tag to filter the profile by. This can be an ID for your user, a project ID, or + any other identifier you wish to use to filter memories. + + q: Optional search query to include search results in the response + + 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( + "/v4/profile", + body=await async_maybe_transform( + { + "container_tag": container_tag, + "q": q, + }, + shared_profile_params.SharedProfileParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProfileResponse, + ) + + +class SharedResourceWithRawResponse: + def __init__(self, shared: SharedResource) -> None: + self._shared = shared + + self.profile = to_raw_response_wrapper( + shared.profile, + ) + + +class AsyncSharedResourceWithRawResponse: + def __init__(self, shared: AsyncSharedResource) -> None: + self._shared = shared + + self.profile = async_to_raw_response_wrapper( + shared.profile, + ) + + +class SharedResourceWithStreamingResponse: + def __init__(self, shared: SharedResource) -> None: + self._shared = shared + + self.profile = to_streamed_response_wrapper( + shared.profile, + ) + + +class AsyncSharedResourceWithStreamingResponse: + def __init__(self, shared: AsyncSharedResource) -> None: + self._shared = shared + + self.profile = async_to_streamed_response_wrapper( + shared.profile, + ) diff --git a/src/supermemory/types/__init__.py b/src/supermemory/types/__init__.py index 54bc0e85..5a100926 100644 --- a/src/supermemory/types/__init__.py +++ b/src/supermemory/types/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from .shared import Or as Or, And as And +from .shared import Or as Or, And as And, ProfileResponse as ProfileResponse from .memory_add_params import MemoryAddParams as MemoryAddParams from .memory_list_params import MemoryListParams as MemoryListParams from .document_add_params import DocumentAddParams as DocumentAddParams diff --git a/src/supermemory/types/shared/__init__.py b/src/supermemory/types/shared/__init__.py index 96ecf13e..e30cbf32 100644 --- a/src/supermemory/types/shared/__init__.py +++ b/src/supermemory/types/shared/__init__.py @@ -2,3 +2,4 @@ from .or_ import Or as Or from .and_ import And as And +from .profile_response import ProfileResponse as ProfileResponse diff --git a/src/supermemory/types/shared/profile_response.py b/src/supermemory/types/shared/profile_response.py new file mode 100644 index 00000000..7ee6d7a2 --- /dev/null +++ b/src/supermemory/types/shared/profile_response.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ProfileResponse", "Profile", "SearchResults"] + + +class Profile(BaseModel): + dynamic: List[str] + """Dynamic profile information (recent memories)""" + + static: List[str] + """Static profile information that remains relevant long-term""" + + +class SearchResults(BaseModel): + results: List[object] + """Search results for the provided query""" + + timing: float + """Search timing in milliseconds""" + + total: float + """Total number of search results""" + + +class ProfileResponse(BaseModel): + profile: Profile + + search_results: Optional[SearchResults] = FieldInfo(alias="searchResults", default=None) + """Search results if a search query was provided""" diff --git a/src/supermemory/types/shared/profile_response1.py b/src/supermemory/types/shared/profile_response1.py new file mode 100644 index 00000000..7ee6d7a2 --- /dev/null +++ b/src/supermemory/types/shared/profile_response1.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ProfileResponse", "Profile", "SearchResults"] + + +class Profile(BaseModel): + dynamic: List[str] + """Dynamic profile information (recent memories)""" + + static: List[str] + """Static profile information that remains relevant long-term""" + + +class SearchResults(BaseModel): + results: List[object] + """Search results for the provided query""" + + timing: float + """Search timing in milliseconds""" + + total: float + """Total number of search results""" + + +class ProfileResponse(BaseModel): + profile: Profile + + search_results: Optional[SearchResults] = FieldInfo(alias="searchResults", default=None) + """Search results if a search query was provided""" diff --git a/src/supermemory/types/shared/shared_profile_params.py b/src/supermemory/types/shared/shared_profile_params.py new file mode 100644 index 00000000..2f2994f3 --- /dev/null +++ b/src/supermemory/types/shared/shared_profile_params.py @@ -0,0 +1,21 @@ +# 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 ..._utils import PropertyInfo + +__all__ = ["SharedProfileParams"] + + +class SharedProfileParams(TypedDict, total=False): + container_tag: Required[Annotated[str, PropertyInfo(alias="containerTag")]] + """Tag to filter the profile by. + + This can be an ID for your user, a project ID, or any other identifier you wish + to use to filter memories. + """ + + q: str + """Optional search query to include search results in the response""" diff --git a/tests/api_resources/test_shared.py b/tests/api_resources/test_shared.py new file mode 100644 index 00000000..6958f25c --- /dev/null +++ b/tests/api_resources/test_shared.py @@ -0,0 +1,110 @@ +# 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.shared import ProfileResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestShared: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_profile(self, client: Supermemory) -> None: + shared = client.shared.profile( + container_tag="containerTag", + ) + assert_matches_type(ProfileResponse, shared, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_profile_with_all_params(self, client: Supermemory) -> None: + shared = client.shared.profile( + container_tag="containerTag", + q="q", + ) + assert_matches_type(ProfileResponse, shared, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_profile(self, client: Supermemory) -> None: + response = client.shared.with_raw_response.profile( + container_tag="containerTag", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + shared = response.parse() + assert_matches_type(ProfileResponse, shared, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_profile(self, client: Supermemory) -> None: + with client.shared.with_streaming_response.profile( + container_tag="containerTag", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + shared = response.parse() + assert_matches_type(ProfileResponse, shared, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncShared: + 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_profile(self, async_client: AsyncSupermemory) -> None: + shared = await async_client.shared.profile( + container_tag="containerTag", + ) + assert_matches_type(ProfileResponse, shared, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_profile_with_all_params(self, async_client: AsyncSupermemory) -> None: + shared = await async_client.shared.profile( + container_tag="containerTag", + q="q", + ) + assert_matches_type(ProfileResponse, shared, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_profile(self, async_client: AsyncSupermemory) -> None: + response = await async_client.shared.with_raw_response.profile( + container_tag="containerTag", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + shared = await response.parse() + assert_matches_type(ProfileResponse, shared, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_profile(self, async_client: AsyncSupermemory) -> None: + async with async_client.shared.with_streaming_response.profile( + container_tag="containerTag", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + shared = await response.parse() + assert_matches_type(ProfileResponse, shared, path=["response"]) + + assert cast(Any, response.is_closed) is True From 3f2f954a542c4f2e6fc7d6e204c7e44fe640ec7d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 23:45:31 +0000 Subject: [PATCH 2/7] feat(api): manual updates --- .stats.yml | 4 +- api.md | 2 +- src/supermemory/_client.py | 6 +- src/supermemory/resources/shared.py | 187 ------------------ src/supermemory/types/__init__.py | 2 +- src/supermemory/types/shared/__init__.py | 1 - .../types/shared/profile_response.py | 35 ---- .../types/shared/profile_response1.py | 35 ---- .../types/shared/shared_profile_params.py | 21 -- tests/api_resources/test_shared.py | 110 ----------- 10 files changed, 5 insertions(+), 398 deletions(-) delete mode 100644 src/supermemory/resources/shared.py delete mode 100644 src/supermemory/types/shared/profile_response.py delete mode 100644 src/supermemory/types/shared/profile_response1.py delete mode 100644 src/supermemory/types/shared/shared_profile_params.py delete mode 100644 tests/api_resources/test_shared.py diff --git a/.stats.yml b/.stats.yml index 842960e6..da8e35f0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 19 +configured_endpoints: 18 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-ebd5e757d0e76cb83013e01a1e0bb3dba62beb83b2a2ffa28d148ea032e96fd0.yml openapi_spec_hash: f930474a6ad230545154244045cc602e -config_hash: 73c4fae15631e979e9bf690ec9aea665 +config_hash: 5b7cec4b962a2ef1b02ac789757eaf15 diff --git a/api.md b/api.md index c772f1b1..4451d8b1 100644 --- a/api.md +++ b/api.md @@ -1,7 +1,7 @@ # Shared Types ```python -from supermemory.types import And, Or, ProfileResponse +from supermemory.types import And, Or ``` # Memories diff --git a/src/supermemory/_client.py b/src/supermemory/_client.py index 7403db31..0de41593 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, shared, memories, settings, documents, 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 ( @@ -396,7 +396,6 @@ def _make_status_error( class SupermemoryWithRawResponse: def __init__(self, client: Supermemory) -> None: - self.shared = shared.SharedResourceWithRawResponse(client.shared) self.memories = memories.MemoriesResourceWithRawResponse(client.memories) self.documents = documents.DocumentsResourceWithRawResponse(client.documents) self.search = search.SearchResourceWithRawResponse(client.search) @@ -406,7 +405,6 @@ def __init__(self, client: Supermemory) -> None: class AsyncSupermemoryWithRawResponse: def __init__(self, client: AsyncSupermemory) -> None: - self.shared = shared.AsyncSharedResourceWithRawResponse(client.shared) self.memories = memories.AsyncMemoriesResourceWithRawResponse(client.memories) self.documents = documents.AsyncDocumentsResourceWithRawResponse(client.documents) self.search = search.AsyncSearchResourceWithRawResponse(client.search) @@ -416,7 +414,6 @@ def __init__(self, client: AsyncSupermemory) -> None: class SupermemoryWithStreamedResponse: def __init__(self, client: Supermemory) -> None: - self.shared = shared.SharedResourceWithStreamingResponse(client.shared) self.memories = memories.MemoriesResourceWithStreamingResponse(client.memories) self.documents = documents.DocumentsResourceWithStreamingResponse(client.documents) self.search = search.SearchResourceWithStreamingResponse(client.search) @@ -426,7 +423,6 @@ def __init__(self, client: Supermemory) -> None: class AsyncSupermemoryWithStreamedResponse: def __init__(self, client: AsyncSupermemory) -> None: - self.shared = shared.AsyncSharedResourceWithStreamingResponse(client.shared) self.memories = memories.AsyncMemoriesResourceWithStreamingResponse(client.memories) self.documents = documents.AsyncDocumentsResourceWithStreamingResponse(client.documents) self.search = search.AsyncSearchResourceWithStreamingResponse(client.search) diff --git a/src/supermemory/resources/shared.py b/src/supermemory/resources/shared.py deleted file mode 100644 index 3eed258e..00000000 --- a/src/supermemory/resources/shared.py +++ /dev/null @@ -1,187 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -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 -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.shared import shared_profile_params -from ..types.shared.profile_response import ProfileResponse - -__all__ = ["SharedResource", "AsyncSharedResource"] - - -class SharedResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> SharedResourceWithRawResponse: - """ - 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 SharedResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> SharedResourceWithStreamingResponse: - """ - 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 SharedResourceWithStreamingResponse(self) - - def profile( - self, - *, - container_tag: str, - q: 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, - ) -> ProfileResponse: - """ - Get user profile with optional search results - - Args: - container_tag: Tag to filter the profile by. This can be an ID for your user, a project ID, or - any other identifier you wish to use to filter memories. - - q: Optional search query to include search results in the response - - 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( - "/v4/profile", - body=maybe_transform( - { - "container_tag": container_tag, - "q": q, - }, - shared_profile_params.SharedProfileParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ProfileResponse, - ) - - -class AsyncSharedResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncSharedResourceWithRawResponse: - """ - 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 AsyncSharedResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncSharedResourceWithStreamingResponse: - """ - 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 AsyncSharedResourceWithStreamingResponse(self) - - async def profile( - self, - *, - container_tag: str, - q: 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, - ) -> ProfileResponse: - """ - Get user profile with optional search results - - Args: - container_tag: Tag to filter the profile by. This can be an ID for your user, a project ID, or - any other identifier you wish to use to filter memories. - - q: Optional search query to include search results in the response - - 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( - "/v4/profile", - body=await async_maybe_transform( - { - "container_tag": container_tag, - "q": q, - }, - shared_profile_params.SharedProfileParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ProfileResponse, - ) - - -class SharedResourceWithRawResponse: - def __init__(self, shared: SharedResource) -> None: - self._shared = shared - - self.profile = to_raw_response_wrapper( - shared.profile, - ) - - -class AsyncSharedResourceWithRawResponse: - def __init__(self, shared: AsyncSharedResource) -> None: - self._shared = shared - - self.profile = async_to_raw_response_wrapper( - shared.profile, - ) - - -class SharedResourceWithStreamingResponse: - def __init__(self, shared: SharedResource) -> None: - self._shared = shared - - self.profile = to_streamed_response_wrapper( - shared.profile, - ) - - -class AsyncSharedResourceWithStreamingResponse: - def __init__(self, shared: AsyncSharedResource) -> None: - self._shared = shared - - self.profile = async_to_streamed_response_wrapper( - shared.profile, - ) diff --git a/src/supermemory/types/__init__.py b/src/supermemory/types/__init__.py index 5a100926..54bc0e85 100644 --- a/src/supermemory/types/__init__.py +++ b/src/supermemory/types/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from .shared import Or as Or, And as And, ProfileResponse as ProfileResponse +from .shared import Or as Or, And as And from .memory_add_params import MemoryAddParams as MemoryAddParams from .memory_list_params import MemoryListParams as MemoryListParams from .document_add_params import DocumentAddParams as DocumentAddParams diff --git a/src/supermemory/types/shared/__init__.py b/src/supermemory/types/shared/__init__.py index e30cbf32..96ecf13e 100644 --- a/src/supermemory/types/shared/__init__.py +++ b/src/supermemory/types/shared/__init__.py @@ -2,4 +2,3 @@ from .or_ import Or as Or from .and_ import And as And -from .profile_response import ProfileResponse as ProfileResponse diff --git a/src/supermemory/types/shared/profile_response.py b/src/supermemory/types/shared/profile_response.py deleted file mode 100644 index 7ee6d7a2..00000000 --- a/src/supermemory/types/shared/profile_response.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["ProfileResponse", "Profile", "SearchResults"] - - -class Profile(BaseModel): - dynamic: List[str] - """Dynamic profile information (recent memories)""" - - static: List[str] - """Static profile information that remains relevant long-term""" - - -class SearchResults(BaseModel): - results: List[object] - """Search results for the provided query""" - - timing: float - """Search timing in milliseconds""" - - total: float - """Total number of search results""" - - -class ProfileResponse(BaseModel): - profile: Profile - - search_results: Optional[SearchResults] = FieldInfo(alias="searchResults", default=None) - """Search results if a search query was provided""" diff --git a/src/supermemory/types/shared/profile_response1.py b/src/supermemory/types/shared/profile_response1.py deleted file mode 100644 index 7ee6d7a2..00000000 --- a/src/supermemory/types/shared/profile_response1.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["ProfileResponse", "Profile", "SearchResults"] - - -class Profile(BaseModel): - dynamic: List[str] - """Dynamic profile information (recent memories)""" - - static: List[str] - """Static profile information that remains relevant long-term""" - - -class SearchResults(BaseModel): - results: List[object] - """Search results for the provided query""" - - timing: float - """Search timing in milliseconds""" - - total: float - """Total number of search results""" - - -class ProfileResponse(BaseModel): - profile: Profile - - search_results: Optional[SearchResults] = FieldInfo(alias="searchResults", default=None) - """Search results if a search query was provided""" diff --git a/src/supermemory/types/shared/shared_profile_params.py b/src/supermemory/types/shared/shared_profile_params.py deleted file mode 100644 index 2f2994f3..00000000 --- a/src/supermemory/types/shared/shared_profile_params.py +++ /dev/null @@ -1,21 +0,0 @@ -# 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 ..._utils import PropertyInfo - -__all__ = ["SharedProfileParams"] - - -class SharedProfileParams(TypedDict, total=False): - container_tag: Required[Annotated[str, PropertyInfo(alias="containerTag")]] - """Tag to filter the profile by. - - This can be an ID for your user, a project ID, or any other identifier you wish - to use to filter memories. - """ - - q: str - """Optional search query to include search results in the response""" diff --git a/tests/api_resources/test_shared.py b/tests/api_resources/test_shared.py deleted file mode 100644 index 6958f25c..00000000 --- a/tests/api_resources/test_shared.py +++ /dev/null @@ -1,110 +0,0 @@ -# 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.shared import ProfileResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestShared: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Prism tests are disabled") - @parametrize - def test_method_profile(self, client: Supermemory) -> None: - shared = client.shared.profile( - container_tag="containerTag", - ) - assert_matches_type(ProfileResponse, shared, path=["response"]) - - @pytest.mark.skip(reason="Prism tests are disabled") - @parametrize - def test_method_profile_with_all_params(self, client: Supermemory) -> None: - shared = client.shared.profile( - container_tag="containerTag", - q="q", - ) - assert_matches_type(ProfileResponse, shared, path=["response"]) - - @pytest.mark.skip(reason="Prism tests are disabled") - @parametrize - def test_raw_response_profile(self, client: Supermemory) -> None: - response = client.shared.with_raw_response.profile( - container_tag="containerTag", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - shared = response.parse() - assert_matches_type(ProfileResponse, shared, path=["response"]) - - @pytest.mark.skip(reason="Prism tests are disabled") - @parametrize - def test_streaming_response_profile(self, client: Supermemory) -> None: - with client.shared.with_streaming_response.profile( - container_tag="containerTag", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - shared = response.parse() - assert_matches_type(ProfileResponse, shared, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncShared: - 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_profile(self, async_client: AsyncSupermemory) -> None: - shared = await async_client.shared.profile( - container_tag="containerTag", - ) - assert_matches_type(ProfileResponse, shared, path=["response"]) - - @pytest.mark.skip(reason="Prism tests are disabled") - @parametrize - async def test_method_profile_with_all_params(self, async_client: AsyncSupermemory) -> None: - shared = await async_client.shared.profile( - container_tag="containerTag", - q="q", - ) - assert_matches_type(ProfileResponse, shared, path=["response"]) - - @pytest.mark.skip(reason="Prism tests are disabled") - @parametrize - async def test_raw_response_profile(self, async_client: AsyncSupermemory) -> None: - response = await async_client.shared.with_raw_response.profile( - container_tag="containerTag", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - shared = await response.parse() - assert_matches_type(ProfileResponse, shared, path=["response"]) - - @pytest.mark.skip(reason="Prism tests are disabled") - @parametrize - async def test_streaming_response_profile(self, async_client: AsyncSupermemory) -> None: - async with async_client.shared.with_streaming_response.profile( - container_tag="containerTag", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - shared = await response.parse() - assert_matches_type(ProfileResponse, shared, path=["response"]) - - assert cast(Any, response.is_closed) is True From a4c6e8aa94f7076ce381d521743c18e45c8cbbd5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 23:48:32 +0000 Subject: [PATCH 3/7] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index da8e35f0..aa77b7c0 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-ebd5e757d0e76cb83013e01a1e0bb3dba62beb83b2a2ffa28d148ea032e96fd0.yml openapi_spec_hash: f930474a6ad230545154244045cc602e -config_hash: 5b7cec4b962a2ef1b02ac789757eaf15 +config_hash: 2bf91b867343b1e48759e1b957074d85 From 7f0b5aa308004d68b5620f6956068e0c7fbc20da Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 23:51:24 +0000 Subject: [PATCH 4/7] feat(api): manual updates --- .stats.yml | 2 +- api.md | 6 ------ src/supermemory/types/__init__.py | 1 - src/supermemory/types/document_list_params.py | 18 ++++++++++++------ src/supermemory/types/memory_list_params.py | 18 ++++++++++++------ .../types/search_documents_params.py | 16 +++++++++++----- src/supermemory/types/search_execute_params.py | 16 +++++++++++----- .../types/search_memories_params.py | 16 +++++++++++----- src/supermemory/types/shared/__init__.py | 4 ---- src/supermemory/types/shared/and_.py | 13 ------------- src/supermemory/types/shared/or_.py | 13 ------------- .../types/shared_params/__init__.py | 4 ---- src/supermemory/types/shared_params/and_.py | 14 -------------- src/supermemory/types/shared_params/or_.py | 14 -------------- 14 files changed, 58 insertions(+), 97 deletions(-) delete mode 100644 src/supermemory/types/shared/__init__.py delete mode 100644 src/supermemory/types/shared/and_.py delete mode 100644 src/supermemory/types/shared/or_.py delete mode 100644 src/supermemory/types/shared_params/__init__.py delete mode 100644 src/supermemory/types/shared_params/and_.py delete mode 100644 src/supermemory/types/shared_params/or_.py diff --git a/.stats.yml b/.stats.yml index aa77b7c0..3ed6119a 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-ebd5e757d0e76cb83013e01a1e0bb3dba62beb83b2a2ffa28d148ea032e96fd0.yml openapi_spec_hash: f930474a6ad230545154244045cc602e -config_hash: 2bf91b867343b1e48759e1b957074d85 +config_hash: 2113359488acead9b94556d37765c57e diff --git a/api.md b/api.md index 4451d8b1..7aa6afa9 100644 --- a/api.md +++ b/api.md @@ -1,9 +1,3 @@ -# Shared Types - -```python -from supermemory.types import And, Or -``` - # Memories Types: diff --git a/src/supermemory/types/__init__.py b/src/supermemory/types/__init__.py index 54bc0e85..beace710 100644 --- a/src/supermemory/types/__init__.py +++ b/src/supermemory/types/__init__.py @@ -2,7 +2,6 @@ from __future__ import annotations -from .shared import Or as Or, And as And from .memory_add_params import MemoryAddParams as MemoryAddParams from .memory_list_params import MemoryListParams as MemoryListParams from .document_add_params import DocumentAddParams as DocumentAddParams diff --git a/src/supermemory/types/document_list_params.py b/src/supermemory/types/document_list_params.py index f48c76f1..3b62b1a6 100644 --- a/src/supermemory/types/document_list_params.py +++ b/src/supermemory/types/document_list_params.py @@ -2,15 +2,13 @@ from __future__ import annotations -from typing import Union -from typing_extensions import Literal, Annotated, TypeAlias, TypedDict +from typing import Union, Iterable +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict from .._types import SequenceNotStr from .._utils import PropertyInfo -from .shared_params.or_ import Or -from .shared_params.and_ import And -__all__ = ["DocumentListParams", "Filters"] +__all__ = ["DocumentListParams", "Filters", "FiltersOr", "FiltersAnd"] class DocumentListParams(TypedDict, total=False): @@ -43,4 +41,12 @@ class DocumentListParams(TypedDict, total=False): """Field to sort by""" -Filters: TypeAlias = Union[Or, And] +class FiltersOr(TypedDict, total=False): + or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]] + + +class FiltersAnd(TypedDict, total=False): + and_: Required[Annotated[Iterable[object], 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 07eb8d9a..48eb7f6d 100644 --- a/src/supermemory/types/memory_list_params.py +++ b/src/supermemory/types/memory_list_params.py @@ -2,15 +2,13 @@ from __future__ import annotations -from typing import Union -from typing_extensions import Literal, Annotated, TypeAlias, TypedDict +from typing import Union, Iterable +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict from .._types import SequenceNotStr from .._utils import PropertyInfo -from .shared_params.or_ import Or -from .shared_params.and_ import And -__all__ = ["MemoryListParams", "Filters"] +__all__ = ["MemoryListParams", "Filters", "FiltersOr", "FiltersAnd"] class MemoryListParams(TypedDict, total=False): @@ -43,4 +41,12 @@ class MemoryListParams(TypedDict, total=False): """Field to sort by""" -Filters: TypeAlias = Union[Or, And] +class FiltersOr(TypedDict, total=False): + or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]] + + +class FiltersAnd(TypedDict, total=False): + and_: Required[Annotated[Iterable[object], 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 20f62b3c..2b88d453 100644 --- a/src/supermemory/types/search_documents_params.py +++ b/src/supermemory/types/search_documents_params.py @@ -2,15 +2,13 @@ from __future__ import annotations -from typing import Union +from typing import Union, Iterable from typing_extensions import Required, Annotated, TypeAlias, TypedDict from .._types import SequenceNotStr from .._utils import PropertyInfo -from .shared_params.or_ import Or -from .shared_params.and_ import And -__all__ = ["SearchDocumentsParams", "Filters"] +__all__ = ["SearchDocumentsParams", "Filters", "FiltersOr", "FiltersAnd"] class SearchDocumentsParams(TypedDict, total=False): @@ -84,4 +82,12 @@ class SearchDocumentsParams(TypedDict, total=False): """ -Filters: TypeAlias = Union[Or, And] +class FiltersOr(TypedDict, total=False): + or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]] + + +class FiltersAnd(TypedDict, total=False): + and_: Required[Annotated[Iterable[object], 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 da786065..9a49c448 100644 --- a/src/supermemory/types/search_execute_params.py +++ b/src/supermemory/types/search_execute_params.py @@ -2,15 +2,13 @@ from __future__ import annotations -from typing import Union +from typing import Union, Iterable from typing_extensions import Required, Annotated, TypeAlias, TypedDict from .._types import SequenceNotStr from .._utils import PropertyInfo -from .shared_params.or_ import Or -from .shared_params.and_ import And -__all__ = ["SearchExecuteParams", "Filters"] +__all__ = ["SearchExecuteParams", "Filters", "FiltersOr", "FiltersAnd"] class SearchExecuteParams(TypedDict, total=False): @@ -84,4 +82,12 @@ class SearchExecuteParams(TypedDict, total=False): """ -Filters: TypeAlias = Union[Or, And] +class FiltersOr(TypedDict, total=False): + or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]] + + +class FiltersAnd(TypedDict, total=False): + and_: Required[Annotated[Iterable[object], 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 cca09bc1..20328dc7 100644 --- a/src/supermemory/types/search_memories_params.py +++ b/src/supermemory/types/search_memories_params.py @@ -2,14 +2,12 @@ from __future__ import annotations -from typing import Union +from typing import Union, Iterable from typing_extensions import Required, Annotated, TypeAlias, TypedDict from .._utils import PropertyInfo -from .shared_params.or_ import Or -from .shared_params.and_ import And -__all__ = ["SearchMemoriesParams", "Filters", "Include"] +__all__ = ["SearchMemoriesParams", "Filters", "FiltersOr", "FiltersAnd", "Include"] class SearchMemoriesParams(TypedDict, total=False): @@ -51,7 +49,15 @@ class SearchMemoriesParams(TypedDict, total=False): """ -Filters: TypeAlias = Union[Or, And] +class FiltersOr(TypedDict, total=False): + or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]] + + +class FiltersAnd(TypedDict, total=False): + and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]] + + +Filters: TypeAlias = Union[FiltersOr, FiltersAnd] class Include(TypedDict, total=False): diff --git a/src/supermemory/types/shared/__init__.py b/src/supermemory/types/shared/__init__.py deleted file mode 100644 index 96ecf13e..00000000 --- a/src/supermemory/types/shared/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .or_ import Or as Or -from .and_ import And as And diff --git a/src/supermemory/types/shared/and_.py b/src/supermemory/types/shared/and_.py deleted file mode 100644 index 980dbb24..00000000 --- a/src/supermemory/types/shared/and_.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["And"] - - -class And(BaseModel): - and_: List[object] = FieldInfo(alias="AND") diff --git a/src/supermemory/types/shared/or_.py b/src/supermemory/types/shared/or_.py deleted file mode 100644 index fe2c5a95..00000000 --- a/src/supermemory/types/shared/or_.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["Or"] - - -class Or(BaseModel): - or_: List[object] = FieldInfo(alias="OR") diff --git a/src/supermemory/types/shared_params/__init__.py b/src/supermemory/types/shared_params/__init__.py deleted file mode 100644 index 96ecf13e..00000000 --- a/src/supermemory/types/shared_params/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .or_ import Or as Or -from .and_ import And as And diff --git a/src/supermemory/types/shared_params/and_.py b/src/supermemory/types/shared_params/and_.py deleted file mode 100644 index 0e0dad21..00000000 --- a/src/supermemory/types/shared_params/and_.py +++ /dev/null @@ -1,14 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Required, Annotated, TypedDict - -from ..._utils import PropertyInfo - -__all__ = ["And"] - - -class And(TypedDict, total=False): - and_: Required[Annotated[Iterable[object], PropertyInfo(alias="AND")]] diff --git a/src/supermemory/types/shared_params/or_.py b/src/supermemory/types/shared_params/or_.py deleted file mode 100644 index fdb83e1f..00000000 --- a/src/supermemory/types/shared_params/or_.py +++ /dev/null @@ -1,14 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Required, Annotated, TypedDict - -from ..._utils import PropertyInfo - -__all__ = ["Or"] - - -class Or(TypedDict, total=False): - or_: Required[Annotated[Iterable[object], PropertyInfo(alias="OR")]] From 89a6e6d1220cd8fd2c38d1c54f412650913a9184 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 23:54:17 +0000 Subject: [PATCH 5/7] feat(api): manual updates --- .stats.yml | 4 +- api.md | 12 ++ src/supermemory/_client.py | 124 +++++++++++++++++- src/supermemory/types/__init__.py | 2 + .../types/client_profile_params.py | 21 +++ src/supermemory/types/profile_response.py | 35 +++++ tests/api_resources/test_client.py | 110 ++++++++++++++++ 7 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 src/supermemory/types/client_profile_params.py create mode 100644 src/supermemory/types/profile_response.py create mode 100644 tests/api_resources/test_client.py diff --git a/.stats.yml b/.stats.yml index 3ed6119a..b06ef664 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 18 +configured_endpoints: 19 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-ebd5e757d0e76cb83013e01a1e0bb3dba62beb83b2a2ffa28d148ea032e96fd0.yml openapi_spec_hash: f930474a6ad230545154244045cc602e -config_hash: 2113359488acead9b94556d37765c57e +config_hash: 23f1770611dec274363355d52f3918cc diff --git a/api.md b/api.md index 7aa6afa9..952a85d7 100644 --- a/api.md +++ b/api.md @@ -1,3 +1,15 @@ +# Supermemory + +Types: + +```python +from supermemory.types import ProfileResponse +``` + +Methods: + +- client.profile(\*\*params) -> ProfileResponse + # Memories Types: diff --git a/src/supermemory/_client.py b/src/supermemory/_client.py index 0de41593..c11e246c 100644 --- a/src/supermemory/_client.py +++ b/src/supermemory/_client.py @@ -10,17 +10,33 @@ from . import _exceptions from ._qs import Querystring +from .types import client_profile_params from ._types import ( + Body, Omit, + Query, + Headers, Timeout, NotGiven, Transport, ProxiesTypes, RequestOptions, + omit, not_given, ) -from ._utils import is_given, get_async_library +from ._utils import ( + is_given, + maybe_transform, + get_async_library, + async_maybe_transform, +) from ._version import __version__ +from ._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) from .resources import search, memories, settings, documents, connections from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import APIStatusError, SupermemoryError @@ -28,7 +44,9 @@ DEFAULT_MAX_RETRIES, SyncAPIClient, AsyncAPIClient, + make_request_options, ) +from .types.profile_response import ProfileResponse __all__ = [ "Timeout", @@ -184,6 +202,50 @@ def copy( # client.with_options(timeout=10).foo.create(...) with_options = copy + def profile( + self, + *, + container_tag: str, + q: 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, + ) -> ProfileResponse: + """ + Get user profile with optional search results + + Args: + container_tag: Tag to filter the profile by. This can be an ID for your user, a project ID, or + any other identifier you wish to use to filter memories. + + q: Optional search query to include search results in the response + + 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( + "/v4/profile", + body=maybe_transform( + { + "container_tag": container_tag, + "q": q, + }, + client_profile_params.ClientProfileParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProfileResponse, + ) + @override def _make_status_error( self, @@ -360,6 +422,50 @@ def copy( # client.with_options(timeout=10).foo.create(...) with_options = copy + async def profile( + self, + *, + container_tag: str, + q: 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, + ) -> ProfileResponse: + """ + Get user profile with optional search results + + Args: + container_tag: Tag to filter the profile by. This can be an ID for your user, a project ID, or + any other identifier you wish to use to filter memories. + + q: Optional search query to include search results in the response + + 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( + "/v4/profile", + body=await async_maybe_transform( + { + "container_tag": container_tag, + "q": q, + }, + client_profile_params.ClientProfileParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProfileResponse, + ) + @override def _make_status_error( self, @@ -402,6 +508,10 @@ def __init__(self, client: Supermemory) -> None: self.settings = settings.SettingsResourceWithRawResponse(client.settings) self.connections = connections.ConnectionsResourceWithRawResponse(client.connections) + self.profile = to_raw_response_wrapper( + client.profile, + ) + class AsyncSupermemoryWithRawResponse: def __init__(self, client: AsyncSupermemory) -> None: @@ -411,6 +521,10 @@ def __init__(self, client: AsyncSupermemory) -> None: self.settings = settings.AsyncSettingsResourceWithRawResponse(client.settings) self.connections = connections.AsyncConnectionsResourceWithRawResponse(client.connections) + self.profile = async_to_raw_response_wrapper( + client.profile, + ) + class SupermemoryWithStreamedResponse: def __init__(self, client: Supermemory) -> None: @@ -420,6 +534,10 @@ def __init__(self, client: Supermemory) -> None: self.settings = settings.SettingsResourceWithStreamingResponse(client.settings) self.connections = connections.ConnectionsResourceWithStreamingResponse(client.connections) + self.profile = to_streamed_response_wrapper( + client.profile, + ) + class AsyncSupermemoryWithStreamedResponse: def __init__(self, client: AsyncSupermemory) -> None: @@ -429,6 +547,10 @@ def __init__(self, client: AsyncSupermemory) -> None: self.settings = settings.AsyncSettingsResourceWithStreamingResponse(client.settings) self.connections = connections.AsyncConnectionsResourceWithStreamingResponse(client.connections) + self.profile = async_to_streamed_response_wrapper( + client.profile, + ) + Client = Supermemory diff --git a/src/supermemory/types/__init__.py b/src/supermemory/types/__init__.py index beace710..dd3b18c6 100644 --- a/src/supermemory/types/__init__.py +++ b/src/supermemory/types/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations +from .profile_response import ProfileResponse as ProfileResponse from .memory_add_params import MemoryAddParams as MemoryAddParams from .memory_list_params import MemoryListParams as MemoryListParams from .document_add_params import DocumentAddParams as DocumentAddParams @@ -11,6 +12,7 @@ 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 .client_profile_params import ClientProfileParams as ClientProfileParams from .document_add_response import DocumentAddResponse as DocumentAddResponse from .document_get_response import DocumentGetResponse as DocumentGetResponse from .search_execute_params import SearchExecuteParams as SearchExecuteParams diff --git a/src/supermemory/types/client_profile_params.py b/src/supermemory/types/client_profile_params.py new file mode 100644 index 00000000..428b62aa --- /dev/null +++ b/src/supermemory/types/client_profile_params.py @@ -0,0 +1,21 @@ +# 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 .._utils import PropertyInfo + +__all__ = ["ClientProfileParams"] + + +class ClientProfileParams(TypedDict, total=False): + container_tag: Required[Annotated[str, PropertyInfo(alias="containerTag")]] + """Tag to filter the profile by. + + This can be an ID for your user, a project ID, or any other identifier you wish + to use to filter memories. + """ + + q: str + """Optional search query to include search results in the response""" diff --git a/src/supermemory/types/profile_response.py b/src/supermemory/types/profile_response.py new file mode 100644 index 00000000..3eb5e2b0 --- /dev/null +++ b/src/supermemory/types/profile_response.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ProfileResponse", "Profile", "SearchResults"] + + +class Profile(BaseModel): + dynamic: List[str] + """Dynamic profile information (recent memories)""" + + static: List[str] + """Static profile information that remains relevant long-term""" + + +class SearchResults(BaseModel): + results: List[object] + """Search results for the provided query""" + + timing: float + """Search timing in milliseconds""" + + total: float + """Total number of search results""" + + +class ProfileResponse(BaseModel): + profile: Profile + + search_results: Optional[SearchResults] = FieldInfo(alias="searchResults", default=None) + """Search results if a search query was provided""" diff --git a/tests/api_resources/test_client.py b/tests/api_resources/test_client.py new file mode 100644 index 00000000..15697156 --- /dev/null +++ b/tests/api_resources/test_client.py @@ -0,0 +1,110 @@ +# 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 ProfileResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestClient: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_profile(self, client: Supermemory) -> None: + client_ = client.profile( + container_tag="containerTag", + ) + assert_matches_type(ProfileResponse, client_, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_profile_with_all_params(self, client: Supermemory) -> None: + client_ = client.profile( + container_tag="containerTag", + q="q", + ) + assert_matches_type(ProfileResponse, client_, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_profile(self, client: Supermemory) -> None: + response = client.with_raw_response.profile( + container_tag="containerTag", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + client_ = response.parse() + assert_matches_type(ProfileResponse, client_, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_profile(self, client: Supermemory) -> None: + with client.with_streaming_response.profile( + container_tag="containerTag", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + client_ = response.parse() + assert_matches_type(ProfileResponse, client_, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncClient: + 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_profile(self, async_client: AsyncSupermemory) -> None: + client = await async_client.profile( + container_tag="containerTag", + ) + assert_matches_type(ProfileResponse, client, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_profile_with_all_params(self, async_client: AsyncSupermemory) -> None: + client = await async_client.profile( + container_tag="containerTag", + q="q", + ) + assert_matches_type(ProfileResponse, client, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_profile(self, async_client: AsyncSupermemory) -> None: + response = await async_client.with_raw_response.profile( + container_tag="containerTag", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + client = await response.parse() + assert_matches_type(ProfileResponse, client, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_profile(self, async_client: AsyncSupermemory) -> None: + async with async_client.with_streaming_response.profile( + container_tag="containerTag", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + client = await response.parse() + assert_matches_type(ProfileResponse, client, path=["response"]) + + assert cast(Any, response.is_closed) is True From ee2daac3a0c1a085971a71ef9605d1d4f6fdb3f7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 23:59:20 +0000 Subject: [PATCH 6/7] feat(api): manual updates --- .stats.yml | 2 +- README.md | 14 +-- api.md | 3 +- src/supermemory/_client.py | 130 ++++++++++++++++++++- src/supermemory/types/__init__.py | 2 + src/supermemory/types/add_response.py | 13 +++ src/supermemory/types/client_add_params.py | 36 ++++++ tests/api_resources/test_client.py | 94 ++++++++++++++- tests/test_client.py | 24 ++-- 9 files changed, 292 insertions(+), 26 deletions(-) create mode 100644 src/supermemory/types/add_response.py create mode 100644 src/supermemory/types/client_add_params.py diff --git a/.stats.yml b/.stats.yml index b06ef664..fa22dd06 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 19 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc%2Fsupermemory-new-ebd5e757d0e76cb83013e01a1e0bb3dba62beb83b2a2ffa28d148ea032e96fd0.yml openapi_spec_hash: f930474a6ad230545154244045cc602e -config_hash: 23f1770611dec274363355d52f3918cc +config_hash: ec08a36e60458b4d83e71798a8043484 diff --git a/README.md b/README.md index 9ed1ed88..7cc684a6 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ from supermemory import Supermemory client = Supermemory() try: - client.memories.add( + client.add( content="content", ) except supermemory.APIConnectionError as e: @@ -205,7 +205,7 @@ client = Supermemory( ) # Or, configure per-request: -client.with_options(max_retries=5).memories.add( +client.with_options(max_retries=5).add( content="content", ) ``` @@ -230,7 +230,7 @@ client = Supermemory( ) # Override per-request: -client.with_options(timeout=5.0).memories.add( +client.with_options(timeout=5.0).add( content="content", ) ``` @@ -273,13 +273,13 @@ 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.add( +response = client.with_raw_response.add( content="content", ) print(response.headers.get('X-My-Header')) -memory = response.parse() # get the object that `memories.add()` would have returned -print(memory.id) +client = response.parse() # get the object that `add()` would have returned +print(client.id) ``` These methods return an [`APIResponse`](https://github.com/supermemoryai/python-sdk/tree/main/src/supermemory/_response.py) object. @@ -293,7 +293,7 @@ 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.add( +with client.with_streaming_response.add( content="content", ) as response: print(response.headers.get("X-My-Header")) diff --git a/api.md b/api.md index 952a85d7..43179a60 100644 --- a/api.md +++ b/api.md @@ -3,11 +3,12 @@ Types: ```python -from supermemory.types import ProfileResponse +from supermemory.types import AddResponse, ProfileResponse ``` Methods: +- client.add(\*\*params) -> AddResponse - client.profile(\*\*params) -> ProfileResponse # Memories diff --git a/src/supermemory/_client.py b/src/supermemory/_client.py index c11e246c..e9070a3b 100644 --- a/src/supermemory/_client.py +++ b/src/supermemory/_client.py @@ -3,14 +3,14 @@ from __future__ import annotations import os -from typing import Any, Mapping +from typing import Any, Dict, Union, Mapping from typing_extensions import Self, override import httpx from . import _exceptions from ._qs import Querystring -from .types import client_profile_params +from .types import client_add_params, client_profile_params from ._types import ( Body, Omit, @@ -21,6 +21,7 @@ Transport, ProxiesTypes, RequestOptions, + SequenceNotStr, omit, not_given, ) @@ -46,6 +47,7 @@ AsyncAPIClient, make_request_options, ) +from .types.add_response import AddResponse from .types.profile_response import ProfileResponse __all__ = [ @@ -202,6 +204,62 @@ def copy( # client.with_options(timeout=10).foo.create(...) with_options = copy + def add( + self, + *, + content: str, + container_tag: str | Omit = omit, + container_tags: SequenceNotStr[str] | Omit = omit, + custom_id: str | Omit = omit, + metadata: Dict[str, Union[str, float, bool, 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, + ) -> AddResponse: + """ + 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. + + container_tag: Optional tag this document should be containerized by. Max 100 characters, + alphanumeric with hyphens and underscores only. + + custom_id: Optional custom ID of the document. Max 100 characters, alphanumeric with + hyphens and underscores only. + + metadata: Optional metadata for the document. + + 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, + "metadata": metadata, + }, + client_add_params.ClientAddParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AddResponse, + ) + def profile( self, *, @@ -422,6 +480,62 @@ def copy( # client.with_options(timeout=10).foo.create(...) with_options = copy + async def add( + self, + *, + content: str, + container_tag: str | Omit = omit, + container_tags: SequenceNotStr[str] | Omit = omit, + custom_id: str | Omit = omit, + metadata: Dict[str, Union[str, float, bool, 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, + ) -> AddResponse: + """ + 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. + + container_tag: Optional tag this document should be containerized by. Max 100 characters, + alphanumeric with hyphens and underscores only. + + custom_id: Optional custom ID of the document. Max 100 characters, alphanumeric with + hyphens and underscores only. + + metadata: Optional metadata for the document. + + 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, + "metadata": metadata, + }, + client_add_params.ClientAddParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AddResponse, + ) + async def profile( self, *, @@ -508,6 +622,9 @@ def __init__(self, client: Supermemory) -> None: self.settings = settings.SettingsResourceWithRawResponse(client.settings) self.connections = connections.ConnectionsResourceWithRawResponse(client.connections) + self.add = to_raw_response_wrapper( + client.add, + ) self.profile = to_raw_response_wrapper( client.profile, ) @@ -521,6 +638,9 @@ def __init__(self, client: AsyncSupermemory) -> None: self.settings = settings.AsyncSettingsResourceWithRawResponse(client.settings) self.connections = connections.AsyncConnectionsResourceWithRawResponse(client.connections) + self.add = async_to_raw_response_wrapper( + client.add, + ) self.profile = async_to_raw_response_wrapper( client.profile, ) @@ -534,6 +654,9 @@ def __init__(self, client: Supermemory) -> None: self.settings = settings.SettingsResourceWithStreamingResponse(client.settings) self.connections = connections.ConnectionsResourceWithStreamingResponse(client.connections) + self.add = to_streamed_response_wrapper( + client.add, + ) self.profile = to_streamed_response_wrapper( client.profile, ) @@ -547,6 +670,9 @@ def __init__(self, client: AsyncSupermemory) -> None: self.settings = settings.AsyncSettingsResourceWithStreamingResponse(client.settings) self.connections = connections.AsyncConnectionsResourceWithStreamingResponse(client.connections) + self.add = async_to_streamed_response_wrapper( + client.add, + ) self.profile = async_to_streamed_response_wrapper( client.profile, ) diff --git a/src/supermemory/types/__init__.py b/src/supermemory/types/__init__.py index dd3b18c6..33058382 100644 --- a/src/supermemory/types/__init__.py +++ b/src/supermemory/types/__init__.py @@ -2,7 +2,9 @@ from __future__ import annotations +from .add_response import AddResponse as AddResponse from .profile_response import ProfileResponse as ProfileResponse +from .client_add_params import ClientAddParams as ClientAddParams from .memory_add_params import MemoryAddParams as MemoryAddParams from .memory_list_params import MemoryListParams as MemoryListParams from .document_add_params import DocumentAddParams as DocumentAddParams diff --git a/src/supermemory/types/add_response.py b/src/supermemory/types/add_response.py new file mode 100644 index 00000000..cfa9c5fb --- /dev/null +++ b/src/supermemory/types/add_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["AddResponse"] + + +class AddResponse(BaseModel): + id: str + """Unique identifier of the document""" + + status: str + """Status of the document""" diff --git a/src/supermemory/types/client_add_params.py b/src/supermemory/types/client_add_params.py new file mode 100644 index 00000000..2d9e5c02 --- /dev/null +++ b/src/supermemory/types/client_add_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 import Dict, Union +from typing_extensions import Required, Annotated, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["ClientAddParams"] + + +class ClientAddParams(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. + """ + + container_tag: Annotated[str, PropertyInfo(alias="containerTag")] + """Optional tag this document should be containerized by. + + Max 100 characters, alphanumeric with hyphens and underscores only. + """ + + container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")] + + custom_id: Annotated[str, PropertyInfo(alias="customId")] + """Optional custom ID of the document. + + Max 100 characters, alphanumeric with hyphens and underscores only. + """ + + metadata: Dict[str, Union[str, float, bool, SequenceNotStr[str]]] + """Optional metadata for the document.""" diff --git a/tests/api_resources/test_client.py b/tests/api_resources/test_client.py index 15697156..37b1c63e 100644 --- a/tests/api_resources/test_client.py +++ b/tests/api_resources/test_client.py @@ -9,7 +9,7 @@ from supermemory import Supermemory, AsyncSupermemory from tests.utils import assert_matches_type -from supermemory.types import ProfileResponse +from supermemory.types import AddResponse, ProfileResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -17,6 +17,52 @@ class TestClient: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_add(self, client: Supermemory) -> None: + client_ = client.add( + content="content", + ) + assert_matches_type(AddResponse, client_, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_add_with_all_params(self, client: Supermemory) -> None: + client_ = client.add( + content="content", + container_tag="containerTag", + container_tags=["string"], + custom_id="customId", + metadata={"foo": "string"}, + ) + assert_matches_type(AddResponse, client_, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_add(self, client: Supermemory) -> None: + response = client.with_raw_response.add( + content="content", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + client_ = response.parse() + assert_matches_type(AddResponse, client_, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_add(self, client: Supermemory) -> None: + with client.with_streaming_response.add( + content="content", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + client_ = response.parse() + assert_matches_type(AddResponse, client_, path=["response"]) + + assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_method_profile(self, client: Supermemory) -> None: @@ -66,6 +112,52 @@ class TestAsyncClient: "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_add(self, async_client: AsyncSupermemory) -> None: + client = await async_client.add( + content="content", + ) + assert_matches_type(AddResponse, client, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_add_with_all_params(self, async_client: AsyncSupermemory) -> None: + client = await async_client.add( + content="content", + container_tag="containerTag", + container_tags=["string"], + custom_id="customId", + metadata={"foo": "string"}, + ) + assert_matches_type(AddResponse, client, 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.with_raw_response.add( + content="content", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + client = await response.parse() + assert_matches_type(AddResponse, client, 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.with_streaming_response.add( + content="content", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + client = await response.parse() + assert_matches_type(AddResponse, client, path=["response"]) + + assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_method_profile(self, async_client: AsyncSupermemory) -> None: diff --git a/tests/test_client.py b/tests/test_client.py index aa1ea71c..3d65c9a7 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -747,7 +747,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien respx_mock.post("/v3/documents").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - client.memories.with_streaming_response.add(content="content").__enter__() + client.with_streaming_response.add(content="content").__enter__() assert _get_open_connections(client) == 0 @@ -757,7 +757,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client respx_mock.post("/v3/documents").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - client.memories.with_streaming_response.add(content="content").__enter__() + client.with_streaming_response.add(content="content").__enter__() assert _get_open_connections(client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -786,7 +786,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v3/documents").mock(side_effect=retry_handler) - response = client.memories.with_raw_response.add(content="content") + response = client.with_raw_response.add(content="content") assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -810,9 +810,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v3/documents").mock(side_effect=retry_handler) - response = client.memories.with_raw_response.add( - content="content", extra_headers={"x-stainless-retry-count": Omit()} - ) + response = client.with_raw_response.add(content="content", extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -835,9 +833,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v3/documents").mock(side_effect=retry_handler) - response = client.memories.with_raw_response.add( - content="content", extra_headers={"x-stainless-retry-count": "42"} - ) + response = client.with_raw_response.add(content="content", extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @@ -1587,7 +1583,7 @@ async def test_retrying_timeout_errors_doesnt_leak( respx_mock.post("/v3/documents").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - await async_client.memories.with_streaming_response.add(content="content").__aenter__() + await async_client.with_streaming_response.add(content="content").__aenter__() assert _get_open_connections(async_client) == 0 @@ -1599,7 +1595,7 @@ async def test_retrying_status_errors_doesnt_leak( respx_mock.post("/v3/documents").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - await async_client.memories.with_streaming_response.add(content="content").__aenter__() + await async_client.with_streaming_response.add(content="content").__aenter__() assert _get_open_connections(async_client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -1628,7 +1624,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v3/documents").mock(side_effect=retry_handler) - response = await client.memories.with_raw_response.add(content="content") + response = await client.with_raw_response.add(content="content") assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -1652,7 +1648,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v3/documents").mock(side_effect=retry_handler) - response = await client.memories.with_raw_response.add( + response = await client.with_raw_response.add( content="content", extra_headers={"x-stainless-retry-count": Omit()} ) @@ -1677,7 +1673,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v3/documents").mock(side_effect=retry_handler) - response = await client.memories.with_raw_response.add( + response = await client.with_raw_response.add( content="content", extra_headers={"x-stainless-retry-count": "42"} ) From f95ae079d45e4dad7ab4bf91a7a007d284cb26e4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 23:59:37 +0000 Subject: [PATCH 7/7] release: 3.7.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 12 ++++++++++++ pyproject.toml | 2 +- src/supermemory/_version.py | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f391d416..27d2fbbc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.6.0" + ".": "3.7.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e3dbe79..0a6f9c74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 3.7.0 (2025-11-26) + +Full Changelog: [v3.6.0...v3.7.0](https://github.com/supermemoryai/python-sdk/compare/v3.6.0...v3.7.0) + +### Features + +* **api:** manual updates ([ee2daac](https://github.com/supermemoryai/python-sdk/commit/ee2daac3a0c1a085971a71ef9605d1d4f6fdb3f7)) +* **api:** manual updates ([89a6e6d](https://github.com/supermemoryai/python-sdk/commit/89a6e6d1220cd8fd2c38d1c54f412650913a9184)) +* **api:** manual updates ([7f0b5aa](https://github.com/supermemoryai/python-sdk/commit/7f0b5aa308004d68b5620f6956068e0c7fbc20da)) +* **api:** manual updates ([3f2f954](https://github.com/supermemoryai/python-sdk/commit/3f2f954a542c4f2e6fc7d6e204c7e44fe640ec7d)) +* **api:** manual updates ([8680e72](https://github.com/supermemoryai/python-sdk/commit/8680e723f9bd9cdc930ed33914557dc60d5242c0)) + ## 3.6.0 (2025-11-26) Full Changelog: [v3.5.0...v3.6.0](https://github.com/supermemoryai/python-sdk/compare/v3.5.0...v3.6.0) diff --git a/pyproject.toml b/pyproject.toml index ac4ed2c5..e7dcc47a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "supermemory" -version = "3.6.0" +version = "3.7.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 859e0c9e..3beee285 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.6.0" # x-release-please-version +__version__ = "3.7.0" # x-release-please-version