picklepete / pyicloud

A Python + iCloud wrapper to access iPhone and Calendar data.
MIT License
2.45k stars 436 forks source link

Authentication required for Account. (421) when trying to query api.calendar.events() #330

Open radoystoyanov opened 3 years ago

radoystoyanov commented 3 years ago

The problem

I'm trying to retrieve calendar data from iCloud. I can authenticate successfully using the sample 2fa/2sa code. I can successfully call some of the APIs such as api.iphone.location(). However, when trying the following code, I get an error "pyicloud.exceptions.PyiCloudAPIResponseException: Authentication required for Account. (421)".

from_dt = datetime(2021, 3, 27)
to_dt = datetime(2021, 3, 28)
events = api.calendar.events(from_dt, to_dt)

Environment

Traceback/Error logs

DEBUG:pyicloud.services.calendar.http:GET https://p17-calendarws.icloud.com:443/ca/events 
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): p17-calendarws.icloud.com:443
DEBUG:urllib3.connectionpool:https://p17-calendarws.icloud.com:443 "GET /ca/events?lang=en-us&usertz=Europe%2FSofia&startDate=2021-03-27&endDate=2021-03-28 HTTP/1.1" 421 0
DEBUG:pyicloud.base:Saved session data to file
DEBUG:pyicloud.base:Cookies saved to /var/folders/vj/x_87xd5j5tz71ntl61101tfm0000gn/T/pyicloud/XXXXXX/XXXXXX
DEBUG:pyicloud.services.calendar.http:Misdirected Request (421). Retrying ...
DEBUG:requests.sessions.http:GET https://p17-calendarws.icloud.com:443/ca/events 
DEBUG:urllib3.connectionpool:https://p17-calendarws.icloud.com:443 "GET /ca/events?lang=en-us&usertz=Europe%2FSofia&startDate=2021-03-27&endDate=2021-03-28 HTTP/1.1" 421 0
DEBUG:pyicloud.base:Saved session data to file
DEBUG:pyicloud.base:Cookies saved to /var/folders/vj/x_87xd5j5tz71ntl61101tfm0000gn/T/pyicloud/XXXXXX/XXXXXX
ERROR:pyicloud.base:Authentication required for Account. (421)
Traceback (most recent call last):
  File "/Users/radoystoyanov/Documents/Code/alchemy-pipeline/calendars/icloud.py", line 67, in <module>
    events = api.calendar.events(from_dt, to_dt)
  File "/Users/radoystoyanov/Documents/Code/alchemy-pipeline/calendars/lib/python3.7/site-packages/pyicloud/services/calendar.py", line 65, in events
    self.refresh_client(from_dt, to_dt)
  File "XXXXXX/lib/python3.7/site-packages/pyicloud/services/calendar.py", line 58, in refresh_client
    req = self.session.get(self._calendar_refresh_url, params=params)
  File "XXXXXX/lib/python3.7/site-packages/requests/sessions.py", line 555, in get
    return self.request('GET', url, **kwargs)
  File "XXXXXX/lib/python3.7/site-packages/pyicloud/base.py", line 128, in request
    return self.request(method, url, **kwargs)
  File "XXXXXX/lib/python3.7/site-packages/pyicloud/base.py", line 130, in request
    self._raise_error(response.status_code, response.reason)
  File "XXXXXX/lib/python3.7/site-packages/pyicloud/base.py", line 186, in _raise_error
    raise api_error
pyicloud.exceptions.PyiCloudAPIResponseException: Authentication required for Account. (421)

Additional information

I have including additional debug logging using:

logging.basicConfig(level=logging.DEBUG)

Thanks in advance for your support!

leres commented 3 years ago

My script needed a verification code today and hit this error for the first time. While writing a simple test script to show the issue and was reminded that it uses cookies; I got curious and found two files in the directory, {foo} and {foo}.session (where {foo} is an appleid email address with punctuation removed). After removing these files I was able to re-authenticate (after satisfying the verification challenge of course).

asfaltboy commented 3 years ago

That didn't work for me, and the same happens for me with the reminders service ... the fmip and contacts services, however, seem to work just fine ...

Any chance one of the contributors can guide us to how we can debug this further?

One thing I found interesting, not sure if related to the above issue, is that the api.requires_2fa and api.requires_2sa both return False while my appleid settings show TWO-FACTOR AUTHENTICATION as "On". Though, why would the contacts service returns info without further 2fa? Note that I use a keyring, but I also tried instantiating PyiCloudService with a password directly, to no avail.

pali6 commented 3 years ago

A duplicate of #322. (Also experiencing the same issue.)

Cyberbird85 commented 3 years ago

Same thing for me.

dexma-dev commented 2 years ago

Having the same issue. Would really love to find a solution here.

tomx-sh commented 2 years ago

Same here

plk commented 2 years ago

Same issue here

xaoyaoo commented 2 years ago

Same here

zarkin404 commented 2 years ago

After comparing the request fired at browser to the payload generated at pyicloud, i found that param dsid is lost and it causes 419 http error.

To fix the problem, you can append the following code to pyicloud/services/calendar.py:L55

        params.update(
            {
                "lang": "en-us",
                "usertz": get_localzone().zone,
                "startDate": from_dt.strftime("%Y-%m-%d"),
                "endDate": to_dt.strftime("%Y-%m-%d"),
                "dsid": self.session.service.data["dsInfo"]["dsid"],  # PATCH HERE!!
            }
        )
plk commented 2 years ago

Many thanks @zarkin404 - that fixed it for me but needed to be patched on line 83 also.

xaoyaoo commented 2 years ago

Thank you very much

clstaudt commented 2 years ago

The monkeypatch is working for me. If this is generally a working solution, please merge soon.

WillPeak commented 2 years ago

Happening for me today after monkey patching the suggested. Anyone else seeing this?

ffHakke commented 1 year ago

I'm sorry fix didn't work for me on Python 3.9.2

File "/home/pi/python/./icloudlogin.py", line 62, in print(api.calendar.events(from_dt, to_dt)) File "/home/pi/.local/lib/python3.9/site-packages/pyicloud/services/calendar.py", line 64, in events self.refresh_client(from_dt, to_dt) File "/home/pi/.local/lib/python3.9/site-packages/pyicloud/services/calendar.py", line 57, in refresh_client req = self.session.get(self._calendar_refresh_url, params=params) File "/usr/lib/python3/dist-packages/requests/sessions.py", line 555, in get return self.request('GET', url, kwargs) File "/home/pi/.local/lib/python3.9/site-packages/pyicloud/base.py", line 131, in request return self.request(method, url, kwargs) File "/home/pi/.local/lib/python3.9/site-packages/pyicloud/base.py", line 133, in request self._raise_error(response.status_code, response.reason) File "/home/pi/.local/lib/python3.9/site-packages/pyicloud/base.py", line 189, in _raise_error raise api_error pyicloud.exceptions.PyiCloudAPIResponseException: Authentication required for Account. (421)

WhyNineKay commented 1 year ago

I did the patch, but I'm now getting pyicloud.exceptions.PyiCloudAPIResponseException: Authentication required for Account. (500)

Which is different as the error code is 500. Still not working, really need a solution.