Over the next few posts we’re going to take a look at the steps needed to build the Steampunk Morgan Viewer, my first sample using Autodesk’s new View & Data API. In today’s post we’re going to look at the steps needed to host content to be served up to instances of the viewer. In a subsequent post we’ll look at the client-side implementation, connecting to and streaming down content and controlling how it gets viewed.
So let’s start with some basics. The first thing you need to do when working with the new View & Data API is to get your access key. You get that from the new developer portal:
Clicking on the middle button will allow you to enter the information Autodesk needs to generate a key for you:
Once approved, you’ll be able to access your consumer key and secret via the developer portal. This is information your application will need to pass to the View & Data API when it needs to use it.
(The above key and secret are several characters shorter than yours will be: I’ve gone and cut a chunk out of the middle of each: please feel free to apply for your own. :-)
We’ll talk more about this topic in the next post, but one thing that’s worth pointing out, right away, is that the key and secret should not be embedded as part of client-resident modules (local JavaScript files, DLLs, etc.). Best practice is to implement your own web-service that calls into Autodesk’s API to get an authorization code and return it to the caller to be used in subsequent calls into Autodesk’s API. But again – we’ll see this specifically in the next post.
We now have the access information we need to use the View & Data API. Content uploaded to Autodesk storage is only accessible by an application using the same access information that was used to upload it, so we need to use our key and secret to upload our content.
But let’s take a quick step back. Where does this content come from? In my case I used Fusion 360 to prepare the content for my application, but you can upload content in any of about 70 or so file formats:
ipt, neu, stla, stl, xlsx, jt, jpg, skp, prt, dwf, xls, png, sldasm, step, dwg, zip, nwc, model, sim, stp, ste, f3d, pdf, iges, dwt, catproduct, csv, igs, sldprt, cgr, 3dm, sab, obj, pptx, cam360, jpeg, bmp, exp, ppt, doc, wire, ige, rcp, txt, dae, x_b, 3ds, rtf, rvt, g, sim360, iam, asm, dlv3, x_t, pps, session, xas, xpr, docx, catpart, stlb, tiff, nwd, sat, fbx, smb, smt, ifc, dwfx, tif.
We’re going to want to upload our Fusion 360 export (an .F3D file) for it to be viewed in our application. Our application only wants to view a single model, which makes things easier. We’re going to use a command-line HTTP tool called cURL to make calls into the web-service we need to post content, performing this as a one-time process. If you have a more dynamic use case, then this process could very easily be replicated in code.
The steps we’re going to follow are all posted here, but anyway: it’s better to go through it twice than not at all. :-)
Getting an access token
To perform transactions with the View & Data API, we need to pass a valid access token. We get one based on the customer key (client_id) and the secret (client_secret). Access tokens typically only last 30 minutes, so you may well need multiple tokens during a session. Which is fine: they are transient, in any case, and the main thing is the key and secret they were based on is the same.
curl --data "client_id=K8whhq86fnoYqw4GXAW0ID1hH&client_secret=DC2cBoXIy8&grant_type=client_credentials" https://developer.api.autodesk.com/authentication/v1/authenticate --header "Content-Type: application/x-www-form-urlencoded" – -k
[You may need to copy and paste this into a text editor to see the whole thing, as my blog’s format doesn’t like the long first line.]
You should get a JSON fragment back containing the access token:
{"token_type":"Bearer","expires_in":1799,"access_token":"9RVLOhMtO29QoTkgPkZ6KBN3ywkx"}
Now that we have the token we can use to make API calls, there are a number of activities to perform. One optional activity is to check the valid file formats, but we’re going to skip that and assume the file we want to upload is in an accepted format.
In terms of the steps to perform, we need to: create a container for our data (also called a bucket), upload a file into that container and then register it with the viewing service.
Creating a bucket
Buckets can be transient (24 hour), temporary (30 day) or persistent in nature. The type you create will depend on your use case. For our application we want a persistent bucket, which means the data it contains will stay around as long as the service exists (although if it doesn’t get accessed for 2 or more years then it might get archived).
Bucket names need to be unique across the system – as they form the root of the URN that will be used to identify content – so you won’t be able to call yours “steambuck”:
curl -k --header "Content-Type: application/json" --header "Authorization: Bearer 9RVLOhMtO29QoTkgPkZ6KBN3ywkx" --data '{"bucketKey":"steambuck","policy":"persistent"}' https://developer.api.autodesk.com/oss/v1/buckets
In response we receive this confirmation:
{"key":"steambuck","owner":"K8whhq86fnoYqw4GXAW0ID1hH",
"createDate":1403681174529,"permissions":[{"serviceId":"K8whhq86fnoYqw4GXAW0ID1hH","access":"full"}],
"policyKey":"persistent"}
Uploading our file
Once we have a container for it, we can upload our data. The “tricky” bit here is to find out the size of the file we want to upload. I either use the dir command (if on Windows) or ls –l (if on OS X) for this. You will also need to provide the full file path or be in the folder containing it, of course. (The file I uploaded is named SpM3W7.f3d, as it’s the 7th version of the Steampunk Morgan 3 Wheeler, in case you’re wondering. :-)
curl --header "Authorization: Bearer 9RVLOhMtO29QoTkgPkZ6KBN3ywkx" --header "Content-Length: 82984198" -H "Content-Type:application/octet-stream" --header "Expect:" --upload-file "SpM3W7.f3d" -X PUT https://developer.api.autodesk.com/oss/v1/buckets/steambuck/objects/SpM3W7.f3d -k
We get back a confirmation of the upload which includes the URN and the hash of the file.
{
"bucket-key" : "steambuck",
"objects" : [ {
"location" : "https://developer.api.autodesk.com/oss/v1/buckets/steambuck/objects/SpM3W7.f3d",
"size" : 82984198,
"key" : "SpM3W7.f3d",
"id" : "urn:adsk.objects:os.object:steambuck/SpM3W.f3d",
"sha-1" : "724a4a7353132bf803cb907248043ed5873f2c01",
"content-type" : "application/octet-stream"
} ]
}
Registering our file with the viewing service
Now that our file is uploaded, we can register it with the viewing service. This basically asks that the file gets translated into the internal format that will get streamed down to the WebGL viewer.
The inputs for this part of the process are the access token (of course) and the URN of the file we’ve uploaded. The URN needs to be Base64 encoded: there’s a handy website that allows you to encode and decode Base64.
[If you take the below string, for instance - dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlYW1idWNrL1NwTTNXNy5mM2Q= – you’ll find that decoding it returns the string “urn:adsk.objects:os.object:steambuck/SpM3W7.f3d”… yes, the “urn:” is embedded, so do watch out for that.]
curl -k -H "Content-Type: application/json" -H "Authorization:Bearer 9RVLOhMtO29QoTkgPkZ6KBN3ywkx" -i -d '{"urn":"dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlYW1idWNrL1NwTTNXNy5mM2Q="}' https://developer.api.autodesk.com/viewingservice/v1/register
The response you get back just indicates the translation has been requested:
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
x-ads-app-identifier: platform-viewing-1.6.2.788.069ca82-production
x-ads-duration: 390 ms
x-ads-error-id:
x-ads-startup-time: Wed Jun 25 06:28:52 UTC 2014
Content-Length: 20
Connection: keep-alive
{"Result":"Success"}
Which is fine, but we will also need to check the status of a particular translation job. We can do this using this call:
curl -k -i -H "Authorization: Bearer 9RVLOhMtO29QoTkgPkZ6KBN3ywkx" -X GET https://developer.api.autodesk.com/viewingservice/v1/dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c3RlYW1idWNrL1NwTTNXNy5mM2Q=
This returns the status of the current job in a rather long-winded piece of JSON, the important pieces of which are the “progress” and “success” entries.
That’s the basic process for getting content hosted for use in the viewer. There’s an additional step needed for maintaining references between files, but having a self-contained model meant we didn’t need to worry about that, at least.
In the next post we’ll look at hooking this hosted content into our client-side viewer.