devrev-Python-SDK 1.0.0__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.
Files changed (45) hide show
  1. devrev/__init__.py +47 -0
  2. devrev/client.py +343 -0
  3. devrev/config.py +180 -0
  4. devrev/exceptions.py +205 -0
  5. devrev/models/__init__.py +499 -0
  6. devrev/models/accounts.py +187 -0
  7. devrev/models/articles.py +109 -0
  8. devrev/models/base.py +147 -0
  9. devrev/models/code_changes.py +103 -0
  10. devrev/models/conversations.py +115 -0
  11. devrev/models/dev_users.py +258 -0
  12. devrev/models/groups.py +140 -0
  13. devrev/models/links.py +107 -0
  14. devrev/models/parts.py +110 -0
  15. devrev/models/rev_users.py +177 -0
  16. devrev/models/slas.py +112 -0
  17. devrev/models/tags.py +90 -0
  18. devrev/models/timeline_entries.py +100 -0
  19. devrev/models/webhooks.py +109 -0
  20. devrev/models/works.py +280 -0
  21. devrev/py.typed +1 -0
  22. devrev/services/__init__.py +74 -0
  23. devrev/services/accounts.py +325 -0
  24. devrev/services/articles.py +80 -0
  25. devrev/services/base.py +234 -0
  26. devrev/services/code_changes.py +80 -0
  27. devrev/services/conversations.py +98 -0
  28. devrev/services/dev_users.py +401 -0
  29. devrev/services/groups.py +103 -0
  30. devrev/services/links.py +68 -0
  31. devrev/services/parts.py +100 -0
  32. devrev/services/rev_users.py +235 -0
  33. devrev/services/slas.py +82 -0
  34. devrev/services/tags.py +80 -0
  35. devrev/services/timeline_entries.py +80 -0
  36. devrev/services/webhooks.py +80 -0
  37. devrev/services/works.py +363 -0
  38. devrev/utils/__init__.py +14 -0
  39. devrev/utils/deprecation.py +49 -0
  40. devrev/utils/http.py +521 -0
  41. devrev/utils/logging.py +139 -0
  42. devrev/utils/pagination.py +155 -0
  43. devrev_python_sdk-1.0.0.dist-info/METADATA +774 -0
  44. devrev_python_sdk-1.0.0.dist-info/RECORD +45 -0
  45. devrev_python_sdk-1.0.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,155 @@
1
+ """Pagination utilities for DevRev SDK.
2
+
3
+ This module provides iterator-based pagination for list endpoints.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from collections.abc import AsyncIterator, Callable, Iterator
9
+ from typing import TYPE_CHECKING, Any, TypeVar
10
+
11
+ if TYPE_CHECKING:
12
+ from devrev.models.base import PaginatedResponse
13
+
14
+ T = TypeVar("T")
15
+
16
+
17
+ class PaginatedIterator(Iterator[T]):
18
+ """Iterator for synchronous paginated responses.
19
+
20
+ Automatically fetches next pages as needed.
21
+
22
+ Example:
23
+ ```python
24
+ from devrev import DevRevClient
25
+ from devrev.utils.pagination import paginate
26
+
27
+ client = DevRevClient()
28
+ for account in paginate(client.accounts.list, "accounts"):
29
+ print(account.display_name)
30
+ ```
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ fetch_page: Callable[[str | None], PaginatedResponse],
36
+ items_attr: str,
37
+ limit: int | None = None,
38
+ ) -> None:
39
+ """Initialize the paginated iterator.
40
+
41
+ Args:
42
+ fetch_page: Function that fetches a page given a cursor
43
+ items_attr: Attribute name for items in the response
44
+ limit: Maximum total items to return (None = unlimited)
45
+ """
46
+ self._fetch_page = fetch_page
47
+ self._items_attr = items_attr
48
+ self._limit = limit
49
+ self._cursor: str | None = None
50
+ self._items: list[T] = []
51
+ self._item_index = 0
52
+ self._total_returned = 0
53
+ self._exhausted = False
54
+
55
+ def __iter__(self) -> PaginatedIterator[T]:
56
+ """Return self as iterator."""
57
+ return self
58
+
59
+ def __next__(self) -> T:
60
+ """Get next item, fetching more pages as needed."""
61
+ # Check if we've hit our limit
62
+ if self._limit is not None and self._total_returned >= self._limit:
63
+ raise StopIteration
64
+
65
+ # If we've consumed all items in current page, fetch next
66
+ while self._item_index >= len(self._items):
67
+ if self._exhausted:
68
+ raise StopIteration
69
+
70
+ response = self._fetch_page(self._cursor)
71
+ self._items = getattr(response, self._items_attr, [])
72
+ self._item_index = 0
73
+ self._cursor = response.next_cursor
74
+
75
+ if not self._cursor:
76
+ self._exhausted = True
77
+
78
+ # If no items in this page, check if we're done
79
+ if not self._items and self._exhausted:
80
+ raise StopIteration
81
+
82
+ item = self._items[self._item_index]
83
+ self._item_index += 1
84
+ self._total_returned += 1
85
+ return item
86
+
87
+
88
+ class AsyncPaginatedIterator(AsyncIterator[T]):
89
+ """Async iterator for paginated responses.
90
+
91
+ Automatically fetches next pages as needed.
92
+
93
+ Example:
94
+ ```python
95
+ from devrev import AsyncDevRevClient
96
+ from devrev.utils.pagination import async_paginate
97
+
98
+ async with AsyncDevRevClient() as client:
99
+ async for account in async_paginate(client.accounts.list, "accounts"):
100
+ print(account.display_name)
101
+ ```
102
+ """
103
+
104
+ def __init__(
105
+ self,
106
+ fetch_page: Callable[[str | None], Any], # Returns Awaitable
107
+ items_attr: str,
108
+ limit: int | None = None,
109
+ ) -> None:
110
+ """Initialize the async paginated iterator.
111
+
112
+ Args:
113
+ fetch_page: Async function that fetches a page given a cursor
114
+ items_attr: Attribute name for items in the response
115
+ limit: Maximum total items to return (None = unlimited)
116
+ """
117
+ self._fetch_page = fetch_page
118
+ self._items_attr = items_attr
119
+ self._limit = limit
120
+ self._cursor: str | None = None
121
+ self._items: list[T] = []
122
+ self._item_index = 0
123
+ self._total_returned = 0
124
+ self._exhausted = False
125
+
126
+ def __aiter__(self) -> AsyncPaginatedIterator[T]:
127
+ """Return self as async iterator."""
128
+ return self
129
+
130
+ async def __anext__(self) -> T:
131
+ """Get next item, fetching more pages as needed."""
132
+ # Check if we've hit our limit
133
+ if self._limit is not None and self._total_returned >= self._limit:
134
+ raise StopAsyncIteration
135
+
136
+ # If we've consumed all items in current page, fetch next
137
+ while self._item_index >= len(self._items):
138
+ if self._exhausted:
139
+ raise StopAsyncIteration
140
+
141
+ response = await self._fetch_page(self._cursor)
142
+ self._items = getattr(response, self._items_attr, [])
143
+ self._item_index = 0
144
+ self._cursor = response.next_cursor
145
+
146
+ if not self._cursor:
147
+ self._exhausted = True
148
+
149
+ if not self._items and self._exhausted:
150
+ raise StopAsyncIteration
151
+
152
+ item = self._items[self._item_index]
153
+ self._item_index += 1
154
+ self._total_returned += 1
155
+ return item