findmy.reports#
Code related to fetching location reports.
Submodules#
Attributes#
Classes#
JSON mapping representing state of an Apple account instance. |
|
A sync implementation of |
|
An async implementation of |
|
Base class for an Apple account. |
|
Abstract base class for Anisette providers. |
|
JSON mapping representing state of a local Anisette provider. |
|
Local anisette provider using the anisette library. |
|
JSON mapping representing state of a remote Anisette provider. |
|
Anisette provider. Fetches headers from a remote Anisette server. |
|
Location report corresponding to a certain |
|
JSON mapping representing a decrypted location report. |
|
JSON mapping representing an encrypted location report. |
|
Enum of possible login states. Used for |
|
An async implementation of |
|
An async implementation of |
|
Base class for a second-factor authentication method for an Apple account. |
|
Base class for SMS-based two-factor authentication. |
|
A sync implementation of |
|
A sync implementation of |
|
Base class for trusted device-based two-factor authentication. |
Package Contents#
- class findmy.reports.AccountStateMapping#
Bases:
TypedDict
JSON mapping representing state of an Apple account instance.
- type: Literal['account']#
- ids: _AccountStateMappingIds#
- account: _AccountStateMappingAccount#
- login: _AccountStateMappingLoginState#
- anisette: findmy.reports.anisette.AnisetteMapping#
- class findmy.reports.AppleAccount(anisette: findmy.reports.anisette.BaseAnisetteProvider, *, state_info: AccountStateMapping | None = None)#
Bases:
BaseAppleAccount
A sync implementation of
BaseappleAccount().Uses
AsyncappleAccount()internally.- async close() None#
- property login_state: findmy.reports.state.LoginState#
- property account_name: str | None#
- property first_name: str | None#
- property last_name: str | None#
- to_json(dst: str | pathlib.Path | None = None, /) AccountStateMapping#
Export the current state of the object as a JSON-serializable dictionary.
If an argument is provided, the output will also be written to that file.
The output of this method is guaranteed to be JSON-serializable, and passing the return value of this function as an argument to
Serializable.from_json()will always result in an exact copy of the internal state as it was when exported.You are encouraged to save and load object states to and from disk whenever possible, to prevent unnecessary API calls or otherwise unexpected behavior.
- classmethod from_json(val: str | pathlib.Path | AccountStateMapping, /, *, anisette_libs_path: str | pathlib.Path | None = None) AppleAccount#
Restore state from a previous
Closable.to_json()export.If given a str or Path, it must point to a json file from
Serializable.to_json(). Otherwise, it should be the Mapping itself.See
Serializable.to_json()for more information.
- login(username: str, password: str) findmy.reports.state.LoginState#
- get_2fa_methods() collections.abc.Sequence[findmy.reports.twofactor.SyncSecondFactorMethod]#
- sms_2fa_request(phone_number_id: int) None#
- sms_2fa_submit(phone_number_id: int, code: str) findmy.reports.state.LoginState#
- td_2fa_request() None#
- td_2fa_submit(code: str) findmy.reports.state.LoginState#
- fetch_location_history(keys: findmy.keys.HasHashedPublicKey) list[findmy.reports.reports.LocationReport]#
- fetch_location_history(keys: findmy.accessory.RollingKeyPairSource) list[findmy.reports.reports.LocationReport]
- fetch_location_history(keys: collections.abc.Sequence[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource]) dict[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource, list[findmy.reports.reports.LocationReport]]
See BaseAppleAccount.fetch_location_history.
- fetch_location(keys: findmy.keys.HasHashedPublicKey) findmy.reports.reports.LocationReport | None#
- fetch_location(keys: findmy.accessory.RollingKeyPairSource) findmy.reports.reports.LocationReport | None
- fetch_location(keys: collections.abc.Sequence[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource]) dict[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource, findmy.reports.reports.LocationReport | None]
- get_anisette_headers(with_client_info: bool = False, serial: str = '0') dict[str, str]#
- class findmy.reports.AsyncAppleAccount(anisette: findmy.reports.anisette.BaseAnisetteProvider, *, state_info: AccountStateMapping | None = None)#
Bases:
BaseAppleAccount
An async implementation of
BaseAppleAccount().- property login_state: findmy.reports.state.LoginState#
- property account_name: str | None#
- property first_name: str | None#
- property last_name: str | None#
- to_json(path: str | pathlib.Path | None = None, /) AccountStateMapping#
Export the current state of the object as a JSON-serializable dictionary.
If an argument is provided, the output will also be written to that file.
The output of this method is guaranteed to be JSON-serializable, and passing the return value of this function as an argument to
Serializable.from_json()will always result in an exact copy of the internal state as it was when exported.You are encouraged to save and load object states to and from disk whenever possible, to prevent unnecessary API calls or otherwise unexpected behavior.
- classmethod from_json(val: str | pathlib.Path | AccountStateMapping, /, *, anisette_libs_path: str | pathlib.Path | None = None) AsyncAppleAccount#
Restore state from a previous
Closable.to_json()export.If given a str or Path, it must point to a json file from
Serializable.to_json(). Otherwise, it should be the Mapping itself.See
Serializable.to_json()for more information.
- async close() None#
Close any sessions or other resources in use by this object.
Should be called when the object will no longer be used.
- async login(username: str, password: str) findmy.reports.state.LoginState#
- async get_2fa_methods() collections.abc.Sequence[findmy.reports.twofactor.AsyncSecondFactorMethod]#
- async sms_2fa_request(phone_number_id: int) None#
- async sms_2fa_submit(phone_number_id: int, code: str) findmy.reports.state.LoginState#
- async td_2fa_request() None#
- async td_2fa_submit(code: str) findmy.reports.state.LoginState#
- async fetch_raw_reports(devices: list[tuple[list[str], list[str]]]) list[findmy.reports.reports.LocationReport]#
Make a request for location reports, returning raw data.
- async fetch_location_history(keys: findmy.keys.HasHashedPublicKey) list[findmy.reports.reports.LocationReport]#
- async fetch_location_history(keys: findmy.accessory.RollingKeyPairSource) list[findmy.reports.reports.LocationReport]
- async fetch_location_history(keys: collections.abc.Sequence[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource]) dict[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource, list[findmy.reports.reports.LocationReport]]
See BaseAppleAccount.fetch_location_history.
- async fetch_location(keys: findmy.keys.HasHashedPublicKey) findmy.reports.reports.LocationReport | None#
- async fetch_location(keys: findmy.accessory.RollingKeyPairSource) findmy.reports.reports.LocationReport | None
- async fetch_location(keys: collections.abc.Sequence[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource]) dict[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource, findmy.reports.reports.LocationReport | None]
- async get_anisette_headers(with_client_info: bool = False, serial: str = '0') dict[str, str]#
- class findmy.reports.BaseAppleAccount(loop: asyncio.AbstractEventLoop | None = None)#
Bases:
findmy.util.abc.Closable,findmy.util.abc.Serializable[AccountStateMapping],abc.ABC
Base class for an Apple account.
- property login_state: findmy.reports.state.LoginState#
- Abstractmethod:
The current login state of the account.
- property account_name: str | None#
- Abstractmethod:
The name of the account as reported by Apple.
This is usually an e-mail address. May be None in some cases, such as when not logged in.
- property first_name: str | None#
- Abstractmethod:
First name of the account holder as reported by Apple.
May be None in some cases, such as when not logged in.
- property last_name: str | None#
- Abstractmethod:
Last name of the account holder as reported by Apple.
May be None in some cases, such as when not logged in.
- abstractmethod login(username: str, password: str) findmy.util.types.MaybeCoro[findmy.reports.state.LoginState]#
Log in to an Apple account using a username and password.
- abstractmethod get_2fa_methods() findmy.util.types.MaybeCoro[collections.abc.Sequence[findmy.reports.twofactor.BaseSecondFactorMethod]]#
Get a list of 2FA methods that can be used as a secondary challenge.
Currently, only SMS-based 2FA methods are supported.
- abstractmethod sms_2fa_request(phone_number_id: int) findmy.util.types.MaybeCoro[None]#
Request a 2FA code to be sent to a specific phone number ID.
Consider using
BaseSecondFactorMethod.request()instead.
- abstractmethod sms_2fa_submit(phone_number_id: int, code: str) findmy.util.types.MaybeCoro[findmy.reports.state.LoginState]#
Submit a 2FA code that was sent to a specific phone number ID.
Consider using
BaseSecondFactorMethod.submit()instead.
- abstractmethod td_2fa_request() findmy.util.types.MaybeCoro[None]#
Request a 2FA code to be sent to a trusted device.
Consider using
BaseSecondFactorMethod.request()instead.
- abstractmethod td_2fa_submit(code: str) findmy.util.types.MaybeCoro[findmy.reports.state.LoginState]#
Submit a 2FA code that was sent to a trusted device.
Consider using
BaseSecondFactorMethod.submit()instead.
- abstractmethod fetch_location_history(keys: findmy.keys.HasHashedPublicKey) findmy.util.types.MaybeCoro[list[findmy.reports.reports.LocationReport]]#
- abstractmethod fetch_location_history(keys: findmy.accessory.RollingKeyPairSource) findmy.util.types.MaybeCoro[list[findmy.reports.reports.LocationReport]]
- abstractmethod fetch_location_history(keys: collections.abc.Sequence[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource]) findmy.util.types.MaybeCoro[dict[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource, list[findmy.reports.reports.LocationReport]]]
Fetch location history for :class:`HasHashedPublicKey`s and :class:`RollingKeyPairSource`s.
Note that location history for devices is provided on a best-effort basis and may not be fully complete or stable. Multiple consecutive calls to this method may result in different location reports, especially for reports further in the past. However, each one of these reports is guaranteed to be in line with the data reported by Apple, and the most recent report will always be included in the results.
Unless you really need to use this method, and use
fetch_location()instead.
- abstractmethod fetch_location(keys: findmy.keys.HasHashedPublicKey) findmy.util.types.MaybeCoro[findmy.reports.reports.LocationReport | None]#
- abstractmethod fetch_location(keys: findmy.accessory.RollingKeyPairSource) findmy.util.types.MaybeCoro[findmy.reports.reports.LocationReport | None]
- abstractmethod fetch_location(keys: collections.abc.Sequence[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource]) findmy.util.types.MaybeCoro[dict[findmy.keys.HasHashedPublicKey | findmy.accessory.RollingKeyPairSource, findmy.reports.reports.LocationReport | None] | None]
Fetch location for :class:`HasHashedPublicKey`s.
Returns a dictionary mapping :class:`HasHashedPublicKey`s to their location reports.
- abstractmethod get_anisette_headers(with_client_info: bool = False, serial: str = '0') findmy.util.types.MaybeCoro[dict[str, str]]#
Retrieve a complete dictionary of Anisette headers.
Utility method for
AnisetteProvider.get_headers()using this account’s user/device ID.
- findmy.reports.AnisetteMapping#
- class findmy.reports.BaseAnisetteProvider(loop: asyncio.AbstractEventLoop | None = None)#
Bases:
findmy.util.abc.Closable,findmy.util.abc.Serializable,abc.ABC
Abstract base class for Anisette providers.
Generously derived from nythepegasus/grandslam.
- property otp: str#
- Abstractmethod:
A seemingly random base64 string containing 28 bytes.
- property machine: str#
- Abstractmethod:
A base64 encoded string of 60 ‘random’ bytes.
- property timestamp: str#
Current timestamp in ISO 8601 format.
- property timezone: str#
Abbreviation of the timezone of the device.
- property locale: str#
Locale of the device (e.g. en_US).
- property router: str#
A number, either 17106176 or 50660608.
It doesn’t seem to matter which one we use. - 17106176 is used by Sideloadly and Provision (android) based servers. - 50660608 is used by Windows iCloud based servers.
- property client: str#
Client string.
The format is as follows: <%MODEL%> <%OS%;%MAJOR%.%MINOR%(%SPMAJOR%,%SPMINOR%);%BUILD%>
<%AUTHKIT_BUNDLE_ID%/%AUTHKIT_VERSION% (%APP_BUNDLE_ID%/%APP_VERSION%)>
- Where:
MODEL: The model of the device (e.g. MacBookPro15,1 or ‘PC’ OS: The OS of the device (e.g. Mac OS X or Windows) MAJOR: The major version of the OS (e.g. 10) MINOR: The minor version of the OS (e.g. 15) SPMAJOR: The major version of the service pack (e.g. 0) (Windows only) SPMINOR: The minor version of the service pack (e.g. 0) (Windows only) BUILD: The build number of the OS (e.g. 19C57) AUTHKIT_BUNDLE_ID: The bundle ID of the AuthKit framework (e.g. com.apple.AuthKit) AUTHKIT_VERSION: The version of the AuthKit framework (e.g. 1) APP_BUNDLE_ID: The bundle ID of the app (e.g. com.apple.dt.Xcode) APP_VERSION: The version of the app (e.g. 3594.4.19)
- async get_headers(user_id: str, device_id: str, serial: str = '0', with_client_info: bool = False) dict[str, str]#
Generate a complete dictionary of Anisette headers.
Consider using
BaseAppleAccount.get_anisette_headers()instead.
- async get_cpd(user_id: str, device_id: str, serial: str = '0') dict[str, str]#
Generate a complete dictionary of CPD data.
Intended for internal use.
- class findmy.reports.LocalAnisetteMapping#
Bases:
TypedDict
JSON mapping representing state of a local Anisette provider.
- type: Literal['aniLocal']#
- prov_data: str#
- class findmy.reports.LocalAnisetteProvider(*, state_blob: BinaryIO | None = None, libs_path: str | pathlib.Path | None = None)#
Bases:
BaseAnisetteProvider,findmy.util.abc.Serializable[LocalAnisetteMapping]
Local anisette provider using the anisette library.
- to_json(dst: str | pathlib.Path | None = None, /) LocalAnisetteMapping#
See
BaseAnisetteProvider.serialize().
- classmethod from_json(val: str | pathlib.Path | LocalAnisetteMapping, *, libs_path: str | pathlib.Path | None = None) LocalAnisetteProvider#
See
BaseAnisetteProvider.deserialize().
- async get_headers(user_id: str, device_id: str, serial: str = '0', with_client_info: bool = False) dict[str, str]#
- property otp: str#
- property machine: str#
- async close() None#
See
BaseAnisetteProvider.close().
- class findmy.reports.RemoteAnisetteMapping#
Bases:
TypedDict
JSON mapping representing state of a remote Anisette provider.
- type: Literal['aniRemote']#
- url: str#
- class findmy.reports.RemoteAnisetteProvider(server_url: str)#
Bases:
BaseAnisetteProvider,findmy.util.abc.Serializable[RemoteAnisetteMapping]
Anisette provider. Fetches headers from a remote Anisette server.
- to_json(dst: str | pathlib.Path | None = None, /) RemoteAnisetteMapping#
See
BaseAnisetteProvider.serialize().
- classmethod from_json(val: str | pathlib.Path | RemoteAnisetteMapping) RemoteAnisetteProvider#
See
BaseAnisetteProvider.deserialize().
- property otp: str#
- property machine: str#
- async get_headers(user_id: str, device_id: str, serial: str = '0', with_client_info: bool = False) dict[str, str]#
See :meth:
BaseAnisetteProvider.get_headers().
- async close() None#
See
AnisetteProvider.close().
- class findmy.reports.LocationReport(payload: bytes, hashed_adv_key: bytes)#
Bases:
findmy.keys.HasHashedPublicKey,findmy.util.abc.Serializable[LocationReportMapping]
Location report corresponding to a certain
HasHashedPublicKey().- property hashed_adv_key_bytes: bytes#
See
HasHashedPublicKey.hashed_adv_key_bytes().
- property key: findmy.keys.KeyPair#
KeyPair using which this report was decrypted.
- property payload: bytes#
Full (partially encrypted) payload of the report, as retrieved from Apple.
- property is_decrypted: bool#
Whether the report is currently decrypted.
- can_decrypt(key: findmy.keys.KeyPair, /) bool#
Whether the report can be decrypted using the given key.
- decrypt(key: findmy.keys.KeyPair) None#
Decrypt the report using its corresponding
KeyPair().
- property timestamp: datetime.datetime#
The
datetime()when this report was recorded by a device.
- property confidence: int#
Confidence of the location of this report. Int between 1 and 3.
- property latitude: float#
Latitude of the location of this report.
- property longitude: float#
Longitude of the location of this report.
- property horizontal_accuracy: int#
Horizontal accuracy of the location of this report.
- property status: int#
Status byte of the accessory as recorded by a device, as an integer.
- to_json(dst: str | pathlib.Path | None = None, /, *, include_key: Literal[True]) LocationReportEncryptedMapping#
- to_json(dst: str | pathlib.Path | None = None, /, *, include_key: Literal[False]) LocationReportDecryptedMapping
- to_json(dst: str | pathlib.Path | None = None, /, *, include_key: None = None) LocationReportMapping
Export the current state of the object as a JSON-serializable dictionary.
If an argument is provided, the output will also be written to that file.
The output of this method is guaranteed to be JSON-serializable, and passing the return value of this function as an argument to
Serializable.from_json()will always result in an exact copy of the internal state as it was when exported.You are encouraged to save and load object states to and from disk whenever possible, to prevent unnecessary API calls or otherwise unexpected behavior.
- classmethod from_json(val: str | pathlib.Path | LocationReportMapping, /) LocationReport#
Restore state from a previous
Closable.to_json()export.If given a str or Path, it must point to a json file from
Serializable.to_json(). Otherwise, it should be the Mapping itself.See
Serializable.to_json()for more information.
- __eq__(other: object) bool#
Compare two report instances.
Two reports are considered equal iff they correspond to the same key, were reported at the same timestamp and represent the same physical location.
- __hash__() int#
Get the hash of this instance.
Two instances will have the same hash iff they correspond to the same key, were reported at the same timestamp and represent the same physical location.
- __lt__(other: LocationReport) bool#
Compare against another
LocationReport().A
LocationReport()is said to be “less than” anotherLocationReport()iff its recorded timestamp is strictly less than the other report.
- __repr__() str#
Human-readable string representation of the location report.
- class findmy.reports.LocationReportDecryptedMapping#
Bases:
TypedDict
JSON mapping representing a decrypted location report.
- type: Literal['locReportDecrypted']#
- payload: str#
- hashed_adv_key: str#
- class findmy.reports.LocationReportEncryptedMapping#
Bases:
TypedDict
JSON mapping representing an encrypted location report.
- type: Literal['locReportEncrypted']#
- payload: str#
- hashed_adv_key: str#
- findmy.reports.LocationReportMapping#
- class findmy.reports.LoginState(*args, **kwds)#
Bases:
enum.Enum
Enum of possible login states. Used for
AppleAccount()’s internal state machine.- LOGGED_OUT = 0#
- REQUIRE_2FA = 1#
- AUTHENTICATED = 2#
- LOGGED_IN = 3#
- __lt__(other: LoginState) bool#
Compare against another
LoginState().A
LoginState()is said to be “less than” anotherLoginState()iff it is in an “earlier” stage of the login process, going from LOGGED_OUT to LOGGED_IN.
- __repr__() str#
Human-readable string representation of the state.
- class findmy.reports.AsyncSmsSecondFactor(account: findmy.reports.account.AsyncAppleAccount, number_id: int, phone_number: str)#
Bases:
AsyncSecondFactorMethod,SmsSecondFactorMethod
An async implementation of
SmsSecondFactorMethod().- property phone_number_id: int#
The phone number’s ID. You most likely don’t need this.
- property phone_number: str#
The 2FA method’s phone number.
May be masked using unicode characters; should only be used for identification purposes.
- async request() None#
Request an SMS to the corresponding phone number containing a 2FA code.
- async submit(code: str) findmy.reports.state.LoginState#
Submit the 2FA code as received over SMS.
- class findmy.reports.AsyncTrustedDeviceSecondFactor(account: findmy.reports.account.AsyncAppleAccount)#
Bases:
AsyncSecondFactorMethod,TrustedDeviceSecondFactorMethod
An async implementation of
TrustedDeviceSecondFactorMethod().- async request() None#
- async submit(code: str) findmy.reports.state.LoginState#
- class findmy.reports.BaseSecondFactorMethod(account: _AccType)#
Bases:
abc.ABC,Generic[_AccType]
Base class for a second-factor authentication method for an Apple account.
- property account: _AccType#
The account associated with the second-factor method.
- abstractmethod request() findmy.util.types.MaybeCoro[None]#
Put in a request for the second-factor challenge.
Exact meaning is up to the implementing class.
- abstractmethod submit(code: str) findmy.util.types.MaybeCoro[findmy.reports.state.LoginState]#
Submit a code to complete the second-factor challenge.
- class findmy.reports.SmsSecondFactorMethod(account: _AccType)#
Bases:
BaseSecondFactorMethod,abc.ABC
Base class for SMS-based two-factor authentication.
- property phone_number_id: int#
- Abstractmethod:
The phone number’s ID. You most likely don’t need this.
- property phone_number: str#
- Abstractmethod:
The 2FA method’s phone number.
May be masked using unicode characters; should only be used for identification purposes.
- class findmy.reports.SyncSmsSecondFactor(account: findmy.reports.account.AppleAccount, number_id: int, phone_number: str)#
Bases:
SyncSecondFactorMethod,SmsSecondFactorMethod
A sync implementation of
SmsSecondFactorMethod().- property phone_number_id: int#
- property phone_number: str#
- request() None#
- submit(code: str) findmy.reports.state.LoginState#
- class findmy.reports.SyncTrustedDeviceSecondFactor(account: findmy.reports.account.AppleAccount)#
Bases:
SyncSecondFactorMethod,TrustedDeviceSecondFactorMethod
A sync implementation of
TrustedDeviceSecondFactorMethod().- request() None#
- submit(code: str) findmy.reports.state.LoginState#
- class findmy.reports.TrustedDeviceSecondFactorMethod(account: _AccType)#
Bases:
BaseSecondFactorMethod,abc.ABC
Base class for trusted device-based two-factor authentication.