Forge Developer's Guide Prepare Cloud Storage - Issue with uploading a file to signed url - autodesk-forge

I am following the Design Automation API for Revit Step by Step Tutorial.
I am stuck at the prepare cloud storage - step 3 where I upload a file to the signed url.
I keep getting this error:
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
I copy paste the signed url I get from the response of step 2 so there shouldn't be any issue with signature.

You are doing this on a PUT call and also passing in the Data Binary of the file to be uploaded.

Related

upload file via Data Management API, but return 403

The scope includes data:write data:create, and accessToken can be obtained. But when uploading files through Api, it returns 403 and the message prompt: "No write access".
I checked it according to the document, which means: "The Authorization was successfully validated but permission is not granted. Don't try again unless you solve permissions first.".
I'm not sure if there is something wrong with the permission when get the accessToken, or because the free user has no permission to call the upload file interface. But it worked normally before.
you are correct the scope can be data:write or data:create with uploading file. The most possibility is you are trying to uploading to a bucket which is NOT created by this Forge app. e.g. you may have a few Forge apps (different client id and secret). The bucket may be created by the other Forge app, so this app cannot write the data. Or even the bucket is created by other customers, while you thought you are the owner. Please GET:Buckets firstly to check which buckets available with this app (client id + secret) :forge.autodesk.com/en/docs/data/v2/reference/http/buckets-GET

How to Download G Suite docs/sheets to pdf/xls programatically?

I'm trying to download a Google doc to PDF or Sheet to XLS given an ID programmatically from the CLI.
Steps I've tried so far:
Contact support, but can't see a (?) help icon
Google for 10 minutes... I think Google Drive API does this (not sure)
Enable the Google Drive API
Signed up for a GCP project
Navigated thought the UI to enable the API
Trying the GET API results in 400 Invalid field selection using the fields for the ID of the document
I'm a bit stuck now and I am not sure how to proceed. Any suggestions?
Warning: hopefully
informative wall of text ahead! I've also uploaded the full Jupyter Notebook for you to clone and run here since, as you've realized, putting this sort of stuff together can be challenging.
Since we're going to be exporting files via the google drive API, we need credentials for that scope as detailed in https://developers.google.com/drive/api/v3/reference/files/export#auth.
However, first we need to choose an authentication method as detailed in https://developers.google.com/identity/protocols/oauth2#scenarios.
Since you mentioned creating a GCP project, I assume you're interested in using a GCP service account
as detailed in https://developers.google.com/identity/protocols/oauth2#serviceaccount
You can create a service account at https://console.developers.google.com/apis/credentials
or as explained in https://developers.google.com/identity/protocols/oauth2/service-account#creatinganaccount
Make sure to enable domain-wide-delegation for that service account while creating it and grant it https://www.googleapis.com/auth/drive scope under https://admin.google.com/ac/owl/domainwidedelegation since you otherwise won't be able to impersonate other users, including yourself, and download their files.
We then use the SERVICE_ACCOUNT_FILE we just downloaded and the SCOPES we defined to create a Credentials object.
However, you'll need to first install the Python bindings for the Google API as per https://developers.google.com/drive/api/v3/quickstart/python (pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib)
With that, the following should be enough to authenticate to the API:
from googleapiclient.discovery import build
from google.oauth2 import service_account
SCOPES = ['https://www.googleapis.com/auth/drive']
SERVICE_ACCOUNT_FILE = 'credentials.json'
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE,
scopes=SCOPES)
# Remember, you must have created credentials.json with domain-wide delegation!
credentials = credentials.with_subject('user#example.com')
# We then build a drive_v3 service using the credentials we just created
service = build('drive', 'v3', credentials=credentials)
We can access the files resource as shown in https://developers.google.com/drive/api/v3/reference/files/get and request the metadata of a file to which user#example.com has access https://docs.google.com/document/d/fileId/edit. In your case fileId=141g8UkQfdMQSTfIn475gHj1ezZVV16f5ONDxpWrrvts.
files = service.files()
print(service.files().get(fileId='1U3eMevKxTwDxzvOBUsqa36zvwBzKPVYOFgy3k_9vxb8').execute())
{'kind': 'drive#file', 'id':
'1U3eMevKxTwDxzvOBUsqa36zvwBzKPVYOFgy3k_9vxb8', 'name': 'empty',
'mimeType': 'application/vnd.google-apps.document'}
We access the files resource again but this time to export the file as detailed in
https://developers.google.com/resources/api-libraries/documentation/drive/v3/python/latest/drive_v3.files.html#export
This could also be achieved using https://developers.google.com/drive/api/v3/manage-downloads.
Valid MIME types are listed in https://developers.google.com/drive/api/v3/ref-export-formats.
fconr = files.export(fileId='1U3eMevKxTwDxzvOBUsqa36zvwBzKPVYOFgy3k_9vxb8',
mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
fcont = fconr.execute()
print('{}...'.format(fcont[:10]))
file = open("/tmp/sample.doc", "wb")
file.write(fcont)
file.close()
b'MN\xc30\x10\x85O\xc0\x1d"'...
As you can see, fcont contains a binary blob that corresponds to the document and of which I'm showing the first 10 bytes. Finally, the blob is saved to sample.doc.
ls -alh1 /tmp/sample.doc
-rw-rw-r-- 1 jdsalaro jdsalaro 6,0K Jan 20 23:38 /tmp/sample.doc
As mentioned above, I encourage you to experiment with the Jupyter notebook once you've created the service account with domain-wide delegation, have saved it to credentials.json and have granted it the https://www.googleapis.com/auth/drive scope.

How to read all data using Revit API?

we are generated client id and secret id. And also we have got access token using Internal Token.
when running the project we can view Revit file which we are uploaded using forge bucket.
Then again are trying to get all elelments (Building,floor,rooms,equipments etc)in Revit model using API.
using this Link:https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-metadata-GET/
we have using API in onDocumentLoadSuccess this event.
we are passing url:https://developer.api.autodesk.com/modelderivative/v2/designdata/:urn/metadata
headers :'Authorization': 'Bearer ' + access_token.
In this we are passing urn,access_token parameters also fine.
But we face "Token does not have the privilege for this request" error.(we have already have access token through API.But for the second time we face the error)
How to solve this, please help me on this.
Note that the different endpoints provided by the Forge services require a specific "scope" that the access token must be generated for. For example, according to the GET :urn/metadata docs, this endpoint requires the the access token to be generated with the "data:read" scope.
Also, note that properties of a design processed by the Model Derivative service are actually obtained by a different endpoint - not using GET :urn/metadata, but using GET :urn/metadata/:guid/properties.

Create Signed URL for Object in BIM360 OSS

I'm trying to set up an Signed URL for an Design Automation Workflow which is triggered by an Webhook inside of the BIM360 OSS. If a file is added the webhooks triggers an endpoint to start a Design Automation. The webhook is working. And the Design Automation is working too. The Problem occurs if i try to wire both up. I#m trying to create a Signed URL of the File like suggested in this post from Petr Broz link stackoverflow.
To use this API it is requierd to use an Token which is obatined by 2-Legged-Auth which is working with all necessary Scopes. In the response of the Webhook is an ID for the Folder and Version. The API is recognizing the ID.
The problem occurs in the response of this endpoint to create the signed url: https://developer.api.autodesk.com/oss/v2/buckets/:bucketKey/objects/:objectKey/signed
I'm using the wip.dm.emea as bucket because the file is stored in the EU BIM360 OSS.
The response is a 403 Forbidden:
{
"reason": "Only the bucket creator is allowed to access this api."
}
Is it even possible to get the File ID like in this example Forge how to Download File ?
Because this Solution requires a 3-Legged-Auth Flow which is not possible for a complete Automation.
The thing which makes me question is, that you can achieve this Workflow in plane Forge. But not in BIM360 where i have no control over the Buckets that are created by the System!?
I think this is an architectural missmatch between the Forge API and the BIM360 implementation!? Will there be a solution for this in the future?
Best regards
Jan
Unfortunately, I can confirm that it's not possible to create a signed URL for your BIM360 storage currently, as the error message mentioned, the endpoint requires the bucket owner to do this operation, this is what it is now. But I agree with you that this should be an architecture mismatch between Forge OSS and BIM360 implementation, and it's already been requested in our system, please keep "CPOSS-1066" to check with us about the progress.
As for the current way, you can keep the 3 legged token and using that for the output Url and also in the onComplete() callback, I have the blog post https://forge.autodesk.com/blog/upload-your-design-automation-output-file-bim360-docs which details the way to work, hope it helps at this moment.

How to upload application to Cloud Foundry using API (not CLI)?

I'm trying to develop a simple NodeJS web app that can more or less replace the Cloud Foundry (CF) CLI. I'm following the API documentation to send the application.zip to the CF Service, however I get an error response Unsupported Media Type.
For the application part of the body I'm sending the application.zip file that is uploaded from the browser.
For the resources part of the body I'm sending an empty Json array. My understanding is that as there is nothing uploaded initially there are no pre-uploaded resources that I want to specify, hence the array is empty.
With the Unsupported Media Type response, I suspect you send invalid request headers to the API. There is a CloudFoundry API client written in node.js and you may read the source code to see how they upload the app code.
If that does not help you, please refine your question and add some code that you have.