0

I have been playing with Quire API using python and while the GET calls work fine, I can't do any successful POST calls. I get 400 error: Bad Request. I would appreciate any hints on what I might be doing wrong.

Below are relevant code snippets:

AUTH_ENDPOINT = 'https://quire.io/oauth/token'
API_ENDPOINT = 'https://quire.io/api'

data = {
    'grant_type' : 'refresh_token',
    'refresh_token' : 'my_refresh_code',
    'client_id' : 'my_client_id',
    'client_secret' : 'my_client_secret'
}

r = requests.post(url=AUTH_ENDPOINT, data=data)
response = json.loads(r.text)
access_token = response['access_token']
headers = {'Authorization' : 'Bearer {token}'.format(token=access_token)}

# This works fine
r = requests.get(url=API_ENDPOINT + '/user/id/me', headers=headers)
user = json.loads(r.text)
print(user)

# This doesn't work
task_oid = 'my_task_oid'

data = {
    'description' : 'Test Comment'
}

r = requests.post(
    url=API_ENDPOINT + '/comment/' + task_oid,
    data=data,
    headers=headers,
)

Qbaza
  • 33
  • 4
  • Try [`raise_for_status`](http://requests.kennethreitz.org/en/master/user/quickstart/#response-status-codes) to give a more detailed error. (Add this just after the last `post` line.) – Unapiedra Oct 06 '19 at 23:54
  • key for authorization code is `code`, not `refresh_token` (that token will be in the response) – njzk2 Oct 06 '19 at 23:54
  • @njzk2 that's true for first time authorization, later when you need to refresh auth, you need to use `refresh_token`. Anyway, since the first call is successful I don't think this a problem here. – Qbaza Oct 07 '19 at 01:51
  • @Unapiedra : Seems that detailed errors is not much more helpful: `400 Client Error: Bad Request for url: https://quire.io/api/comment/my_task_oid` – Qbaza Oct 07 '19 at 01:56

2 Answers2

1

I am not familiar with the python requests API, so I don't know about default headers. However it looks like you missed to send the request data as a JSON string:

here what worked for me from java script:

uri: '/comment/my_task_oid',
method: 'POST',
body: '{"description":"hello comment"}'

maybe it helps, in python as well.

also a curl example:

curl -X POST -H 'Authorization: Bearer my_access_token' -d "{\"description\" : \"a test comment\"}" https://quire.io/api/comment/my_task_oid
cor3000
  • 936
  • 1
  • 6
  • 16
  • I will definitely test it with curl, but surprisingly `POST` to auth endpoint works fine as is. I can retrieve access token. – Qbaza Oct 07 '19 at 23:39
  • yes the quire-API communicates via json while the oauth/token endpoint uses x-url-form-encoded POST data data, still it returns a JSON string containing the token data. Seems like the documentation isn't fully clear on this detail. However the official oauth docs show an example clearly using form encoded data for the token request: https://www.oauth.com/oauth2-servers/access-tokens/authorization-code-request/ the quire-api docs show JSON request content to be posted: https://quire.io/dev/api/#tag-comment – cor3000 Oct 09 '19 at 15:21
1

The answer provided by @cor3000 hinted that post data should be passed as JSON. I tested it out and indeed it works. Here is required modification to the POST reqest:

r = requests.post(
    url=API_ENDPOINT + '/comment/' + task_oid,
    data=json.dumps(data),
    headers=headers,
)

Alternatively you can also do:

r = requests.post(
    url=API_ENDPOINT + '/comment/' + task_oid,
    json=data,
    headers=headers,
)

More details in requests documentation: https://requests.kennethreitz.org/en/master/user/quickstart/#more-complicated-post-requests

Qbaza
  • 33
  • 4