Skip to content

Commit 5aaf7cd

Browse files
feat(api): api update (#39)
1 parent fd5a6d5 commit 5aaf7cd

File tree

10 files changed

+255
-38
lines changed

10 files changed

+255
-38
lines changed

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
configured_endpoints: 10
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-1c1bcc83d3f82bc2978105dc0845602e61b0fdff61814e493d4109d4f5907798.yml
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hyperspell%2Fhyperspell-7632a025f14cf4ef9630966e00cb47fd93e8b43f1e9111f3917eb5adf145f0dd.yml

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,77 @@ Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typ
7979

8080
Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`.
8181

82+
## Pagination
83+
84+
List methods in the Hyperspell API are paginated.
85+
86+
This library provides auto-paginating iterators with each list response, so you do not have to request successive pages manually:
87+
88+
```python
89+
from hyperspell import Hyperspell
90+
91+
client = Hyperspell()
92+
93+
all_documents = []
94+
# Automatically fetches more pages as needed.
95+
for document in client.documents.list(
96+
collection="REPLACE_ME",
97+
):
98+
# Do something with document here
99+
all_documents.append(document)
100+
print(all_documents)
101+
```
102+
103+
Or, asynchronously:
104+
105+
```python
106+
import asyncio
107+
from hyperspell import AsyncHyperspell
108+
109+
client = AsyncHyperspell()
110+
111+
112+
async def main() -> None:
113+
all_documents = []
114+
# Iterate through items across all pages, issuing requests as needed.
115+
async for document in client.documents.list(
116+
collection="REPLACE_ME",
117+
):
118+
all_documents.append(document)
119+
print(all_documents)
120+
121+
122+
asyncio.run(main())
123+
```
124+
125+
Alternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages:
126+
127+
```python
128+
first_page = await client.documents.list(
129+
collection="REPLACE_ME",
130+
)
131+
if first_page.has_next_page():
132+
print(f"will fetch next page using these details: {first_page.next_page_info()}")
133+
next_page = await first_page.get_next_page()
134+
print(f"number of items we just fetched: {len(next_page.items)}")
135+
136+
# Remove `await` for non-async usage.
137+
```
138+
139+
Or just work directly with the returned data:
140+
141+
```python
142+
first_page = await client.documents.list(
143+
collection="REPLACE_ME",
144+
)
145+
146+
print(f"next page cursor: {first_page.next_cursor}") # => "next page cursor: ..."
147+
for document in first_page.items:
148+
print(document.id)
149+
150+
# Remove `await` for non-async usage.
151+
```
152+
82153
## Handling errors
83154

84155
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `hyperspell.APIConnectionError` is raised.

api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ from hyperspell.types import Document, DocumentStatus, DocumentListResponse
88

99
Methods:
1010

11-
- <code title="get /documents/list">client.documents.<a href="./src/hyperspell/resources/documents.py">list</a>(\*\*<a href="src/hyperspell/types/document_list_params.py">params</a>) -> <a href="./src/hyperspell/types/document_list_response.py">object</a></code>
11+
- <code title="get /documents/list">client.documents.<a href="./src/hyperspell/resources/documents.py">list</a>(\*\*<a href="src/hyperspell/types/document_list_params.py">params</a>) -> <a href="./src/hyperspell/types/document_list_response.py">SyncCursorPage[DocumentListResponse]</a></code>
1212
- <code title="post /documents/add">client.documents.<a href="./src/hyperspell/resources/documents.py">add</a>(\*\*<a href="src/hyperspell/types/document_add_params.py">params</a>) -> <a href="./src/hyperspell/types/document_status.py">DocumentStatus</a></code>
1313
- <code title="post /documents/scrape">client.documents.<a href="./src/hyperspell/resources/documents.py">add_url</a>(\*\*<a href="src/hyperspell/types/document_add_url_params.py">params</a>) -> <a href="./src/hyperspell/types/document_status.py">DocumentStatus</a></code>
1414
- <code title="get /documents/get/{document_id}">client.documents.<a href="./src/hyperspell/resources/documents.py">get</a>(document_id) -> <a href="./src/hyperspell/types/document.py">Document</a></code>
@@ -25,7 +25,7 @@ from hyperspell.types import Collection, CollectionListResponse
2525
Methods:
2626

2727
- <code title="post /collections/add">client.collections.<a href="./src/hyperspell/resources/collections.py">create</a>(\*\*<a href="src/hyperspell/types/collection_create_params.py">params</a>) -> <a href="./src/hyperspell/types/collection.py">Collection</a></code>
28-
- <code title="get /collections/list">client.collections.<a href="./src/hyperspell/resources/collections.py">list</a>(\*\*<a href="src/hyperspell/types/collection_list_params.py">params</a>) -> <a href="./src/hyperspell/types/collection_list_response.py">object</a></code>
28+
- <code title="get /collections/list">client.collections.<a href="./src/hyperspell/resources/collections.py">list</a>(\*\*<a href="src/hyperspell/types/collection_list_params.py">params</a>) -> <a href="./src/hyperspell/types/collection_list_response.py">SyncCursorPage[CollectionListResponse]</a></code>
2929
- <code title="get /collections/get/{name}">client.collections.<a href="./src/hyperspell/resources/collections.py">get</a>(name) -> <a href="./src/hyperspell/types/collection.py">Collection</a></code>
3030

3131
# Query

src/hyperspell/resources/collections.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
async_to_raw_response_wrapper,
2121
async_to_streamed_response_wrapper,
2222
)
23-
from .._base_client import make_request_options
23+
from ..pagination import SyncCursorPage, AsyncCursorPage
24+
from .._base_client import AsyncPaginator, make_request_options
2425
from ..types.collection import Collection
26+
from ..types.collection_list_response import CollectionListResponse
2527

2628
__all__ = ["CollectionsResource", "AsyncCollectionsResource"]
2729

@@ -103,7 +105,7 @@ def list(
103105
extra_query: Query | None = None,
104106
extra_body: Body | None = None,
105107
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
106-
) -> object:
108+
) -> SyncCursorPage[CollectionListResponse]:
107109
"""
108110
Lists all collections the user has access to.
109111
@@ -116,8 +118,9 @@ def list(
116118
117119
timeout: Override the client-level default timeout for this request, in seconds
118120
"""
119-
return self._get(
121+
return self._get_api_list(
120122
"/collections/list",
123+
page=SyncCursorPage[CollectionListResponse],
121124
options=make_request_options(
122125
extra_headers=extra_headers,
123126
extra_query=extra_query,
@@ -131,7 +134,7 @@ def list(
131134
collection_list_params.CollectionListParams,
132135
),
133136
),
134-
cast_to=object,
137+
model=CollectionListResponse,
135138
)
136139

137140
def get(
@@ -234,7 +237,7 @@ async def create(
234237
cast_to=Collection,
235238
)
236239

237-
async def list(
240+
def list(
238241
self,
239242
*,
240243
cursor: Optional[str] | NotGiven = NOT_GIVEN,
@@ -245,7 +248,7 @@ async def list(
245248
extra_query: Query | None = None,
246249
extra_body: Body | None = None,
247250
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
248-
) -> object:
251+
) -> AsyncPaginator[CollectionListResponse, AsyncCursorPage[CollectionListResponse]]:
249252
"""
250253
Lists all collections the user has access to.
251254
@@ -258,22 +261,23 @@ async def list(
258261
259262
timeout: Override the client-level default timeout for this request, in seconds
260263
"""
261-
return await self._get(
264+
return self._get_api_list(
262265
"/collections/list",
266+
page=AsyncCursorPage[CollectionListResponse],
263267
options=make_request_options(
264268
extra_headers=extra_headers,
265269
extra_query=extra_query,
266270
extra_body=extra_body,
267271
timeout=timeout,
268-
query=await async_maybe_transform(
272+
query=maybe_transform(
269273
{
270274
"cursor": cursor,
271275
"size": size,
272276
},
273277
collection_list_params.CollectionListParams,
274278
),
275279
),
276-
cast_to=object,
280+
model=CollectionListResponse,
277281
)
278282

279283
async def get(

src/hyperspell/resources/documents.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929
async_to_raw_response_wrapper,
3030
async_to_streamed_response_wrapper,
3131
)
32-
from .._base_client import make_request_options
32+
from ..pagination import SyncCursorPage, AsyncCursorPage
33+
from .._base_client import AsyncPaginator, make_request_options
3334
from ..types.document import Document
3435
from ..types.document_status import DocumentStatus
36+
from ..types.document_list_response import DocumentListResponse
3537

3638
__all__ = ["DocumentsResource", "AsyncDocumentsResource"]
3739

@@ -68,7 +70,7 @@ def list(
6870
extra_query: Query | None = None,
6971
extra_body: Body | None = None,
7072
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
71-
) -> object:
73+
) -> SyncCursorPage[DocumentListResponse]:
7274
"""This endpoint allows you to paginate through all documents in the index.
7375
7476
You can
@@ -83,8 +85,9 @@ def list(
8385
8486
timeout: Override the client-level default timeout for this request, in seconds
8587
"""
86-
return self._get(
88+
return self._get_api_list(
8789
"/documents/list",
90+
page=SyncCursorPage[DocumentListResponse],
8891
options=make_request_options(
8992
extra_headers=extra_headers,
9093
extra_query=extra_query,
@@ -99,7 +102,7 @@ def list(
99102
document_list_params.DocumentListParams,
100103
),
101104
),
102-
cast_to=object,
105+
model=DocumentListResponse,
103106
)
104107

105108
def add(
@@ -331,7 +334,7 @@ def with_streaming_response(self) -> AsyncDocumentsResourceWithStreamingResponse
331334
"""
332335
return AsyncDocumentsResourceWithStreamingResponse(self)
333336

334-
async def list(
337+
def list(
335338
self,
336339
*,
337340
collection: str,
@@ -343,7 +346,7 @@ async def list(
343346
extra_query: Query | None = None,
344347
extra_body: Body | None = None,
345348
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
346-
) -> object:
349+
) -> AsyncPaginator[DocumentListResponse, AsyncCursorPage[DocumentListResponse]]:
347350
"""This endpoint allows you to paginate through all documents in the index.
348351
349352
You can
@@ -358,14 +361,15 @@ async def list(
358361
359362
timeout: Override the client-level default timeout for this request, in seconds
360363
"""
361-
return await self._get(
364+
return self._get_api_list(
362365
"/documents/list",
366+
page=AsyncCursorPage[DocumentListResponse],
363367
options=make_request_options(
364368
extra_headers=extra_headers,
365369
extra_query=extra_query,
366370
extra_body=extra_body,
367371
timeout=timeout,
368-
query=await async_maybe_transform(
372+
query=maybe_transform(
369373
{
370374
"collection": collection,
371375
"cursor": cursor,
@@ -374,7 +378,7 @@ async def list(
374378
document_list_params.DocumentListParams,
375379
),
376380
),
377-
cast_to=object,
381+
model=DocumentListResponse,
378382
)
379383

380384
async def add(

src/hyperspell/types/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
from .query_search_response import QuerySearchResponse as QuerySearchResponse
1313
from .auth_user_token_params import AuthUserTokenParams as AuthUserTokenParams
1414
from .collection_list_params import CollectionListParams as CollectionListParams
15+
from .document_list_response import DocumentListResponse as DocumentListResponse
1516
from .document_upload_params import DocumentUploadParams as DocumentUploadParams
1617
from .document_add_url_params import DocumentAddURLParams as DocumentAddURLParams
1718
from .collection_create_params import CollectionCreateParams as CollectionCreateParams
19+
from .collection_list_response import CollectionListResponse as CollectionListResponse
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing import Optional
4+
from datetime import datetime
5+
6+
from .._models import BaseModel
7+
8+
__all__ = ["CollectionListResponse"]
9+
10+
11+
class CollectionListResponse(BaseModel):
12+
name: str
13+
14+
id: Optional[int] = None
15+
16+
created_at: Optional[datetime] = None
17+
18+
documents_count: Optional[int] = None
19+
20+
owner: Optional[str] = None

0 commit comments

Comments
 (0)