Skip to content

Commit b6baad4

Browse files
committed
Release 0.0.9
1 parent a14ea26 commit b6baad4

File tree

8 files changed

+128
-20
lines changed

8 files changed

+128
-20
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ except ApiError as e:
6060
print(e.body)
6161
```
6262

63+
## Pagination
64+
65+
Paginated requests will return a `SyncPager` or `AsyncPager`, which can be used as generators for the underlying object.
66+
67+
```python
68+
from vapi import Vapi
69+
70+
client = Vapi(
71+
token="YOUR_TOKEN",
72+
)
73+
response = client.logs.get()
74+
for item in response:
75+
yield item
76+
# alternatively, you can paginate page-by-page
77+
for page in response.iter_pages():
78+
yield page
79+
```
80+
6381
## Advanced
6482

6583
### Retries

poetry.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "Vapi"
3-
version = "0.0.1"
3+
version = "0.0.9"
44
description = ""
55
readme = "README.md"
66
authors = []

reference.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3486,7 +3486,12 @@ from vapi import Vapi
34863486
client = Vapi(
34873487
token="YOUR_TOKEN",
34883488
)
3489-
client.logs.get()
3489+
response = client.logs.get()
3490+
for item in response:
3491+
yield item
3492+
# alternatively, you can paginate page-by-page
3493+
for page in response.iter_pages():
3494+
yield page
34903495

34913496
```
34923497
</dd>

src/vapi/core/client_wrapper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def get_headers(self) -> typing.Dict[str, str]:
2222
headers: typing.Dict[str, str] = {
2323
"X-Fern-Language": "Python",
2424
"X-Fern-SDK-Name": "Vapi",
25-
"X-Fern-SDK-Version": "0.0.1",
25+
"X-Fern-SDK-Version": "0.0.9",
2626
}
2727
headers["Authorization"] = f"Bearer {self._get_token()}"
2828
return headers

src/vapi/core/http_client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ def request(
224224
json=json_body,
225225
data=data_body,
226226
content=content,
227-
files=convert_file_dict_to_httpx_tuples(remove_none_from_dict(files)) if files is not None else None,
227+
files=convert_file_dict_to_httpx_tuples(remove_none_from_dict(files))
228+
if (files is not None and files is not omit)
229+
else None,
228230
timeout=timeout,
229231
)
230232

@@ -306,7 +308,9 @@ def stream(
306308
json=json_body,
307309
data=data_body,
308310
content=content,
309-
files=convert_file_dict_to_httpx_tuples(remove_none_from_dict(files)) if files is not None else None,
311+
files=convert_file_dict_to_httpx_tuples(remove_none_from_dict(files))
312+
if (files is not None and files is not omit)
313+
else None,
310314
timeout=timeout,
311315
) as stream:
312316
yield stream

src/vapi/core/serialization.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,24 @@ def convert_and_respect_annotation_metadata(
7171
if typing_extensions.is_typeddict(clean_type) and isinstance(object_, typing.Mapping):
7272
return _convert_mapping(object_, clean_type, direction)
7373

74+
if (
75+
typing_extensions.get_origin(clean_type) == typing.Dict
76+
or typing_extensions.get_origin(clean_type) == dict
77+
or clean_type == typing.Dict
78+
) and isinstance(object_, typing.Dict):
79+
key_type = typing_extensions.get_args(clean_type)[0]
80+
value_type = typing_extensions.get_args(clean_type)[1]
81+
82+
return {
83+
key: convert_and_respect_annotation_metadata(
84+
object_=value,
85+
annotation=annotation,
86+
inner_type=value_type,
87+
direction=direction,
88+
)
89+
for key, value in object_.items()
90+
}
91+
7492
# If you're iterating on a string, do not bother to coerce it to a sequence.
7593
if not isinstance(object_, str):
7694
if (

src/vapi/logs/client.py

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
from .types.logs_get_request_sort_order import LogsGetRequestSortOrder
77
import datetime as dt
88
from ..core.request_options import RequestOptions
9-
from ..types.logs_paginated_response import LogsPaginatedResponse
9+
from ..core.pagination import SyncPager
10+
from ..types.log import Log
1011
from ..core.datetime_utils import serialize_datetime
12+
from ..types.logs_paginated_response import LogsPaginatedResponse
1113
from ..core.pydantic_utilities import parse_obj_as
1214
from json.decoder import JSONDecodeError
1315
from ..core.api_error import ApiError
1416
from ..core.client_wrapper import AsyncClientWrapper
17+
from ..core.pagination import AsyncPager
1518

1619

1720
class LogsClient:
@@ -40,7 +43,7 @@ def get(
4043
updated_at_ge: typing.Optional[dt.datetime] = None,
4144
updated_at_le: typing.Optional[dt.datetime] = None,
4245
request_options: typing.Optional[RequestOptions] = None,
43-
) -> LogsPaginatedResponse:
46+
) -> SyncPager[Log]:
4447
"""
4548
Parameters
4649
----------
@@ -103,7 +106,7 @@ def get(
103106
104107
Returns
105108
-------
106-
LogsPaginatedResponse
109+
SyncPager[Log]
107110
108111
109112
Examples
@@ -113,8 +116,14 @@ def get(
113116
client = Vapi(
114117
token="YOUR_TOKEN",
115118
)
116-
client.logs.get()
119+
response = client.logs.get()
120+
for item in response:
121+
yield item
122+
# alternatively, you can paginate page-by-page
123+
for page in response.iter_pages():
124+
yield page
117125
"""
126+
page = page if page is not None else 1
118127
_response = self._client_wrapper.httpx_client.request(
119128
"logs",
120129
method="GET",
@@ -142,13 +151,37 @@ def get(
142151
)
143152
try:
144153
if 200 <= _response.status_code < 300:
145-
return typing.cast(
154+
_parsed_response = typing.cast(
146155
LogsPaginatedResponse,
147156
parse_obj_as(
148157
type_=LogsPaginatedResponse, # type: ignore
149158
object_=_response.json(),
150159
),
151160
)
161+
_has_next = True
162+
_get_next = lambda: self.get(
163+
org_id=org_id,
164+
type=type,
165+
assistant_id=assistant_id,
166+
phone_number_id=phone_number_id,
167+
customer_id=customer_id,
168+
squad_id=squad_id,
169+
call_id=call_id,
170+
page=page + 1,
171+
sort_order=sort_order,
172+
limit=limit,
173+
created_at_gt=created_at_gt,
174+
created_at_lt=created_at_lt,
175+
created_at_ge=created_at_ge,
176+
created_at_le=created_at_le,
177+
updated_at_gt=updated_at_gt,
178+
updated_at_lt=updated_at_lt,
179+
updated_at_ge=updated_at_ge,
180+
updated_at_le=updated_at_le,
181+
request_options=request_options,
182+
)
183+
_items = _parsed_response.results
184+
return SyncPager(has_next=_has_next, items=_items, get_next=_get_next)
152185
_response_json = _response.json()
153186
except JSONDecodeError:
154187
raise ApiError(status_code=_response.status_code, body=_response.text)
@@ -181,7 +214,7 @@ async def get(
181214
updated_at_ge: typing.Optional[dt.datetime] = None,
182215
updated_at_le: typing.Optional[dt.datetime] = None,
183216
request_options: typing.Optional[RequestOptions] = None,
184-
) -> LogsPaginatedResponse:
217+
) -> AsyncPager[Log]:
185218
"""
186219
Parameters
187220
----------
@@ -244,7 +277,7 @@ async def get(
244277
245278
Returns
246279
-------
247-
LogsPaginatedResponse
280+
AsyncPager[Log]
248281
249282
250283
Examples
@@ -259,11 +292,17 @@ async def get(
259292
260293
261294
async def main() -> None:
262-
await client.logs.get()
295+
response = await client.logs.get()
296+
async for item in response:
297+
yield item
298+
# alternatively, you can paginate page-by-page
299+
async for page in response.iter_pages():
300+
yield page
263301
264302
265303
asyncio.run(main())
266304
"""
305+
page = page if page is not None else 1
267306
_response = await self._client_wrapper.httpx_client.request(
268307
"logs",
269308
method="GET",
@@ -291,13 +330,37 @@ async def main() -> None:
291330
)
292331
try:
293332
if 200 <= _response.status_code < 300:
294-
return typing.cast(
333+
_parsed_response = typing.cast(
295334
LogsPaginatedResponse,
296335
parse_obj_as(
297336
type_=LogsPaginatedResponse, # type: ignore
298337
object_=_response.json(),
299338
),
300339
)
340+
_has_next = True
341+
_get_next = lambda: self.get(
342+
org_id=org_id,
343+
type=type,
344+
assistant_id=assistant_id,
345+
phone_number_id=phone_number_id,
346+
customer_id=customer_id,
347+
squad_id=squad_id,
348+
call_id=call_id,
349+
page=page + 1,
350+
sort_order=sort_order,
351+
limit=limit,
352+
created_at_gt=created_at_gt,
353+
created_at_lt=created_at_lt,
354+
created_at_ge=created_at_ge,
355+
created_at_le=created_at_le,
356+
updated_at_gt=updated_at_gt,
357+
updated_at_lt=updated_at_lt,
358+
updated_at_ge=updated_at_ge,
359+
updated_at_le=updated_at_le,
360+
request_options=request_options,
361+
)
362+
_items = _parsed_response.results
363+
return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next)
301364
_response_json = _response.json()
302365
except JSONDecodeError:
303366
raise ApiError(status_code=_response.status_code, body=_response.text)

0 commit comments

Comments
 (0)