Python Requests to Forge API - 401 Response "Authorization failed" - python-3.x

def get_token():
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
data = {'client_id': 'XXX', 'client_secret': 'XXX', 'grant_type': 'client_credentials', 'scope': 'data:read'}
response = requests.post('https://developer.api.autodesk.com/authentication/v1/authenticate', headers=headers, data=data)
return response.json()['access_token']
print('Bearer ' + get_token())
response_form_templates = requests.get('https://developer.api.autodesk.com/construction/forms/v1/projects/:projectId/form-templates', headers={'Authorization': 'Bearer ' + get_token()})
print(response_form_templates.json())
print(response_form_templates)
I'm trying to use python requests to simply get back the form-templates and all I'm getting back is a 401 response and a message saying "Authorization failed". The few print statements in there are from my trying to debug what's going wrong, but with my client_id and client_secret in there, it gives me those errors.
Any idea as to what could be wrong would be really helpful, thanks.

Btw. we don't have an official Forge SDK for Python yet but there's a simple, unofficial one here: https://github.com/petrbroz/forge-sdk-python that you could perhaps use as a reference when building the HTTP requests yourself. For example, here's how the SDK retrieves the 2-legged access token: https://github.com/petrbroz/forge-sdk-python/blob/develop/src/autodesk_forge_sdk/auth.py#L147-L178.

You are using a 2-legged token instead of a 3-legged token. As you can see from the image below, you require a 3-legged token when you want to retrieve form templates.
Use this link and see how you can get a 3-legged token.

Related

How to use jwt authorization with python's library requests?

I'm developing a Flask RESTFULL API with flask_jwt_extended library as extension for authorization.
Now, I have two usuals resources for register an user and for login, that works perfectly. With login resource an user can give their email and password and get back a token. From Postman this token works as expected using Bearer Token mode.
However, I need to make some requests directly from Python3 terminal. Until now, I was using a simple name-password authentication in my requests, so an example of a request would be:
import requests as rs
rs.get('http://localhost:5000/api/samples', auth = ('user', 'pass'))
Now, using jwt tokens, I'm trying the following:
import requests as rs
# xxxxxx is a really long string got previously with login resource
rs.get('http://localhost:5000/api/samples', auth = ("xxxxxx"))
but this approach give to me:
TypeError: 'str' object is not callable
In other posts I've checked that this type of authorization is made through headers, so I've also tried:
import requests as rs
# xxxxxx is a really long string got previously with login resource
rs.get('http://localhost:5000/api/samples', headers = {'Authorization': 'access_token xxxxxx'})
and the error here is an instantly 401 http response.
Hope someone could help me!
Thanks you in advance!
If someone comes here looking for an answer: you just need to add a header just like the following
headers = {'Authorization': 'Bearer {token}'}
Source: https://reqbin.com/req/python/5k564bhv/get-request-bearer-token-authorization-header-example

Upload Video with the Imgur RapidAPI

So I know this question has been asked here before but not specifically with RapidAPI. Anyways, the RapidAPI page forwards the documentation to https://api.imgur.com/
which further forwards to https://apidocs.imgur.com/
where finally we can find the api endpoint https://api.imgur.com/3/upload
now this endpoint is not compatible with the rapid api because there is simply no /3/upload endpoint on rapidapi. although it is written in the documentation that /3/upload is the same as /3/image which would make https://api.imgur.com/3/upload into https://imgur-apiv3.p.rapidapi.com/3/image. Problem here is that when i make a request to this endpoint with a video instead of an image in the payload i get this response json:
{'data': {'error': 'Could not process upload!', 'request': '/3/image', 'method': 'POST'}, 'success': False, 'status': 500}
Which basically tells me that it cannot parse the file format because when uploading any type of image it works. So what's going on?
This works for me:
import requests
url = "https://api.imgur.com/3/upload"
payload = {'album': 'ALBUMID',
'type': 'file',
'disable_audio': '0'}
files = [
('video', open('/path/to/Video.mp4','rb'))
]
headers = {
'Authorization': 'Bearer BEARERTOKENHERE'
}
response = requests.request("POST", url, headers=headers, data = payload, files = files)
print(response.text.encode('utf8'))
As far as I can understand their API /3/upload is for video & image but requires a token to use.
/3/image is for images only and should be used for uploading anonymous images with no user authentication.
But I am not 100% sure about that since I was not able to get a token to upload to /upload myself. (since I wanted to upload to my account in a 2 legged OAuth which looks like is not supported?)
So what you would need to do is to call /auth to get your token, exchange this token for a BEARER TOKEN to use the /upload path.
Hope this explains it a bit.

Not getting auth headers when setting axios default

I am trying to send an auth header along with an axios POST request from inside a Vue application. I currently am getting a 401 from my back end with an auth header that works when I do a curl.
I've tried splitting it up into variables and putting it in but that did not work and resulted in the same error (401).
This is just the axios code I am trying to get to work. I have checked with console.log and all values I am trying to send exist, though I don't know how to check the axios headers before sending.
axios.defaults.headers.common["Authorization"] = JWTtoken;
axios.post(updateURL, {
token: result.token
});
The backend code can't be changed easily for testing so need to figure out why not sending from the front end
I'd like it to send the correct header along with my request so I don't get a 401 status code.
I think you need this..
axios.defaults.headers.common["Authorization"] = "Bearer " + JWTtoken;
axios.post(updateURL, {
token: result.token
});
Notice that I add Bearer in the Authorization. It is how JWT was meant to be used according to their introduction.
However, if the answer is wrong. Help us by providing more information about your response in Developer Console as #RuChernChong suggest. Any error logs would be helpful as well.
Another way by using Axios globals to set for example X-Auth-Token encoding from JWT.io directly like this:
axios.defaults.headers.common["X-Auth-Token"] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";

Receiving HTML code in response to my token request

Using this info:
https://account-d.docusign.com/restapi/v2/oauth/token
Content-Type: application/application/x-www-form-urlencoded
Authorization: Basic xxxx
Note: (xxxx is my integrator_id:secret_key base 64 encoded, i didnt want to post the value publicly)
I do a post call using the following params in the body:
grant_type: 'authorization_code',
code: '{The code returned from the /oauth/auth call}'
Instead of getting a json response, I get an HTML response that I can't seem to post in this message, because its too large.
I am completely stuck and can't finish my project because of this problem.
I think you are using wrong host in calling the /oauth/token, you need to call
https://account-d.docusign.com/oauth/token for Demo and
https://account.docusign.com/oauth/token for PROD
You should not call demo.docusign.net or www.docusign.com, these hosts are for rest of the API calls but not for OAUTH.

shopify - nodejs - get permanent token fails

I have written an application that talks with the shopify API. I manage to get the temporary code from shopify and redirect back to my app where I store the code to later exchange for the permanent token.
According to the docs all I need to do is then send a POST request to https://{shop}.myshopify.com/admin/oauth/access_token with the client_id, client_secret and code is the body of the request.
I am using the request module to send the request and have it set up to send the request as such:
var options = {
method: POST,
url: https://my-develop-shop.myshopify.com/admin/oauth/access_token,
json: true
};
var _body = {
"client_id": config.get('SHOP_ID'),
"client_secret": config.get('SHOP_SECRET'),
"code": tempCode
}
_body = JSON.stringify(_body);
options.body = _body;
request(options, callback);
However when I send the request it always returns with : error_description: 'Could not find Shopify API application with api_key ' }
The app is installed successfully on the client's shop, so why would this error be returned?
Is there a special header that shopify expects? The docs are so vague.
Why does it not authenticate?
Well I cheated and used the shopify-node-api package. There I just use the exchange_temporary_token method. This api also handles throttling so it's a decent investment in the time you might spend incorporating it.

Resources