python-kanka 2.5.0__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 CHANGED
@@ -1,3 +1,3 @@
1
1
  """Version information for python-kanka."""
2
2
 
3
- __version__ = "2.5.0"
3
+ __version__ = "2.6.0"
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
 
@@ -322,7 +323,11 @@ class KankaClient:
322
323
  return response["data"] # type: ignore[no-any-return]
323
324
 
324
325
  def entities(
325
- self, page: int = 1, limit: int = 15, **filters
326
+ self,
327
+ page: int = 1,
328
+ limit: int = 15,
329
+ last_sync: str | None = None,
330
+ **filters,
326
331
  ) -> list[dict[str, Any]]:
327
332
  """Access the /entities endpoint with filters.
328
333
 
@@ -332,19 +337,28 @@ class KankaClient:
332
337
  Args:
333
338
  page: Page number (default: 1)
334
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.
335
343
  **filters: Filter parameters like types, name, is_private, tags
336
344
 
337
345
  Returns:
338
346
  List of entity data
339
347
 
340
348
  Note:
341
- Pagination information is available after calling entities():
349
+ After calling entities(), the following properties are available:
342
350
  - client.last_entities_meta: Contains total count, current page, etc.
343
351
  - client.last_entities_links: Contains URLs for first, last, prev, next
344
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
345
355
  """
346
356
  params: dict[str, int | str] = {"page": page, "limit": limit}
347
357
 
358
+ # Add lastSync parameter for incremental sync
359
+ if last_sync is not None:
360
+ params["lastSync"] = last_sync
361
+
348
362
  # Handle special filters
349
363
  if "types" in filters and isinstance(filters["types"], list):
350
364
  params["types"] = ",".join(filters["types"])
@@ -367,6 +381,7 @@ class KankaClient:
367
381
  response = self._request("GET", "entities", params=params)
368
382
  self._last_entities_meta = response.get("meta", {})
369
383
  self._last_entities_links = response.get("links", {})
384
+ self._last_entities_sync: str | None = response.get("sync")
370
385
  return response["data"] # type: ignore[no-any-return]
371
386
 
372
387
  def _parse_rate_limit_headers(self, response) -> float | None:
@@ -705,6 +720,15 @@ class KankaClient:
705
720
  """
706
721
  return getattr(self, "_last_search_links", {})
707
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
+
708
732
  @property
709
733
  def last_entities_meta(self) -> dict[str, Any]:
710
734
  """Get metadata from the last entities() call.
@@ -724,6 +748,19 @@ class KankaClient:
724
748
  """
725
749
  return getattr(self, "_last_entities_links", {})
726
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
+
727
764
  @property
728
765
  def entities_has_next_page(self) -> bool:
729
766
  """Check if more pages are available from the last entities() call."""
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, page: int = 1, limit: int = 30, related: bool = False, **filters
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
- Pagination information is available after calling list():
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 on the manager for access if needed
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-kanka
3
- Version: 2.5.0
3
+ Version: 2.6.0
4
4
  Summary: Python client for the Kanka API
5
5
  Project-URL: Homepage, https://github.com/ervwalter/python-kanka
6
6
  Project-URL: Documentation, https://github.com/ervwalter/python-kanka#readme
@@ -1,15 +1,15 @@
1
1
  kanka/__init__.py,sha256=S_Pl6xBtHOpUGr3eOEkq4QEMtByZx4kEWYoQfv3LLrQ,2102
2
- kanka/_version.py,sha256=CbCNgca30mRPFdjB04QfU2j2_o36aDbjiakPVgp44gE,67
3
- kanka/client.py,sha256=r4Q0IyF0LwD8VPHB5dV2fhfLTS5tLcwUJqcEWoWoHxU,25095
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=QQN4HX8CDyx8zLvJ2Bvh8f-h7xGy8E7ClY4CnYMlK5E,34225
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.5.0.dist-info/METADATA,sha256=-RkLCqgQEN4QtIMsePgKYupX2ZWvvZMXpo2T_-fDnpI,3249
13
- python_kanka-2.5.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
14
- python_kanka-2.5.0.dist-info/licenses/LICENSE,sha256=37op2CRJ_dU2qGU-iJjczcP-ljtJjpKAgBdKFaiF2GY,1067
15
- python_kanka-2.5.0.dist-info/RECORD,,
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,,