Commit 4765229
Paginate the feed and collections, align timestamp types, and deprecate dead methods (#51)
* Fix missing created_at on feed items
Some AnyFeedItem union members were not enumerated individually in the FEED
query, so they returned without createdAt and newest_edge/filter skipped
them. Add an inline fragment on the FeedItem interface so every member
selects id and createdAt.
Fixes #24
* Paginate collection() to return all media
collection() returned only the first page, silently truncating larger
collections. Follow the connection cursor until hasNextPage is false so
the full set of media is returned.
Add a page_size argument (default 50) that caps the per-request batch.
The API rejects a page size above 100 -- it responds HTTP 200 with a
GraphQL INTERNAL_SERVER_ERROR rather than a client error -- so guard the
input to 1-100 and raise ValueError instead of round-tripping to fail.
page_size only tunes how many media are fetched per request; the full
collection is returned regardless.
Paginate through a shared _iter_pages helper that advances by endCursor
and stops defensively when the server claims another page but returns no
advancing cursor (missing, null, or already seen), so a stuck cursor
cannot spin the client in an infinite request loop.
supersedes #38
Co-authored-by: tombeaulah <tom.beaulah@gmail.com>
* Paginate and guard the feed
The feed methods fetched only the first page. refresh_feed therefore
under-reported when more than one page of items was new since the last
refresh -- fewer results than the app showed -- and new_postcards and
feed_nodes saw only the newest page. feed() also passed first straight
through, so grabbing a large window with first above 100 errored server
side (HTTP 200 with a GraphQL INTERNAL_SERVER_ERROR).
Guard feed(first=) to 1-100 and raise ValueError otherwise. Page
refresh_feed backward through the feed until it reaches items no newer
than since, so every new item is returned rather than truncated; with
no cutoff (no prior refresh) it still returns only the newest page to
avoid replaying the whole history on startup. Page feed_nodes and
new_postcards across every page.
All of it reuses the defensive _iter_pages cursor walk, so a server that
reports another page without an advancing cursor cannot spin the client
in an infinite request loop.
Refs #29
* Deprecate latest_collections in favor of refresh_collections
latest_collections referenced queries.me.LATEST_MEDIA, which is not
defined, so every call raised AttributeError. Rather than remove the
public method, mark it deprecated (PEP 702) and delegate to
refresh_collections, so existing callers keep working and now receive a
real result.
Adds typing_extensions>=4.5 as a runtime dependency for the decorator.
PEP 702 landed in the standard library as warnings.deprecated only in
Python 3.13; the package supports Python 3.10+, so the backport is
required to reach older runtimes.
* Add the ULTRA_FRENZY power profile
The API reports ULTRA_FRENZY_MODE as a power profile; without a matching
member it fell back to PowerProfile.UNKNOWN. Add the member so it maps
directly.
* Guard update_firmware_start when no update is available
Starting a firmware update on a feeder already running the latest version
returns an internal server error rather than a client error -- the same
class of misbehavior as the collection and feed page-size limits. The
feeder reports firmwareVersion and availableFirmwareVersion, so compare
them after the progress check and raise NoFirmwareUpdateAvailableError
instead of round-tripping into the server error.
* Type BirdBuddy timestamps to match the schema
createdAt (Media, FeedItem) and visitLastTime (collections) are DateTime!
in the schema, and every query returning those objects selects them, so the
values are never null. Type Media.created_at and Collection.last_visit as
datetime, raising UnexpectedResponseError if a response ever omits the field
rather than returning None for a value the schema guarantees.
FeedNode.created_at stays optional: feed items are AnyFeedItem union
members, and a member whose createdAt the query does not select carries no
timestamp. parse_datetime is left tolerant of None, so its public signature
is unchanged.
Feed.newest_edge filters undated edges with a walrus guard so the type
checker can follow that the compared values are non-null. That max()
comparison is the code cited in #24; the interface fragment added earlier
requests createdAt for every member, and this hardens the comparison against
a member that still omits it. Refs #24.
* Document the deprecations in the README
Add a Deprecations section noting that deprecated methods keep working and
emit a DeprecationWarning, with latest_collections (deprecated in 0.0.22)
and its refresh_collections replacement.
* (fixup) clarify yield docstring in _iter_pages()
_iter_pages() is generic and follows the natural order of the cursor, i.e., doesn't impose age ordering. Clarify the confusing language as it contradicts the docstrings of the callers that consume it.
Co-authored-by: Joe <madcoder@gmail.com>
---------
Co-authored-by: tombeaulah <tom.beaulah@gmail.com>
Co-authored-by: Joe <madcoder@gmail.com>1 parent d0e15ec commit 4765229
12 files changed
Lines changed: 568 additions & 56 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
95 | 105 | | |
96 | 106 | | |
97 | 107 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| 12 | + | |
11 | 13 | | |
12 | 14 | | |
13 | 15 | | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| 20 | + | |
18 | 21 | | |
19 | 22 | | |
20 | 23 | | |
| |||
35 | 38 | | |
36 | 39 | | |
37 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
38 | 45 | | |
39 | 46 | | |
40 | 47 | | |
41 | 48 | | |
42 | 49 | | |
43 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
44 | 65 | | |
45 | 66 | | |
46 | 67 | | |
| |||
269 | 290 | | |
270 | 291 | | |
271 | 292 | | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
272 | 346 | | |
273 | 347 | | |
274 | 348 | | |
| |||
403 | 477 | | |
404 | 478 | | |
405 | 479 | | |
406 | | - | |
| 480 | + | |
| 481 | + | |
407 | 482 | | |
408 | 483 | | |
409 | 484 | | |
| |||
412 | 487 | | |
413 | 488 | | |
414 | 489 | | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
415 | 493 | | |
| 494 | + | |
416 | 495 | | |
417 | 496 | | |
418 | 497 | | |
| |||
434 | 513 | | |
435 | 514 | | |
436 | 515 | | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
437 | 541 | | |
438 | 542 | | |
439 | 543 | | |
440 | 544 | | |
441 | 545 | | |
442 | 546 | | |
443 | | - | |
444 | | - | |
445 | | - | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
446 | 556 | | |
447 | 557 | | |
448 | 558 | | |
449 | 559 | | |
450 | 560 | | |
451 | 561 | | |
452 | | - | |
| 562 | + | |
453 | 563 | | |
454 | 564 | | |
455 | 565 | | |
456 | 566 | | |
457 | | - | |
458 | | - | |
459 | | - | |
460 | | - | |
461 | | - | |
462 | | - | |
463 | | - | |
464 | | - | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
465 | 584 | | |
466 | | - | |
467 | | - | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
468 | 590 | | |
469 | 591 | | |
470 | | - | |
| 592 | + | |
471 | 593 | | |
472 | 594 | | |
473 | 595 | | |
474 | 596 | | |
475 | 597 | | |
476 | | - | |
| 598 | + | |
477 | 599 | | |
478 | | - | |
479 | | - | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
480 | 604 | | |
481 | 605 | | |
482 | 606 | | |
| |||
947 | 1071 | | |
948 | 1072 | | |
949 | 1073 | | |
| 1074 | + | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
950 | 1078 | | |
951 | 1079 | | |
952 | 1080 | | |
953 | 1081 | | |
954 | 1082 | | |
955 | 1083 | | |
956 | 1084 | | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
957 | 1092 | | |
958 | 1093 | | |
959 | 1094 | | |
| |||
1025 | 1160 | | |
1026 | 1161 | | |
1027 | 1162 | | |
1028 | | - | |
1029 | | - | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
1030 | 1170 | | |
1031 | 1171 | | |
1032 | 1172 | | |
| 1173 | + | |
| 1174 | + | |
1033 | 1175 | | |
1034 | 1176 | | |
1035 | 1177 | | |
| 1178 | + | |
| 1179 | + | |
| 1180 | + | |
1036 | 1181 | | |
1037 | | - | |
1038 | | - | |
1039 | | - | |
1040 | | - | |
1041 | | - | |
1042 | | - | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
1043 | 1189 | | |
1044 | | - | |
1045 | | - | |
1046 | | - | |
1047 | | - | |
1048 | | - | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
1049 | 1195 | | |
1050 | | - | |
1051 | | - | |
1052 | | - | |
1053 | | - | |
1054 | | - | |
1055 | | - | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
| 1203 | + | |
| 1204 | + | |
| 1205 | + | |
1056 | 1206 | | |
1057 | 1207 | | |
1058 | 1208 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
73 | 77 | | |
74 | 78 | | |
75 | 79 | | |
| |||
0 commit comments