At https://github.com/icloud-photos-downloader/icloud_photos_downloader/blob/master/src/pyicloud_ipd/base.py#L271 , y'all don't check for 403; it turns out this is the return code for "you've tried too many times we've locked your account". With the code as it is we get:
2024-11-30 18:44:15 DEBUG Authenticating...
2024-11-30 18:44:16 ERROR Missing apple_id field (Missing apple_id field)
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/base.py", line 303, in _authenticate_with_token
req = self.session.post(
^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 637, in post
return self.request("POST", url, data=data, json=json, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/session.py", line 167, in request
self._raise_error(code or "Unknown", reason)
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/session.py", line 196, in _raise_error
raise api_error
pyicloud_ipd.exceptions.PyiCloudAPIResponseException: Missing apple_id field (Missing apple_id field)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/bin/icloudpd", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/icloudpd/base.py", line 745, in main
result = core(
^^^^^
File "/usr/local/lib/python3.12/site-packages/icloudpd/base.py", line 1183, in core
icloud = authenticator(
^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/icloudpd/authentication.py", line 53, in authenticate_
icloud = PyiCloudService(
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/base.py", line 160, in __init__
self.authenticate()
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/base.py", line 283, in authenticate
self._authenticate_with_token()
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/base.py", line 309, in _authenticate_with_token
raise PyiCloudFailedLoginException(msg, error) from error
pyicloud_ipd.exceptions.PyiCloudFailedLoginException: ('Invalid authentication token.', PyiCloudAPIResponseException('Missing apple_id field (Missing apple_id field)'))
, which as you can see is extremely unhelpful.
If we add a branch like so:
if response.status_code == 401:
raise PyiCloudAPIResponseException(response.text, str(response.status_code))
if response.status_code == 403:
raise PyiCloudAPIResponseException(response.text, str(response.status_code))
if response.status_code == 412:
# non 2FA account returns 412 "precondition no met"
we instead get:
2024-11-30 18:49:09 DEBUG Authenticating...
in authenticate
in authenticate4
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/base.py", line 279, in authenticate
raise PyiCloudAPIResponseException(response.text, str(response.status_code))
pyicloud_ipd.exceptions.PyiCloudAPIResponseException: {
"serviceErrors" : [ {
"code" : "-20209",
"message" : "This Apple Account has been locked for security reasons. Visit iForgot to reset your account (https://iforgot.apple.com).",
"suppressDismissal" : false
} ]
} (403)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/bin/icloudpd", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/icloudpd/base.py", line 745, in main
result = core(
^^^^^
File "/usr/local/lib/python3.12/site-packages/icloudpd/base.py", line 1183, in core
icloud = authenticator(
^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/icloudpd/authentication.py", line 53, in authenticate_
icloud = PyiCloudService(
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/base.py", line 160, in __init__
self.authenticate()
File "/usr/local/lib/python3.12/site-packages/pyicloud_ipd/base.py", line 291, in authenticate
raise PyiCloudFailedLoginException(msg, error) from error
pyicloud_ipd.exceptions.PyiCloudFailedLoginException: ('Invalid email/password combination.', PyiCloudAPIResponseException('{\n "serviceErrors" : [ {\n "code" : "-20209",\n "message" : "This Apple Account has been\xa0locked\xa0for se
curity reasons. Visit iForgot to reset your account (https://iforgot.apple.com).",\n "suppressDismissal" : false\n } ]\n} (403)'))
, which is waaaaay more helpful.
At https://github.com/icloud-photos-downloader/icloud_photos_downloader/blob/master/src/pyicloud_ipd/base.py#L271 , y'all don't check for 403; it turns out this is the return code for "you've tried too many times we've locked your account". With the code as it is we get:
, which as you can see is extremely unhelpful.
If we add a branch like so:
we instead get:
, which is waaaaay more helpful.