I've been following the Autodesk Model Derive API tutorial on
Extracting Data From a Source File and keep getting a Translation Failure when attempting to convert the uploaded source file to SVF.
I have tried .step, .sldprt, .stl and .igs files (supported file extensions here), but all seem to throw the same error message.
The request
def self.convert_to_svf(urn, key)
url = URI("https://developer.api.autodesk.com/modelderivative/v2/designdata/job")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
body = {"input": { "urn": "#{urn}", "compressedUrn": true, "rootFilename": "#{key}" }, "output": { "formats": [{ "type": "svf", "views": ["2d", "3d"] }] }}
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["authorization"] = 'Bearer ' + token
request.body = body.to_json
JSON.parse(http.request(request).read_body)
end
The response
{"type"=>"manifest", "hasThumbnail"=>"false", "status"=>"failed", "progress"=>"complete", "region"=>"US", "urn"=>"dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6aXNvcXVlLzE4Ynk4cG9pbnQ1X2dvb2R5ZWFyLmlncw", "derivatives"=>[{"name"=>"LMV Bubble", "hasThumbnail"=>"false", "status"=>"failed", "progress"=>"complete", "messages"=>[{"type"=>"error", "message"=>"Translation failure", "code"=>"TranslationWorker-InternalFailure"}], "outputType"=>"svf"}]}
I did not see an obvious issue in your code snippet, however may I know if you have uploaded the source file(s) in zip format or only the single file of the original format (say .step, .sldprt, .stl and .igs) ?
I had the practice on the relevant APIs. I tested with Inventor assembly (with sub-assemblies and parts) and AutoCAD drawing (with Xrefs). The endpoint can work well with compressedUrn = true, specifying root file, after I uploaded file package in a zip.
If compressedUrn = true, that means the source file is compressed (zip), but this applies to the composite files, i.e. a main file has some dependent files. If it is a single file which has no dependent files, upload the source file directly, then call/modelderivative/v2/designdata/job without specifying compressedUrn and
rootFilename.
If I misunderstood your question, could you provide a bit more information or a demo dataset? Note, do not post any data that is confidential to your company.
Related
I have some Revit files stored in a BIM360 project. I am trying to visualize those files inside Forge Viewer. Now Forge Viewer won't work directly with Revit file/documents, but require the 'urn' of a translated file, in 'svf' format.
I could transform my Revit file into the 'svf' file using the Forge Model Derivative API, but that consume some credits, and I shouldn't be able to do this because when uploading a Revit file into BIM360, the translation is happening already there.
I was wondering then, how do I find out the 'urn' of the underlying 'svf' file for my Revit document ?
I found few resources helping there, when browsing the content of my BIM360 folder, or checking the versions of my Revit document using Forge Data Management API, I should be able to access a derivative object in the response which represent the derived model that can be used by the Forge viewer.
https://forums.autodesk.com/t5/bim-360-api-forum/connecting-forge-viewer-with-bim-360/td-p/6742779
However for me, there are no derivatives object in the API response, see below a sample of the API response (I have obfuscated some data for security purpose):
{
"type": "versions",
"id": "urn:adsk.wipprod:fs.file:vf.XXXXXXXXXXXXXXXXXXXX?version=1",
"attributes": "#{name=139200.33_Amenities Building_R21.rvt; displayName=139200.33_Amenities Building_R21.rvt; createTime=2021-09-03T04:24:18.0000000Z; createUserId=XXXXXXXXXX; createUserName=Holmes Consulting; lastModifiedTime=2021-09-03T04:28:02.0000000Z; lastModifiedUserId=XXXXXXXXXXXX; lastModifiedUserName=XXXXXXXXXX; versionNumber=1; storageSize=19808256; fileType=rvt; extension=}",
"links": "#{self=; webView=}",
"relationships": "#{item=; links=; refs=; downloadFormats=; derivatives=; thumbnails=; storage=}"
},
I am using the API call as used in the link I provided above:https://developer.api.autodesk.com/data/v1/projects/:project_id/folders/:folder_id/contents
Why is it that my response contains so little data ?
First thank Eason for contributing.
Since my derivatives object was empty I tried to directly use the 'urn' of my object version.
When listing all my folder documents using the folder get content API method mentioned in my issue, I get all the documents in the 'data' item array and all their versions in the 'included' version array. We need to use the document version id to build the urn. See my sample below:
"included": [
{
"type": "versions",
"id": "urn:adsk.wipprod:fs.file:vf.l9pc9re6QOmeEVHvTCTlIQ?version=1",
"attributes": "#{name=139200.33_Amenities Building_R21.rvt; displayName=139200.33_Amenities Building_R21.rvt; createTime=2021-09-03T04:24:18.0000000Z; createUserId=XXXXXX; createUserName=XXXXXXXX; lastModifiedTime=2021-09-03T04:28:02.0000000Z; lastModifiedUserId=XXXXXXXXXXXX; lastModifiedUserName=XXXXXXXXXXXX; versionNumber=1; storageSize=19808256; fileType=rvt; extension=}",
"links": "#{self=; webView=}",
"relationships": "#{item=; links=; refs=; downloadFormats=; derivatives=; thumbnails=; storage=}"
},
Now the id has to be base64 encoded. I am using https://www.freeformatter.com/base64-encoder.html to encode the id urn:adsk.wipprod:fs.file:vf.l9pc9re6QOmeEVHvTCTlIQ?version=1. Beware the result will be dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmw5cGM5cmU2UU9tZUVWSHZUQ1RsSVE/dmVyc2lvbj0 which is not valid in my JS code to load the document in the Forge Viewer, because of the /. It needs to be replaced with a _. So eventually the bit of JS that load my document into the Forge Viewer looks like this:
var documentId = 'urn:dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLmw5cGM5cmU2UU9tZUVWSHZUQ1RsSVE_dmVyc2lvbj0x'; //139200.33_Amenities Building_R21.rvt
Autodesk.Viewing.Initializer(options, function() {
var htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
viewer.start();
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
function onDocumentLoadSuccess(viewerDocument) {
// Choose the default viewable - most likely a 3D model, rather than a 2D sheet.
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
}
function onDocumentLoadFailure() {
console.error('Failed fetching Forge manifest');
}
});
Please find it in the id value of relationships.data.derivatives. For example,
"derivatives": {
"data": {
"type": "derivatives",
"id": "dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLkVueWtrU3FjU0lPVTVYMGhRdy1mQUM_dmVyc2lvbj0x"
},
// ...
},
Or check this line: https://github.com/Autodesk-Forge/learn.forge.viewhubmodels/blob/nodejs/routes/datamanagement.js#L155
const viewerUrn = (version.relationships != null && version.relationships.derivatives != null ? version.relationships.derivatives.data.id : null);
I'm trying to donwload a file i've uploaded to a Team Drive using the v3 method from drive().files().get() as described in documentation.
I can get the metadata, like file ID and permissions, but don't know how to access the actual binary content, e.g. to write it to a file. The file in question is a plain text file.
This is part of the code i'm using.
request = service.files().get(fileId=file_id, supportsTeamDrives=True)
pprint.pprint(request.to_json())
response = request.execute()
pprint.pprint(response)
And the response (from the pprints)
Request
{
"uri": "https://www.googleapis.com/drive/v3/files/1CxxxxxxxxxxxxHp?supportsTeamDrives=true&alt=json",
"method": "GET",
"body": null,
"headers": {
"accept": "application/json",
"accept-encoding": "gzip, deflate",
"user-agent": "google-api-python-client/1.7.8 (gzip)"
},
"methodId": "drive.files.get",
"resumable": null,
"response_callbacks": [],
"_in_error_state": false,
"body_size": 0,
"resumable_uri": null,
"resumable_progress": 0
}
File Metadata
{'id': '1CxxxxxxxxxxxxHp',
'kind': 'drive#file',
'mimeType': 'text/plain',
'name': 'test.txt',
'teamDriveId': 'XXXXXXXXXXXXXXX'}
I can access file metadata, but don't know how to get the file's contents, to write to a file.
I'm using the full access scope, "https://www.googleapis.com/auth/drive".
Documentation says "Gets a file's metadata or content by ID.", but it doesn't explain how.
Ok. After trying different options, i came to a solution mixing info from different posts.
1 - The get_media() method works in v3 but is not documented anywhere (even on v2 docs).
2 - io.BytesIO dindn't work, changed to FileIO.
The result code was something like this:
request = drive_service.files().get_media(fileId=file_id)
fh = io.FileIO(filename, "wb")
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
Google Api documentation is really messy and inconsistent in so many ways.
My test objective:
Using POST method I have to send the json data but there is an ex.
A, b, c property in that Json file that need to be updated, so It should consider the different request at application end.
To prepare lot .Json file and provide input to j meter is not a feasible solution. How to simulate the data in the.Json file .
I have tried .config csv method but my packet is not formed by appending csv file values . Kindly help me. How to use the variable method to achieve this
Note : This is not the full .json file . Just part of the body . "Properties": { "AccessToken": "111111111-11111-11111-1111111111", "InstallationId": "E1", "AgentType": "xxx", "AgentId": "Vxxx", "SentDateTime": "2018-07-19-13-50-24-5916045", "SourceDateTimeOfEvent": "2018-07-19T13:50:24.5916045+05:30Z", "DateTimeOfEvent": "2018-07-19T08:06:24.5786045Z" "MachineName": "AS-72" } This three parameter need to be updated with every new POST request SourceDateTimeOfEvent,DateTimeOfEvent,SentDateTime and rest of whole body should remains
I'm trying to get the appProperties field to be returned with my files on gdrive, but currently unable to get it working.
"googleapis": "^29.0.0"
Here's my scopes and fields:
scopes: [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive.metadata.readonly"
]
fields = ["id", "name", "mimeType", "parents", "description", "modifiedTime", "appProperties"]
All of the other properties come back using drive.files.list without issue, but it won't return the appProperties field.
getFilesByQuery: function( queryString , extraFields ){
var fields = ["id", "name", "mimeType", "parents", "description", "modifiedTime", "appProperties"];
if( extraFields && extraFields.length )
fields = fields.concat( extraFields );
return drive.files.list({
'pageSize': 200,
'fields': `nextPageToken, files(${ fields.join(', ') })`,
'q': queryString
});
}
When I query directly through files/get on dev.google API, this is what I get back for that file:
{
"name": "US",
"appProperties": {
"order": "1"
}
}
Any ideas?
Thanks!
In my environment, I confirmed that appProperties can be retrieved using files.list and files.get of googleapis with v29.0.0. And I thought about the possibility of the reason for your situation. So can you confirm the following point?
When I read the document of Custom File Properties, it says as follows.
Properties are accessed using the properties (visible to all apps) and appProperties (restricted to single apps) fields on files
I investigated about this. As a sample, it supposes that {"key1": "value1"} was written to appProperties and properties by client_id_A.
For appProperties, when the appProperties is read, only the client ID which is the same with the client ID used when appProperties was written can read it.
Namely, when the access token retrieved from client_id_B is used, it cannot read appProperties written by client_id_A.
For properties, when the properties is read, it can be read by various client IDs.
Namely, even if the access token retrieved from client_id_B is used, it can read properties written by client_id_A.
From these results, appProperties and properties can be used as "Private" and "Public", respectively.
Using this, can you confirm your situation again? If you will write appProperties using node.js, you can use the following script. By this, you can confirm that you can write and read appProperties using the same client ID.
drive.files.update({
fileId: "### file ID ###",
resource: {"appProperties": {"key": "value"}},
fields: 'id,appProperties',
});
If this was not useful for your situation, I'm sorry.
In Google Drive, it's possible to download an app script project as a .json file.
When such file is imported back to a Google Drive it's not properly associated with Google Script editor app.
Is there any way to do it properly?
Importing and exporting of Apps Script files requires the use of the import/export API.
To modify an existing script you will need to have a Oauth2 token with the scope of: https://www.googleapis.com/auth/drive.scripts
For updating a file you will "PUT" the updated JSON to:
https://www.googleapis.com/upload/drive/v2/files/{FileId}
The Apps Script file looks like
{
files:
[
{
name:{fileName},
type:{/* server_js or html */},
source:{/* source code for this file */},
id:{ /* Autogenerated. Omit this key for a new file, or leave value unmodified for an updated file */},
},
{...}
]
}
To add a file:
Add an object to the files array with the keys name, type, source
To modify a file:
Modify the values of name, type, or source of the file object but do not modify the id.
When you PUT the file back make sure you put the entire files array with your modifications, not just the new file object.
To make the modification in GAS itself would look like:
var scriptFiles = JSON.parse(downloadedJSONFile);
scriptFiles.files.push({"name":fileName,"type":fileType,"source":source});
var url = "https://www.googleapis.com/upload/drive/v2/files/"+scriptId;
var parameters = { method : 'PUT',
headers : {'Authorization': 'Bearer '+ tokenWithProperScope,
payload : JSON.stringify(scriptFiles),
contentType:'application/vnd.google-apps.script+json',
muteHttpExceptions:true};
var response = UrlFetchApp.fetch(url,parameters);
You will get a response code of 200 for a successful change. The response text will include the entire new JSON files with the assigned id to the file you added.
Fine more at:
https://developers.google.com/apps-script/import-export
Set the mimetype as application/vnd.google-apps.script