diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d52d2b97..b4e9013b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.0" + ".": "0.16.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index fd6cf3f6..6b2619bf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 10 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-287b83fd66b657b044f4ab280ab0e72a2ed72c0da50e4a7d09ce98123982262f.yml -openapi_spec_hash: fcef51b5cf5e602a2d8025546e27e24a -config_hash: a39dfe90372d06d735dfb3d27b30409f +configured_endpoints: 12 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-472f6034747ca75f970d64e57875f1cb24991ad422e17f3e9839757b84e2cb3d.yml +openapi_spec_hash: 9759125c6a0c64da09c94923667f34a5 +config_hash: da009f16a6b9b4db17be2949180ace1e diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ebd15c3..db238388 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.16.0 (2025-05-29) + +Full Changelog: [v0.13.0...v0.16.0](https://github.com/hyperspell/python-sdk/compare/v0.13.0...v0.16.0) + +### Features + +* **api:** api update ([3334f14](https://github.com/hyperspell/python-sdk/commit/3334f14582bda6ec78c9b479317c8d818b1c1227)) +* **api:** api update ([b6ad9f4](https://github.com/hyperspell/python-sdk/commit/b6ad9f43113a8cbf23580027c37ecaf95cb37cb3)) +* **api:** update via SDK Studio ([bff74c9](https://github.com/hyperspell/python-sdk/commit/bff74c98b5b08e45e291381753340a22c6b04c89)) + ## 0.13.0 (2025-05-26) Full Changelog: [v0.12.0...v0.13.0](https://github.com/hyperspell/python-sdk/compare/v0.12.0...v0.13.0) diff --git a/api.md b/api.md index e5aee0a0..c8fcbbc2 100644 --- a/api.md +++ b/api.md @@ -39,13 +39,15 @@ Methods: Types: ```python -from hyperspell.types import DocumentStatus, DocumentListResponse +from hyperspell.types import Document, DocumentStatus, DocumentStatusResponse ``` Methods: -- client.documents.list(\*\*params) -> SyncCursorPage[DocumentListResponse] +- client.documents.list(\*\*params) -> SyncCursorPage[Document] - client.documents.add(\*\*params) -> DocumentStatus +- client.documents.get(resource_id, \*, source) -> Document +- client.documents.status() -> DocumentStatusResponse - client.documents.upload(\*\*params) -> DocumentStatus # Collections diff --git a/pyproject.toml b/pyproject.toml index 5e390d44..01599def 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "hyperspell" -version = "0.13.0" +version = "0.16.0" description = "The official Python library for the hyperspell API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/hyperspell/_version.py b/src/hyperspell/_version.py index 58ec2dd0..1d221945 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.13.0" # x-release-please-version +__version__ = "0.16.0" # x-release-please-version diff --git a/src/hyperspell/resources/auth.py b/src/hyperspell/resources/auth.py index c579a191..b9e17f87 100644 --- a/src/hyperspell/resources/auth.py +++ b/src/hyperspell/resources/auth.py @@ -2,6 +2,8 @@ from __future__ import annotations +from typing import Optional + import httpx from ..types import auth_user_token_params @@ -65,6 +67,7 @@ def user_token( self, *, user_id: str, + expires_in: Optional[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -78,6 +81,8 @@ def user_token( safely passed to your user-facing front-end. Args: + expires_in: Token lifetime, e.g., '30m', '2h', '1d'. Defaults to 24 hours if not provided. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -88,7 +93,13 @@ def user_token( """ return self._post( "/auth/user_token", - body=maybe_transform({"user_id": user_id}, auth_user_token_params.AuthUserTokenParams), + body=maybe_transform( + { + "user_id": user_id, + "expires_in": expires_in, + }, + auth_user_token_params.AuthUserTokenParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -139,6 +150,7 @@ async def user_token( self, *, user_id: str, + expires_in: Optional[str] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -152,6 +164,8 @@ async def user_token( safely passed to your user-facing front-end. Args: + expires_in: Token lifetime, e.g., '30m', '2h', '1d'. Defaults to 24 hours if not provided. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -162,7 +176,13 @@ async def user_token( """ return await self._post( "/auth/user_token", - body=await async_maybe_transform({"user_id": user_id}, auth_user_token_params.AuthUserTokenParams), + body=await async_maybe_transform( + { + "user_id": user_id, + "expires_in": expires_in, + }, + auth_user_token_params.AuthUserTokenParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/hyperspell/resources/documents.py b/src/hyperspell/resources/documents.py index 8b35d2e2..eda88282 100644 --- a/src/hyperspell/resources/documents.py +++ b/src/hyperspell/resources/documents.py @@ -4,6 +4,7 @@ from typing import Union, Mapping, Optional, cast from datetime import datetime +from typing_extensions import Literal import httpx @@ -20,8 +21,9 @@ ) from ..pagination import SyncCursorPage, AsyncCursorPage from .._base_client import AsyncPaginator, make_request_options +from ..types.document import Document from ..types.document_status import DocumentStatus -from ..types.document_list_response import DocumentListResponse +from ..types.document_status_response import DocumentStatusResponse __all__ = ["DocumentsResource", "AsyncDocumentsResource"] @@ -52,13 +54,63 @@ def list( collection: Optional[str] | NotGiven = NOT_GIVEN, cursor: Optional[str] | NotGiven = NOT_GIVEN, size: int | NotGiven = NOT_GIVEN, + source: Optional[ + Literal[ + "collections", + "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", + ] + ] + | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> SyncCursorPage[DocumentListResponse]: + ) -> SyncCursorPage[Document]: """This endpoint allows you to paginate through all documents in the index. You can @@ -67,6 +119,8 @@ def list( Args: collection: Filter documents by collection. + source: Filter documents by source. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -77,7 +131,7 @@ def list( """ return self._get_api_list( "/documents/list", - page=SyncCursorPage[DocumentListResponse], + page=SyncCursorPage[Document], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -88,11 +142,12 @@ def list( "collection": collection, "cursor": cursor, "size": size, + "source": source, }, document_list_params.DocumentListParams, ), ), - model=DocumentListResponse, + model=Document, ) def add( @@ -152,6 +207,110 @@ def add( cast_to=DocumentStatus, ) + def get( + self, + resource_id: str, + *, + source: Literal[ + "collections", + "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", + ], + # 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, + ) -> Document: + """ + Retrieves a document by provider and resource_id. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not source: + raise ValueError(f"Expected a non-empty value for `source` but received {source!r}") + if not resource_id: + raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}") + return self._get( + f"/documents/get/{source}/{resource_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Document, + ) + + def status( + 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, + ) -> DocumentStatusResponse: + """ + This endpoint shows the indexing progress of documents, both by provider and + total. + """ + return self._get( + "/documents/status", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DocumentStatusResponse, + ) + def upload( self, *, @@ -232,13 +391,63 @@ def list( collection: Optional[str] | NotGiven = NOT_GIVEN, cursor: Optional[str] | NotGiven = NOT_GIVEN, size: int | NotGiven = NOT_GIVEN, + source: Optional[ + Literal[ + "collections", + "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", + ] + ] + | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[DocumentListResponse, AsyncCursorPage[DocumentListResponse]]: + ) -> AsyncPaginator[Document, AsyncCursorPage[Document]]: """This endpoint allows you to paginate through all documents in the index. You can @@ -247,6 +456,8 @@ def list( Args: collection: Filter documents by collection. + source: Filter documents by source. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -257,7 +468,7 @@ def list( """ return self._get_api_list( "/documents/list", - page=AsyncCursorPage[DocumentListResponse], + page=AsyncCursorPage[Document], options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, @@ -268,11 +479,12 @@ def list( "collection": collection, "cursor": cursor, "size": size, + "source": source, }, document_list_params.DocumentListParams, ), ), - model=DocumentListResponse, + model=Document, ) async def add( @@ -332,6 +544,110 @@ async def add( cast_to=DocumentStatus, ) + async def get( + self, + resource_id: str, + *, + source: Literal[ + "collections", + "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", + ], + # 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, + ) -> Document: + """ + Retrieves a document by provider and resource_id. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not source: + raise ValueError(f"Expected a non-empty value for `source` but received {source!r}") + if not resource_id: + raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}") + return await self._get( + f"/documents/get/{source}/{resource_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Document, + ) + + async def status( + 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, + ) -> DocumentStatusResponse: + """ + This endpoint shows the indexing progress of documents, both by provider and + total. + """ + return await self._get( + "/documents/status", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=DocumentStatusResponse, + ) + async def upload( self, *, @@ -396,6 +712,12 @@ def __init__(self, documents: DocumentsResource) -> None: self.add = to_raw_response_wrapper( documents.add, ) + self.get = to_raw_response_wrapper( + documents.get, + ) + self.status = to_raw_response_wrapper( + documents.status, + ) self.upload = to_raw_response_wrapper( documents.upload, ) @@ -411,6 +733,12 @@ def __init__(self, documents: AsyncDocumentsResource) -> None: self.add = async_to_raw_response_wrapper( documents.add, ) + self.get = async_to_raw_response_wrapper( + documents.get, + ) + self.status = async_to_raw_response_wrapper( + documents.status, + ) self.upload = async_to_raw_response_wrapper( documents.upload, ) @@ -426,6 +754,12 @@ def __init__(self, documents: DocumentsResource) -> None: self.add = to_streamed_response_wrapper( documents.add, ) + self.get = to_streamed_response_wrapper( + documents.get, + ) + self.status = to_streamed_response_wrapper( + documents.status, + ) self.upload = to_streamed_response_wrapper( documents.upload, ) @@ -441,6 +775,12 @@ def __init__(self, documents: AsyncDocumentsResource) -> None: self.add = async_to_streamed_response_wrapper( documents.add, ) + self.get = async_to_streamed_response_wrapper( + documents.get, + ) + self.status = async_to_streamed_response_wrapper( + documents.status, + ) self.upload = async_to_streamed_response_wrapper( documents.upload, ) diff --git a/src/hyperspell/types/__init__.py b/src/hyperspell/types/__init__.py index 178fb32e..4027566b 100644 --- a/src/hyperspell/types/__init__.py +++ b/src/hyperspell/types/__init__.py @@ -3,6 +3,7 @@ from __future__ import annotations from .token import Token as Token +from .document import Document as Document from .document_status import DocumentStatus as DocumentStatus from .auth_me_response import AuthMeResponse as AuthMeResponse from .document_add_params import DocumentAddParams as DocumentAddParams @@ -11,7 +12,7 @@ from .query_search_response import QuerySearchResponse as QuerySearchResponse from .auth_user_token_params import AuthUserTokenParams as AuthUserTokenParams from .collection_list_params import CollectionListParams as CollectionListParams -from .document_list_response import DocumentListResponse as DocumentListResponse from .document_upload_params import DocumentUploadParams as DocumentUploadParams from .collection_list_response import CollectionListResponse as CollectionListResponse +from .document_status_response import DocumentStatusResponse as DocumentStatusResponse from .integration_revoke_response import IntegrationRevokeResponse as IntegrationRevokeResponse diff --git a/src/hyperspell/types/auth_user_token_params.py b/src/hyperspell/types/auth_user_token_params.py index b1e44fdc..fa7cc949 100644 --- a/src/hyperspell/types/auth_user_token_params.py +++ b/src/hyperspell/types/auth_user_token_params.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Optional from typing_extensions import Required, TypedDict __all__ = ["AuthUserTokenParams"] @@ -9,3 +10,6 @@ class AuthUserTokenParams(TypedDict, total=False): user_id: Required[str] + + expires_in: Optional[str] + """Token lifetime, e.g., '30m', '2h', '1d'. Defaults to 24 hours if not provided.""" diff --git a/src/hyperspell/types/document_list_response.py b/src/hyperspell/types/document.py similarity index 78% rename from src/hyperspell/types/document_list_response.py rename to src/hyperspell/types/document.py index de9f9bf8..69eab7b2 100644 --- a/src/hyperspell/types/document_list_response.py +++ b/src/hyperspell/types/document.py @@ -1,20 +1,30 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, List, Optional from datetime import datetime from typing_extensions import Literal from .._models import BaseModel -__all__ = ["DocumentListResponse", "Metadata"] +__all__ = ["Document", "Metadata", "MetadataEvent"] + + +class MetadataEvent(BaseModel): + message: str + + type: Literal["error", "warning", "info", "success"] + + time: Optional[datetime] = None class Metadata(BaseModel): - created_at: Optional[datetime] = None + events: Optional[List[MetadataEvent]] = None + + indexed_at: Optional[datetime] = None last_modified: Optional[datetime] = None - url: Optional[str] = None + status: Optional[Literal["pending", "processing", "completed", "failed"]] = None if TYPE_CHECKING: # Stub to indicate that arbitrary properties are accepted. @@ -23,7 +33,7 @@ class Metadata(BaseModel): def __getattr__(self, attr: str) -> object: ... -class DocumentListResponse(BaseModel): +class Document(BaseModel): resource_id: str source: Literal[ diff --git a/src/hyperspell/types/document_list_params.py b/src/hyperspell/types/document_list_params.py index 6d142ffc..53440ca9 100644 --- a/src/hyperspell/types/document_list_params.py +++ b/src/hyperspell/types/document_list_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Optional -from typing_extensions import TypedDict +from typing_extensions import Literal, TypedDict __all__ = ["DocumentListParams"] @@ -15,3 +15,54 @@ class DocumentListParams(TypedDict, total=False): cursor: Optional[str] size: int + + source: Optional[ + Literal[ + "collections", + "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", + ] + ] + """Filter documents by source.""" diff --git a/src/hyperspell/types/document_status_response.py b/src/hyperspell/types/document_status_response.py new file mode 100644 index 00000000..022be1c7 --- /dev/null +++ b/src/hyperspell/types/document_status_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict + +from .._models import BaseModel + +__all__ = ["DocumentStatusResponse"] + + +class DocumentStatusResponse(BaseModel): + providers: Dict[str, Dict[str, int]] + + total: Dict[str, int] diff --git a/src/hyperspell/types/query_search_response.py b/src/hyperspell/types/query_search_response.py index 498aa516..e02d76d4 100644 --- a/src/hyperspell/types/query_search_response.py +++ b/src/hyperspell/types/query_search_response.py @@ -1,83 +1,11 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import TYPE_CHECKING, Dict, List, Optional -from datetime import datetime -from typing_extensions import Literal +from typing import Dict, List, Optional from .._models import BaseModel +from .document import Document -__all__ = ["QuerySearchResponse", "Document", "DocumentMetadata"] - - -class DocumentMetadata(BaseModel): - created_at: Optional[datetime] = None - - last_modified: Optional[datetime] = None - - url: Optional[str] = None - - if TYPE_CHECKING: - # Stub to indicate that arbitrary properties are accepted. - # To access properties that are not valid identifiers you can use `getattr`, e.g. - # `getattr(obj, '$type')` - def __getattr__(self, attr: str) -> object: ... - - -class Document(BaseModel): - resource_id: str - - source: Literal[ - "collections", - "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", - ] - - metadata: Optional[DocumentMetadata] = None - - score: Optional[float] = None - """The relevance of the resource to the query""" +__all__ = ["QuerySearchResponse"] class QuerySearchResponse(BaseModel): diff --git a/tests/api_resources/test_auth.py b/tests/api_resources/test_auth.py index a609ea76..e4207ba8 100644 --- a/tests/api_resources/test_auth.py +++ b/tests/api_resources/test_auth.py @@ -49,6 +49,14 @@ def test_method_user_token(self, client: Hyperspell) -> None: ) assert_matches_type(Token, auth, path=["response"]) + @parametrize + def test_method_user_token_with_all_params(self, client: Hyperspell) -> None: + auth = client.auth.user_token( + user_id="user_id", + expires_in="30m", + ) + assert_matches_type(Token, auth, path=["response"]) + @parametrize def test_raw_response_user_token(self, client: Hyperspell) -> None: response = client.auth.with_raw_response.user_token( @@ -109,6 +117,14 @@ async def test_method_user_token(self, async_client: AsyncHyperspell) -> None: ) assert_matches_type(Token, auth, path=["response"]) + @parametrize + async def test_method_user_token_with_all_params(self, async_client: AsyncHyperspell) -> None: + auth = await async_client.auth.user_token( + user_id="user_id", + expires_in="30m", + ) + assert_matches_type(Token, auth, path=["response"]) + @parametrize async def test_raw_response_user_token(self, async_client: AsyncHyperspell) -> None: response = await async_client.auth.with_raw_response.user_token( diff --git a/tests/api_resources/test_documents.py b/tests/api_resources/test_documents.py index 37d3c95a..5f4260a5 100644 --- a/tests/api_resources/test_documents.py +++ b/tests/api_resources/test_documents.py @@ -10,8 +10,9 @@ from hyperspell import Hyperspell, AsyncHyperspell from tests.utils import assert_matches_type from hyperspell.types import ( + Document, DocumentStatus, - DocumentListResponse, + DocumentStatusResponse, ) from hyperspell._utils import parse_datetime from hyperspell.pagination import SyncCursorPage, AsyncCursorPage @@ -25,7 +26,7 @@ class TestDocuments: @parametrize def test_method_list(self, client: Hyperspell) -> None: document = client.documents.list() - assert_matches_type(SyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(SyncCursorPage[Document], document, path=["response"]) @parametrize def test_method_list_with_all_params(self, client: Hyperspell) -> None: @@ -33,8 +34,9 @@ def test_method_list_with_all_params(self, client: Hyperspell) -> None: collection="collection", cursor="cursor", size=0, + source="collections", ) - assert_matches_type(SyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(SyncCursorPage[Document], document, path=["response"]) @parametrize def test_raw_response_list(self, client: Hyperspell) -> None: @@ -43,7 +45,7 @@ def test_raw_response_list(self, client: Hyperspell) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" document = response.parse() - assert_matches_type(SyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(SyncCursorPage[Document], document, path=["response"]) @parametrize def test_streaming_response_list(self, client: Hyperspell) -> None: @@ -52,7 +54,7 @@ def test_streaming_response_list(self, client: Hyperspell) -> None: assert response.http_request.headers.get("X-Stainless-Lang") == "python" document = response.parse() - assert_matches_type(SyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(SyncCursorPage[Document], document, path=["response"]) assert cast(Any, response.is_closed) is True @@ -97,6 +99,73 @@ def test_streaming_response_add(self, client: Hyperspell) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_get(self, client: Hyperspell) -> None: + document = client.documents.get( + resource_id="resource_id", + source="collections", + ) + assert_matches_type(Document, document, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Hyperspell) -> None: + response = client.documents.with_raw_response.get( + resource_id="resource_id", + source="collections", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + document = response.parse() + assert_matches_type(Document, document, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Hyperspell) -> None: + with client.documents.with_streaming_response.get( + resource_id="resource_id", + source="collections", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + document = response.parse() + assert_matches_type(Document, document, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Hyperspell) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `resource_id` but received ''"): + client.documents.with_raw_response.get( + resource_id="", + source="collections", + ) + + @parametrize + def test_method_status(self, client: Hyperspell) -> None: + document = client.documents.status() + assert_matches_type(DocumentStatusResponse, document, path=["response"]) + + @parametrize + def test_raw_response_status(self, client: Hyperspell) -> None: + response = client.documents.with_raw_response.status() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + document = response.parse() + assert_matches_type(DocumentStatusResponse, document, path=["response"]) + + @parametrize + def test_streaming_response_status(self, client: Hyperspell) -> None: + with client.documents.with_streaming_response.status() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + document = response.parse() + assert_matches_type(DocumentStatusResponse, document, path=["response"]) + + assert cast(Any, response.is_closed) is True + @parametrize def test_method_upload(self, client: Hyperspell) -> None: document = client.documents.upload( @@ -143,7 +212,7 @@ class TestAsyncDocuments: @parametrize async def test_method_list(self, async_client: AsyncHyperspell) -> None: document = await async_client.documents.list() - assert_matches_type(AsyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(AsyncCursorPage[Document], document, path=["response"]) @parametrize async def test_method_list_with_all_params(self, async_client: AsyncHyperspell) -> None: @@ -151,8 +220,9 @@ async def test_method_list_with_all_params(self, async_client: AsyncHyperspell) collection="collection", cursor="cursor", size=0, + source="collections", ) - assert_matches_type(AsyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(AsyncCursorPage[Document], document, path=["response"]) @parametrize async def test_raw_response_list(self, async_client: AsyncHyperspell) -> None: @@ -161,7 +231,7 @@ async def test_raw_response_list(self, async_client: AsyncHyperspell) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" document = await response.parse() - assert_matches_type(AsyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(AsyncCursorPage[Document], document, path=["response"]) @parametrize async def test_streaming_response_list(self, async_client: AsyncHyperspell) -> None: @@ -170,7 +240,7 @@ async def test_streaming_response_list(self, async_client: AsyncHyperspell) -> N assert response.http_request.headers.get("X-Stainless-Lang") == "python" document = await response.parse() - assert_matches_type(AsyncCursorPage[DocumentListResponse], document, path=["response"]) + assert_matches_type(AsyncCursorPage[Document], document, path=["response"]) assert cast(Any, response.is_closed) is True @@ -215,6 +285,73 @@ async def test_streaming_response_add(self, async_client: AsyncHyperspell) -> No assert cast(Any, response.is_closed) is True + @parametrize + async def test_method_get(self, async_client: AsyncHyperspell) -> None: + document = await async_client.documents.get( + resource_id="resource_id", + source="collections", + ) + assert_matches_type(Document, document, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncHyperspell) -> None: + response = await async_client.documents.with_raw_response.get( + resource_id="resource_id", + source="collections", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + document = await response.parse() + assert_matches_type(Document, document, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncHyperspell) -> None: + async with async_client.documents.with_streaming_response.get( + resource_id="resource_id", + source="collections", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + document = await response.parse() + assert_matches_type(Document, document, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncHyperspell) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `resource_id` but received ''"): + await async_client.documents.with_raw_response.get( + resource_id="", + source="collections", + ) + + @parametrize + async def test_method_status(self, async_client: AsyncHyperspell) -> None: + document = await async_client.documents.status() + assert_matches_type(DocumentStatusResponse, document, path=["response"]) + + @parametrize + async def test_raw_response_status(self, async_client: AsyncHyperspell) -> None: + response = await async_client.documents.with_raw_response.status() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + document = await response.parse() + assert_matches_type(DocumentStatusResponse, document, path=["response"]) + + @parametrize + async def test_streaming_response_status(self, async_client: AsyncHyperspell) -> None: + async with async_client.documents.with_streaming_response.status() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + document = await response.parse() + assert_matches_type(DocumentStatusResponse, document, path=["response"]) + + assert cast(Any, response.is_closed) is True + @parametrize async def test_method_upload(self, async_client: AsyncHyperspell) -> None: document = await async_client.documents.upload(