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