fathom-python 0.0.25__py3-none-any.whl → 0.0.27__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fathom/base_client.py CHANGED
@@ -1,18 +1,17 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- import os
4
3
  import typing
5
4
 
6
5
  import httpx
7
- from .core.api_error import ApiError
8
6
  from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
7
+ from .core.pagination import AsyncPager, SyncPager
9
8
  from .core.request_options import RequestOptions
10
9
  from .environment import FathomApiEnvironment
11
10
  from .raw_base_client import AsyncRawBaseClient, RawBaseClient
12
11
  from .types.list_meetings_request_meeting_type import ListMeetingsRequestMeetingType
13
- from .types.meeting_list_response import MeetingListResponse
14
- from .types.team_list_response import TeamListResponse
15
- from .types.team_member_list_response import TeamMemberListResponse
12
+ from .types.meeting import Meeting
13
+ from .types.team import Team
14
+ from .types.team_member import TeamMember
16
15
 
17
16
 
18
17
  class BaseClient:
@@ -31,7 +30,7 @@ class BaseClient:
31
30
 
32
31
 
33
32
 
34
- api_key : typing.Optional[typing.Union[str, typing.Callable[[], str]]]
33
+ api_key : str
35
34
  timeout : typing.Optional[float]
36
35
  The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
37
36
 
@@ -52,7 +51,7 @@ class BaseClient:
52
51
  *,
53
52
  base_url: typing.Optional[str] = None,
54
53
  environment: FathomApiEnvironment = FathomApiEnvironment.DEFAULT,
55
- api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("FATHOM_API_KEY"),
54
+ api_key: str,
56
55
  timeout: typing.Optional[float] = None,
57
56
  follow_redirects: typing.Optional[bool] = True,
58
57
  httpx_client: typing.Optional[httpx.Client] = None,
@@ -60,10 +59,6 @@ class BaseClient:
60
59
  _defaulted_timeout = (
61
60
  timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
62
61
  )
63
- if api_key is None:
64
- raise ApiError(
65
- body="The client must be instantiated be either passing in api_key or setting FATHOM_API_KEY"
66
- )
67
62
  self._client_wrapper = SyncClientWrapper(
68
63
  base_url=_get_base_url(base_url=base_url, environment=environment),
69
64
  api_key=api_key,
@@ -93,12 +88,15 @@ class BaseClient:
93
88
  recorded_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
94
89
  teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
95
90
  calendar_invitees: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
91
+ created_before: typing.Optional[str] = None,
96
92
  created_after: typing.Optional[str] = None,
93
+ calendar_invitees_domains: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
97
94
  meeting_type: typing.Optional[ListMeetingsRequestMeetingType] = None,
98
95
  include_transcript: typing.Optional[bool] = None,
96
+ include_crm_matches: typing.Optional[bool] = None,
99
97
  cursor: typing.Optional[str] = None,
100
98
  request_options: typing.Optional[RequestOptions] = None,
101
- ) -> MeetingListResponse:
99
+ ) -> SyncPager[Meeting]:
102
100
  """
103
101
  Parameters
104
102
  ----------
@@ -119,7 +117,7 @@ class BaseClient:
119
117
  Returns meetings that belong to any of the specified teams.
120
118
 
121
119
  calendar_invitees : typing.Optional[typing.Union[str, typing.Sequence[str]]]
122
- Email addresses of calendar_invitees.
120
+ Email address of calendar_invitees to filter by.
123
121
 
124
122
  Pass the parameter once per value, e.g.
125
123
  `calendar_invitees[]=cfo@acme.com&calendar_invitees[]=legal@acme.com`.
@@ -127,15 +125,29 @@ class BaseClient:
127
125
  Returns meetings where any of the given email addresses appear
128
126
  in the calendar_invitees list.
129
127
 
128
+ created_before : typing.Optional[str]
129
+ Filter to meetings with created_at before this timestamp, e.g. `created_before=2025-01-01T00:00:00Z`.
130
+
130
131
  created_after : typing.Optional[str]
131
132
  Filter to meetings with created_at after this timestamp, e.g. `created_after=2025-01-01T00:00:00Z`.
132
133
 
134
+ calendar_invitees_domains : typing.Optional[typing.Union[str, typing.Sequence[str]]]
135
+ Domains of the companies to filter by. Exact match.
136
+
137
+ Pass the parameter once per value, e.g.
138
+ `calendar_invitees_domains[]=acme.com&calendar_invitees_domains[]=client.com`.
139
+
140
+ Returns meetings where any of the given company domains appear in the meeting.
141
+
133
142
  meeting_type : typing.Optional[ListMeetingsRequestMeetingType]
134
143
  Filter by meeting type.
135
144
 
136
145
  include_transcript : typing.Optional[bool]
137
146
  Include the transcript for each meeting.
138
147
 
148
+ include_crm_matches : typing.Optional[bool]
149
+ Include CRM matches for each meeting. Only returns data from your or your team's linked CRM.
150
+
139
151
  cursor : typing.Optional[str]
140
152
  Cursor for pagination.
141
153
 
@@ -144,30 +156,37 @@ class BaseClient:
144
156
 
145
157
  Returns
146
158
  -------
147
- MeetingListResponse
159
+ SyncPager[Meeting]
148
160
  Paginated list of meetings.
149
161
 
150
162
  Examples
151
163
  --------
152
164
  from fathom import FathomApi
153
165
  client = FathomApi(api_key="YOUR_API_KEY", )
154
- client.list_meetings()
166
+ response = client.list_meetings()
167
+ for item in response:
168
+ yield item
169
+ # alternatively, you can paginate page-by-page
170
+ for page in response.iter_pages():
171
+ yield page
155
172
  """
156
- _response = self._raw_client.list_meetings(
173
+ return self._raw_client.list_meetings(
157
174
  recorded_by=recorded_by,
158
175
  teams=teams,
159
176
  calendar_invitees=calendar_invitees,
177
+ created_before=created_before,
160
178
  created_after=created_after,
179
+ calendar_invitees_domains=calendar_invitees_domains,
161
180
  meeting_type=meeting_type,
162
181
  include_transcript=include_transcript,
182
+ include_crm_matches=include_crm_matches,
163
183
  cursor=cursor,
164
184
  request_options=request_options,
165
185
  )
166
- return _response.data
167
186
 
168
187
  def list_teams(
169
188
  self, *, cursor: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
170
- ) -> TeamListResponse:
189
+ ) -> SyncPager[Team]:
171
190
  """
172
191
  Parameters
173
192
  ----------
@@ -179,17 +198,21 @@ class BaseClient:
179
198
 
180
199
  Returns
181
200
  -------
182
- TeamListResponse
201
+ SyncPager[Team]
183
202
  Paginated list of teams.
184
203
 
185
204
  Examples
186
205
  --------
187
206
  from fathom import FathomApi
188
207
  client = FathomApi(api_key="YOUR_API_KEY", )
189
- client.list_teams()
208
+ response = client.list_teams()
209
+ for item in response:
210
+ yield item
211
+ # alternatively, you can paginate page-by-page
212
+ for page in response.iter_pages():
213
+ yield page
190
214
  """
191
- _response = self._raw_client.list_teams(cursor=cursor, request_options=request_options)
192
- return _response.data
215
+ return self._raw_client.list_teams(cursor=cursor, request_options=request_options)
193
216
 
194
217
  def list_team_members(
195
218
  self,
@@ -197,7 +220,7 @@ class BaseClient:
197
220
  team: typing.Optional[str] = None,
198
221
  cursor: typing.Optional[str] = None,
199
222
  request_options: typing.Optional[RequestOptions] = None,
200
- ) -> TeamMemberListResponse:
223
+ ) -> SyncPager[TeamMember]:
201
224
  """
202
225
  Parameters
203
226
  ----------
@@ -212,17 +235,21 @@ class BaseClient:
212
235
 
213
236
  Returns
214
237
  -------
215
- TeamMemberListResponse
238
+ SyncPager[TeamMember]
216
239
  Paginated list of team members.
217
240
 
218
241
  Examples
219
242
  --------
220
243
  from fathom import FathomApi
221
244
  client = FathomApi(api_key="YOUR_API_KEY", )
222
- client.list_team_members()
245
+ response = client.list_team_members()
246
+ for item in response:
247
+ yield item
248
+ # alternatively, you can paginate page-by-page
249
+ for page in response.iter_pages():
250
+ yield page
223
251
  """
224
- _response = self._raw_client.list_team_members(team=team, cursor=cursor, request_options=request_options)
225
- return _response.data
252
+ return self._raw_client.list_team_members(team=team, cursor=cursor, request_options=request_options)
226
253
 
227
254
 
228
255
  class AsyncBaseClient:
@@ -241,7 +268,7 @@ class AsyncBaseClient:
241
268
 
242
269
 
243
270
 
244
- api_key : typing.Optional[typing.Union[str, typing.Callable[[], str]]]
271
+ api_key : str
245
272
  timeout : typing.Optional[float]
246
273
  The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
247
274
 
@@ -262,7 +289,7 @@ class AsyncBaseClient:
262
289
  *,
263
290
  base_url: typing.Optional[str] = None,
264
291
  environment: FathomApiEnvironment = FathomApiEnvironment.DEFAULT,
265
- api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("FATHOM_API_KEY"),
292
+ api_key: str,
266
293
  timeout: typing.Optional[float] = None,
267
294
  follow_redirects: typing.Optional[bool] = True,
268
295
  httpx_client: typing.Optional[httpx.AsyncClient] = None,
@@ -270,10 +297,6 @@ class AsyncBaseClient:
270
297
  _defaulted_timeout = (
271
298
  timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
272
299
  )
273
- if api_key is None:
274
- raise ApiError(
275
- body="The client must be instantiated be either passing in api_key or setting FATHOM_API_KEY"
276
- )
277
300
  self._client_wrapper = AsyncClientWrapper(
278
301
  base_url=_get_base_url(base_url=base_url, environment=environment),
279
302
  api_key=api_key,
@@ -303,12 +326,15 @@ class AsyncBaseClient:
303
326
  recorded_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
304
327
  teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
305
328
  calendar_invitees: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
329
+ created_before: typing.Optional[str] = None,
306
330
  created_after: typing.Optional[str] = None,
331
+ calendar_invitees_domains: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
307
332
  meeting_type: typing.Optional[ListMeetingsRequestMeetingType] = None,
308
333
  include_transcript: typing.Optional[bool] = None,
334
+ include_crm_matches: typing.Optional[bool] = None,
309
335
  cursor: typing.Optional[str] = None,
310
336
  request_options: typing.Optional[RequestOptions] = None,
311
- ) -> MeetingListResponse:
337
+ ) -> AsyncPager[Meeting]:
312
338
  """
313
339
  Parameters
314
340
  ----------
@@ -329,7 +355,7 @@ class AsyncBaseClient:
329
355
  Returns meetings that belong to any of the specified teams.
330
356
 
331
357
  calendar_invitees : typing.Optional[typing.Union[str, typing.Sequence[str]]]
332
- Email addresses of calendar_invitees.
358
+ Email address of calendar_invitees to filter by.
333
359
 
334
360
  Pass the parameter once per value, e.g.
335
361
  `calendar_invitees[]=cfo@acme.com&calendar_invitees[]=legal@acme.com`.
@@ -337,15 +363,29 @@ class AsyncBaseClient:
337
363
  Returns meetings where any of the given email addresses appear
338
364
  in the calendar_invitees list.
339
365
 
366
+ created_before : typing.Optional[str]
367
+ Filter to meetings with created_at before this timestamp, e.g. `created_before=2025-01-01T00:00:00Z`.
368
+
340
369
  created_after : typing.Optional[str]
341
370
  Filter to meetings with created_at after this timestamp, e.g. `created_after=2025-01-01T00:00:00Z`.
342
371
 
372
+ calendar_invitees_domains : typing.Optional[typing.Union[str, typing.Sequence[str]]]
373
+ Domains of the companies to filter by. Exact match.
374
+
375
+ Pass the parameter once per value, e.g.
376
+ `calendar_invitees_domains[]=acme.com&calendar_invitees_domains[]=client.com`.
377
+
378
+ Returns meetings where any of the given company domains appear in the meeting.
379
+
343
380
  meeting_type : typing.Optional[ListMeetingsRequestMeetingType]
344
381
  Filter by meeting type.
345
382
 
346
383
  include_transcript : typing.Optional[bool]
347
384
  Include the transcript for each meeting.
348
385
 
386
+ include_crm_matches : typing.Optional[bool]
387
+ Include CRM matches for each meeting. Only returns data from your or your team's linked CRM.
388
+
349
389
  cursor : typing.Optional[str]
350
390
  Cursor for pagination.
351
391
 
@@ -354,7 +394,7 @@ class AsyncBaseClient:
354
394
 
355
395
  Returns
356
396
  -------
357
- MeetingListResponse
397
+ AsyncPager[Meeting]
358
398
  Paginated list of meetings.
359
399
 
360
400
  Examples
@@ -363,24 +403,32 @@ class AsyncBaseClient:
363
403
  import asyncio
364
404
  client = AsyncFathomApi(api_key="YOUR_API_KEY", )
365
405
  async def main() -> None:
366
- await client.list_meetings()
406
+ response = await client.list_meetings()
407
+ async for item in response:
408
+ yield item
409
+
410
+ # alternatively, you can paginate page-by-page
411
+ async for page in response.iter_pages():
412
+ yield page
367
413
  asyncio.run(main())
368
414
  """
369
- _response = await self._raw_client.list_meetings(
415
+ return await self._raw_client.list_meetings(
370
416
  recorded_by=recorded_by,
371
417
  teams=teams,
372
418
  calendar_invitees=calendar_invitees,
419
+ created_before=created_before,
373
420
  created_after=created_after,
421
+ calendar_invitees_domains=calendar_invitees_domains,
374
422
  meeting_type=meeting_type,
375
423
  include_transcript=include_transcript,
424
+ include_crm_matches=include_crm_matches,
376
425
  cursor=cursor,
377
426
  request_options=request_options,
378
427
  )
379
- return _response.data
380
428
 
381
429
  async def list_teams(
382
430
  self, *, cursor: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
383
- ) -> TeamListResponse:
431
+ ) -> AsyncPager[Team]:
384
432
  """
385
433
  Parameters
386
434
  ----------
@@ -392,7 +440,7 @@ class AsyncBaseClient:
392
440
 
393
441
  Returns
394
442
  -------
395
- TeamListResponse
443
+ AsyncPager[Team]
396
444
  Paginated list of teams.
397
445
 
398
446
  Examples
@@ -401,11 +449,16 @@ class AsyncBaseClient:
401
449
  import asyncio
402
450
  client = AsyncFathomApi(api_key="YOUR_API_KEY", )
403
451
  async def main() -> None:
404
- await client.list_teams()
452
+ response = await client.list_teams()
453
+ async for item in response:
454
+ yield item
455
+
456
+ # alternatively, you can paginate page-by-page
457
+ async for page in response.iter_pages():
458
+ yield page
405
459
  asyncio.run(main())
406
460
  """
407
- _response = await self._raw_client.list_teams(cursor=cursor, request_options=request_options)
408
- return _response.data
461
+ return await self._raw_client.list_teams(cursor=cursor, request_options=request_options)
409
462
 
410
463
  async def list_team_members(
411
464
  self,
@@ -413,7 +466,7 @@ class AsyncBaseClient:
413
466
  team: typing.Optional[str] = None,
414
467
  cursor: typing.Optional[str] = None,
415
468
  request_options: typing.Optional[RequestOptions] = None,
416
- ) -> TeamMemberListResponse:
469
+ ) -> AsyncPager[TeamMember]:
417
470
  """
418
471
  Parameters
419
472
  ----------
@@ -428,7 +481,7 @@ class AsyncBaseClient:
428
481
 
429
482
  Returns
430
483
  -------
431
- TeamMemberListResponse
484
+ AsyncPager[TeamMember]
432
485
  Paginated list of team members.
433
486
 
434
487
  Examples
@@ -437,11 +490,16 @@ class AsyncBaseClient:
437
490
  import asyncio
438
491
  client = AsyncFathomApi(api_key="YOUR_API_KEY", )
439
492
  async def main() -> None:
440
- await client.list_team_members()
493
+ response = await client.list_team_members()
494
+ async for item in response:
495
+ yield item
496
+
497
+ # alternatively, you can paginate page-by-page
498
+ async for page in response.iter_pages():
499
+ yield page
441
500
  asyncio.run(main())
442
501
  """
443
- _response = await self._raw_client.list_team_members(team=team, cursor=cursor, request_options=request_options)
444
- return _response.data
502
+ return await self._raw_client.list_team_members(team=team, cursor=cursor, request_options=request_options)
445
503
 
446
504
 
447
505
  def _get_base_url(*, base_url: typing.Optional[str] = None, environment: FathomApiEnvironment) -> str:
fathom/core/__init__.py CHANGED
@@ -9,6 +9,7 @@ from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
9
9
  from .http_client import AsyncHttpClient, HttpClient
10
10
  from .http_response import AsyncHttpResponse, HttpResponse
11
11
  from .jsonable_encoder import jsonable_encoder
12
+ from .pagination import AsyncPager, SyncPager
12
13
  from .pydantic_utilities import (
13
14
  IS_PYDANTIC_V2,
14
15
  UniversalBaseModel,
@@ -28,6 +29,7 @@ __all__ = [
28
29
  "AsyncClientWrapper",
29
30
  "AsyncHttpClient",
30
31
  "AsyncHttpResponse",
32
+ "AsyncPager",
31
33
  "BaseClientWrapper",
32
34
  "FieldMetadata",
33
35
  "File",
@@ -36,6 +38,7 @@ __all__ = [
36
38
  "IS_PYDANTIC_V2",
37
39
  "RequestOptions",
38
40
  "SyncClientWrapper",
41
+ "SyncPager",
39
42
  "UniversalBaseModel",
40
43
  "UniversalRootModel",
41
44
  "convert_and_respect_annotation_metadata",
@@ -7,33 +7,21 @@ from .http_client import AsyncHttpClient, HttpClient
7
7
 
8
8
 
9
9
  class BaseClientWrapper:
10
- def __init__(
11
- self,
12
- *,
13
- api_key: typing.Union[str, typing.Callable[[], str]],
14
- base_url: str,
15
- timeout: typing.Optional[float] = None,
16
- ):
17
- self._api_key = api_key
10
+ def __init__(self, *, api_key: str, base_url: str, timeout: typing.Optional[float] = None):
11
+ self.api_key = api_key
18
12
  self._base_url = base_url
19
13
  self._timeout = timeout
20
14
 
21
15
  def get_headers(self) -> typing.Dict[str, str]:
22
16
  headers: typing.Dict[str, str] = {
23
- "User-Agent": "fathom-python/0.0.25",
17
+ "User-Agent": "fathom-python/0.0.27",
24
18
  "X-Fern-Language": "Python",
25
19
  "X-Fern-SDK-Name": "fathom-python",
26
- "X-Fern-SDK-Version": "0.0.25",
20
+ "X-Fern-SDK-Version": "0.0.27",
27
21
  }
28
- headers["Authorization"] = f"Bearer {self._get_api_key()}"
22
+ headers["X-Api-Key"] = self.api_key
29
23
  return headers
30
24
 
31
- def _get_api_key(self) -> str:
32
- if isinstance(self._api_key, str):
33
- return self._api_key
34
- else:
35
- return self._api_key()
36
-
37
25
  def get_base_url(self) -> str:
38
26
  return self._base_url
39
27
 
@@ -43,12 +31,7 @@ class BaseClientWrapper:
43
31
 
44
32
  class SyncClientWrapper(BaseClientWrapper):
45
33
  def __init__(
46
- self,
47
- *,
48
- api_key: typing.Union[str, typing.Callable[[], str]],
49
- base_url: str,
50
- timeout: typing.Optional[float] = None,
51
- httpx_client: httpx.Client,
34
+ self, *, api_key: str, base_url: str, timeout: typing.Optional[float] = None, httpx_client: httpx.Client
52
35
  ):
53
36
  super().__init__(api_key=api_key, base_url=base_url, timeout=timeout)
54
37
  self.httpx_client = HttpClient(
@@ -61,12 +44,7 @@ class SyncClientWrapper(BaseClientWrapper):
61
44
 
62
45
  class AsyncClientWrapper(BaseClientWrapper):
63
46
  def __init__(
64
- self,
65
- *,
66
- api_key: typing.Union[str, typing.Callable[[], str]],
67
- base_url: str,
68
- timeout: typing.Optional[float] = None,
69
- httpx_client: httpx.AsyncClient,
47
+ self, *, api_key: str, base_url: str, timeout: typing.Optional[float] = None, httpx_client: httpx.AsyncClient
70
48
  ):
71
49
  super().__init__(api_key=api_key, base_url=base_url, timeout=timeout)
72
50
  self.httpx_client = AsyncHttpClient(
@@ -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
+ T = TypeVar("T")
11
+ """Generic to represent the underlying type of the results within a page"""
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
fathom/raw_base_client.py CHANGED
@@ -5,14 +5,17 @@ from json.decoder import JSONDecodeError
5
5
 
6
6
  from .core.api_error import ApiError
7
7
  from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
- from .core.http_response import AsyncHttpResponse, HttpResponse
8
+ from .core.pagination import AsyncPager, BaseHttpResponse, SyncPager
9
9
  from .core.pydantic_utilities import parse_obj_as
10
10
  from .core.request_options import RequestOptions
11
11
  from .errors.bad_request_error import BadRequestError
12
12
  from .errors.unauthorized_error import UnauthorizedError
13
13
  from .types.list_meetings_request_meeting_type import ListMeetingsRequestMeetingType
14
+ from .types.meeting import Meeting
14
15
  from .types.meeting_list_response import MeetingListResponse
16
+ from .types.team import Team
15
17
  from .types.team_list_response import TeamListResponse
18
+ from .types.team_member import TeamMember
16
19
  from .types.team_member_list_response import TeamMemberListResponse
17
20
 
18
21
 
@@ -26,12 +29,15 @@ class RawBaseClient:
26
29
  recorded_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
27
30
  teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
28
31
  calendar_invitees: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
32
+ created_before: typing.Optional[str] = None,
29
33
  created_after: typing.Optional[str] = None,
34
+ calendar_invitees_domains: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
30
35
  meeting_type: typing.Optional[ListMeetingsRequestMeetingType] = None,
31
36
  include_transcript: typing.Optional[bool] = None,
37
+ include_crm_matches: typing.Optional[bool] = None,
32
38
  cursor: typing.Optional[str] = None,
33
39
  request_options: typing.Optional[RequestOptions] = None,
34
- ) -> HttpResponse[MeetingListResponse]:
40
+ ) -> SyncPager[Meeting]:
35
41
  """
36
42
  Parameters
37
43
  ----------
@@ -52,7 +58,7 @@ class RawBaseClient:
52
58
  Returns meetings that belong to any of the specified teams.
53
59
 
54
60
  calendar_invitees : typing.Optional[typing.Union[str, typing.Sequence[str]]]
55
- Email addresses of calendar_invitees.
61
+ Email address of calendar_invitees to filter by.
56
62
 
57
63
  Pass the parameter once per value, e.g.
58
64
  `calendar_invitees[]=cfo@acme.com&calendar_invitees[]=legal@acme.com`.
@@ -60,15 +66,29 @@ class RawBaseClient:
60
66
  Returns meetings where any of the given email addresses appear
61
67
  in the calendar_invitees list.
62
68
 
69
+ created_before : typing.Optional[str]
70
+ Filter to meetings with created_at before this timestamp, e.g. `created_before=2025-01-01T00:00:00Z`.
71
+
63
72
  created_after : typing.Optional[str]
64
73
  Filter to meetings with created_at after this timestamp, e.g. `created_after=2025-01-01T00:00:00Z`.
65
74
 
75
+ calendar_invitees_domains : typing.Optional[typing.Union[str, typing.Sequence[str]]]
76
+ Domains of the companies to filter by. Exact match.
77
+
78
+ Pass the parameter once per value, e.g.
79
+ `calendar_invitees_domains[]=acme.com&calendar_invitees_domains[]=client.com`.
80
+
81
+ Returns meetings where any of the given company domains appear in the meeting.
82
+
66
83
  meeting_type : typing.Optional[ListMeetingsRequestMeetingType]
67
84
  Filter by meeting type.
68
85
 
69
86
  include_transcript : typing.Optional[bool]
70
87
  Include the transcript for each meeting.
71
88
 
89
+ include_crm_matches : typing.Optional[bool]
90
+ Include CRM matches for each meeting. Only returns data from your or your team's linked CRM.
91
+
72
92
  cursor : typing.Optional[str]
73
93
  Cursor for pagination.
74
94
 
@@ -77,7 +97,7 @@ class RawBaseClient:
77
97
 
78
98
  Returns
79
99
  -------
80
- HttpResponse[MeetingListResponse]
100
+ SyncPager[Meeting]
81
101
  Paginated list of meetings.
82
102
  """
83
103
  _response = self._client_wrapper.httpx_client.request(
@@ -87,23 +107,44 @@ class RawBaseClient:
87
107
  "recorded_by[]": recorded_by,
88
108
  "teams[]": teams,
89
109
  "calendar_invitees[]": calendar_invitees,
110
+ "created_before": created_before,
90
111
  "created_after": created_after,
112
+ "calendar_invitees_domains[]": calendar_invitees_domains,
91
113
  "meeting_type": meeting_type,
92
114
  "include_transcript": include_transcript,
115
+ "include_crm_matches": include_crm_matches,
93
116
  "cursor": cursor,
94
117
  },
95
118
  request_options=request_options,
96
119
  )
97
120
  try:
98
121
  if 200 <= _response.status_code < 300:
99
- _data = typing.cast(
122
+ _parsed_response = typing.cast(
100
123
  MeetingListResponse,
101
124
  parse_obj_as(
102
125
  type_=MeetingListResponse, # type: ignore
103
126
  object_=_response.json(),
104
127
  ),
105
128
  )
106
- return HttpResponse(response=_response, data=_data)
129
+ _items = _parsed_response.items
130
+ _parsed_next = _parsed_response.next_cursor
131
+ _has_next = _parsed_next is not None and _parsed_next != ""
132
+ _get_next = lambda: self.list_meetings(
133
+ recorded_by=recorded_by,
134
+ teams=teams,
135
+ calendar_invitees=calendar_invitees,
136
+ created_before=created_before,
137
+ created_after=created_after,
138
+ calendar_invitees_domains=calendar_invitees_domains,
139
+ meeting_type=meeting_type,
140
+ include_transcript=include_transcript,
141
+ include_crm_matches=include_crm_matches,
142
+ cursor=_parsed_next,
143
+ request_options=request_options,
144
+ )
145
+ return SyncPager(
146
+ has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
147
+ )
107
148
  if _response.status_code == 400:
108
149
  raise BadRequestError(
109
150
  headers=dict(_response.headers),
@@ -133,7 +174,7 @@ class RawBaseClient:
133
174
 
134
175
  def list_teams(
135
176
  self, *, cursor: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
136
- ) -> HttpResponse[TeamListResponse]:
177
+ ) -> SyncPager[Team]:
137
178
  """
138
179
  Parameters
139
180
  ----------
@@ -145,7 +186,7 @@ class RawBaseClient:
145
186
 
146
187
  Returns
147
188
  -------
148
- HttpResponse[TeamListResponse]
189
+ SyncPager[Team]
149
190
  Paginated list of teams.
150
191
  """
151
192
  _response = self._client_wrapper.httpx_client.request(
@@ -158,14 +199,23 @@ class RawBaseClient:
158
199
  )
159
200
  try:
160
201
  if 200 <= _response.status_code < 300:
161
- _data = typing.cast(
202
+ _parsed_response = typing.cast(
162
203
  TeamListResponse,
163
204
  parse_obj_as(
164
205
  type_=TeamListResponse, # type: ignore
165
206
  object_=_response.json(),
166
207
  ),
167
208
  )
168
- return HttpResponse(response=_response, data=_data)
209
+ _items = _parsed_response.items
210
+ _parsed_next = _parsed_response.next_cursor
211
+ _has_next = _parsed_next is not None and _parsed_next != ""
212
+ _get_next = lambda: self.list_teams(
213
+ cursor=_parsed_next,
214
+ request_options=request_options,
215
+ )
216
+ return SyncPager(
217
+ has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
218
+ )
169
219
  if _response.status_code == 400:
170
220
  raise BadRequestError(
171
221
  headers=dict(_response.headers),
@@ -199,7 +249,7 @@ class RawBaseClient:
199
249
  team: typing.Optional[str] = None,
200
250
  cursor: typing.Optional[str] = None,
201
251
  request_options: typing.Optional[RequestOptions] = None,
202
- ) -> HttpResponse[TeamMemberListResponse]:
252
+ ) -> SyncPager[TeamMember]:
203
253
  """
204
254
  Parameters
205
255
  ----------
@@ -214,7 +264,7 @@ class RawBaseClient:
214
264
 
215
265
  Returns
216
266
  -------
217
- HttpResponse[TeamMemberListResponse]
267
+ SyncPager[TeamMember]
218
268
  Paginated list of team members.
219
269
  """
220
270
  _response = self._client_wrapper.httpx_client.request(
@@ -228,14 +278,24 @@ class RawBaseClient:
228
278
  )
229
279
  try:
230
280
  if 200 <= _response.status_code < 300:
231
- _data = typing.cast(
281
+ _parsed_response = typing.cast(
232
282
  TeamMemberListResponse,
233
283
  parse_obj_as(
234
284
  type_=TeamMemberListResponse, # type: ignore
235
285
  object_=_response.json(),
236
286
  ),
237
287
  )
238
- return HttpResponse(response=_response, data=_data)
288
+ _items = _parsed_response.items
289
+ _parsed_next = _parsed_response.next_cursor
290
+ _has_next = _parsed_next is not None and _parsed_next != ""
291
+ _get_next = lambda: self.list_team_members(
292
+ team=team,
293
+ cursor=_parsed_next,
294
+ request_options=request_options,
295
+ )
296
+ return SyncPager(
297
+ has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
298
+ )
239
299
  if _response.status_code == 400:
240
300
  raise BadRequestError(
241
301
  headers=dict(_response.headers),
@@ -274,12 +334,15 @@ class AsyncRawBaseClient:
274
334
  recorded_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
275
335
  teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
276
336
  calendar_invitees: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
337
+ created_before: typing.Optional[str] = None,
277
338
  created_after: typing.Optional[str] = None,
339
+ calendar_invitees_domains: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
278
340
  meeting_type: typing.Optional[ListMeetingsRequestMeetingType] = None,
279
341
  include_transcript: typing.Optional[bool] = None,
342
+ include_crm_matches: typing.Optional[bool] = None,
280
343
  cursor: typing.Optional[str] = None,
281
344
  request_options: typing.Optional[RequestOptions] = None,
282
- ) -> AsyncHttpResponse[MeetingListResponse]:
345
+ ) -> AsyncPager[Meeting]:
283
346
  """
284
347
  Parameters
285
348
  ----------
@@ -300,7 +363,7 @@ class AsyncRawBaseClient:
300
363
  Returns meetings that belong to any of the specified teams.
301
364
 
302
365
  calendar_invitees : typing.Optional[typing.Union[str, typing.Sequence[str]]]
303
- Email addresses of calendar_invitees.
366
+ Email address of calendar_invitees to filter by.
304
367
 
305
368
  Pass the parameter once per value, e.g.
306
369
  `calendar_invitees[]=cfo@acme.com&calendar_invitees[]=legal@acme.com`.
@@ -308,15 +371,29 @@ class AsyncRawBaseClient:
308
371
  Returns meetings where any of the given email addresses appear
309
372
  in the calendar_invitees list.
310
373
 
374
+ created_before : typing.Optional[str]
375
+ Filter to meetings with created_at before this timestamp, e.g. `created_before=2025-01-01T00:00:00Z`.
376
+
311
377
  created_after : typing.Optional[str]
312
378
  Filter to meetings with created_at after this timestamp, e.g. `created_after=2025-01-01T00:00:00Z`.
313
379
 
380
+ calendar_invitees_domains : typing.Optional[typing.Union[str, typing.Sequence[str]]]
381
+ Domains of the companies to filter by. Exact match.
382
+
383
+ Pass the parameter once per value, e.g.
384
+ `calendar_invitees_domains[]=acme.com&calendar_invitees_domains[]=client.com`.
385
+
386
+ Returns meetings where any of the given company domains appear in the meeting.
387
+
314
388
  meeting_type : typing.Optional[ListMeetingsRequestMeetingType]
315
389
  Filter by meeting type.
316
390
 
317
391
  include_transcript : typing.Optional[bool]
318
392
  Include the transcript for each meeting.
319
393
 
394
+ include_crm_matches : typing.Optional[bool]
395
+ Include CRM matches for each meeting. Only returns data from your or your team's linked CRM.
396
+
320
397
  cursor : typing.Optional[str]
321
398
  Cursor for pagination.
322
399
 
@@ -325,7 +402,7 @@ class AsyncRawBaseClient:
325
402
 
326
403
  Returns
327
404
  -------
328
- AsyncHttpResponse[MeetingListResponse]
405
+ AsyncPager[Meeting]
329
406
  Paginated list of meetings.
330
407
  """
331
408
  _response = await self._client_wrapper.httpx_client.request(
@@ -335,23 +412,47 @@ class AsyncRawBaseClient:
335
412
  "recorded_by[]": recorded_by,
336
413
  "teams[]": teams,
337
414
  "calendar_invitees[]": calendar_invitees,
415
+ "created_before": created_before,
338
416
  "created_after": created_after,
417
+ "calendar_invitees_domains[]": calendar_invitees_domains,
339
418
  "meeting_type": meeting_type,
340
419
  "include_transcript": include_transcript,
420
+ "include_crm_matches": include_crm_matches,
341
421
  "cursor": cursor,
342
422
  },
343
423
  request_options=request_options,
344
424
  )
345
425
  try:
346
426
  if 200 <= _response.status_code < 300:
347
- _data = typing.cast(
427
+ _parsed_response = typing.cast(
348
428
  MeetingListResponse,
349
429
  parse_obj_as(
350
430
  type_=MeetingListResponse, # type: ignore
351
431
  object_=_response.json(),
352
432
  ),
353
433
  )
354
- return AsyncHttpResponse(response=_response, data=_data)
434
+ _items = _parsed_response.items
435
+ _parsed_next = _parsed_response.next_cursor
436
+ _has_next = _parsed_next is not None and _parsed_next != ""
437
+
438
+ async def _get_next():
439
+ return await self.list_meetings(
440
+ recorded_by=recorded_by,
441
+ teams=teams,
442
+ calendar_invitees=calendar_invitees,
443
+ created_before=created_before,
444
+ created_after=created_after,
445
+ calendar_invitees_domains=calendar_invitees_domains,
446
+ meeting_type=meeting_type,
447
+ include_transcript=include_transcript,
448
+ include_crm_matches=include_crm_matches,
449
+ cursor=_parsed_next,
450
+ request_options=request_options,
451
+ )
452
+
453
+ return AsyncPager(
454
+ has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
455
+ )
355
456
  if _response.status_code == 400:
356
457
  raise BadRequestError(
357
458
  headers=dict(_response.headers),
@@ -381,7 +482,7 @@ class AsyncRawBaseClient:
381
482
 
382
483
  async def list_teams(
383
484
  self, *, cursor: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
384
- ) -> AsyncHttpResponse[TeamListResponse]:
485
+ ) -> AsyncPager[Team]:
385
486
  """
386
487
  Parameters
387
488
  ----------
@@ -393,7 +494,7 @@ class AsyncRawBaseClient:
393
494
 
394
495
  Returns
395
496
  -------
396
- AsyncHttpResponse[TeamListResponse]
497
+ AsyncPager[Team]
397
498
  Paginated list of teams.
398
499
  """
399
500
  _response = await self._client_wrapper.httpx_client.request(
@@ -406,14 +507,26 @@ class AsyncRawBaseClient:
406
507
  )
407
508
  try:
408
509
  if 200 <= _response.status_code < 300:
409
- _data = typing.cast(
510
+ _parsed_response = typing.cast(
410
511
  TeamListResponse,
411
512
  parse_obj_as(
412
513
  type_=TeamListResponse, # type: ignore
413
514
  object_=_response.json(),
414
515
  ),
415
516
  )
416
- return AsyncHttpResponse(response=_response, data=_data)
517
+ _items = _parsed_response.items
518
+ _parsed_next = _parsed_response.next_cursor
519
+ _has_next = _parsed_next is not None and _parsed_next != ""
520
+
521
+ async def _get_next():
522
+ return await self.list_teams(
523
+ cursor=_parsed_next,
524
+ request_options=request_options,
525
+ )
526
+
527
+ return AsyncPager(
528
+ has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
529
+ )
417
530
  if _response.status_code == 400:
418
531
  raise BadRequestError(
419
532
  headers=dict(_response.headers),
@@ -447,7 +560,7 @@ class AsyncRawBaseClient:
447
560
  team: typing.Optional[str] = None,
448
561
  cursor: typing.Optional[str] = None,
449
562
  request_options: typing.Optional[RequestOptions] = None,
450
- ) -> AsyncHttpResponse[TeamMemberListResponse]:
563
+ ) -> AsyncPager[TeamMember]:
451
564
  """
452
565
  Parameters
453
566
  ----------
@@ -462,7 +575,7 @@ class AsyncRawBaseClient:
462
575
 
463
576
  Returns
464
577
  -------
465
- AsyncHttpResponse[TeamMemberListResponse]
578
+ AsyncPager[TeamMember]
466
579
  Paginated list of team members.
467
580
  """
468
581
  _response = await self._client_wrapper.httpx_client.request(
@@ -476,14 +589,27 @@ class AsyncRawBaseClient:
476
589
  )
477
590
  try:
478
591
  if 200 <= _response.status_code < 300:
479
- _data = typing.cast(
592
+ _parsed_response = typing.cast(
480
593
  TeamMemberListResponse,
481
594
  parse_obj_as(
482
595
  type_=TeamMemberListResponse, # type: ignore
483
596
  object_=_response.json(),
484
597
  ),
485
598
  )
486
- return AsyncHttpResponse(response=_response, data=_data)
599
+ _items = _parsed_response.items
600
+ _parsed_next = _parsed_response.next_cursor
601
+ _has_next = _parsed_next is not None and _parsed_next != ""
602
+
603
+ async def _get_next():
604
+ return await self.list_team_members(
605
+ team=team,
606
+ cursor=_parsed_next,
607
+ request_options=request_options,
608
+ )
609
+
610
+ return AsyncPager(
611
+ has_next=_has_next, items=_items, get_next=_get_next, response=BaseHttpResponse(response=_response)
612
+ )
487
613
  if _response.status_code == 400:
488
614
  raise BadRequestError(
489
615
  headers=dict(_response.headers),
fathom/types/assignee.py CHANGED
@@ -7,8 +7,8 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
7
 
8
8
 
9
9
  class Assignee(UniversalBaseModel):
10
- name: str
11
- email: str
10
+ name: typing.Optional[str] = None
11
+ email: typing.Optional[str] = None
12
12
  team: typing.Optional[str] = None
13
13
 
14
14
  if IS_PYDANTIC_V2:
@@ -8,7 +8,11 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
8
 
9
9
  class CrmDealMatch(UniversalBaseModel):
10
10
  name: str
11
- amount: int
11
+ amount: float = pydantic.Field()
12
+ """
13
+ The amount in dollars.
14
+ """
15
+
12
16
  record_url: str
13
17
 
14
18
  if IS_PYDANTIC_V2:
@@ -11,7 +11,7 @@ from .crm_deal_match import CrmDealMatch
11
11
 
12
12
  class CrmMatches(UniversalBaseModel):
13
13
  """
14
- **Coming soon** - CRM match data is not yet available in API responses.
14
+ CRM data linked to the meeting. Only returns data from your or your team's linked CRM.
15
15
  If no CRM is connected for the workspace, the `error` field will be populated.
16
16
  """
17
17
 
fathom/types/invitee.py CHANGED
@@ -7,9 +7,9 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
7
 
8
8
 
9
9
  class Invitee(UniversalBaseModel):
10
- name: str
10
+ name: typing.Optional[str] = None
11
11
  matched_speaker_display_name: typing.Optional[str] = None
12
- email: str
12
+ email: typing.Optional[str] = None
13
13
  is_external: bool
14
14
 
15
15
  if IS_PYDANTIC_V2:
fathom/types/meeting.py CHANGED
@@ -21,11 +21,6 @@ class Meeting(UniversalBaseModel):
21
21
  Calendar event title.
22
22
  """
23
23
 
24
- abstract: typing.Optional[str] = pydantic.Field(default=None)
25
- """
26
- Short meeting summary.
27
- """
28
-
29
24
  url: str
30
25
  share_url: str
31
26
  created_at: dt.datetime
@@ -34,11 +29,11 @@ class Meeting(UniversalBaseModel):
34
29
  recording_start_time: dt.datetime
35
30
  recording_end_time: dt.datetime
36
31
  meeting_type: MeetingMeetingType
32
+ transcript_language: str
37
33
  transcript: typing.Optional[typing.List[TranscriptItem]] = None
38
- summary: typing.Optional[MeetingSummary] = None
34
+ default_summary: typing.Optional[MeetingSummary] = None
39
35
  action_items: typing.Optional[typing.List[ActionItem]] = None
40
36
  calendar_invitees: typing.List[Invitee]
41
- transcript_language: str
42
37
  recorded_by: FathomUser
43
38
  crm_matches: typing.Optional[CrmMatches] = None
44
39
 
@@ -8,7 +8,7 @@ from .meeting import Meeting
8
8
 
9
9
 
10
10
  class MeetingListResponse(UniversalBaseModel):
11
- limit: int
11
+ limit: typing.Optional[int] = None
12
12
  next_cursor: typing.Optional[str] = None
13
13
  items: typing.List[Meeting]
14
14
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fathom-python
3
- Version: 0.0.25
3
+ Version: 0.0.27
4
4
  Summary:
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Intended Audience :: Developers
@@ -1,15 +1,16 @@
1
1
  fathom/__init__.py,sha256=dBibCxSr7T9FV3mfW_hkQ1hOPTqt8gPC0dMa4ub3Sv8,1227
2
- fathom/base_client.py,sha256=k-Z2XYZ59MKs82zsTup0edBND7dMz5l4G_S8f_82pGc,16496
2
+ fathom/base_client.py,sha256=CAkMW-t38xdBgckdOlBIQXK92CfZL2jeBWDIxm45XPk,18961
3
3
  fathom/client.py,sha256=8o_WuoWBVyKB6xDmqqZqOJCBJia8eGrapg0Q6yzNUeg,500
4
- fathom/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
4
+ fathom/core/__init__.py,sha256=4POYbbRlgR7TwGFY5nmHpaa7nFgXOX_pYHcN1Ezh2p8,1643
5
5
  fathom/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
6
- fathom/core/client_wrapper.py,sha256=Cl_-KZVFlx_6__7uvloAwptEEkL66J5vHD4W3otURCw,2270
6
+ fathom/core/client_wrapper.py,sha256=XEfbxVMSYOLpvCv8wM2WcLnBvlT3PQUFsjX7mTcL2PM,1836
7
7
  fathom/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
8
8
  fathom/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
9
9
  fathom/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
10
10
  fathom/core/http_client.py,sha256=QurkBvCZZz2Z1d8znp4M2YbOXebBUPcPXRhPIS84Wvk,21214
11
11
  fathom/core/http_response.py,sha256=4uOAtXXFTyFXHLXeQWSfQST9PGcOCRAdHVgGTxdyg84,1334
12
12
  fathom/core/jsonable_encoder.py,sha256=hGgcEEeX11sqxxsll7h15pO3pTNVxk_n79Kcn0laoWA,3655
13
+ fathom/core/pagination.py,sha256=ALaZ0NatgXUByLSuyyMwGABMpANR2cWRePgp5rtNQbo,2868
13
14
  fathom/core/pydantic_utilities.py,sha256=HxbbISfaP1XBvzbIkc0ZcF_GHKd9BfYsJAcFh9B126k,10787
14
15
  fathom/core/query_encoder.py,sha256=ekulqNd0j8TgD7ox-Qbz7liqX8-KP9blvT9DsRCenYM,2144
15
16
  fathom/core/remove_none_from_dict.py,sha256=EU9SGgYidWq7SexuJbNs4-PZ-5Bl3Vppd864mS6vQZw,342
@@ -20,19 +21,19 @@ fathom/errors/__init__.py,sha256=Ua3Z6OWyRhcgrq0FSXOpwmOc4RxyTgzP2LXbkzGbMhk,234
20
21
  fathom/errors/bad_request_error.py,sha256=PnE3v3kETCXm9E3LiNcHLNtjPEUvpe98-r59q-kQb78,338
21
22
  fathom/errors/unauthorized_error.py,sha256=mryinHCAaknn5St2VF17R9XybZUcWRRYWEjxg63dQSA,340
22
23
  fathom/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- fathom/raw_base_client.py,sha256=PUMmbRqTNIDZ2CZQ7j90jOgMkUbRvJiCcRwh106ThFQ,20197
24
+ fathom/raw_base_client.py,sha256=EZDi1xVpKJvFxGN91igKSRmxiIVNpWQHYBiBJGILZCY,26338
24
25
  fathom/types/__init__.py,sha256=Q0EMWBgFpA3vP3JPSIEQ01ek63ptoInTP7dEYoYslSs,1350
25
26
  fathom/types/action_item.py,sha256=twWuS_Rg4R4crXt6OEZmPbk1qQziPiZCY392nbZDui4,854
26
- fathom/types/assignee.py,sha256=miCmTy4uvGVJEkVXif0Spt76R5SYOX-2augtqFHEizc,568
27
+ fathom/types/assignee.py,sha256=9lEX-MEAK-BEIpcCaHEwikpAI7UPJTJqYidJ0pa8bto,616
27
28
  fathom/types/crm_company_match.py,sha256=Eb4ai8sE0hbeJCYpO_qHk_RiE_qbsvUmLsc_dF59NZU,542
28
29
  fathom/types/crm_contact_match.py,sha256=hPi_-tVuCU6y-kmx9PYNbpMgEJmLSfPsXErSac16Ag0,557
29
- fathom/types/crm_deal_match.py,sha256=m3VCj78bg0m-AGyLYNt7oNj8fJ7ebgWuRwrROoL70Y0,555
30
- fathom/types/crm_matches.py,sha256=c_KwylurVtz-un2m2Dmm1SSiGZgpr-z_Tbw1IIdt7bw,1049
30
+ fathom/types/crm_deal_match.py,sha256=PU1zkCx0U2LPxFyxY7VmsMnDz_LArHDJcqtIdNKl3ok,620
31
+ fathom/types/crm_matches.py,sha256=pjY3f2XCEhYXK-pcnLFaHYgf7Iwagi6BwVJ063ToXE4,1064
31
32
  fathom/types/fathom_user.py,sha256=pbazdvCuf773i6KykIS1LFOLZs8t114HZzD9pw-w53E,570
32
- fathom/types/invitee.py,sha256=XWoooSUrs9aG30pr14I-DP_uz5Owbb8zeUK92Vj7si8,613
33
+ fathom/types/invitee.py,sha256=ktdjTyobFOHzEiSLqsHijWMtNj63F3e8r-1gtNDi-aI,661
33
34
  fathom/types/list_meetings_request_meeting_type.py,sha256=SuiWhjvW_6CrfxfcPx5MkzHMfVMa1R94WnVFcsDUkyw,185
34
- fathom/types/meeting.py,sha256=n9g9-Q7edtfntRZpCKz4DIOU-5Q-H5ISNIWTfVHBokQ,1594
35
- fathom/types/meeting_list_response.py,sha256=zOLT9Y-vc4qJ_ExdsM_k_l0PaVJhzCg6ehlCqZDDhY4,633
35
+ fathom/types/meeting.py,sha256=Tq6MG0-D7SPVzqSYKH9FfWU1-UmlOtBqWK8MkGqSBkY,1492
36
+ fathom/types/meeting_list_response.py,sha256=fLwJRhoYln2OevpYqnfBzJ-exCIjk9ewjipkJDKkp7w,657
36
37
  fathom/types/meeting_meeting_type.py,sha256=RDatwTAHwLn7U5mvkWJupIcWqYpGGd_bZPBXUtPb6Q8,166
37
38
  fathom/types/meeting_summary.py,sha256=l1tw0CfcFdc1YFWQ_huBwyAKiaP0eMGy118pl60L0AM,679
38
39
  fathom/types/team.py,sha256=Gcu_IVvtHFZCyEqZBYYOWss0J5O9Vua_QbktgFMjA9k,561
@@ -42,6 +43,6 @@ fathom/types/team_member_list_response.py,sha256=ryj2LciQ7YIjaIrlRISVOYS1Eak1e5S
42
43
  fathom/types/transcript_item.py,sha256=Iooc8CqKxrjxp5CjG-ZWgSzhThWe3h3RF7E6zLbUAwY,732
43
44
  fathom/types/transcript_item_speaker.py,sha256=BGViyMkjOBCK8I_iD3ZeYv3Nl32PIWi5ecsMAEfBwiQ,600
44
45
  fathom/version.py,sha256=ZqzW2It05JBdkkFCwQ_n2tpcYp3ivm-jvdflQl2gd6A,80
45
- fathom_python-0.0.25.dist-info/METADATA,sha256=EuuQcDKl6hlFyYJ_hSkr4dyV94CcYiKoEYVZXAdaJdk,4856
46
- fathom_python-0.0.25.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
47
- fathom_python-0.0.25.dist-info/RECORD,,
46
+ fathom_python-0.0.27.dist-info/METADATA,sha256=RUR-2J0pIPCw1_jff2-8KzU8x2BKwko1R9p-3xmPa8k,4856
47
+ fathom_python-0.0.27.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
48
+ fathom_python-0.0.27.dist-info/RECORD,,