python-kanka 2.4.1__py3-none-any.whl → 2.6.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.
- kanka/_version.py +1 -1
- kanka/client.py +76 -3
- kanka/managers.py +31 -3
- {python_kanka-2.4.1.dist-info → python_kanka-2.6.0.dist-info}/METADATA +1 -1
- {python_kanka-2.4.1.dist-info → python_kanka-2.6.0.dist-info}/RECORD +7 -7
- {python_kanka-2.4.1.dist-info → python_kanka-2.6.0.dist-info}/WHEEL +1 -1
- {python_kanka-2.4.1.dist-info → python_kanka-2.6.0.dist-info}/licenses/LICENSE +0 -0
kanka/_version.py
CHANGED
kanka/client.py
CHANGED
|
@@ -298,9 +298,10 @@ class KankaClient:
|
|
|
298
298
|
params: dict[str, int | str] = {"page": page}
|
|
299
299
|
response = self._request("GET", f"search/{term}", params=params)
|
|
300
300
|
|
|
301
|
-
# Store pagination metadata for access if needed
|
|
301
|
+
# Store pagination metadata and sync timestamp for access if needed
|
|
302
302
|
self._last_search_meta = response.get("meta", {})
|
|
303
303
|
self._last_search_links = response.get("links", {})
|
|
304
|
+
self._last_search_sync: str | None = response.get("sync")
|
|
304
305
|
|
|
305
306
|
return [SearchResult(**item) for item in response["data"]]
|
|
306
307
|
|
|
@@ -321,19 +322,42 @@ class KankaClient:
|
|
|
321
322
|
response = self._request("GET", f"entities/{entity_id}")
|
|
322
323
|
return response["data"] # type: ignore[no-any-return]
|
|
323
324
|
|
|
324
|
-
def entities(
|
|
325
|
+
def entities(
|
|
326
|
+
self,
|
|
327
|
+
page: int = 1,
|
|
328
|
+
limit: int = 15,
|
|
329
|
+
last_sync: str | None = None,
|
|
330
|
+
**filters,
|
|
331
|
+
) -> list[dict[str, Any]]:
|
|
325
332
|
"""Access the /entities endpoint with filters.
|
|
326
333
|
|
|
327
334
|
This endpoint provides a unified way to query entities across all types
|
|
328
335
|
with various filtering options.
|
|
329
336
|
|
|
330
337
|
Args:
|
|
338
|
+
page: Page number (default: 1)
|
|
339
|
+
limit: Number of results per page (default: 15)
|
|
340
|
+
last_sync: ISO 8601 timestamp; only return entities modified after
|
|
341
|
+
this time. Use the ``last_entities_sync`` property from a
|
|
342
|
+
previous call to implement incremental sync.
|
|
331
343
|
**filters: Filter parameters like types, name, is_private, tags
|
|
332
344
|
|
|
333
345
|
Returns:
|
|
334
346
|
List of entity data
|
|
347
|
+
|
|
348
|
+
Note:
|
|
349
|
+
After calling entities(), the following properties are available:
|
|
350
|
+
- client.last_entities_meta: Contains total count, current page, etc.
|
|
351
|
+
- client.last_entities_links: Contains URLs for first, last, prev, next
|
|
352
|
+
- client.entities_has_next_page: True if more pages are available
|
|
353
|
+
- client.last_entities_sync: Server-generated sync timestamp for use
|
|
354
|
+
with the ``last_sync`` parameter on subsequent calls
|
|
335
355
|
"""
|
|
336
|
-
params: dict[str, int | str] = {}
|
|
356
|
+
params: dict[str, int | str] = {"page": page, "limit": limit}
|
|
357
|
+
|
|
358
|
+
# Add lastSync parameter for incremental sync
|
|
359
|
+
if last_sync is not None:
|
|
360
|
+
params["lastSync"] = last_sync
|
|
337
361
|
|
|
338
362
|
# Handle special filters
|
|
339
363
|
if "types" in filters and isinstance(filters["types"], list):
|
|
@@ -355,6 +379,9 @@ class KankaClient:
|
|
|
355
379
|
params[key] = filters[key]
|
|
356
380
|
|
|
357
381
|
response = self._request("GET", "entities", params=params)
|
|
382
|
+
self._last_entities_meta = response.get("meta", {})
|
|
383
|
+
self._last_entities_links = response.get("links", {})
|
|
384
|
+
self._last_entities_sync: str | None = response.get("sync")
|
|
358
385
|
return response["data"] # type: ignore[no-any-return]
|
|
359
386
|
|
|
360
387
|
def _parse_rate_limit_headers(self, response) -> float | None:
|
|
@@ -692,3 +719,49 @@ class KankaClient:
|
|
|
692
719
|
Dict[str, Any]: Links for pagination including first, last, prev, next URLs
|
|
693
720
|
"""
|
|
694
721
|
return getattr(self, "_last_search_links", {})
|
|
722
|
+
|
|
723
|
+
@property
|
|
724
|
+
def last_search_sync(self) -> str | None:
|
|
725
|
+
"""Get the sync timestamp from the last search() call.
|
|
726
|
+
|
|
727
|
+
Returns:
|
|
728
|
+
The sync timestamp string, or None if search() has not been called.
|
|
729
|
+
"""
|
|
730
|
+
return getattr(self, "_last_search_sync", None)
|
|
731
|
+
|
|
732
|
+
@property
|
|
733
|
+
def last_entities_meta(self) -> dict[str, Any]:
|
|
734
|
+
"""Get metadata from the last entities() call.
|
|
735
|
+
|
|
736
|
+
Returns:
|
|
737
|
+
Dict[str, Any]: Pagination metadata including current_page, from, to,
|
|
738
|
+
last_page, per_page, total
|
|
739
|
+
"""
|
|
740
|
+
return getattr(self, "_last_entities_meta", {})
|
|
741
|
+
|
|
742
|
+
@property
|
|
743
|
+
def last_entities_links(self) -> dict[str, Any]:
|
|
744
|
+
"""Get pagination links from the last entities() call.
|
|
745
|
+
|
|
746
|
+
Returns:
|
|
747
|
+
Dict[str, Any]: Links for pagination including first, last, prev, next URLs
|
|
748
|
+
"""
|
|
749
|
+
return getattr(self, "_last_entities_links", {})
|
|
750
|
+
|
|
751
|
+
@property
|
|
752
|
+
def last_entities_sync(self) -> str | None:
|
|
753
|
+
"""Get the sync timestamp from the last entities() call.
|
|
754
|
+
|
|
755
|
+
This is a server-generated ISO 8601 timestamp representing when the
|
|
756
|
+
response was produced. Pass it as the ``last_sync`` parameter on a
|
|
757
|
+
subsequent ``entities()`` call to fetch only entities modified since then.
|
|
758
|
+
|
|
759
|
+
Returns:
|
|
760
|
+
The sync timestamp string, or None if entities() has not been called.
|
|
761
|
+
"""
|
|
762
|
+
return getattr(self, "_last_entities_sync", None)
|
|
763
|
+
|
|
764
|
+
@property
|
|
765
|
+
def entities_has_next_page(self) -> bool:
|
|
766
|
+
"""Check if more pages are available from the last entities() call."""
|
|
767
|
+
return bool(getattr(self, "_last_entities_links", {}).get("next"))
|
kanka/managers.py
CHANGED
|
@@ -80,7 +80,12 @@ class EntityManager[T: Entity]:
|
|
|
80
80
|
return bool(self.pagination_links.get("next"))
|
|
81
81
|
|
|
82
82
|
def list(
|
|
83
|
-
self,
|
|
83
|
+
self,
|
|
84
|
+
page: int = 1,
|
|
85
|
+
limit: int = 30,
|
|
86
|
+
related: bool = False,
|
|
87
|
+
last_sync: str | None = None,
|
|
88
|
+
**filters,
|
|
84
89
|
) -> list[T]:
|
|
85
90
|
"""List entities with optional filters.
|
|
86
91
|
|
|
@@ -88,6 +93,9 @@ class EntityManager[T: Entity]:
|
|
|
88
93
|
page: Page number (default: 1)
|
|
89
94
|
limit: Number of results per page (default: 30)
|
|
90
95
|
related: Include related data (posts, attributes, etc.)
|
|
96
|
+
last_sync: ISO 8601 timestamp; only return entities modified after
|
|
97
|
+
this time. Use the ``last_sync`` property from a previous call
|
|
98
|
+
to implement incremental sync.
|
|
91
99
|
**filters: Additional filters supported by the API
|
|
92
100
|
|
|
93
101
|
Supported filters:
|
|
@@ -104,10 +112,12 @@ class EntityManager[T: Entity]:
|
|
|
104
112
|
List of entity instances
|
|
105
113
|
|
|
106
114
|
Note:
|
|
107
|
-
|
|
115
|
+
After calling list(), the following properties are available:
|
|
108
116
|
- manager.pagination_meta: Contains total count, current page, etc.
|
|
109
117
|
- manager.pagination_links: Contains URLs for first, last, prev, next
|
|
110
118
|
- manager.has_next_page: True if more pages are available
|
|
119
|
+
- manager.last_sync: Server-generated sync timestamp for use with
|
|
120
|
+
the ``last_sync`` parameter on subsequent calls
|
|
111
121
|
|
|
112
122
|
Examples:
|
|
113
123
|
# Get all public characters
|
|
@@ -154,6 +164,10 @@ class EntityManager[T: Entity]:
|
|
|
154
164
|
if related:
|
|
155
165
|
params["related"] = 1
|
|
156
166
|
|
|
167
|
+
# Add lastSync parameter for incremental sync
|
|
168
|
+
if last_sync is not None:
|
|
169
|
+
params["lastSync"] = last_sync
|
|
170
|
+
|
|
157
171
|
# Add filters
|
|
158
172
|
for key, value in filters.items():
|
|
159
173
|
if value is not None:
|
|
@@ -175,9 +189,10 @@ class EntityManager[T: Entity]:
|
|
|
175
189
|
|
|
176
190
|
response = self.client._request("GET", self.endpoint, params=params)
|
|
177
191
|
|
|
178
|
-
# Store pagination metadata
|
|
192
|
+
# Store pagination metadata and sync timestamp for access if needed
|
|
179
193
|
self._last_meta = response.get("meta", {})
|
|
180
194
|
self._last_links = response.get("links", {})
|
|
195
|
+
self._last_sync: str | None = response.get("sync")
|
|
181
196
|
|
|
182
197
|
return [self.model(**item) for item in response["data"]]
|
|
183
198
|
|
|
@@ -379,6 +394,19 @@ class EntityManager[T: Entity]:
|
|
|
379
394
|
"""
|
|
380
395
|
return getattr(self, "_last_links", {})
|
|
381
396
|
|
|
397
|
+
@property
|
|
398
|
+
def last_sync(self) -> str | None:
|
|
399
|
+
"""Get the sync timestamp from the last list() call.
|
|
400
|
+
|
|
401
|
+
This is a server-generated ISO 8601 timestamp representing when the
|
|
402
|
+
response was produced. Pass it as the ``last_sync`` parameter on a
|
|
403
|
+
subsequent ``list()`` call to fetch only entities modified since then.
|
|
404
|
+
|
|
405
|
+
Returns:
|
|
406
|
+
The sync timestamp string, or None if list() has not been called.
|
|
407
|
+
"""
|
|
408
|
+
return getattr(self, "_last_sync", None)
|
|
409
|
+
|
|
382
410
|
def _extract_entity_id(self, entity_or_id: T | int) -> int:
|
|
383
411
|
"""Extract entity_id from an entity object or integer.
|
|
384
412
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
kanka/__init__.py,sha256=S_Pl6xBtHOpUGr3eOEkq4QEMtByZx4kEWYoQfv3LLrQ,2102
|
|
2
|
-
kanka/_version.py,sha256=
|
|
3
|
-
kanka/client.py,sha256=
|
|
2
|
+
kanka/_version.py,sha256=P6p0L1OUViSUGyScSsOQ9rEhgsRzs8E-Td230MFMta8,67
|
|
3
|
+
kanka/client.py,sha256=obnGFpdXwPRQAbxeaL_UvAqsHiEL7h_bYqh1GROlBaY,26632
|
|
4
4
|
kanka/exceptions.py,sha256=A4P7T7VO_Rp5IYldvFaecE3z4N7WYDgCDojYPu_yDzk,3871
|
|
5
|
-
kanka/managers.py,sha256=
|
|
5
|
+
kanka/managers.py,sha256=OExFz64XdVSCP3zOnn8D_eUonNZLhDL-gd9v0zgvj-w,35343
|
|
6
6
|
kanka/py.typed,sha256=mZgbv7X8oKfyMzYIbodUlHrC15905jgP-ZbYviEIL18,86
|
|
7
7
|
kanka/types.py,sha256=onIdSW-3rh6Bqv2VTvx6INFa7tkaQxqg6gJkiAh8YGA,262
|
|
8
8
|
kanka/models/__init__.py,sha256=IFdzawDK_lhS50puRunnZZalh2S5DOPU96ASHeFITUw,1329
|
|
9
9
|
kanka/models/base.py,sha256=GOt9I2eNb-R_2oD0fbU0LE3y9gWL0x3_2SQ9I5yuq3Y,4037
|
|
10
10
|
kanka/models/common.py,sha256=0RF33RupotK0mWjvWc9oIdQZF7ko5FNc_GG5wUIZOOE,6682
|
|
11
11
|
kanka/models/entities.py,sha256=-2ztBZn8-K8czQyd9vPnEtn4eS666v9firmk7UPDT5A,8885
|
|
12
|
-
python_kanka-2.
|
|
13
|
-
python_kanka-2.
|
|
14
|
-
python_kanka-2.
|
|
15
|
-
python_kanka-2.
|
|
12
|
+
python_kanka-2.6.0.dist-info/METADATA,sha256=X10zzfn_ePoL9ZR4FFb0vk3oMjrm8Tn_7qSLCY_g3EM,3249
|
|
13
|
+
python_kanka-2.6.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
14
|
+
python_kanka-2.6.0.dist-info/licenses/LICENSE,sha256=37op2CRJ_dU2qGU-iJjczcP-ljtJjpKAgBdKFaiF2GY,1067
|
|
15
|
+
python_kanka-2.6.0.dist-info/RECORD,,
|
|
File without changes
|