From 2a31753949f8f7334104d50eee98fc9ae0c71bb1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 29 Sep 2025 18:31:50 +0000
Subject: [PATCH 01/11] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 7a16060c..27faf06c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-55497442c9c2cf4077d1e8661fdf82ebe905dbb140ec65421ffa78da6d06a015.yml
-openapi_spec_hash: aa9abda3ed926041c12f664e4225c5ed
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-59cfdc939d8d499a2054081f5852f2ac4243ba5525173678fac0dae2605e13a0.yml
+openapi_spec_hash: 29b0495f6c6650a8b6e650c756ea66c5
config_hash: bd953556a1d60f48307815fdaf9ba88b
From 210e641ade71c871f0f80f1c0a0cc043169be302 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 11 Oct 2025 02:43:06 +0000
Subject: [PATCH 02/11] chore(internal): detect missing future annotations with
ruff
---
pyproject.toml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/pyproject.toml b/pyproject.toml
index 0cdb5090..6c70ed58 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -224,6 +224,8 @@ select = [
"B",
# remove unused imports
"F401",
+ # check for missing future annotations
+ "FA102",
# bare except statements
"E722",
# unused arguments
@@ -246,6 +248,8 @@ unfixable = [
"T203",
]
+extend-safe-fixes = ["FA102"]
+
[tool.ruff.lint.flake8-tidy-imports.banned-api]
"functools.lru_cache".msg = "This function does not retain type information for the wrapped function's arguments; The `lru_cache` function from `_utils` should be used instead"
From 476c23d01aae74bc13013d71e32430264d45bab1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 13 Oct 2025 17:32:06 +0000
Subject: [PATCH 03/11] feat(api): api update
---
.stats.yml | 4 +-
src/hyperspell/types/auth_me_response.py | 63 +++++++++++++++++++++++-
2 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 27faf06c..b984588b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-59cfdc939d8d499a2054081f5852f2ac4243ba5525173678fac0dae2605e13a0.yml
-openapi_spec_hash: 29b0495f6c6650a8b6e650c756ea66c5
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-02e7812c1884f52abc262b661200ba5f97e497d5c981db3e0fdcd45f3df9f1a7.yml
+openapi_spec_hash: 7c4d4f673badcf00e63a2bf17fbc149f
config_hash: bd953556a1d60f48307815fdaf9ba88b
diff --git a/src/hyperspell/types/auth_me_response.py b/src/hyperspell/types/auth_me_response.py
index d4ca2c54..7eb70095 100644
--- a/src/hyperspell/types/auth_me_response.py
+++ b/src/hyperspell/types/auth_me_response.py
@@ -6,7 +6,7 @@
from .._models import BaseModel
-__all__ = ["AuthMeResponse", "App"]
+__all__ = ["AuthMeResponse", "App", "Connection"]
class App(BaseModel):
@@ -23,6 +23,64 @@ class App(BaseModel):
"""The app's redirect URL"""
+class Connection(BaseModel):
+ id: str
+ """The connection's id"""
+
+ label: Optional[str] = None
+ """The connection's label"""
+
+ provider: Literal[
+ "collections",
+ "vault",
+ "web_crawler",
+ "notion",
+ "slack",
+ "google_calendar",
+ "reddit",
+ "box",
+ "google_drive",
+ "airtable",
+ "algolia",
+ "amplitude",
+ "asana",
+ "ashby",
+ "bamboohr",
+ "basecamp",
+ "bubbles",
+ "calendly",
+ "confluence",
+ "clickup",
+ "datadog",
+ "deel",
+ "discord",
+ "dropbox",
+ "exa",
+ "facebook",
+ "front",
+ "github",
+ "gitlab",
+ "google_docs",
+ "google_mail",
+ "google_sheet",
+ "hubspot",
+ "jira",
+ "linear",
+ "microsoft_teams",
+ "mixpanel",
+ "monday",
+ "outlook",
+ "perplexity",
+ "rippling",
+ "salesforce",
+ "segment",
+ "todoist",
+ "twitter",
+ "zoom",
+ ]
+ """The connection's provider"""
+
+
class AuthMeResponse(BaseModel):
id: str
"""The user's id"""
@@ -82,6 +140,9 @@ class AuthMeResponse(BaseModel):
]
"""All integrations available for the app"""
+ connections: List[Connection]
+ """Established connections for the user"""
+
installed_integrations: List[
Literal[
"collections",
From 9f27d7f462d15b54cf1aa62e962da1d34a03e616 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 01:45:35 +0000
Subject: [PATCH 04/11] feat(api): api update
---
.stats.yml | 6 +-
api.md | 10 --
.../resources/integrations/integrations.py | 95 -----------------
src/hyperspell/types/__init__.py | 1 -
.../types/integration_revoke_response.py | 11 --
tests/api_resources/test_integrations.py | 100 ------------------
6 files changed, 3 insertions(+), 220 deletions(-)
delete mode 100644 src/hyperspell/types/integration_revoke_response.py
delete mode 100644 tests/api_resources/test_integrations.py
diff --git a/.stats.yml b/.stats.yml
index b984588b..953baecb 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 18
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-02e7812c1884f52abc262b661200ba5f97e497d5c981db3e0fdcd45f3df9f1a7.yml
-openapi_spec_hash: 7c4d4f673badcf00e63a2bf17fbc149f
+configured_endpoints: 17
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-5c32c854b3a68ddee47fb9f4ae077ac9df93d9ecb46311282285e9ff56f979be.yml
+openapi_spec_hash: eb7f5be1d2520355ad5657607c1c03d2
config_hash: bd953556a1d60f48307815fdaf9ba88b
diff --git a/api.md b/api.md
index 568a25d8..cde7710d 100644
--- a/api.md
+++ b/api.md
@@ -6,16 +6,6 @@ from hyperspell.types import QueryResult
# Integrations
-Types:
-
-```python
-from hyperspell.types import IntegrationRevokeResponse
-```
-
-Methods:
-
-- client.integrations.revoke(provider) -> IntegrationRevokeResponse
-
## GoogleCalendar
Types:
diff --git a/src/hyperspell/resources/integrations/integrations.py b/src/hyperspell/resources/integrations/integrations.py
index 937c8d3c..273d99ae 100644
--- a/src/hyperspell/resources/integrations/integrations.py
+++ b/src/hyperspell/resources/integrations/integrations.py
@@ -2,8 +2,6 @@
from __future__ import annotations
-import httpx
-
from .slack import (
SlackResource,
AsyncSlackResource,
@@ -12,15 +10,8 @@
SlackResourceWithStreamingResponse,
AsyncSlackResourceWithStreamingResponse,
)
-from ..._types import Body, Query, Headers, NotGiven, not_given
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 .web_crawler import (
WebCrawlerResource,
AsyncWebCrawlerResource,
@@ -29,7 +20,6 @@
WebCrawlerResourceWithStreamingResponse,
AsyncWebCrawlerResourceWithStreamingResponse,
)
-from ..._base_client import make_request_options
from .google_calendar import (
GoogleCalendarResource,
AsyncGoogleCalendarResource,
@@ -38,7 +28,6 @@
GoogleCalendarResourceWithStreamingResponse,
AsyncGoogleCalendarResourceWithStreamingResponse,
)
-from ...types.integration_revoke_response import IntegrationRevokeResponse
__all__ = ["IntegrationsResource", "AsyncIntegrationsResource"]
@@ -75,40 +64,6 @@ def with_streaming_response(self) -> IntegrationsResourceWithStreamingResponse:
"""
return IntegrationsResourceWithStreamingResponse(self)
- def revoke(
- self,
- provider: 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,
- ) -> IntegrationRevokeResponse:
- """
- Revokes Hyperspell's access the given provider and deletes all stored
- credentials and indexed data.
-
- 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._get(
- f"/integrations/{provider}/revoke",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=IntegrationRevokeResponse,
- )
-
class AsyncIntegrationsResource(AsyncAPIResource):
@cached_property
@@ -142,49 +97,11 @@ def with_streaming_response(self) -> AsyncIntegrationsResourceWithStreamingRespo
"""
return AsyncIntegrationsResourceWithStreamingResponse(self)
- async def revoke(
- self,
- provider: 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,
- ) -> IntegrationRevokeResponse:
- """
- Revokes Hyperspell's access the given provider and deletes all stored
- credentials and indexed data.
-
- 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._get(
- f"/integrations/{provider}/revoke",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=IntegrationRevokeResponse,
- )
-
class IntegrationsResourceWithRawResponse:
def __init__(self, integrations: IntegrationsResource) -> None:
self._integrations = integrations
- self.revoke = to_raw_response_wrapper(
- integrations.revoke,
- )
-
@cached_property
def google_calendar(self) -> GoogleCalendarResourceWithRawResponse:
return GoogleCalendarResourceWithRawResponse(self._integrations.google_calendar)
@@ -202,10 +119,6 @@ class AsyncIntegrationsResourceWithRawResponse:
def __init__(self, integrations: AsyncIntegrationsResource) -> None:
self._integrations = integrations
- self.revoke = async_to_raw_response_wrapper(
- integrations.revoke,
- )
-
@cached_property
def google_calendar(self) -> AsyncGoogleCalendarResourceWithRawResponse:
return AsyncGoogleCalendarResourceWithRawResponse(self._integrations.google_calendar)
@@ -223,10 +136,6 @@ class IntegrationsResourceWithStreamingResponse:
def __init__(self, integrations: IntegrationsResource) -> None:
self._integrations = integrations
- self.revoke = to_streamed_response_wrapper(
- integrations.revoke,
- )
-
@cached_property
def google_calendar(self) -> GoogleCalendarResourceWithStreamingResponse:
return GoogleCalendarResourceWithStreamingResponse(self._integrations.google_calendar)
@@ -244,10 +153,6 @@ class AsyncIntegrationsResourceWithStreamingResponse:
def __init__(self, integrations: AsyncIntegrationsResource) -> None:
self._integrations = integrations
- self.revoke = async_to_streamed_response_wrapper(
- integrations.revoke,
- )
-
@cached_property
def google_calendar(self) -> AsyncGoogleCalendarResourceWithStreamingResponse:
return AsyncGoogleCalendarResourceWithStreamingResponse(self._integrations.google_calendar)
diff --git a/src/hyperspell/types/__init__.py b/src/hyperspell/types/__init__.py
index 0ed74dd4..bf8028b9 100644
--- a/src/hyperspell/types/__init__.py
+++ b/src/hyperspell/types/__init__.py
@@ -18,7 +18,6 @@
from .memory_status_response import MemoryStatusResponse as MemoryStatusResponse
from .auth_delete_user_response import AuthDeleteUserResponse as AuthDeleteUserResponse
from .evaluate_score_query_params import EvaluateScoreQueryParams as EvaluateScoreQueryParams
-from .integration_revoke_response import IntegrationRevokeResponse as IntegrationRevokeResponse
from .evaluate_score_query_response import EvaluateScoreQueryResponse as EvaluateScoreQueryResponse
from .evaluate_score_highlight_params import EvaluateScoreHighlightParams as EvaluateScoreHighlightParams
from .evaluate_score_highlight_response import EvaluateScoreHighlightResponse as EvaluateScoreHighlightResponse
diff --git a/src/hyperspell/types/integration_revoke_response.py b/src/hyperspell/types/integration_revoke_response.py
deleted file mode 100644
index 2385ca96..00000000
--- a/src/hyperspell/types/integration_revoke_response.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .._models import BaseModel
-
-__all__ = ["IntegrationRevokeResponse"]
-
-
-class IntegrationRevokeResponse(BaseModel):
- message: str
-
- success: bool
diff --git a/tests/api_resources/test_integrations.py b/tests/api_resources/test_integrations.py
deleted file mode 100644
index 25babdd3..00000000
--- a/tests/api_resources/test_integrations.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from hyperspell import Hyperspell, AsyncHyperspell
-from tests.utils import assert_matches_type
-from hyperspell.types import IntegrationRevokeResponse
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestIntegrations:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_revoke(self, client: Hyperspell) -> None:
- integration = client.integrations.revoke(
- "provider",
- )
- assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
-
- @parametrize
- def test_raw_response_revoke(self, client: Hyperspell) -> None:
- response = client.integrations.with_raw_response.revoke(
- "provider",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- integration = response.parse()
- assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
-
- @parametrize
- def test_streaming_response_revoke(self, client: Hyperspell) -> None:
- with client.integrations.with_streaming_response.revoke(
- "provider",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- integration = response.parse()
- assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_revoke(self, client: Hyperspell) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider` but received ''"):
- client.integrations.with_raw_response.revoke(
- "",
- )
-
-
-class TestAsyncIntegrations:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_revoke(self, async_client: AsyncHyperspell) -> None:
- integration = await async_client.integrations.revoke(
- "provider",
- )
- assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
-
- @parametrize
- async def test_raw_response_revoke(self, async_client: AsyncHyperspell) -> None:
- response = await async_client.integrations.with_raw_response.revoke(
- "provider",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- integration = await response.parse()
- assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
-
- @parametrize
- async def test_streaming_response_revoke(self, async_client: AsyncHyperspell) -> None:
- async with async_client.integrations.with_streaming_response.revoke(
- "provider",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- integration = await response.parse()
- assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_revoke(self, async_client: AsyncHyperspell) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `provider` but received ''"):
- await async_client.integrations.with_raw_response.revoke(
- "",
- )
From 3e0d0f2df97581fe1b62649e06dbd3e522da12d5 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 01:59:27 +0000
Subject: [PATCH 05/11] codegen metadata
---
.stats.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 953baecb..1217c511 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 17
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-5c32c854b3a68ddee47fb9f4ae077ac9df93d9ecb46311282285e9ff56f979be.yml
-openapi_spec_hash: eb7f5be1d2520355ad5657607c1c03d2
-config_hash: bd953556a1d60f48307815fdaf9ba88b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-02e7812c1884f52abc262b661200ba5f97e497d5c981db3e0fdcd45f3df9f1a7.yml
+openapi_spec_hash: 7c4d4f673badcf00e63a2bf17fbc149f
+config_hash: 331712c9dfb31af34bdab84fd3f7d48d
From df1dc5d547313a241604e554cf515d904ad196a6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 02:01:02 +0000
Subject: [PATCH 06/11] feat(api): update via SDK Studio
---
.stats.yml | 6 +-
api.md | 16 ++
.../resources/integrations/integrations.py | 243 +++++++++++++++++
src/hyperspell/types/__init__.py | 4 +
.../types/integration_connect_params.py | 12 +
.../types/integration_connect_response.py | 13 +
.../types/integration_list_response.py | 70 +++++
.../types/integration_revoke_response.py | 11 +
tests/api_resources/test_integrations.py | 246 ++++++++++++++++++
9 files changed, 618 insertions(+), 3 deletions(-)
create mode 100644 src/hyperspell/types/integration_connect_params.py
create mode 100644 src/hyperspell/types/integration_connect_response.py
create mode 100644 src/hyperspell/types/integration_list_response.py
create mode 100644 src/hyperspell/types/integration_revoke_response.py
create mode 100644 tests/api_resources/test_integrations.py
diff --git a/.stats.yml b/.stats.yml
index 1217c511..5bed2d49 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 17
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-02e7812c1884f52abc262b661200ba5f97e497d5c981db3e0fdcd45f3df9f1a7.yml
-openapi_spec_hash: 7c4d4f673badcf00e63a2bf17fbc149f
+configured_endpoints: 20
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-cd8c28747615d8967e4e20e6fd5b9488a3022fece37f1c4c133c9b8d9c4415f3.yml
+openapi_spec_hash: 2aa6c5d6faa2cbd4038108b5ebc103b3
config_hash: 331712c9dfb31af34bdab84fd3f7d48d
diff --git a/api.md b/api.md
index cde7710d..a0af7c08 100644
--- a/api.md
+++ b/api.md
@@ -6,6 +6,22 @@ from hyperspell.types import QueryResult
# Integrations
+Types:
+
+```python
+from hyperspell.types import (
+ IntegrationListResponse,
+ IntegrationConnectResponse,
+ IntegrationRevokeResponse,
+)
+```
+
+Methods:
+
+- client.integrations.list() -> IntegrationListResponse
+- client.integrations.connect(integration_id, \*\*params) -> IntegrationConnectResponse
+- client.integrations.revoke(integration_id) -> IntegrationRevokeResponse
+
## GoogleCalendar
Types:
diff --git a/src/hyperspell/resources/integrations/integrations.py b/src/hyperspell/resources/integrations/integrations.py
index 273d99ae..178d7b9a 100644
--- a/src/hyperspell/resources/integrations/integrations.py
+++ b/src/hyperspell/resources/integrations/integrations.py
@@ -2,6 +2,10 @@
from __future__ import annotations
+from typing import Optional
+
+import httpx
+
from .slack import (
SlackResource,
AsyncSlackResource,
@@ -10,8 +14,17 @@
SlackResourceWithStreamingResponse,
AsyncSlackResourceWithStreamingResponse,
)
+from ...types import integration_connect_params
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
from .web_crawler import (
WebCrawlerResource,
AsyncWebCrawlerResource,
@@ -20,6 +33,7 @@
WebCrawlerResourceWithStreamingResponse,
AsyncWebCrawlerResourceWithStreamingResponse,
)
+from ..._base_client import make_request_options
from .google_calendar import (
GoogleCalendarResource,
AsyncGoogleCalendarResource,
@@ -28,6 +42,9 @@
GoogleCalendarResourceWithStreamingResponse,
AsyncGoogleCalendarResourceWithStreamingResponse,
)
+from ...types.integration_list_response import IntegrationListResponse
+from ...types.integration_revoke_response import IntegrationRevokeResponse
+from ...types.integration_connect_response import IntegrationConnectResponse
__all__ = ["IntegrationsResource", "AsyncIntegrationsResource"]
@@ -64,6 +81,99 @@ def with_streaming_response(self) -> IntegrationsResourceWithStreamingResponse:
"""
return IntegrationsResourceWithStreamingResponse(self)
+ def list(
+ self,
+ *,
+ # 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,
+ ) -> IntegrationListResponse:
+ """List all integrations for the user."""
+ return self._get(
+ "/integrations/list",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=IntegrationListResponse,
+ )
+
+ def connect(
+ self,
+ integration_id: str,
+ *,
+ redirect_url: Optional[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,
+ ) -> IntegrationConnectResponse:
+ """
+ Redirects to the connect URL to link an integration.
+
+ 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 integration_id:
+ raise ValueError(f"Expected a non-empty value for `integration_id` but received {integration_id!r}")
+ return self._get(
+ f"/integrations/{integration_id}/connect",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"redirect_url": redirect_url}, integration_connect_params.IntegrationConnectParams
+ ),
+ ),
+ cast_to=IntegrationConnectResponse,
+ )
+
+ def revoke(
+ self,
+ integration_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,
+ ) -> IntegrationRevokeResponse:
+ """
+ Revokes Hyperspell's access the given provider and deletes all stored
+ credentials and indexed data.
+
+ 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 integration_id:
+ raise ValueError(f"Expected a non-empty value for `integration_id` but received {integration_id!r}")
+ return self._get(
+ f"/integrations/{integration_id}/revoke",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=IntegrationRevokeResponse,
+ )
+
class AsyncIntegrationsResource(AsyncAPIResource):
@cached_property
@@ -97,11 +207,114 @@ def with_streaming_response(self) -> AsyncIntegrationsResourceWithStreamingRespo
"""
return AsyncIntegrationsResourceWithStreamingResponse(self)
+ async def list(
+ self,
+ *,
+ # 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,
+ ) -> IntegrationListResponse:
+ """List all integrations for the user."""
+ return await self._get(
+ "/integrations/list",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=IntegrationListResponse,
+ )
+
+ async def connect(
+ self,
+ integration_id: str,
+ *,
+ redirect_url: Optional[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,
+ ) -> IntegrationConnectResponse:
+ """
+ Redirects to the connect URL to link an integration.
+
+ 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 integration_id:
+ raise ValueError(f"Expected a non-empty value for `integration_id` but received {integration_id!r}")
+ return await self._get(
+ f"/integrations/{integration_id}/connect",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"redirect_url": redirect_url}, integration_connect_params.IntegrationConnectParams
+ ),
+ ),
+ cast_to=IntegrationConnectResponse,
+ )
+
+ async def revoke(
+ self,
+ integration_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,
+ ) -> IntegrationRevokeResponse:
+ """
+ Revokes Hyperspell's access the given provider and deletes all stored
+ credentials and indexed data.
+
+ 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 integration_id:
+ raise ValueError(f"Expected a non-empty value for `integration_id` but received {integration_id!r}")
+ return await self._get(
+ f"/integrations/{integration_id}/revoke",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=IntegrationRevokeResponse,
+ )
+
class IntegrationsResourceWithRawResponse:
def __init__(self, integrations: IntegrationsResource) -> None:
self._integrations = integrations
+ self.list = to_raw_response_wrapper(
+ integrations.list,
+ )
+ self.connect = to_raw_response_wrapper(
+ integrations.connect,
+ )
+ self.revoke = to_raw_response_wrapper(
+ integrations.revoke,
+ )
+
@cached_property
def google_calendar(self) -> GoogleCalendarResourceWithRawResponse:
return GoogleCalendarResourceWithRawResponse(self._integrations.google_calendar)
@@ -119,6 +332,16 @@ class AsyncIntegrationsResourceWithRawResponse:
def __init__(self, integrations: AsyncIntegrationsResource) -> None:
self._integrations = integrations
+ self.list = async_to_raw_response_wrapper(
+ integrations.list,
+ )
+ self.connect = async_to_raw_response_wrapper(
+ integrations.connect,
+ )
+ self.revoke = async_to_raw_response_wrapper(
+ integrations.revoke,
+ )
+
@cached_property
def google_calendar(self) -> AsyncGoogleCalendarResourceWithRawResponse:
return AsyncGoogleCalendarResourceWithRawResponse(self._integrations.google_calendar)
@@ -136,6 +359,16 @@ class IntegrationsResourceWithStreamingResponse:
def __init__(self, integrations: IntegrationsResource) -> None:
self._integrations = integrations
+ self.list = to_streamed_response_wrapper(
+ integrations.list,
+ )
+ self.connect = to_streamed_response_wrapper(
+ integrations.connect,
+ )
+ self.revoke = to_streamed_response_wrapper(
+ integrations.revoke,
+ )
+
@cached_property
def google_calendar(self) -> GoogleCalendarResourceWithStreamingResponse:
return GoogleCalendarResourceWithStreamingResponse(self._integrations.google_calendar)
@@ -153,6 +386,16 @@ class AsyncIntegrationsResourceWithStreamingResponse:
def __init__(self, integrations: AsyncIntegrationsResource) -> None:
self._integrations = integrations
+ self.list = async_to_streamed_response_wrapper(
+ integrations.list,
+ )
+ self.connect = async_to_streamed_response_wrapper(
+ integrations.connect,
+ )
+ self.revoke = async_to_streamed_response_wrapper(
+ integrations.revoke,
+ )
+
@cached_property
def google_calendar(self) -> AsyncGoogleCalendarResourceWithStreamingResponse:
return AsyncGoogleCalendarResourceWithStreamingResponse(self._integrations.google_calendar)
diff --git a/src/hyperspell/types/__init__.py b/src/hyperspell/types/__init__.py
index bf8028b9..5f3077cf 100644
--- a/src/hyperspell/types/__init__.py
+++ b/src/hyperspell/types/__init__.py
@@ -17,7 +17,11 @@
from .memory_delete_response import MemoryDeleteResponse as MemoryDeleteResponse
from .memory_status_response import MemoryStatusResponse as MemoryStatusResponse
from .auth_delete_user_response import AuthDeleteUserResponse as AuthDeleteUserResponse
+from .integration_list_response import IntegrationListResponse as IntegrationListResponse
+from .integration_connect_params import IntegrationConnectParams as IntegrationConnectParams
from .evaluate_score_query_params import EvaluateScoreQueryParams as EvaluateScoreQueryParams
+from .integration_revoke_response import IntegrationRevokeResponse as IntegrationRevokeResponse
+from .integration_connect_response import IntegrationConnectResponse as IntegrationConnectResponse
from .evaluate_score_query_response import EvaluateScoreQueryResponse as EvaluateScoreQueryResponse
from .evaluate_score_highlight_params import EvaluateScoreHighlightParams as EvaluateScoreHighlightParams
from .evaluate_score_highlight_response import EvaluateScoreHighlightResponse as EvaluateScoreHighlightResponse
diff --git a/src/hyperspell/types/integration_connect_params.py b/src/hyperspell/types/integration_connect_params.py
new file mode 100644
index 00000000..02eedc83
--- /dev/null
+++ b/src/hyperspell/types/integration_connect_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 Optional
+from typing_extensions import TypedDict
+
+__all__ = ["IntegrationConnectParams"]
+
+
+class IntegrationConnectParams(TypedDict, total=False):
+ redirect_url: Optional[str]
diff --git a/src/hyperspell/types/integration_connect_response.py b/src/hyperspell/types/integration_connect_response.py
new file mode 100644
index 00000000..b403c918
--- /dev/null
+++ b/src/hyperspell/types/integration_connect_response.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+
+from .._models import BaseModel
+
+__all__ = ["IntegrationConnectResponse"]
+
+
+class IntegrationConnectResponse(BaseModel):
+ expires_at: datetime
+
+ url: str
diff --git a/src/hyperspell/types/integration_list_response.py b/src/hyperspell/types/integration_list_response.py
new file mode 100644
index 00000000..36c8fed7
--- /dev/null
+++ b/src/hyperspell/types/integration_list_response.py
@@ -0,0 +1,70 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["IntegrationListResponse", "Integration"]
+
+
+class Integration(BaseModel):
+ id: str
+ """The integration's id"""
+
+ allow_multiple_connections: bool
+ """Whether the integration allows multiple connections"""
+
+ provider: Literal[
+ "collections",
+ "vault",
+ "web_crawler",
+ "notion",
+ "slack",
+ "google_calendar",
+ "reddit",
+ "box",
+ "google_drive",
+ "airtable",
+ "algolia",
+ "amplitude",
+ "asana",
+ "ashby",
+ "bamboohr",
+ "basecamp",
+ "bubbles",
+ "calendly",
+ "confluence",
+ "clickup",
+ "datadog",
+ "deel",
+ "discord",
+ "dropbox",
+ "exa",
+ "facebook",
+ "front",
+ "github",
+ "gitlab",
+ "google_docs",
+ "google_mail",
+ "google_sheet",
+ "hubspot",
+ "jira",
+ "linear",
+ "microsoft_teams",
+ "mixpanel",
+ "monday",
+ "outlook",
+ "perplexity",
+ "rippling",
+ "salesforce",
+ "segment",
+ "todoist",
+ "twitter",
+ "zoom",
+ ]
+ """The integration's provider"""
+
+
+class IntegrationListResponse(BaseModel):
+ integrations: List[Integration]
diff --git a/src/hyperspell/types/integration_revoke_response.py b/src/hyperspell/types/integration_revoke_response.py
new file mode 100644
index 00000000..2385ca96
--- /dev/null
+++ b/src/hyperspell/types/integration_revoke_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["IntegrationRevokeResponse"]
+
+
+class IntegrationRevokeResponse(BaseModel):
+ message: str
+
+ success: bool
diff --git a/tests/api_resources/test_integrations.py b/tests/api_resources/test_integrations.py
new file mode 100644
index 00000000..3b2934d7
--- /dev/null
+++ b/tests/api_resources/test_integrations.py
@@ -0,0 +1,246 @@
+# 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 hyperspell import Hyperspell, AsyncHyperspell
+from tests.utils import assert_matches_type
+from hyperspell.types import (
+ IntegrationListResponse,
+ IntegrationRevokeResponse,
+ IntegrationConnectResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestIntegrations:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Hyperspell) -> None:
+ integration = client.integrations.list()
+ assert_matches_type(IntegrationListResponse, integration, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Hyperspell) -> None:
+ response = client.integrations.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ integration = response.parse()
+ assert_matches_type(IntegrationListResponse, integration, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Hyperspell) -> None:
+ with client.integrations.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ integration = response.parse()
+ assert_matches_type(IntegrationListResponse, integration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_connect(self, client: Hyperspell) -> None:
+ integration = client.integrations.connect(
+ integration_id="integration_id",
+ )
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ @parametrize
+ def test_method_connect_with_all_params(self, client: Hyperspell) -> None:
+ integration = client.integrations.connect(
+ integration_id="integration_id",
+ redirect_url="redirect_url",
+ )
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ @parametrize
+ def test_raw_response_connect(self, client: Hyperspell) -> None:
+ response = client.integrations.with_raw_response.connect(
+ integration_id="integration_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ integration = response.parse()
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ @parametrize
+ def test_streaming_response_connect(self, client: Hyperspell) -> None:
+ with client.integrations.with_streaming_response.connect(
+ integration_id="integration_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ integration = response.parse()
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_connect(self, client: Hyperspell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `integration_id` but received ''"):
+ client.integrations.with_raw_response.connect(
+ integration_id="",
+ )
+
+ @parametrize
+ def test_method_revoke(self, client: Hyperspell) -> None:
+ integration = client.integrations.revoke(
+ "integration_id",
+ )
+ assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
+
+ @parametrize
+ def test_raw_response_revoke(self, client: Hyperspell) -> None:
+ response = client.integrations.with_raw_response.revoke(
+ "integration_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ integration = response.parse()
+ assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
+
+ @parametrize
+ def test_streaming_response_revoke(self, client: Hyperspell) -> None:
+ with client.integrations.with_streaming_response.revoke(
+ "integration_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ integration = response.parse()
+ assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_revoke(self, client: Hyperspell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `integration_id` but received ''"):
+ client.integrations.with_raw_response.revoke(
+ "",
+ )
+
+
+class TestAsyncIntegrations:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncHyperspell) -> None:
+ integration = await async_client.integrations.list()
+ assert_matches_type(IntegrationListResponse, integration, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncHyperspell) -> None:
+ response = await async_client.integrations.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ integration = await response.parse()
+ assert_matches_type(IntegrationListResponse, integration, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncHyperspell) -> None:
+ async with async_client.integrations.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ integration = await response.parse()
+ assert_matches_type(IntegrationListResponse, integration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_connect(self, async_client: AsyncHyperspell) -> None:
+ integration = await async_client.integrations.connect(
+ integration_id="integration_id",
+ )
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ @parametrize
+ async def test_method_connect_with_all_params(self, async_client: AsyncHyperspell) -> None:
+ integration = await async_client.integrations.connect(
+ integration_id="integration_id",
+ redirect_url="redirect_url",
+ )
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ @parametrize
+ async def test_raw_response_connect(self, async_client: AsyncHyperspell) -> None:
+ response = await async_client.integrations.with_raw_response.connect(
+ integration_id="integration_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ integration = await response.parse()
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_connect(self, async_client: AsyncHyperspell) -> None:
+ async with async_client.integrations.with_streaming_response.connect(
+ integration_id="integration_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ integration = await response.parse()
+ assert_matches_type(IntegrationConnectResponse, integration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_connect(self, async_client: AsyncHyperspell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `integration_id` but received ''"):
+ await async_client.integrations.with_raw_response.connect(
+ integration_id="",
+ )
+
+ @parametrize
+ async def test_method_revoke(self, async_client: AsyncHyperspell) -> None:
+ integration = await async_client.integrations.revoke(
+ "integration_id",
+ )
+ assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
+
+ @parametrize
+ async def test_raw_response_revoke(self, async_client: AsyncHyperspell) -> None:
+ response = await async_client.integrations.with_raw_response.revoke(
+ "integration_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ integration = await response.parse()
+ assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_revoke(self, async_client: AsyncHyperspell) -> None:
+ async with async_client.integrations.with_streaming_response.revoke(
+ "integration_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ integration = await response.parse()
+ assert_matches_type(IntegrationRevokeResponse, integration, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_revoke(self, async_client: AsyncHyperspell) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `integration_id` but received ''"):
+ await async_client.integrations.with_raw_response.revoke(
+ "",
+ )
From 518979e489f651145412475c7c262a56f7d3a72b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 02:04:43 +0000
Subject: [PATCH 07/11] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 5bed2d49..087a23d9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 20
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-cd8c28747615d8967e4e20e6fd5b9488a3022fece37f1c4c133c9b8d9c4415f3.yml
openapi_spec_hash: 2aa6c5d6faa2cbd4038108b5ebc103b3
-config_hash: 331712c9dfb31af34bdab84fd3f7d48d
+config_hash: 2b006dd296f0513ea19fc9651203c8d7
From ac6181890c3248491c96e3efabdfcab9084f6094 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 02:06:52 +0000
Subject: [PATCH 08/11] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 087a23d9..2bc8b2ff 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 20
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-cd8c28747615d8967e4e20e6fd5b9488a3022fece37f1c4c133c9b8d9c4415f3.yml
openapi_spec_hash: 2aa6c5d6faa2cbd4038108b5ebc103b3
-config_hash: 2b006dd296f0513ea19fc9651203c8d7
+config_hash: 2dca0734f963a72148ceeab9e97077e9
From 1f502f0278a7c35e76cbdd8b18b0bb3ab8f69287 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 02:09:11 +0000
Subject: [PATCH 09/11] feat(api): update via SDK Studio
---
.stats.yml | 2 +-
api.md | 2 +-
src/hyperspell/types/integrations/__init__.py | 1 +
src/hyperspell/types/integrations/not_given_param.py | 9 +++++++++
src/hyperspell/types/memory_search_params.py | 3 ++-
5 files changed, 14 insertions(+), 3 deletions(-)
create mode 100644 src/hyperspell/types/integrations/not_given_param.py
diff --git a/.stats.yml b/.stats.yml
index 2bc8b2ff..895dc795 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 20
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-cd8c28747615d8967e4e20e6fd5b9488a3022fece37f1c4c133c9b8d9c4415f3.yml
openapi_spec_hash: 2aa6c5d6faa2cbd4038108b5ebc103b3
-config_hash: 2dca0734f963a72148ceeab9e97077e9
+config_hash: 34753d74b4ed6e7aa69608d2daafb50d
diff --git a/api.md b/api.md
index a0af7c08..73b21591 100644
--- a/api.md
+++ b/api.md
@@ -39,7 +39,7 @@ Methods:
Types:
```python
-from hyperspell.types.integrations import WebCrawlerIndexResponse
+from hyperspell.types.integrations import NotGiven, WebCrawlerIndexResponse
```
Methods:
diff --git a/src/hyperspell/types/integrations/__init__.py b/src/hyperspell/types/integrations/__init__.py
index d0911f57..66570604 100644
--- a/src/hyperspell/types/integrations/__init__.py
+++ b/src/hyperspell/types/integrations/__init__.py
@@ -3,6 +3,7 @@
from __future__ import annotations
from .calendar import Calendar as Calendar
+from .not_given_param import NotGivenParam as NotGivenParam
from .slack_list_params import SlackListParams as SlackListParams
from .web_crawler_index_params import WebCrawlerIndexParams as WebCrawlerIndexParams
from .web_crawler_index_response import WebCrawlerIndexResponse as WebCrawlerIndexResponse
diff --git a/src/hyperspell/types/integrations/not_given_param.py b/src/hyperspell/types/integrations/not_given_param.py
new file mode 100644
index 00000000..d34df15c
--- /dev/null
+++ b/src/hyperspell/types/integrations/not_given_param.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypeAlias
+
+__all__ = ["NotGivenParam"]
+
+NotGivenParam: TypeAlias = object
diff --git a/src/hyperspell/types/memory_search_params.py b/src/hyperspell/types/memory_search_params.py
index 07e692a2..7e9ddb4c 100644
--- a/src/hyperspell/types/memory_search_params.py
+++ b/src/hyperspell/types/memory_search_params.py
@@ -8,6 +8,7 @@
from .._types import SequenceNotStr
from .._utils import PropertyInfo
+from .integrations.not_given_param import NotGivenParam
__all__ = [
"MemorySearchParams",
@@ -279,7 +280,7 @@ class OptionsWebCrawler(TypedDict, total=False):
max_depth: int
"""Maximum depth to crawl from the starting URL"""
- url: Union[str, object]
+ url: Union[str, NotGivenParam]
"""The URL to crawl"""
weight: float
From 634025ac77ffe7b2691e53800ee0915dae55e486 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 02:10:09 +0000
Subject: [PATCH 10/11] feat(api): update via SDK Studio
---
.stats.yml | 2 +-
api.md | 2 +-
src/hyperspell/types/integrations/__init__.py | 1 -
src/hyperspell/types/integrations/not_given_param.py | 9 ---------
src/hyperspell/types/memory_search_params.py | 3 +--
5 files changed, 3 insertions(+), 14 deletions(-)
delete mode 100644 src/hyperspell/types/integrations/not_given_param.py
diff --git a/.stats.yml b/.stats.yml
index 895dc795..06232146 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 20
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-cd8c28747615d8967e4e20e6fd5b9488a3022fece37f1c4c133c9b8d9c4415f3.yml
openapi_spec_hash: 2aa6c5d6faa2cbd4038108b5ebc103b3
-config_hash: 34753d74b4ed6e7aa69608d2daafb50d
+config_hash: e29127278ff246754ce4801403db0cd9
diff --git a/api.md b/api.md
index 73b21591..a0af7c08 100644
--- a/api.md
+++ b/api.md
@@ -39,7 +39,7 @@ Methods:
Types:
```python
-from hyperspell.types.integrations import NotGiven, WebCrawlerIndexResponse
+from hyperspell.types.integrations import WebCrawlerIndexResponse
```
Methods:
diff --git a/src/hyperspell/types/integrations/__init__.py b/src/hyperspell/types/integrations/__init__.py
index 66570604..d0911f57 100644
--- a/src/hyperspell/types/integrations/__init__.py
+++ b/src/hyperspell/types/integrations/__init__.py
@@ -3,7 +3,6 @@
from __future__ import annotations
from .calendar import Calendar as Calendar
-from .not_given_param import NotGivenParam as NotGivenParam
from .slack_list_params import SlackListParams as SlackListParams
from .web_crawler_index_params import WebCrawlerIndexParams as WebCrawlerIndexParams
from .web_crawler_index_response import WebCrawlerIndexResponse as WebCrawlerIndexResponse
diff --git a/src/hyperspell/types/integrations/not_given_param.py b/src/hyperspell/types/integrations/not_given_param.py
deleted file mode 100644
index d34df15c..00000000
--- a/src/hyperspell/types/integrations/not_given_param.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypeAlias
-
-__all__ = ["NotGivenParam"]
-
-NotGivenParam: TypeAlias = object
diff --git a/src/hyperspell/types/memory_search_params.py b/src/hyperspell/types/memory_search_params.py
index 7e9ddb4c..07e692a2 100644
--- a/src/hyperspell/types/memory_search_params.py
+++ b/src/hyperspell/types/memory_search_params.py
@@ -8,7 +8,6 @@
from .._types import SequenceNotStr
from .._utils import PropertyInfo
-from .integrations.not_given_param import NotGivenParam
__all__ = [
"MemorySearchParams",
@@ -280,7 +279,7 @@ class OptionsWebCrawler(TypedDict, total=False):
max_depth: int
"""Maximum depth to crawl from the starting URL"""
- url: Union[str, NotGivenParam]
+ url: Union[str, object]
"""The URL to crawl"""
weight: float
From 37ff6e707acc7bbd2830c83b807399dae59c88a6 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 14 Oct 2025 02:10:24 +0000
Subject: [PATCH 11/11] release: 0.26.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 17 +++++++++++++++++
pyproject.toml | 2 +-
src/hyperspell/_version.py | 2 +-
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index a36746b8..caf5ca3f 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.25.0"
+ ".": "0.26.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec94995a..ea68271c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,22 @@
# Changelog
+## 0.26.0 (2025-10-14)
+
+Full Changelog: [v0.25.0...v0.26.0](https://github.com/hyperspell/python-sdk/compare/v0.25.0...v0.26.0)
+
+### Features
+
+* **api:** api update ([9f27d7f](https://github.com/hyperspell/python-sdk/commit/9f27d7f462d15b54cf1aa62e962da1d34a03e616))
+* **api:** api update ([476c23d](https://github.com/hyperspell/python-sdk/commit/476c23d01aae74bc13013d71e32430264d45bab1))
+* **api:** update via SDK Studio ([634025a](https://github.com/hyperspell/python-sdk/commit/634025ac77ffe7b2691e53800ee0915dae55e486))
+* **api:** update via SDK Studio ([1f502f0](https://github.com/hyperspell/python-sdk/commit/1f502f0278a7c35e76cbdd8b18b0bb3ab8f69287))
+* **api:** update via SDK Studio ([df1dc5d](https://github.com/hyperspell/python-sdk/commit/df1dc5d547313a241604e554cf515d904ad196a6))
+
+
+### Chores
+
+* **internal:** detect missing future annotations with ruff ([210e641](https://github.com/hyperspell/python-sdk/commit/210e641ade71c871f0f80f1c0a0cc043169be302))
+
## 0.25.0 (2025-09-29)
Full Changelog: [v0.22.1...v0.25.0](https://github.com/hyperspell/python-sdk/compare/v0.22.1...v0.25.0)
diff --git a/pyproject.toml b/pyproject.toml
index 6c70ed58..1889a095 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "hyperspell"
-version = "0.25.0"
+version = "0.26.0"
description = "The official Python library for the hyperspell API"
dynamic = ["readme"]
license = "MIT"
diff --git a/src/hyperspell/_version.py b/src/hyperspell/_version.py
index 1b27d30f..d4a6d30b 100644
--- a/src/hyperspell/_version.py
+++ b/src/hyperspell/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "hyperspell"
-__version__ = "0.25.0" # x-release-please-version
+__version__ = "0.26.0" # x-release-please-version