py-trello icon indicating copy to clipboard operation
py-trello copied to clipboard

403 Error

Open vlall opened this issue 1 year ago • 15 comments

Hello, I'm getting a 403 error but the site seems to be up and all services are functional on Trello. Not sure if this is a Cloudflare server-side issue with Trello or an API issue.

Recreate the issue with this:

from trello import TrelloClient TrelloClient(TRELLO_API_KEY).list_boards()


Error:
trello.exceptions.ResourceUnavailable: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: qCRWUowLKZ3ESPwzuDguR8rVTFatc3uu6U1O8jvYVwnZhRVJr-Elpg==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML> at https://api.trello.com/1/members/me/boards/?filter=all (HTTP status: 403)

vlall avatar Feb 21 '24 19:02 vlall

Having the same problem...

oliv3z avatar Feb 21 '24 20:02 oliv3z

Having the same problem ... Tengo el mismo problema...

j13c avatar Feb 22 '24 00:02 j13c

Not sure how maintained this project is, but for those who want a workaround, the official API docs here with the requests python library works for me: https://developer.atlassian.com/cloud/trello/rest/

But you have to do your own parsing.

vlall avatar Feb 22 '24 01:02 vlall

Response from Trello support:

We recently released a change in making GET requests. Trello’s API will no longer permit supplying a body with a GET request and will now be blocked with a 403 response. For more information: https://developer.atlassian.com/changelog/#CHANGE-1459

To resolve these errors, you should remove the request body in your API GET requests.

Hope this helps but let me know if you have any more questions or concerns.

beretem avatar Feb 22 '24 01:02 beretem

11am: I set up a Discord bot with Trello integration and everything is good 12pm: Trello updates its API policies and everything goes down the drain lol

It needs to be fixed here, using requests in Python and it started working 🙌

aylmerbolzan avatar Feb 22 '24 03:02 aylmerbolzan

Problem is located here. https://github.com/sarumont/py-trello/blob/a628d545e936ccdab299cb139f56b8f98836618e/trello/trelloclient.py#L221

When files are not specified in the case for GET calls, it will attempt to convert an empty dictionary to JSON string. This will be sent as "{}" in the body of our GET request.

Currently, I am monkey patching with the following to get by.

import trello


def patched_fetch_json(self,
                       uri_path,
                       http_method='GET',
                       headers=None,
                       query_params=None,
                       post_args=None,
                       files=None):
    """ Fetch some JSON from Trello """

    # explicit values here to avoid mutable default values
    if headers is None:
        headers = {}
    if query_params is None:
        query_params = {}
    if post_args is None:
        post_args = {}

    # if files specified, we don't want any data
    data = None
    if files is None and post_args != {}:
        data = json.dumps(post_args)

    # set content type and accept headers to handle JSON
    if http_method in ("POST", "PUT", "DELETE") and not files:
        headers['Content-Type'] = 'application/json; charset=utf-8'

    headers['Accept'] = 'application/json'

    # construct the full URL without query parameters
    if uri_path[0] == '/':
        uri_path = uri_path[1:]
    url = 'https://api.trello.com/1/%s' % uri_path

    if self.oauth is None:
        query_params['key'] = self.api_key
        query_params['token'] = self.api_secret

    # perform the HTTP requests, if possible uses OAuth authentication
    response = self.http_service.request(http_method, url, params=query_params,
                                            headers=headers, data=data,
                                            auth=self.oauth, files=files,
                                            proxies=self.proxies)

    if response.status_code == 401:
        raise trello.Unauthorized("%s at %s" % (response.text, url), response)
    if response.status_code != 200:
        raise trello.ResourceUnavailable("%s at %s" % (response.text, url), response)

    return response.json()


trello.TrelloClient.fetch_json = patched_fetch_json

client = trello.TrelloClient(
        api_key="ABC123",
        token="456DEF")
list_of_boards = client.list_boards()
print(list_of_boards)

kaikok avatar Feb 22 '24 06:02 kaikok

https://github.com/sarumont/py-trello/pull/374

GMartin-dev avatar Feb 22 '24 07:02 GMartin-dev

Problem is located here.

https://github.com/sarumont/py-trello/blob/a628d545e936ccdab299cb139f56b8f98836618e/trello/trelloclient.py#L221

When files are not specified in the case for GET calls, it will attempt to convert an empty dictionary to JSON string. This will be sent as "{}" in the body of our GET request.

Currently, I am monkey patching with the following to get by.

import trello


def patched_fetch_json(self,
                       uri_path,
                       http_method='GET',
                       headers=None,
                       query_params=None,
                       post_args=None,
                       files=None):
    """ Fetch some JSON from Trello """

    # explicit values here to avoid mutable default values
    if headers is None:
        headers = {}
    if query_params is None:
        query_params = {}
    if post_args is None:
        post_args = {}

    # if files specified, we don't want any data
    data = None
    if files is None and post_args != {}:
        data = json.dumps(post_args)

    # set content type and accept headers to handle JSON
    if http_method in ("POST", "PUT", "DELETE") and not files:
        headers['Content-Type'] = 'application/json; charset=utf-8'

    headers['Accept'] = 'application/json'

    # construct the full URL without query parameters
    if uri_path[0] == '/':
        uri_path = uri_path[1:]
    url = 'https://api.trello.com/1/%s' % uri_path

    if self.oauth is None:
        query_params['key'] = self.api_key
        query_params['token'] = self.api_secret

    # perform the HTTP requests, if possible uses OAuth authentication
    response = self.http_service.request(http_method, url, params=query_params,
                                            headers=headers, data=data,
                                            auth=self.oauth, files=files,
                                            proxies=self.proxies)

    if response.status_code == 401:
        raise trello.Unauthorized("%s at %s" % (response.text, url), response)
    if response.status_code != 200:
        raise trello.ResourceUnavailable("%s at %s" % (response.text, url), response)

    return response.json()


trello.TrelloClient.fetch_json = patched_fetch_json

client = trello.TrelloClient(
        api_key="ABC123",
        token="456DEF")
list_of_boards = client.list_boards()
print(list_of_boards)

Tested and the code worked. This is a quick fix for those who cannot wait for package update.

jitvimol avatar Feb 22 '24 09:02 jitvimol

This looks to be a permanent change to the API as per: https://developer.atlassian.com/changelog/#CHANGE-1459

Thanks to @jitvimol for the monkey patch -- that did the trick for me!

Coppersmith avatar Mar 14 '24 11:03 Coppersmith

This looks to be a permanent change to the API as per: https://developer.atlassian.com/changelog/#CHANGE-1459

Thanks to @jitvimol for the monkey patch -- that did the trick for me!

FYI : @kaikok is the one who develop the code. (I tested his code)

jitvimol avatar Mar 15 '24 06:03 jitvimol

Thank you @jitvimol for testing out the fix and the attribution! Glad that it was useful to everyone here.

kaikok avatar Mar 16 '24 02:03 kaikok

Monkey patch from @jitvimol worked for me. Just be careful, when you import only part of py-trello module like me by from trello import TrelloClient then you need to add also import json

frankiexo avatar Mar 16 '24 19:03 frankiexo

Not fully tested but just wondering if it might be an idea that the library uses its own requests.Session that always blanks out the data (and anything else necessary) for GETs as the default to http_service instead of requests.

Far from properly tested and just throwing it out there in case it's of use (and might just be a possible alternative monkey patch).

from trello import TrelloClient
import requests

class TrelloSession(requests.Session):
    def request(self, method, url, **kwargs):
        if method == 'GET':
            kwargs = {**kwargs, 'data': None}
        return super().request(method, url, **kwargs)

Then initialise the client as (although TrelloSession() would become the default)

client = TrelloClient(api_key=api_key, token=api_token, http_service=TrelloSession())

joncle avatar Mar 25 '24 22:03 joncle

For personal needs, I have forked this repository and merged two pending PRs into the new repository. https://github.com/Konano/py-trello-api

As a temporary solution, I have also uploaded the new package to Pypi. You can download the fixed py-trello with this command: pip install py-trello-api==0.20.0

I hope this helps someone in need.

Konano avatar Apr 02 '24 10:04 Konano

For personal needs, I have forked this repository and merged two pending PRs into the new repository. https://github.com/Konano/py-trello-api

As a temporary solution, I have also uploaded the new package to Pypi. You can download the fixed py-trello with this command: pip install py-trello-api==0.20.0

I hope this helps someone in need.

BTW it does not support 2.7 / didn't test 3.x but thank for the contribution!

zymptomLabs avatar Apr 04 '24 19:04 zymptomLabs