From 335432d2a7e43026494f4e265576010e53895663 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 19:27:18 +0000 Subject: [PATCH 1/3] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a203b6d..2e63203 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 16 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc/supermemory-new-7185975161e0406ec7c438985acd80273dfd95ade0983d2029bed87c46182d62.yml -openapi_spec_hash: ced6ea198b00867f09ef26384d3eaa6a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc/supermemory-new-0b058be57286eb780b0da0790aa595e5c370d833bbf6c2b16854bc7122c623f1.yml +openapi_spec_hash: d95cfa175546e781b11889263b259378 config_hash: cde97ef3188581c5f4924c633ec33ddb From 36a55ee2b26fb0ed076892d486e464c11eb4c2e4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 09:27:20 +0000 Subject: [PATCH 2/3] feat(api): api update --- .stats.yml | 6 +- api.md | 32 + src/supermemory/_client.py | 45 +- src/supermemory/resources/__init__.py | 14 + src/supermemory/resources/connections.py | 1028 +++++++++++++++++ src/supermemory/types/__init__.py | 21 + .../types/connection_configure_params.py | 12 + .../types/connection_configure_response.py | 17 + .../types/connection_create_params.py | 23 + .../types/connection_create_response.py | 19 + .../types/connection_delete_by_id_params.py | 14 + .../types/connection_delete_by_id_response.py | 11 + .../connection_delete_by_provider_params.py | 15 + .../connection_delete_by_provider_response.py | 11 + .../types/connection_get_by_id_response.py | 27 + .../types/connection_get_by_tag_params.py | 15 + .../types/connection_get_by_tag_response.py | 27 + .../types/connection_import_params.py | 15 + .../types/connection_import_response.py | 7 + .../types/connection_list_documents_params.py | 15 + .../connection_list_documents_response.py | 29 + .../types/connection_list_params.py | 15 + .../types/connection_list_response.py | 31 + .../types/connection_resources_params.py | 15 + .../types/connection_resources_response.py | 13 + tests/api_resources/test_connections.py | 904 +++++++++++++++ 26 files changed, 2377 insertions(+), 4 deletions(-) create mode 100644 src/supermemory/resources/connections.py create mode 100644 src/supermemory/types/connection_configure_params.py create mode 100644 src/supermemory/types/connection_configure_response.py create mode 100644 src/supermemory/types/connection_create_params.py create mode 100644 src/supermemory/types/connection_create_response.py create mode 100644 src/supermemory/types/connection_delete_by_id_params.py create mode 100644 src/supermemory/types/connection_delete_by_id_response.py create mode 100644 src/supermemory/types/connection_delete_by_provider_params.py create mode 100644 src/supermemory/types/connection_delete_by_provider_response.py create mode 100644 src/supermemory/types/connection_get_by_id_response.py create mode 100644 src/supermemory/types/connection_get_by_tag_params.py create mode 100644 src/supermemory/types/connection_get_by_tag_response.py create mode 100644 src/supermemory/types/connection_import_params.py create mode 100644 src/supermemory/types/connection_import_response.py create mode 100644 src/supermemory/types/connection_list_documents_params.py create mode 100644 src/supermemory/types/connection_list_documents_response.py create mode 100644 src/supermemory/types/connection_list_params.py create mode 100644 src/supermemory/types/connection_list_response.py create mode 100644 src/supermemory/types/connection_resources_params.py create mode 100644 src/supermemory/types/connection_resources_response.py create mode 100644 tests/api_resources/test_connections.py diff --git a/.stats.yml b/.stats.yml index 2e63203..d5cfbed 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 16 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc/supermemory-new-0b058be57286eb780b0da0790aa595e5c370d833bbf6c2b16854bc7122c623f1.yml -openapi_spec_hash: d95cfa175546e781b11889263b259378 +configured_endpoints: 26 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/supermemory--inc/supermemory-new-cb64e01550fb988a58095de96451432deff2ab195b1381b50595a0dd15d6d64d.yml +openapi_spec_hash: d915b2e4ec955bd600a43eeb5603965f config_hash: cde97ef3188581c5f4924c633ec33ddb diff --git a/api.md b/api.md index 838d92d..2b72f5d 100644 --- a/api.md +++ b/api.md @@ -79,3 +79,35 @@ Methods: - client.settings.update(\*\*params) -> SettingUpdateResponse - client.settings.get() -> SettingGetResponse + +# Connections + +Types: + +```python +from supermemory.types import ( + ConnectionCreateResponse, + ConnectionListResponse, + ConnectionConfigureResponse, + ConnectionDeleteByIDResponse, + ConnectionDeleteByProviderResponse, + ConnectionGetByIDResponse, + ConnectionGetByTagResponse, + ConnectionImportResponse, + ConnectionListDocumentsResponse, + ConnectionResourcesResponse, +) +``` + +Methods: + +- client.connections.create(provider, \*\*params) -> ConnectionCreateResponse +- client.connections.list(\*\*params) -> ConnectionListResponse +- client.connections.configure(connection_id, \*\*params) -> ConnectionConfigureResponse +- client.connections.delete_by_id(connection_id, \*\*params) -> ConnectionDeleteByIDResponse +- client.connections.delete_by_provider(provider, \*\*params) -> ConnectionDeleteByProviderResponse +- client.connections.get_by_id(connection_id) -> ConnectionGetByIDResponse +- client.connections.get_by_tag(provider, \*\*params) -> ConnectionGetByTagResponse +- client.connections.import\_(provider, \*\*params) -> str +- client.connections.list_documents(provider, \*\*params) -> ConnectionListDocumentsResponse +- client.connections.resources(connection_id, \*\*params) -> ConnectionResourcesResponse diff --git a/src/supermemory/_client.py b/src/supermemory/_client.py index 916594a..b6f5e0a 100644 --- a/src/supermemory/_client.py +++ b/src/supermemory/_client.py @@ -52,11 +52,12 @@ from .types.profile_response import ProfileResponse if TYPE_CHECKING: - from .resources import search, memories, settings, documents + from .resources import search, memories, settings, documents, connections from .resources.search import SearchResource, AsyncSearchResource from .resources.memories import MemoriesResource, AsyncMemoriesResource from .resources.settings import SettingsResource, AsyncSettingsResource from .resources.documents import DocumentsResource, AsyncDocumentsResource + from .resources.connections import ConnectionsResource, AsyncConnectionsResource __all__ = [ "Timeout", @@ -160,6 +161,13 @@ def settings(self) -> SettingsResource: return SettingsResource(self) + @cached_property + def connections(self) -> ConnectionsResource: + """External service integrations""" + from .resources.connections import ConnectionsResource + + return ConnectionsResource(self) + @cached_property def with_raw_response(self) -> SupermemoryWithRawResponse: return SupermemoryWithRawResponse(self) @@ -510,6 +518,13 @@ def settings(self) -> AsyncSettingsResource: return AsyncSettingsResource(self) + @cached_property + def connections(self) -> AsyncConnectionsResource: + """External service integrations""" + from .resources.connections import AsyncConnectionsResource + + return AsyncConnectionsResource(self) + @cached_property def with_raw_response(self) -> AsyncSupermemoryWithRawResponse: return AsyncSupermemoryWithRawResponse(self) @@ -809,6 +824,13 @@ def settings(self) -> settings.SettingsResourceWithRawResponse: return SettingsResourceWithRawResponse(self._client.settings) + @cached_property + def connections(self) -> connections.ConnectionsResourceWithRawResponse: + """External service integrations""" + from .resources.connections import ConnectionsResourceWithRawResponse + + return ConnectionsResourceWithRawResponse(self._client.connections) + class AsyncSupermemoryWithRawResponse: _client: AsyncSupermemory @@ -849,6 +871,13 @@ def settings(self) -> settings.AsyncSettingsResourceWithRawResponse: return AsyncSettingsResourceWithRawResponse(self._client.settings) + @cached_property + def connections(self) -> connections.AsyncConnectionsResourceWithRawResponse: + """External service integrations""" + from .resources.connections import AsyncConnectionsResourceWithRawResponse + + return AsyncConnectionsResourceWithRawResponse(self._client.connections) + class SupermemoryWithStreamedResponse: _client: Supermemory @@ -889,6 +918,13 @@ def settings(self) -> settings.SettingsResourceWithStreamingResponse: return SettingsResourceWithStreamingResponse(self._client.settings) + @cached_property + def connections(self) -> connections.ConnectionsResourceWithStreamingResponse: + """External service integrations""" + from .resources.connections import ConnectionsResourceWithStreamingResponse + + return ConnectionsResourceWithStreamingResponse(self._client.connections) + class AsyncSupermemoryWithStreamedResponse: _client: AsyncSupermemory @@ -929,6 +965,13 @@ def settings(self) -> settings.AsyncSettingsResourceWithStreamingResponse: return AsyncSettingsResourceWithStreamingResponse(self._client.settings) + @cached_property + def connections(self) -> connections.AsyncConnectionsResourceWithStreamingResponse: + """External service integrations""" + from .resources.connections import AsyncConnectionsResourceWithStreamingResponse + + return AsyncConnectionsResourceWithStreamingResponse(self._client.connections) + Client = Supermemory diff --git a/src/supermemory/resources/__init__.py b/src/supermemory/resources/__init__.py index 9225a82..ca24f73 100644 --- a/src/supermemory/resources/__init__.py +++ b/src/supermemory/resources/__init__.py @@ -32,6 +32,14 @@ DocumentsResourceWithStreamingResponse, AsyncDocumentsResourceWithStreamingResponse, ) +from .connections import ( + ConnectionsResource, + AsyncConnectionsResource, + ConnectionsResourceWithRawResponse, + AsyncConnectionsResourceWithRawResponse, + ConnectionsResourceWithStreamingResponse, + AsyncConnectionsResourceWithStreamingResponse, +) __all__ = [ "MemoriesResource", @@ -58,4 +66,10 @@ "AsyncSettingsResourceWithRawResponse", "SettingsResourceWithStreamingResponse", "AsyncSettingsResourceWithStreamingResponse", + "ConnectionsResource", + "AsyncConnectionsResource", + "ConnectionsResourceWithRawResponse", + "AsyncConnectionsResourceWithRawResponse", + "ConnectionsResourceWithStreamingResponse", + "AsyncConnectionsResourceWithStreamingResponse", ] diff --git a/src/supermemory/resources/connections.py b/src/supermemory/resources/connections.py new file mode 100644 index 0000000..c3910fb --- /dev/null +++ b/src/supermemory/resources/connections.py @@ -0,0 +1,1028 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Iterable, Optional +from typing_extensions import Literal + +import httpx + +from ..types import ( + connection_list_params, + connection_create_params, + connection_import_params, + connection_configure_params, + connection_resources_params, + connection_get_by_tag_params, + connection_delete_by_id_params, + connection_list_documents_params, + connection_delete_by_provider_params, +) +from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from .._utils import path_template, 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.connection_list_response import ConnectionListResponse +from ..types.connection_create_response import ConnectionCreateResponse +from ..types.connection_configure_response import ConnectionConfigureResponse +from ..types.connection_get_by_id_response import ConnectionGetByIDResponse +from ..types.connection_resources_response import ConnectionResourcesResponse +from ..types.connection_get_by_tag_response import ConnectionGetByTagResponse +from ..types.connection_delete_by_id_response import ConnectionDeleteByIDResponse +from ..types.connection_list_documents_response import ConnectionListDocumentsResponse +from ..types.connection_delete_by_provider_response import ConnectionDeleteByProviderResponse + +__all__ = ["ConnectionsResource", "AsyncConnectionsResource"] + + +class ConnectionsResource(SyncAPIResource): + """External service integrations""" + + @cached_property + def with_raw_response(self) -> ConnectionsResourceWithRawResponse: + """ + 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 ConnectionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ConnectionsResourceWithStreamingResponse: + """ + 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 ConnectionsResourceWithStreamingResponse(self) + + def create( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + container_tag: str | Omit = omit, + 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, + ) -> ConnectionCreateResponse: + """ + Initialize connection and get authorization URL + + 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 provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return self._post( + path_template("/v3/connections/{provider}", provider=provider), + body=maybe_transform( + { + "container_tag": container_tag, + "container_tags": container_tags, + "document_limit": document_limit, + "metadata": metadata, + "redirect_url": redirect_url, + }, + connection_create_params.ConnectionCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionCreateResponse, + ) + + def list( + self, + *, + 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, + ) -> ConnectionListResponse: + """ + List all connections + + Args: + container_tags: Optional comma-separated list of container tags to filter documents 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/connections/list", + body=maybe_transform({"container_tags": container_tags}, connection_list_params.ConnectionListParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionListResponse, + ) + + def configure( + self, + connection_id: str, + *, + resources: Iterable[Dict[str, object]], + # 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, + ) -> ConnectionConfigureResponse: + """ + Configure resources for a connection (supported providers: GitHub for now) + + 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return self._post( + path_template("/v3/connections/{connection_id}/configure", connection_id=connection_id), + body=maybe_transform({"resources": resources}, connection_configure_params.ConnectionConfigureParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionConfigureResponse, + ) + + def delete_by_id( + self, + connection_id: str, + *, + delete_documents: 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, + ) -> ConnectionDeleteByIDResponse: + """ + Delete a specific connection by ID + + Args: + delete_documents: Whether to also delete documents imported by this connection. Defaults to true. + + 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return self._delete( + path_template("/v3/connections/{connection_id}", connection_id=connection_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + {"delete_documents": delete_documents}, connection_delete_by_id_params.ConnectionDeleteByIDParams + ), + ), + cast_to=ConnectionDeleteByIDResponse, + ) + + def delete_by_provider( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + container_tags: SequenceNotStr[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, + ) -> ConnectionDeleteByProviderResponse: + """ + Delete connection for a specific provider and container tags + + Args: + container_tags: Optional comma-separated list of container tags to filter connections 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return self._delete( + path_template("/v3/connections/{provider}", provider=provider), + body=maybe_transform( + {"container_tags": container_tags}, + connection_delete_by_provider_params.ConnectionDeleteByProviderParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionDeleteByProviderResponse, + ) + + def get_by_id( + self, + connection_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, + ) -> ConnectionGetByIDResponse: + """ + Get connection details with 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return self._get( + path_template("/v3/connections/{connection_id}", connection_id=connection_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionGetByIDResponse, + ) + + def get_by_tag( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + container_tags: SequenceNotStr[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, + ) -> ConnectionGetByTagResponse: + """ + Get connection details with provider and container tags + + Args: + container_tags: Comma-separated list of container tags to filter connection 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return self._post( + path_template("/v3/connections/{provider}/connection", provider=provider), + body=maybe_transform( + {"container_tags": container_tags}, connection_get_by_tag_params.ConnectionGetByTagParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionGetByTagResponse, + ) + + def import_( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + 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, + ) -> str: + """ + Initiate a manual sync of connections + + Args: + container_tags: Optional comma-separated list of container tags to filter connections 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + extra_headers = {"Accept": "text/plain", **(extra_headers or {})} + return self._post( + path_template("/v3/connections/{provider}/import", provider=provider), + body=maybe_transform({"container_tags": container_tags}, connection_import_params.ConnectionImportParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=str, + ) + + def list_documents( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + 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, + ) -> ConnectionListDocumentsResponse: + """ + List documents indexed for a provider and container tags + + Args: + container_tags: Optional comma-separated list of container tags to filter documents 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return self._post( + path_template("/v3/connections/{provider}/documents", provider=provider), + body=maybe_transform( + {"container_tags": container_tags}, connection_list_documents_params.ConnectionListDocumentsParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionListDocumentsResponse, + ) + + def resources( + self, + connection_id: str, + *, + page: float | Omit = omit, + parent_id: str | Omit = omit, + per_page: 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, + ) -> ConnectionResourcesResponse: + """ + Fetch resources for a connection (supported providers: GitHub for now) + + 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return self._get( + path_template("/v3/connections/{connection_id}/resources", connection_id=connection_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "parent_id": parent_id, + "per_page": per_page, + }, + connection_resources_params.ConnectionResourcesParams, + ), + ), + cast_to=ConnectionResourcesResponse, + ) + + +class AsyncConnectionsResource(AsyncAPIResource): + """External service integrations""" + + @cached_property + def with_raw_response(self) -> AsyncConnectionsResourceWithRawResponse: + """ + 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 AsyncConnectionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncConnectionsResourceWithStreamingResponse: + """ + 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 AsyncConnectionsResourceWithStreamingResponse(self) + + async def create( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + container_tag: str | Omit = omit, + 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, + ) -> ConnectionCreateResponse: + """ + Initialize connection and get authorization URL + + 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 provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return await self._post( + path_template("/v3/connections/{provider}", provider=provider), + body=await async_maybe_transform( + { + "container_tag": container_tag, + "container_tags": container_tags, + "document_limit": document_limit, + "metadata": metadata, + "redirect_url": redirect_url, + }, + connection_create_params.ConnectionCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionCreateResponse, + ) + + async def list( + self, + *, + 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, + ) -> ConnectionListResponse: + """ + List all connections + + Args: + container_tags: Optional comma-separated list of container tags to filter documents 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/connections/list", + body=await async_maybe_transform( + {"container_tags": container_tags}, connection_list_params.ConnectionListParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionListResponse, + ) + + async def configure( + self, + connection_id: str, + *, + resources: Iterable[Dict[str, object]], + # 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, + ) -> ConnectionConfigureResponse: + """ + Configure resources for a connection (supported providers: GitHub for now) + + 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return await self._post( + path_template("/v3/connections/{connection_id}/configure", connection_id=connection_id), + body=await async_maybe_transform( + {"resources": resources}, connection_configure_params.ConnectionConfigureParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionConfigureResponse, + ) + + async def delete_by_id( + self, + connection_id: str, + *, + delete_documents: 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, + ) -> ConnectionDeleteByIDResponse: + """ + Delete a specific connection by ID + + Args: + delete_documents: Whether to also delete documents imported by this connection. Defaults to true. + + 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return await self._delete( + path_template("/v3/connections/{connection_id}", connection_id=connection_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + {"delete_documents": delete_documents}, connection_delete_by_id_params.ConnectionDeleteByIDParams + ), + ), + cast_to=ConnectionDeleteByIDResponse, + ) + + async def delete_by_provider( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + container_tags: SequenceNotStr[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, + ) -> ConnectionDeleteByProviderResponse: + """ + Delete connection for a specific provider and container tags + + Args: + container_tags: Optional comma-separated list of container tags to filter connections 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return await self._delete( + path_template("/v3/connections/{provider}", provider=provider), + body=await async_maybe_transform( + {"container_tags": container_tags}, + connection_delete_by_provider_params.ConnectionDeleteByProviderParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionDeleteByProviderResponse, + ) + + async def get_by_id( + self, + connection_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, + ) -> ConnectionGetByIDResponse: + """ + Get connection details with 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return await self._get( + path_template("/v3/connections/{connection_id}", connection_id=connection_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionGetByIDResponse, + ) + + async def get_by_tag( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + container_tags: SequenceNotStr[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, + ) -> ConnectionGetByTagResponse: + """ + Get connection details with provider and container tags + + Args: + container_tags: Comma-separated list of container tags to filter connection 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return await self._post( + path_template("/v3/connections/{provider}/connection", provider=provider), + body=await async_maybe_transform( + {"container_tags": container_tags}, connection_get_by_tag_params.ConnectionGetByTagParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionGetByTagResponse, + ) + + async def import_( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + 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, + ) -> str: + """ + Initiate a manual sync of connections + + Args: + container_tags: Optional comma-separated list of container tags to filter connections 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + extra_headers = {"Accept": "text/plain", **(extra_headers or {})} + return await self._post( + path_template("/v3/connections/{provider}/import", provider=provider), + body=await async_maybe_transform( + {"container_tags": container_tags}, connection_import_params.ConnectionImportParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=str, + ) + + async def list_documents( + self, + provider: Literal["notion", "google-drive", "onedrive", "gmail", "github", "web-crawler", "s3", "granola"], + *, + 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, + ) -> ConnectionListDocumentsResponse: + """ + List documents indexed for a provider and container tags + + Args: + container_tags: Optional comma-separated list of container tags to filter documents 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 + """ + if not provider: + raise ValueError(f"Expected a non-empty value for `provider` but received {provider!r}") + return await self._post( + path_template("/v3/connections/{provider}/documents", provider=provider), + body=await async_maybe_transform( + {"container_tags": container_tags}, connection_list_documents_params.ConnectionListDocumentsParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ConnectionListDocumentsResponse, + ) + + async def resources( + self, + connection_id: str, + *, + page: float | Omit = omit, + parent_id: str | Omit = omit, + per_page: 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, + ) -> ConnectionResourcesResponse: + """ + Fetch resources for a connection (supported providers: GitHub for now) + + 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 connection_id: + raise ValueError(f"Expected a non-empty value for `connection_id` but received {connection_id!r}") + return await self._get( + path_template("/v3/connections/{connection_id}/resources", connection_id=connection_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "page": page, + "parent_id": parent_id, + "per_page": per_page, + }, + connection_resources_params.ConnectionResourcesParams, + ), + ), + cast_to=ConnectionResourcesResponse, + ) + + +class ConnectionsResourceWithRawResponse: + def __init__(self, connections: ConnectionsResource) -> None: + self._connections = connections + + self.create = to_raw_response_wrapper( + connections.create, + ) + self.list = to_raw_response_wrapper( + connections.list, + ) + self.configure = to_raw_response_wrapper( + connections.configure, + ) + self.delete_by_id = to_raw_response_wrapper( + connections.delete_by_id, + ) + self.delete_by_provider = to_raw_response_wrapper( + connections.delete_by_provider, + ) + self.get_by_id = to_raw_response_wrapper( + connections.get_by_id, + ) + self.get_by_tag = to_raw_response_wrapper( + connections.get_by_tag, + ) + self.import_ = to_raw_response_wrapper( + connections.import_, + ) + self.list_documents = to_raw_response_wrapper( + connections.list_documents, + ) + self.resources = to_raw_response_wrapper( + connections.resources, + ) + + +class AsyncConnectionsResourceWithRawResponse: + def __init__(self, connections: AsyncConnectionsResource) -> None: + self._connections = connections + + self.create = async_to_raw_response_wrapper( + connections.create, + ) + self.list = async_to_raw_response_wrapper( + connections.list, + ) + self.configure = async_to_raw_response_wrapper( + connections.configure, + ) + self.delete_by_id = async_to_raw_response_wrapper( + connections.delete_by_id, + ) + self.delete_by_provider = async_to_raw_response_wrapper( + connections.delete_by_provider, + ) + self.get_by_id = async_to_raw_response_wrapper( + connections.get_by_id, + ) + self.get_by_tag = async_to_raw_response_wrapper( + connections.get_by_tag, + ) + self.import_ = async_to_raw_response_wrapper( + connections.import_, + ) + self.list_documents = async_to_raw_response_wrapper( + connections.list_documents, + ) + self.resources = async_to_raw_response_wrapper( + connections.resources, + ) + + +class ConnectionsResourceWithStreamingResponse: + def __init__(self, connections: ConnectionsResource) -> None: + self._connections = connections + + self.create = to_streamed_response_wrapper( + connections.create, + ) + self.list = to_streamed_response_wrapper( + connections.list, + ) + self.configure = to_streamed_response_wrapper( + connections.configure, + ) + self.delete_by_id = to_streamed_response_wrapper( + connections.delete_by_id, + ) + self.delete_by_provider = to_streamed_response_wrapper( + connections.delete_by_provider, + ) + self.get_by_id = to_streamed_response_wrapper( + connections.get_by_id, + ) + self.get_by_tag = to_streamed_response_wrapper( + connections.get_by_tag, + ) + self.import_ = to_streamed_response_wrapper( + connections.import_, + ) + self.list_documents = to_streamed_response_wrapper( + connections.list_documents, + ) + self.resources = to_streamed_response_wrapper( + connections.resources, + ) + + +class AsyncConnectionsResourceWithStreamingResponse: + def __init__(self, connections: AsyncConnectionsResource) -> None: + self._connections = connections + + self.create = async_to_streamed_response_wrapper( + connections.create, + ) + self.list = async_to_streamed_response_wrapper( + connections.list, + ) + self.configure = async_to_streamed_response_wrapper( + connections.configure, + ) + self.delete_by_id = async_to_streamed_response_wrapper( + connections.delete_by_id, + ) + self.delete_by_provider = async_to_streamed_response_wrapper( + connections.delete_by_provider, + ) + self.get_by_id = async_to_streamed_response_wrapper( + connections.get_by_id, + ) + self.get_by_tag = async_to_streamed_response_wrapper( + connections.get_by_tag, + ) + self.import_ = async_to_streamed_response_wrapper( + connections.import_, + ) + self.list_documents = async_to_streamed_response_wrapper( + connections.list_documents, + ) + self.resources = async_to_streamed_response_wrapper( + connections.resources, + ) diff --git a/src/supermemory/types/__init__.py b/src/supermemory/types/__init__.py index 5184116..695b777 100644 --- a/src/supermemory/types/__init__.py +++ b/src/supermemory/types/__init__.py @@ -14,6 +14,7 @@ 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_forget_response import MemoryForgetResponse as MemoryForgetResponse @@ -21,15 +22,35 @@ from .search_documents_params import SearchDocumentsParams as SearchDocumentsParams from .search_execute_response import SearchExecuteResponse as SearchExecuteResponse from .setting_update_response import SettingUpdateResponse as SettingUpdateResponse +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 .document_batch_add_params import DocumentBatchAddParams as DocumentBatchAddParams 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 .connection_configure_params import ConnectionConfigureParams as ConnectionConfigureParams +from .connection_resources_params import ConnectionResourcesParams as ConnectionResourcesParams from .document_batch_add_response import DocumentBatchAddResponse as DocumentBatchAddResponse from .document_delete_bulk_params import DocumentDeleteBulkParams as DocumentDeleteBulkParams from .document_upload_file_params import DocumentUploadFileParams as DocumentUploadFileParams from .memory_update_memory_params import MemoryUpdateMemoryParams as MemoryUpdateMemoryParams +from .connection_get_by_tag_params import ConnectionGetByTagParams as ConnectionGetByTagParams +from .connection_configure_response import ConnectionConfigureResponse as ConnectionConfigureResponse +from .connection_get_by_id_response import ConnectionGetByIDResponse as ConnectionGetByIDResponse +from .connection_resources_response import ConnectionResourcesResponse as ConnectionResourcesResponse from .document_delete_bulk_response import DocumentDeleteBulkResponse as DocumentDeleteBulkResponse from .document_upload_file_response import DocumentUploadFileResponse as DocumentUploadFileResponse from .memory_update_memory_response import MemoryUpdateMemoryResponse as MemoryUpdateMemoryResponse +from .connection_delete_by_id_params import ConnectionDeleteByIDParams as ConnectionDeleteByIDParams +from .connection_get_by_tag_response import ConnectionGetByTagResponse as ConnectionGetByTagResponse +from .connection_delete_by_id_response import ConnectionDeleteByIDResponse as ConnectionDeleteByIDResponse +from .connection_list_documents_params import ConnectionListDocumentsParams as ConnectionListDocumentsParams from .document_list_processing_response import DocumentListProcessingResponse as DocumentListProcessingResponse +from .connection_list_documents_response import ConnectionListDocumentsResponse as ConnectionListDocumentsResponse +from .connection_delete_by_provider_params import ConnectionDeleteByProviderParams as ConnectionDeleteByProviderParams +from .connection_delete_by_provider_response import ( + ConnectionDeleteByProviderResponse as ConnectionDeleteByProviderResponse, +) diff --git a/src/supermemory/types/connection_configure_params.py b/src/supermemory/types/connection_configure_params.py new file mode 100644 index 0000000..224ed1d --- /dev/null +++ b/src/supermemory/types/connection_configure_params.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable +from typing_extensions import Required, TypedDict + +__all__ = ["ConnectionConfigureParams"] + + +class ConnectionConfigureParams(TypedDict, total=False): + resources: Required[Iterable[Dict[str, object]]] diff --git a/src/supermemory/types/connection_configure_response.py b/src/supermemory/types/connection_configure_response.py new file mode 100644 index 0000000..065c4a8 --- /dev/null +++ b/src/supermemory/types/connection_configure_response.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ConnectionConfigureResponse"] + + +class ConnectionConfigureResponse(BaseModel): + message: str + + success: bool + + webhooks_registered: Optional[float] = FieldInfo(alias="webhooksRegistered", default=None) diff --git a/src/supermemory/types/connection_create_params.py b/src/supermemory/types/connection_create_params.py new file mode 100644 index 0000000..fcd9923 --- /dev/null +++ b/src/supermemory/types/connection_create_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Optional +from typing_extensions import Annotated, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["ConnectionCreateParams"] + + +class ConnectionCreateParams(TypedDict, total=False): + container_tag: Annotated[str, PropertyInfo(alias="containerTag")] + + container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")] + + document_limit: Annotated[int, PropertyInfo(alias="documentLimit")] + + metadata: Optional[Dict[str, Union[str, float, bool]]] + + redirect_url: Annotated[str, PropertyInfo(alias="redirectUrl")] diff --git a/src/supermemory/types/connection_create_response.py b/src/supermemory/types/connection_create_response.py new file mode 100644 index 0000000..f0bf02e --- /dev/null +++ b/src/supermemory/types/connection_create_response.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ConnectionCreateResponse"] + + +class ConnectionCreateResponse(BaseModel): + id: str + + auth_link: str = FieldInfo(alias="authLink") + + expires_in: str = FieldInfo(alias="expiresIn") + + redirects_to: Optional[str] = FieldInfo(alias="redirectsTo", default=None) diff --git a/src/supermemory/types/connection_delete_by_id_params.py b/src/supermemory/types/connection_delete_by_id_params.py new file mode 100644 index 0000000..2f08f96 --- /dev/null +++ b/src/supermemory/types/connection_delete_by_id_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["ConnectionDeleteByIDParams"] + + +class ConnectionDeleteByIDParams(TypedDict, total=False): + delete_documents: Annotated[str, PropertyInfo(alias="deleteDocuments")] + """Whether to also delete documents imported by this connection. Defaults to true.""" diff --git a/src/supermemory/types/connection_delete_by_id_response.py b/src/supermemory/types/connection_delete_by_id_response.py new file mode 100644 index 0000000..4da42f4 --- /dev/null +++ b/src/supermemory/types/connection_delete_by_id_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["ConnectionDeleteByIDResponse"] + + +class ConnectionDeleteByIDResponse(BaseModel): + id: str + + provider: str diff --git a/src/supermemory/types/connection_delete_by_provider_params.py b/src/supermemory/types/connection_delete_by_provider_params.py new file mode 100644 index 0000000..09e136d --- /dev/null +++ b/src/supermemory/types/connection_delete_by_provider_params.py @@ -0,0 +1,15 @@ +# 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 SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["ConnectionDeleteByProviderParams"] + + +class ConnectionDeleteByProviderParams(TypedDict, total=False): + container_tags: Required[Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]] + """Optional comma-separated list of container tags to filter connections by""" diff --git a/src/supermemory/types/connection_delete_by_provider_response.py b/src/supermemory/types/connection_delete_by_provider_response.py new file mode 100644 index 0000000..e698e7e --- /dev/null +++ b/src/supermemory/types/connection_delete_by_provider_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel + +__all__ = ["ConnectionDeleteByProviderResponse"] + + +class ConnectionDeleteByProviderResponse(BaseModel): + id: str + + provider: str diff --git a/src/supermemory/types/connection_get_by_id_response.py b/src/supermemory/types/connection_get_by_id_response.py new file mode 100644 index 0000000..9c04243 --- /dev/null +++ b/src/supermemory/types/connection_get_by_id_response.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ConnectionGetByIDResponse"] + + +class ConnectionGetByIDResponse(BaseModel): + id: str + + created_at: str = FieldInfo(alias="createdAt") + + provider: str + + container_tags: Optional[List[str]] = FieldInfo(alias="containerTags", default=None) + + document_limit: Optional[float] = FieldInfo(alias="documentLimit", default=None) + + email: Optional[str] = None + + expires_at: Optional[str] = FieldInfo(alias="expiresAt", default=None) + + metadata: Optional[Dict[str, object]] = None diff --git a/src/supermemory/types/connection_get_by_tag_params.py b/src/supermemory/types/connection_get_by_tag_params.py new file mode 100644 index 0000000..13a9082 --- /dev/null +++ b/src/supermemory/types/connection_get_by_tag_params.py @@ -0,0 +1,15 @@ +# 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 SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["ConnectionGetByTagParams"] + + +class ConnectionGetByTagParams(TypedDict, total=False): + container_tags: Required[Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")]] + """Comma-separated list of container tags to filter connection by""" diff --git a/src/supermemory/types/connection_get_by_tag_response.py b/src/supermemory/types/connection_get_by_tag_response.py new file mode 100644 index 0000000..8a25c93 --- /dev/null +++ b/src/supermemory/types/connection_get_by_tag_response.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ConnectionGetByTagResponse"] + + +class ConnectionGetByTagResponse(BaseModel): + id: str + + created_at: str = FieldInfo(alias="createdAt") + + provider: str + + container_tags: Optional[List[str]] = FieldInfo(alias="containerTags", default=None) + + document_limit: Optional[float] = FieldInfo(alias="documentLimit", default=None) + + email: Optional[str] = None + + expires_at: Optional[str] = FieldInfo(alias="expiresAt", default=None) + + metadata: Optional[Dict[str, object]] = None diff --git a/src/supermemory/types/connection_import_params.py b/src/supermemory/types/connection_import_params.py new file mode 100644 index 0000000..2e19b22 --- /dev/null +++ b/src/supermemory/types/connection_import_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["ConnectionImportParams"] + + +class ConnectionImportParams(TypedDict, total=False): + container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")] + """Optional comma-separated list of container tags to filter connections by""" diff --git a/src/supermemory/types/connection_import_response.py b/src/supermemory/types/connection_import_response.py new file mode 100644 index 0000000..9e5445b --- /dev/null +++ b/src/supermemory/types/connection_import_response.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import TypeAlias + +__all__ = ["ConnectionImportResponse"] + +ConnectionImportResponse: TypeAlias = str diff --git a/src/supermemory/types/connection_list_documents_params.py b/src/supermemory/types/connection_list_documents_params.py new file mode 100644 index 0000000..8673d26 --- /dev/null +++ b/src/supermemory/types/connection_list_documents_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["ConnectionListDocumentsParams"] + + +class ConnectionListDocumentsParams(TypedDict, total=False): + container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")] + """Optional comma-separated list of container tags to filter documents by""" diff --git a/src/supermemory/types/connection_list_documents_response.py b/src/supermemory/types/connection_list_documents_response.py new file mode 100644 index 0000000..f42fed9 --- /dev/null +++ b/src/supermemory/types/connection_list_documents_response.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import TypeAlias + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ConnectionListDocumentsResponse", "ConnectionListDocumentsResponseItem"] + + +class ConnectionListDocumentsResponseItem(BaseModel): + id: str + + created_at: str = FieldInfo(alias="createdAt") + + status: str + + summary: Optional[str] = None + + title: Optional[str] = None + + type: str + + updated_at: str = FieldInfo(alias="updatedAt") + + +ConnectionListDocumentsResponse: TypeAlias = List[ConnectionListDocumentsResponseItem] diff --git a/src/supermemory/types/connection_list_params.py b/src/supermemory/types/connection_list_params.py new file mode 100644 index 0000000..2948fa3 --- /dev/null +++ b/src/supermemory/types/connection_list_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["ConnectionListParams"] + + +class ConnectionListParams(TypedDict, total=False): + container_tags: Annotated[SequenceNotStr[str], PropertyInfo(alias="containerTags")] + """Optional comma-separated list of container tags to filter documents by""" diff --git a/src/supermemory/types/connection_list_response.py b/src/supermemory/types/connection_list_response.py new file mode 100644 index 0000000..9116c77 --- /dev/null +++ b/src/supermemory/types/connection_list_response.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from typing_extensions import TypeAlias + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ConnectionListResponse", "ConnectionListResponseItem"] + + +class ConnectionListResponseItem(BaseModel): + id: str + + created_at: str = FieldInfo(alias="createdAt") + + provider: str + + container_tags: Optional[List[str]] = FieldInfo(alias="containerTags", default=None) + + document_limit: Optional[float] = FieldInfo(alias="documentLimit", default=None) + + email: Optional[str] = None + + expires_at: Optional[str] = FieldInfo(alias="expiresAt", default=None) + + metadata: Optional[Dict[str, object]] = None + + +ConnectionListResponse: TypeAlias = List[ConnectionListResponseItem] diff --git a/src/supermemory/types/connection_resources_params.py b/src/supermemory/types/connection_resources_params.py new file mode 100644 index 0000000..ff39796 --- /dev/null +++ b/src/supermemory/types/connection_resources_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["ConnectionResourcesParams"] + + +class ConnectionResourcesParams(TypedDict, total=False): + page: float + + parent_id: str + + per_page: float diff --git a/src/supermemory/types/connection_resources_response.py b/src/supermemory/types/connection_resources_response.py new file mode 100644 index 0000000..1d70419 --- /dev/null +++ b/src/supermemory/types/connection_resources_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional + +from .._models import BaseModel + +__all__ = ["ConnectionResourcesResponse"] + + +class ConnectionResourcesResponse(BaseModel): + resources: List[Dict[str, object]] + + total_count: Optional[float] = None diff --git a/tests/api_resources/test_connections.py b/tests/api_resources/test_connections.py new file mode 100644 index 0000000..3eb33fc --- /dev/null +++ b/tests/api_resources/test_connections.py @@ -0,0 +1,904 @@ +# 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 ( + ConnectionListResponse, + ConnectionCreateResponse, + ConnectionGetByIDResponse, + ConnectionGetByTagResponse, + ConnectionConfigureResponse, + ConnectionResourcesResponse, + ConnectionDeleteByIDResponse, + ConnectionListDocumentsResponse, + ConnectionDeleteByProviderResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestConnections: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Supermemory) -> None: + connection = client.connections.create( + provider="notion", + ) + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Supermemory) -> None: + connection = client.connections.create( + provider="notion", + container_tag="containerTag", + container_tags=["_:_k--W2K_1V"], + document_limit=1, + metadata={"foo": "string"}, + redirect_url="redirectUrl", + ) + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.create( + provider="notion", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.create( + provider="notion", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Supermemory) -> None: + connection = client.connections.list() + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Supermemory) -> None: + connection = client.connections.list( + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_configure(self, client: Supermemory) -> None: + connection = client.connections.configure( + connection_id="connectionId", + resources=[{"foo": "bar"}], + ) + assert_matches_type(ConnectionConfigureResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_configure(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.configure( + connection_id="connectionId", + resources=[{"foo": "bar"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionConfigureResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_configure(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.configure( + connection_id="connectionId", + resources=[{"foo": "bar"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionConfigureResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_configure(self, client: Supermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + client.connections.with_raw_response.configure( + connection_id="", + resources=[{"foo": "bar"}], + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete_by_id(self, client: Supermemory) -> None: + connection = client.connections.delete_by_id( + connection_id="connectionId", + ) + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete_by_id_with_all_params(self, client: Supermemory) -> None: + connection = client.connections.delete_by_id( + connection_id="connectionId", + delete_documents="deleteDocuments", + ) + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete_by_id(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.delete_by_id( + connection_id="connectionId", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete_by_id(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.delete_by_id( + connection_id="connectionId", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete_by_id(self, client: Supermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + client.connections.with_raw_response.delete_by_id( + connection_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete_by_provider(self, client: Supermemory) -> None: + connection = client.connections.delete_by_provider( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionDeleteByProviderResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete_by_provider(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.delete_by_provider( + provider="notion", + container_tags=["user_123", "project_123"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionDeleteByProviderResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete_by_provider(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.delete_by_provider( + provider="notion", + container_tags=["user_123", "project_123"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionDeleteByProviderResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_by_id(self, client: Supermemory) -> None: + connection = client.connections.get_by_id( + "connectionId", + ) + assert_matches_type(ConnectionGetByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_by_id(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.get_by_id( + "connectionId", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionGetByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_by_id(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.get_by_id( + "connectionId", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionGetByIDResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_get_by_id(self, client: Supermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + client.connections.with_raw_response.get_by_id( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_by_tag(self, client: Supermemory) -> None: + connection = client.connections.get_by_tag( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionGetByTagResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_by_tag(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.get_by_tag( + provider="notion", + container_tags=["user_123", "project_123"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionGetByTagResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_by_tag(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.get_by_tag( + provider="notion", + container_tags=["user_123", "project_123"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionGetByTagResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_import(self, client: Supermemory) -> None: + connection = client.connections.import_( + provider="notion", + ) + assert_matches_type(str, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_import_with_all_params(self, client: Supermemory) -> None: + connection = client.connections.import_( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(str, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_import(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.import_( + provider="notion", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(str, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_import(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.import_( + provider="notion", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(str, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_documents(self, client: Supermemory) -> None: + connection = client.connections.list_documents( + provider="notion", + ) + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_documents_with_all_params(self, client: Supermemory) -> None: + connection = client.connections.list_documents( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_documents(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.list_documents( + provider="notion", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_documents(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.list_documents( + provider="notion", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_resources(self, client: Supermemory) -> None: + connection = client.connections.resources( + connection_id="connectionId", + ) + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_resources_with_all_params(self, client: Supermemory) -> None: + connection = client.connections.resources( + connection_id="connectionId", + page=0, + parent_id="parent_id", + per_page=0, + ) + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_resources(self, client: Supermemory) -> None: + response = client.connections.with_raw_response.resources( + connection_id="connectionId", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = response.parse() + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_resources(self, client: Supermemory) -> None: + with client.connections.with_streaming_response.resources( + connection_id="connectionId", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = response.parse() + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_resources(self, client: Supermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + client.connections.with_raw_response.resources( + connection_id="", + ) + + +class TestAsyncConnections: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.create( + provider="notion", + ) + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.create( + provider="notion", + container_tag="containerTag", + container_tags=["_:_k--W2K_1V"], + document_limit=1, + metadata={"foo": "string"}, + redirect_url="redirectUrl", + ) + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.create( + provider="notion", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.create( + provider="notion", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.list() + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.list( + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionListResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_configure(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.configure( + connection_id="connectionId", + resources=[{"foo": "bar"}], + ) + assert_matches_type(ConnectionConfigureResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_configure(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.configure( + connection_id="connectionId", + resources=[{"foo": "bar"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionConfigureResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_configure(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.configure( + connection_id="connectionId", + resources=[{"foo": "bar"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionConfigureResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_configure(self, async_client: AsyncSupermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + await async_client.connections.with_raw_response.configure( + connection_id="", + resources=[{"foo": "bar"}], + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete_by_id(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.delete_by_id( + connection_id="connectionId", + ) + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete_by_id_with_all_params(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.delete_by_id( + connection_id="connectionId", + delete_documents="deleteDocuments", + ) + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete_by_id(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.delete_by_id( + connection_id="connectionId", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete_by_id(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.delete_by_id( + connection_id="connectionId", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionDeleteByIDResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete_by_id(self, async_client: AsyncSupermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + await async_client.connections.with_raw_response.delete_by_id( + connection_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete_by_provider(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.delete_by_provider( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionDeleteByProviderResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete_by_provider(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.delete_by_provider( + provider="notion", + container_tags=["user_123", "project_123"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionDeleteByProviderResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete_by_provider(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.delete_by_provider( + provider="notion", + container_tags=["user_123", "project_123"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionDeleteByProviderResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_by_id(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.get_by_id( + "connectionId", + ) + assert_matches_type(ConnectionGetByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_by_id(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.get_by_id( + "connectionId", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionGetByIDResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_by_id(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.get_by_id( + "connectionId", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionGetByIDResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_get_by_id(self, async_client: AsyncSupermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + await async_client.connections.with_raw_response.get_by_id( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_by_tag(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.get_by_tag( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionGetByTagResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_by_tag(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.get_by_tag( + provider="notion", + container_tags=["user_123", "project_123"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionGetByTagResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_by_tag(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.get_by_tag( + provider="notion", + container_tags=["user_123", "project_123"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionGetByTagResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_import(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.import_( + provider="notion", + ) + assert_matches_type(str, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_import_with_all_params(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.import_( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(str, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_import(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.import_( + provider="notion", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(str, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_import(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.import_( + provider="notion", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(str, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_documents(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.list_documents( + provider="notion", + ) + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_documents_with_all_params(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.list_documents( + provider="notion", + container_tags=["user_123", "project_123"], + ) + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_documents(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.list_documents( + provider="notion", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_documents(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.list_documents( + provider="notion", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionListDocumentsResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_resources(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.resources( + connection_id="connectionId", + ) + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_resources_with_all_params(self, async_client: AsyncSupermemory) -> None: + connection = await async_client.connections.resources( + connection_id="connectionId", + page=0, + parent_id="parent_id", + per_page=0, + ) + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_resources(self, async_client: AsyncSupermemory) -> None: + response = await async_client.connections.with_raw_response.resources( + connection_id="connectionId", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + connection = await response.parse() + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_resources(self, async_client: AsyncSupermemory) -> None: + async with async_client.connections.with_streaming_response.resources( + connection_id="connectionId", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + connection = await response.parse() + assert_matches_type(ConnectionResourcesResponse, connection, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_resources(self, async_client: AsyncSupermemory) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `connection_id` but received ''"): + await async_client.connections.with_raw_response.resources( + connection_id="", + ) From 9014192d848678f968e27d781be5553d88eca5a0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 09:27:46 +0000 Subject: [PATCH 3/3] release: 3.50.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- src/supermemory/_version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5007ea2..77d75a0 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.49.0" + ".": "3.50.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 22db4a8..9a630fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 3.50.0 (2026-06-24) + +Full Changelog: [v3.49.0...v3.50.0](https://github.com/supermemoryai/python-sdk/compare/v3.49.0...v3.50.0) + +### Features + +* **api:** api update ([36a55ee](https://github.com/supermemoryai/python-sdk/commit/36a55ee2b26fb0ed076892d486e464c11eb4c2e4)) + ## 3.49.0 (2026-06-22) Full Changelog: [v3.48.0...v3.49.0](https://github.com/supermemoryai/python-sdk/compare/v3.48.0...v3.49.0) diff --git a/pyproject.toml b/pyproject.toml index 8d4d3a5..7343f8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "supermemory" -version = "3.49.0" +version = "3.50.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 8fa1ebb..4af7af5 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.49.0" # x-release-please-version +__version__ = "3.50.0" # x-release-please-version