ModerNews / MAL-API-Client-Upgraded

Improved version of malclient by JFryy
MIT License
2 stars 3 forks source link

Problem with function client.update_my_anime_list_status() #13

Closed YisusChrist closed 2 years ago

YisusChrist commented 2 years ago

When calling the function to add an anime to a given list (watching, completed, on hold, dropped or plan to watch) or to update its status it takes always only the value "watching".

Example:

# Payload data
payload = {
    "status": "completed",
    "is_rewatching": False,
    "score": 0,
    "watched_episodes": 0,
    "priority": 0,
    "num_times_rewatch": 0,
    "rewatch_value": 0,
    "tags": "",
    "comments": "",
}
# 22199 - Akame ga Kill!
client.update_my_anime_list_status(anime_id=22199, data=payload)

When you check the webpage you will see the title in the "Last Anime Updates" section, as it has been recently added or modified, but the status is "watching". I've tried with other statuses in the payload and ended with the same result. I guess payload may be incorrect or incomplete and the request sets a default value.

ModerNews commented 2 years ago

I am aware that list functions are a total mess at the current state. I have finished what I've been focused on recently (whole fields system) so I will be taking those functions as my priority now. I haven't looked through them yet though so I can't say for sure, but maybe this value is just hardcoded? Although if nothing unexpected happens I am looking forward to have it (and new docs) done when I am back home, during the upcoming weekend. I will have syntaxes changed to more user-friendly as well.

YisusChrist commented 2 years ago

Thanks for your time and for giving a high priority. As far as I've seen in the modules it doesn't seem to be hardcoded. By the way, I've taken a look at the official documentation and there is an example of the "Update my anime list status" operation with a curl request. That way currently works, I've been able to set all the possible statuses, so I'm pretty sure that the problem in this function must be related to the values passed inside the payload.

Another important thing, when you send the request with curl you can either the PATCH or PUT operation with the same result (because of some ambiguities...), but it doesn't gets fixed in the code with that. I mean, the last line:

return self._api_handler.call(method="patch", uri=uri, data=data)

There are no changes apparently if you replace "patch" by "put", it doesn't make any effect.

YisusChrist commented 2 years ago

[Update] I've been debugging the "request_handler" and "client" modules and I've found the problem and a way to fix it:

In the file client.py you can find this function which is used to connect the user to the API with his token / client ID.

def _connect_to_api(self):
        if self._bearer_token is not None:
            self.headers = {
                'Content-Type': 'application/json',
                'Authorization': f'Bearer {self._bearer_token}'
            }
            self._api_handler = APICaller(base_url=self._base_url,
                                          headers=self.headers)
            self.authorized = True
        elif self._client_id is not None:
            self.headers = {
                'Content-Type': 'application/json',
                'X-MAL-CLIENT-ID': self._client_id
            }
            self._api_handler = APICaller(base_url=self._base_url,
                                          headers=self.headers)
        else:
            raise AuthorizationError()

If you take again a look at the API documentation you will see that the Update my anime list status operation has a defined body schema: REQUEST BODY SCHEMA: application/x-www-form-urlencoded, but in the code above you can see clearly that at in headers there is the value 'Content-Type': 'application/json' which causes the problem.

I tried setting the correct value as:

self.headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': f'Bearer {self._bearer_token}'
}

and it actually works! I did also remove the 'Content-Type' key like this:

self.headers = {
    'Authorization': f'Bearer {self._bearer_token}'
}

and also works (don't know why yet).

ModerNews commented 2 years ago

Huh, never seen any need to look into that, should have done that when I was adding new authentication method. Anyways good to know what caused the issue, as I said I will be picking it up during the weekend, thanks for info, this will speed up the process definitely.