Almost all of our samples and tutorials are creating web services, however sometimes you might just want to create a small standalone desktop app to automate something.
If the app is just for your personal use then 2-legged authentication might be OK, but if it's for other people as well then you should use PKCE instead:
Getting a Token with PKCE - Desktop App
PKCE is generating a 3-legged token which means that you would also have to sign your activity to use it in a work item:
Using 3-
The Automation CLI Tool can help with that too with the --key, --patch and --sign commands.
The below sample code of a .NET 8 C# Console App is using 2-legged authentication to run a work item based on the resources that are created via the Automation API tutorial.
using System.Text;
using System.Text.Json;
const string _clientId = "your-client-id";
const string _clientSecret = "your-client-secret";
string _activityId = _clientId + ".UpdateIPTParam+dev";
const string _inputFile = "inventor_sample_file.ipt";
const string _outputFile = "output.ipt";
string _bucketKey = _clientId.ToLower() + "-designautomation";
string _inputFileUrn = $"urn:adsk.objects:os.object:{_bucketKey}/{_inputFile}";
string _outputFileUrn = $"urn:adsk.objects:os.object:{_bucketKey}/{_outputFile}";
// Get access token
static async Task<string> GetTokenAsync(string clientId, string clientSecret)
{
using var httpClient = new HttpClient();
var requestBody = new StringContent($"client_id={clientId}&client_secret={clientSecret}&grant_type=client_credentials&scope=code:all data:read data:write", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await httpClient.PostAsync("https://developer.api.autodesk.com/authentication/v2/token", requestBody);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(responseContent);
var token = doc.RootElement.GetProperty("access_token").GetString();
return token ?? string.Empty;
}
// Start work item
static async Task<string> StartWorkItemAsync(string token, string activityId, string inputFileUrn, string outputFileUrn)
{
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var workItemPayload = new
{
activityId = activityId,
arguments = new
{
inputFile = new
{
url = inputFileUrn,
headers = new
{
Authorization = $"Bearer {token}"
},
verb = "get"
},
inputJson = new
{
url = "data:application/json, {\"width\": 10, \"height\": 20}"
},
outputFile = new
{
url = outputFileUrn,
headers = new
{
Authorization = $"Bearer {token}"
},
verb = "put"
}
}
};
var jsonPayload = JsonSerializer.Serialize(workItemPayload);
var requestBody = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("https://developer.api.autodesk.com/da/us-east/v3/workitems", requestBody);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(responseContent);
var workItemId = doc.RootElement.GetProperty("id").GetString();
return workItemId ?? string.Empty;
}
// Check work item status
static async Task<string> CheckWorkItemInfoAsync(string token, string workItemId)
{
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var response = await httpClient.GetAsync($"https://developer.api.autodesk.com/da/us-east/v3/workitems/{workItemId}");
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
return responseContent;
}
// Fetch work item report
static async Task<string> GetReportAsync(string reportUrl)
{
using var httpClient = new HttpClient();
var reportResponse = await httpClient.GetAsync(reportUrl);
reportResponse.EnsureSuccessStatusCode();
var reportContent = await reportResponse.Content.ReadAsStringAsync();
return reportContent;
}
Console.WriteLine("Started");
var token = await GetTokenAsync(_clientId, _clientSecret);
Console.WriteLine(token);
var workItemId = await StartWorkItemAsync(token, _activityId, _inputFileUrn, _outputFileUrn);
Console.WriteLine(workItemId);
while (true)
{
var info = await CheckWorkItemInfoAsync(token, workItemId);
using var doc = JsonDocument.Parse(info);
var status = doc.RootElement.GetProperty("status").GetString();
if (status == "success" || status!.StartsWith("failed"))
{
Console.WriteLine($"Work item {workItemId} finished with status: {status}");
var reportUrl = doc.RootElement.GetProperty("reportUrl").GetString();
var report = await GetReportAsync(reportUrl!);
Console.WriteLine(report);
break;
}
else
{
Console.WriteLine($"Work item {workItemId} is still in progress with status: {status}");
await Task.Delay(5000);
}
}
Console.WriteLine("Finished");You just have to set the values of _clientId and _clientSecret. If you don't want to use the Inventor engine then you should also update the values of _activityId, _inputFile and _outputFile.
If all goes well you should see something like this in the Debug Console:
