lazeroffmichael / ticktick-py

Unofficial TickTick API
https://lazeroffmichael.github.io/ticktick-py/
MIT License
210 stars 30 forks source link

Unable to initialize the client (too many 500 error responses) #26

Open Vermoot opened 2 years ago

Vermoot commented 2 years ago

Hi!

Trying to get back to my project on a new computer, while setting it up and trying to run my script, I can create the .token-oauth file without issues, but then when trying to initialize the client I get an error which I'm unable to figure out.

Here's what it looks like in a python console, doing it all manually to check out what's going on (the oauth token file is already present in the working directory):

Expand ``` notion-ticktick-bridge on  main [!?] via 🐍 v3.10.2 (venv) ❯ python3 Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> from dotenv import load_dotenv >>> from ticktick.oauth2 import OAuth2 >>> from ticktick.api import TickTickClient >>> load_dotenv() True >>> ticktick_client = os.getenv("TICKTICK_ID") >>> ticktick_secret = os.getenv("TICKTICK_SECRET") >>> ticktick_url = os.getenv("TICKTICK_URL") >>> ticktick_username = os.getenv("TICKTICK_USERNAME") >>> ticktick_password = os.getenv("TICKTICK_PWD") >>> oauth = OAuth2(client_id=ticktick_client, client_secret=ticktick_secret, redirect_uri=ticktick_url) >>> tt=TickTickClient(ticktick_username, ticktick_password, oauth) Traceback (most recent call last): File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/requests/adapters.py", line 439, in send resp = conn.urlopen( File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 846, in urlopen return self.urlopen( File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 846, in urlopen return self.urlopen( File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 846, in urlopen return self.urlopen( File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 836, in urlopen retries = retries.increment(method, url, response=response, _pool=self) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/urllib3/util/retry.py", line 574, in increment raise MaxRetryError(_pool, url, error or ResponseError(cause)) urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='api.ticktick.com', port=443): Max retries exceeded with url: /api/v2/user/signin?wc=True&remember=True (Caused by ResponseError('too many 500 error responses')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 1, in File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 47, in __init__ self._prepare_session(username, password) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 62, in _prepare_session self._login(username, password) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 99, in _login response = self.http_post(url, json=user_info, params=parameters, headers=self.HEADERS) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 179, in http_post response = self._session.post(url, **kwargs) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/requests/sessions.py", line 590, in post return self.request('POST', url, data=data, json=json, **kwargs) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/requests/sessions.py", line 542, in request resp = self.send(prep, **send_kwargs) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/requests/sessions.py", line 655, in send r = adapter.send(request, **kwargs) File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/requests/adapters.py", line 507, in send raise RetryError(e, request=request) requests.exceptions.RetryError: HTTPSConnectionPool(host='api.ticktick.com', port=443): Max retries exceeded with url: /api/v2/user/signin?wc=True&remember=True (Caused by ResponseError('too many 500 error responses')) >>> ```

I did verify the credentials in my .env file, everything in there is correct.

lazeroffmichael commented 2 years ago

Hi, try passing a new requests session when initializing the Oauth client like in Issue #7

Vermoot commented 2 years ago

Alright, continuing on from the python console session I posted earlier, (and having deleted the oauth token file to start fresh), here's what I get:

>>> import requests
>>> requests_session = requests.session()
>>> oauth = OAuth2(client_id=ticktick_client, client_secret=ticktick_secret, redirect_uri=ticktick_url, session=requests_session)
Cache could not be read at: .token-oauth
Enter the URL you were redirected to: http://127.0.0.1:8080/?code=srATxb&state=None
>>> tt=TickTickClient(ticktick_username, ticktick_password, oauth)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 47, in __init__
    self._prepare_session(username, password)
  File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 62, in _prepare_session
    self._login(username, password)
  File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 99, in _login
    response = self.http_post(url, json=user_info, params=parameters, headers=self.HEADERS)
  File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 180, in http_post
    self.check_status_code(response, 'Could Not Complete Request')
  File "/home/vermoot/Projects/notion-ticktick-bridge/venv/lib/python3.10/site-packages/ticktick/api.py", line 117, in check_status_code
    raise RuntimeError(error_message)
RuntimeError: Could Not Complete Request
>>>
lazeroffmichael commented 2 years ago

Would you be able to verify that the request error is a 503 error? There are others having this issue such as in #25, however, for some reason, I cannot recreate the error to not be able to initialize the client. At first, I thought it had to do with the user-agent string specifying macos in the library, but I tried on a linux VM and I still can't reproduce the error.

Vermoot commented 2 years ago

I have no idea how to do that but I'd be glad to help in any way I can

vesely-david commented 2 years ago

I'm having the same issue. Is there any known solution yet?

mkakabaev commented 2 years ago

I found a (temporary) solutuion. Session opened during API call stay alive. You will have to clear them using https://ticktick.com/webapp/#settings/profile page

jruzal commented 2 years ago

@lazeroffmichael thanks for this library :). @mkakabaev please, could you explain your solution in details... I log out from any other sessions and exit from web session, but it still not working. Maybe the problem is that i use gmail to sign in. image

mkakabaev commented 2 years ago

@jruzal

@lazeroffmichael thanks for this library :). @mkakabaev please, could you explain your solution in details... I log out from any other sessions and exit from web session, but it still not working. Maybe the problem is that i use gmail to sign in. image

My fault. I should give more details. After cleaning sessions you should wait few hours until the TickTick's antifraud system allows you to open a new one. I discovered it when tried to reconnect my iPhone's TickTick app (I accidentally removed that session as well). The app showed me a message "You did that too much, wait 24 hours or reset password". I decided to wait, returned to my attempts on the next day and everything started working. So either wait a little or reset the password in case you need an immediate access.

If you familiar with Postman/curl/whatever you can perform a manual signing process and get a more/less clear messages in the response to realise what is exactly going

I think the library could be designed better. It uses undocumented API (I think it is the same as official apps use) and call 'user/signin + savePermanent' call to obtain the token (probably not the same as it saved in cache) BUT do not logout on script exiting. So you start with success, use a script for a while and then TickTick blocks you (obviously, it is not an immediate reaction).

So for now I'm using the library just as an unofficial API reference/knowledge base. Thanks author! Will wait for fix.

jruzal commented 2 years ago

@mkakabaev thanks :) I'll try reconnect later.

DougX71 commented 1 year ago

I had been using the API successfully for amost two years. Thanks, Michael for developing it and providing some assistance two years ago. Unfortunately, the API has stopped working for me in that I am now always getting the 'too many 500 error responses' error. I find it interesting that I was able to use the API with no problems long after issue 26 was reported.

I tried Michael’s suggestion from issue 7 in terms of using this line:

requests_session = requests.session()

but the suggestion did not work. I also tried mkakabaev’s suggestion of clearing still-open sessions using the https://ticktick.com/webapp/#settings/profile page but it also did not work.

Having the hypothesis that the 'too many 500 error responses' error was related to my account, I decided to go back to basics in terms of starting with a new test TickTick account and a simple script:

Issue report 03 setup2 py screenshot

In my laptop environment, renamed the .token-oauth file so that TickTick would create a new one for the new account. (I don’t know how to use multiple .token-oauth files.) TickTick did create the new .token-oauth file but the script fails at the yellow highlighted line. The failure is in adapters.py at line 507:

Issue report 03 adapters py screenshot

From the variables in the PyCharm IDE, I see this: HTTPSConnectionPool(host='api.ticktick.com', port=443): Max retries exceeded with url: /api/v2/user/signin?wc=True&remember=True (Caused by ResponseError('too many 500 error responses'))

It seems that in this simple test environment, I am getting the 'too many 500 error responses' error. I can also duplicate the error in a cloud-based VM.

Here is the simple script that generates the error: setup2.txt

My authentication information is in config2.py. I have not included it here, but here is a file with the information masked out: config2masked.txt

I did some experiments using Pipedream and the official TickTick API and was able to create tasks in the same TickTick account. Zapier is also able to authenicate my TickTick account,

Are there other people like mkakabaev who have been able to get past this error?

luutuankiet commented 6 months ago

hi @DougX71 , just chiming in that I also got the 500 error and @mkakabaev 's suggestion resolved it - force sign out the devices, wait an hour or so, everything works as usual. Thanks to this issue I now find a caveat with ticktick-py that there isn't a solution to programmatically sign the session out once it ends. Hoping anyone can point me to an endpoint that might help achieve this.

DougX71 commented 6 months ago

Thanks, @luutuankiet for getting back to me. I did try @mkakabaev 's suggestion. I closed the open sessions and waited over one day and tried again and still got the 'too many 500 error responses' message. I wonder if there could be other causes of the 'too many 500 error responses' message in addition to open sessions.

As an update, I am still using TickTick but no longer using an API. I found that Zapier could do what I wanted but would have cost between $497 and $969 per year which is more than I wanted to spend.

edbock commented 6 months ago

I am very grateful for this library because I need function(s) that aren't available in the official API. Sadly, although this has worked just fine for me for two months, I encountered this error this week. I tried @mkakabaev suggestion and waited but I'm still getting the same error.

I also tried deleting my app from the developer center and creating a new one. I ran my script using a different virtual environment and re-authorized. However, I get the exact same error sequence as before (same as this comment, which led me here from Google).

The requests_session = requests.session() suggested above didn't work for me either.

I added pprint.pprint(response) to http_post function as suggested here and discovered <Response [429]> Too Many Requests.

I wish I had a clue about why Ticktick is giving this response.

Here are the results of pip install --upgrade ticktick-py:

Requirement already satisfied: ticktick-py in /home/ed/.local/lib/python3.10/site-packages (2.0.3) Requirement already satisfied: urllib3==1.26.7 in /home/ed/.local/lib/python3.10/site-packages (from ticktick-py) (1.26.7) Requirement already satisfied: pytz==2021.1 in /home/ed/.local/lib/python3.10/site-packages (from ticktick-py) (2021.1) Requirement already satisfied: requests==2.26.0 in /home/ed/.local/lib/python3.10/site-packages (from ticktick-py) (2.26.0) Requirement already satisfied: regex==2021.4.4 in /home/ed/.local/lib/python3.10/site-packages (from ticktick-py) (2021.4.4) Requirement already satisfied: certifi>=2017.4.17 in /home/ed/.local/lib/python3.10/site-packages (from requests==2.26.0->ticktick-py) (2023.11.17) Requirement already satisfied: idna<4,>=2.5 in /home/ed/.local/lib/python3.10/site-packages (from requests==2.26.0->ticktick-py) (3.6) Requirement already satisfied: charset-normalizer~=2.0.0 in /home/ed/.local/lib/python3.10/site-packages (from requests==2.26.0->ticktick-py) (2.0.12)

edbock commented 6 months ago

Update: I got it to work. I wish I knew exactly what I did, but I'll provide the steps as closely as possible.

  1. I changed the http_post function in api.py to the exact same code I found here (see below). However, I did not add the HEADERS dictionary as specified in that post.
  2. I changed USER_AGENT to my actual user agent.
  3. I deleted the .token-oauth file in my home directory and re-authorized.
  4. Everything is working again.

I hope this works for someone else. I would love to know why this worked.

def http_post(self, url, **kwargs):
    """
    Sends an http post request with the specified url and keyword arguments.

    Arguments:
        url (str): Url to send the request.
        **kwargs: Arguments to send with the request.

    Returns:
        dict: The json parsed response if possible or just a string of the response text if not.

    Raises:
        RunTimeError: If the request could not be completed.
    """
    if 'headers' not in kwargs:
        response = self._session.post(url, headers=self.HEADERS, **kwargs)
    else:
        kwargs['headers'].update(self.HEADERS)
        response = self._session.post(url, **kwargs)
    self.check_status_code(response, 'Could Not Complete Request')

    try:
        return response.json()
    except ValueError:
        return response.text
DougX71 commented 5 months ago

As I mentioned re issue #56 I was able to get past the 'too many 500 error responses' message and the 'too many 405 error responses' message by using the version of api.py supplied by @zozzzC in #55. The API worked fine for a couple of weeks. Then I had a recurrence of the 'too many 500 error responses' message.

As suggested by @mkakabaev I went to https://ticktick.com/webapp/#p/inbox/tasks?modalType=settings&tabs=profile and under Manage scrolled to the bottom of the list of Login Devices and chose the red Sign Out on All Devices button. The API then worked immediately. I did not have to wait a few hours but it was a day after I encountered the issue occurred that I cleared out the sessions.