ACC Build Get Assets Token Problem

ACC Build Get Assets Token Problem

smharch
Advocate Advocate
1,160 Views
3 Replies
Message 1 of 4

ACC Build Get Assets Token Problem

smharch
Advocate
Advocate

Hi all, 

I have followed the instructions on the ACC API web page link here. 

Under headers, it says "<token> is obtained via a three-legged OAuth flow."

Question 1:
Is there any way to use a two-legged OAuth flow? The three-legged ones require a user to log in. I hope to have this script run in headless mode as I am just trying to get a CSV of all assets from a build project regularly like I have set up for BIM360 (to download Revit files). 

When I tried to use a two-legged OAuth flow I set the scope to "data:read" and get a status_code of 200 back. When I check the token it does not have a scope attached (which could be the following problem). When I use the token with the endpoint "

https://developer.api.autodesk.com/construction/assets/v2/projects/{project_id}/assets" it returns the following 403 error. "The client_id specified does not have access to the api product"

The screenshot below shows that my app has the two required APIs checked (Autodesk construction Cloud API and Data Management API). 
smharch_0-1702443933294.png



Everything from question one is what leads me to question 2. When following the documentation to receive a three-legged token it requires one to enter a redirect_uri for after the token has been grated. I am running this script from a secure local computer (again why I want to use a two-legged token) so I do not need a redirect_uri. Since it does require one though I gave it "https://www.google.com/". When I run this code I get the following warning. 

smharch_1-1702444410234.png


code for a two-legged token

 

import base64
import requests

# Step 1: Convert Client ID and Secret to Base64 encoded string
client_id = 'xxx'
client_secret = 'xxx'
project_id = 'b.xxx'

# Concatenate and encode to Base64
combined_credentials = f'{client_id}:{client_secret}'
base64_encoded_credentials = base64.b64encode(combined_credentials.encode()).decode()

print(f'Base64 Encoded String: {base64_encoded_credentials}')

# Step 2: Use encoded string to obtain an Access Token
token_url = 'https://developer.api.autodesk.com/authentication/v2/token'

headers = {
	'Content-Type': 'application/x-www-form-urlencoded',
	'Accept': 'application/json',
	'Authorization': f'Basic {base64_encoded_credentials}'
}

payload = {
	'grant_type': 'client_credentials',
	'scope': 'data:read'
}

# Make the POST request to obtain the access token
token_response = requests.post(token_url, headers=headers, data=payload)
print('Token:')
print(token_response.json())

# Check the response
if token_response.status_code == 200:
	access_token = token_response.json().get('access_token')
	granted_scopes = token_response.json().get('scope')

	# Print the granted scopes
	print(f'Access Token: {access_token}')
	print(f'Granted Scopes: {granted_scopes}')

	# Construct the API endpoint URL
	api_url = f'https://developer.api.autodesk.com/construction/assets/v2/projects/{project_id}/assets'

	# Make the API request
	headers = {'Authorization': f'Bearer {access_token}'}
	print(headers)
	response = requests.get(api_url, headers=headers)
	print(response)

	# Check the response
	if response.status_code == 200:
		asset_data = response.json()

		# Process the asset data as needed
		for asset in asset_data['data']:
			print(f"Asset ID: {asset['id']}, Asset Name: {asset['name']}")

		# Check for pagination
		next_url = asset_data.get('links', {}).get('next', None)
		if next_url:
			print(f"Next page URL: {next_url}")
	else:
		print(f"Error: {response.status_code}, {response.text}")
else:
	print(f'Token request failed. Status code: {token_response.status_code}, {token_response.text}')

 

 

code for three-legged token

 

import requests

# Step 1: Direct the User to the Authorization Web Flow
authorize_url = "https://developer.api.autodesk.com/authentication/v2/authorize"
client_id = 'xxx'
client_secret = 'xxx'
project_id = 'b.xxx'
redirect_uri = "https://www.google.com/"
scope = "data:read"

auth_url = f"{authorize_url}?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}"

print(f"Click on the following link to grant access: {auth_url}")

# Step 2: Implement Code that Extracts the Authorization Code
# After the user grants access, the authorization code will be received in the callback URL.
authorization_code = input("Enter the authorization code from the callback URL: ")

# Step 3: Exchange the Authorization Code for an Access Token
token_url = "https://developer.api.autodesk.com/authentication/v2/token"
client_secret = "Your_Client_Secret"

headers = {
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": f"Basic Your_Base64_Encoded_Client_ID_and_Secret"
}

payload = {
    "grant_type": "authorization_code",
    "code": authorization_code,
    "redirect_uri": redirect_uri
}

response = requests.post(token_url, headers=headers, data=payload)

if response.status_code == 200:
    token_data = response.json()
    access_token = token_data["access_token"]
    refresh_token = token_data["refresh_token"]

    print(f"Access Token: {access_token}")
    print(f"Refresh Token: {refresh_token}")
else:
    print(f"Error: {response.status_code} - {response.text}")

 


Any help would be greatly appreciated. 

Steven

0 Likes
1,161 Views
3 Replies
Replies (3)
Message 2 of 4

jw.vanasselt
Advocate
Advocate

@smharch do you have a solution for this? I want to use the 3-legged too, without open my browser.

0 Likes
Message 3 of 4

smharch
Advocate
Advocate

@jw.vanasselt I have not tried it but through my research, you can open a port on your router and have it returned directly to your computer. Ensure you do your own research as opening ports can lead to others gaining access to your system. 

In case you or others did not know Auth 2 is also a global standard, not an Autodesk-specific signing. When I first started searching I was looking for BIM360-specific articles witch there were only a few. If you look for Auth 2 there is a bunch of stuff. 

0 Likes
Message 4 of 4

jw.vanasselt
Advocate
Advocate

Thanks, will look for that stuff.

There is a nice example in the aps service GitHub with a Revit addin.

In that example they open a browser too, will try to build it inside a wpf form 🙂

0 Likes