Skip to content

Fix rolling accessory location history fetching - #252

Open
hackermengzhi wants to merge 1 commit into
malmeloo:mainfrom
hackermengzhi:fix/full-rolling-location-history
Open

Fix rolling accessory location history fetching#252
hackermengzhi wants to merge 1 commit into
malmeloo:mainfrom
hackermengzhi:fix/full-rolling-location-history

Conversation

@hackermengzhi

Copy link
Copy Markdown

Summary

  • make fetch_location_history() fetch the full rolling key history by default
  • keep fetch_location() on the faster latest-only path explicitly
  • add regression tests for default full-history behavior and the internal latest-only override

Why

LocationReportsFetcher.fetch_location_history() accepted a RollingKeyPairSource, but internally always passed only_latest=True to _fetch_accessory_reports(). That meant callers asking for history could silently get only the newest report batch for rolling accessories.

This keeps the public history method aligned with its name while preserving current-location performance through fetch_location().

Tests

  • .venv/bin/python -m pytest tests/test_reports.py tests/test_keygen.py
  • .venv/bin/python -m ruff check findmy/reports/account.py findmy/reports/reports.py tests/test_reports.py

@hackermengzhi
hackermengzhi force-pushed the fix/full-rolling-location-history branch from 0408b0f to f0e31e1 Compare June 24, 2026 22:48
@malmeloo

Copy link
Copy Markdown
Owner

Hey, sorry for taking a while. I'm a bit hesitant to merge this, let me explain why.

The FindMy API is really not built to obtain a full location history. Apple only stores a few reports per key and all reports expire after a short period of time. The old behavior of FindMy.py was to try to obtain the last location at all times. This worked for a while until they started limiting the API even further.

The purpose of the fetch_location_history method is to provide multiple reports to the user if they were going to be fetched anyway. The idea being, the library will most likely 'accidentally' fetch more reports than necessary. That method is just a way to expose them.

Even if you set only_latest to False, you are still not going to obtain the full location history. The history trace that is received will still be bounded by the accessory's get_min_index. The implementation of this method can feel pretty arbitrary and unintuitive to the user, and it can differ wildly across different accessory implementations. This is, without a doubt, going to cause confusion as to why the method behaves so inconsistently. That's why the current documentation comes with a big fat warning for this method: it is best-effort only, the API is not designed for this purpose, but if you really, really want to, go ahead and use it.

Also, either way, defaulting only_latest to False is not a good idea. If the user passes a static-key accessory as an argument, the fetcher will be trying to make way more requests than necessary, because Apple is not going to be storing old reports for that device anyway. Let's not try to hammer Apple's API any more than necessary, otherwise they might try to start limiting access to prevent abuse.

As an additional note, I'm not sure what the test is trying to accomplish here. Testing whether an internal method is called with a certain parameter does not seem very useful to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants