Skip to content

Commit 006b058

Browse files
committed
Release 0.0.66
1 parent 57121f9 commit 006b058

7 files changed

Lines changed: 107 additions & 12 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ client = AgentMail(
8080
response = client.inboxes.with_raw_response.create(...)
8181
print(response.headers) # access the response headers
8282
print(response.data) # access the underlying object
83+
pager = client.inboxes.list(...)
84+
print(pager.response.headers) # access the response headers for the first page
85+
for item in pager:
86+
print(item) # access the underlying object(s)
87+
for page in pager.iter_pages():
88+
print(page.response.headers) # access the response headers for each page
89+
for item in page:
90+
print(item) # access the underlying object(s)
8391
```
8492

8593
### Retries

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "agentmail"
33

44
[tool.poetry]
55
name = "agentmail"
6-
version = "0.0.60"
6+
version = "0.0.66"
77
description = ""
88
readme = "README.md"
99
authors = []

reference.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ client = AgentMail(
590590
api_key="YOUR_API_KEY",
591591
)
592592
client.domains.get(
593-
domain=" your-domain.com",
593+
domain="domain",
594594
)
595595

596596
```
@@ -646,7 +646,7 @@ client = AgentMail(
646646
api_key="YOUR_API_KEY",
647647
)
648648
client.domains.create(
649-
domain="your-domain.com",
649+
domain="domain",
650650
)
651651

652652
```
@@ -710,7 +710,7 @@ client = AgentMail(
710710
api_key="YOUR_API_KEY",
711711
)
712712
client.domains.delete(
713-
domain="dom_12345",
713+
domain="domain",
714714
)
715715

716716
```

src/agentmail/core/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .http_client import AsyncHttpClient, HttpClient
1515
from .http_response import AsyncHttpResponse, HttpResponse
1616
from .jsonable_encoder import jsonable_encoder
17+
from .pagination import AsyncPager, SyncPager
1718
from .pydantic_utilities import (
1819
IS_PYDANTIC_V2,
1920
UniversalBaseModel,
@@ -33,6 +34,7 @@
3334
"AsyncClientWrapper": ".client_wrapper",
3435
"AsyncHttpClient": ".http_client",
3536
"AsyncHttpResponse": ".http_response",
37+
"AsyncPager": ".pagination",
3638
"BaseClientWrapper": ".client_wrapper",
3739
"EventEmitterMixin": ".events",
3840
"EventType": ".events",
@@ -43,6 +45,7 @@
4345
"IS_PYDANTIC_V2": ".pydantic_utilities",
4446
"RequestOptions": ".request_options",
4547
"SyncClientWrapper": ".client_wrapper",
48+
"SyncPager": ".pagination",
4649
"UncheckedBaseModel": ".unchecked_base_model",
4750
"UnionMetadata": ".unchecked_base_model",
4851
"UniversalBaseModel": ".pydantic_utilities",
@@ -88,6 +91,7 @@ def __dir__():
8891
"AsyncClientWrapper",
8992
"AsyncHttpClient",
9093
"AsyncHttpResponse",
94+
"AsyncPager",
9195
"BaseClientWrapper",
9296
"EventEmitterMixin",
9397
"EventType",
@@ -98,6 +102,7 @@ def __dir__():
98102
"IS_PYDANTIC_V2",
99103
"RequestOptions",
100104
"SyncClientWrapper",
105+
"SyncPager",
101106
"UncheckedBaseModel",
102107
"UnionMetadata",
103108
"UniversalBaseModel",

src/agentmail/core/client_wrapper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ def __init__(
2323

2424
def get_headers(self) -> typing.Dict[str, str]:
2525
headers: typing.Dict[str, str] = {
26-
"User-Agent": "agentmail/0.0.60",
26+
"User-Agent": "agentmail/0.0.66",
2727
"X-Fern-Language": "Python",
2828
"X-Fern-SDK-Name": "agentmail",
29-
"X-Fern-SDK-Version": "0.0.60",
29+
"X-Fern-SDK-Version": "0.0.66",
3030
**(self.get_custom_headers() or {}),
3131
}
3232
headers["Authorization"] = f"Bearer {self._get_api_key()}"

src/agentmail/core/pagination.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
from __future__ import annotations
4+
5+
from dataclasses import dataclass
6+
from typing import AsyncIterator, Awaitable, Callable, Generic, Iterator, List, Optional, TypeVar
7+
8+
from .http_response import BaseHttpResponse
9+
10+
# Generic to represent the underlying type of the results within a page
11+
T = TypeVar("T")
12+
13+
14+
# SDKs implement a Page ABC per-pagination request, the endpoint then returns a pager that wraps this type
15+
# for example, an endpoint will return SyncPager[UserPage] where UserPage implements the Page ABC. ex:
16+
#
17+
# SyncPager<InnerListType>(
18+
# has_next=response.list_metadata.after is not None,
19+
# items=response.data,
20+
# # This should be the outer function that returns the SyncPager again
21+
# get_next=lambda: list(..., cursor: response.cursor) (or list(..., offset: offset + 1))
22+
# )
23+
24+
25+
@dataclass(frozen=True)
26+
class SyncPager(Generic[T]):
27+
get_next: Optional[Callable[[], Optional[SyncPager[T]]]]
28+
has_next: bool
29+
items: Optional[List[T]]
30+
response: Optional[BaseHttpResponse]
31+
32+
# Here we type ignore the iterator to avoid a mypy error
33+
# caused by the type conflict with Pydanitc's __iter__ method
34+
# brought in by extending the base model
35+
def __iter__(self) -> Iterator[T]: # type: ignore[override]
36+
for page in self.iter_pages():
37+
if page.items is not None:
38+
yield from page.items
39+
40+
def iter_pages(self) -> Iterator[SyncPager[T]]:
41+
page: Optional[SyncPager[T]] = self
42+
while page is not None:
43+
yield page
44+
45+
if not page.has_next or page.get_next is None:
46+
return
47+
48+
page = page.get_next()
49+
if page is None or page.items is None or len(page.items) == 0:
50+
return
51+
52+
def next_page(self) -> Optional[SyncPager[T]]:
53+
return self.get_next() if self.get_next is not None else None
54+
55+
56+
@dataclass(frozen=True)
57+
class AsyncPager(Generic[T]):
58+
get_next: Optional[Callable[[], Awaitable[Optional[AsyncPager[T]]]]]
59+
has_next: bool
60+
items: Optional[List[T]]
61+
response: Optional[BaseHttpResponse]
62+
63+
async def __aiter__(self) -> AsyncIterator[T]:
64+
async for page in self.iter_pages():
65+
if page.items is not None:
66+
for item in page.items:
67+
yield item
68+
69+
async def iter_pages(self) -> AsyncIterator[AsyncPager[T]]:
70+
page: Optional[AsyncPager[T]] = self
71+
while page is not None:
72+
yield page
73+
74+
if not page.has_next or page.get_next is None:
75+
return
76+
77+
page = await page.get_next()
78+
if page is None or page.items is None or len(page.items) == 0:
79+
return
80+
81+
async def next_page(self) -> Optional[AsyncPager[T]]:
82+
return await self.get_next() if self.get_next is not None else None

src/agentmail/domains/client.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def get(self, domain: DomainId, *, request_options: typing.Optional[RequestOptio
8686
api_key="YOUR_API_KEY",
8787
)
8888
client.domains.get(
89-
domain=" your-domain.com",
89+
domain="domain",
9090
)
9191
"""
9292
_response = self._raw_client.get(domain, request_options=request_options)
@@ -122,7 +122,7 @@ def create(
122122
api_key="YOUR_API_KEY",
123123
)
124124
client.domains.create(
125-
domain="your-domain.com",
125+
domain="domain",
126126
)
127127
"""
128128
_response = self._raw_client.create(
@@ -151,7 +151,7 @@ def delete(self, domain: DomainId, *, request_options: typing.Optional[RequestOp
151151
api_key="YOUR_API_KEY",
152152
)
153153
client.domains.delete(
154-
domain="dom_12345",
154+
domain="domain",
155155
)
156156
"""
157157
_response = self._raw_client.delete(domain, request_options=request_options)
@@ -240,7 +240,7 @@ async def get(self, domain: DomainId, *, request_options: typing.Optional[Reques
240240
241241
async def main() -> None:
242242
await client.domains.get(
243-
domain=" your-domain.com",
243+
domain="domain",
244244
)
245245
246246
@@ -284,7 +284,7 @@ async def create(
284284
285285
async def main() -> None:
286286
await client.domains.create(
287-
domain="your-domain.com",
287+
domain="domain",
288288
)
289289
290290
@@ -321,7 +321,7 @@ async def delete(self, domain: DomainId, *, request_options: typing.Optional[Req
321321
322322
async def main() -> None:
323323
await client.domains.delete(
324-
domain="dom_12345",
324+
domain="domain",
325325
)
326326
327327

0 commit comments

Comments
 (0)