ShapeDiver.SDK 1.17.1

dotnet add package ShapeDiver.SDK --version 1.17.1                
NuGet\Install-Package ShapeDiver.SDK -Version 1.17.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ShapeDiver.SDK" Version="1.17.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ShapeDiver.SDK --version 1.17.1                
#r "nuget: ShapeDiver.SDK, 1.17.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ShapeDiver.SDK as a Cake Addin
#addin nuget:?package=ShapeDiver.SDK&version=1.17.1

// Install ShapeDiver.SDK as a Cake Tool
#tool nuget:?package=ShapeDiver.SDK&version=1.17.1                

ShapeDiver SDK for .NET

The ShapeDiver SDK for .NET makes it easy to develop .NET applications that access ShapeDiver. The SDK supports .NET Framework 4.6.1 and .NET Standard 2.0, which allows it to be used in a wide range of desktop and web applications.

The SDK bundles the following functionality into a coherent package.

  • Authentication client
  • Platform Backend client
    • SDK for the Platform Backend API
    • Makes use of the Authentication client and transparently handles Json Web Token refresh
  • Geometry Backend client
    • SDK for the Geometry Backend API
    • Can be used with the Platform Backend client for generating Json Web Tokens
    • Can be used with the token generator of dedicated ShapeDiver Geometry Backend systems
    • Transparently handles rate limiting

How to get support

Examples

We provide examples on how to use the SDK on github and .NET Fiddle. Ask us on the Forum if you don’t understand how they work, or you want suggest further examples to be added.

Usage

Use case 1 - Get information about your models from the Platform Backend

To begin with, create an instance of IShapeDiverSDK, which bundles the clients mentioned above.

using ShapeDiver.SDK;
using PDTO = ShapeDiver.SDK.PlatformBackend.DTO;
using GDTO = ShapeDiver.SDK.GeometryBackend.DTO;

var sdk = new ShapeDiverSDK();

Authenticate to the Platform using access keys:

await sdk.AuthenticationClient.Authenticate(keyId, keySecret);

or via your browser using OAuth 2.0 authorization code flow:

await sdk.AuthenticationClient.AuthenticateViaPlatform();

Once you are authenticated, you can get information about your models. This example shows how to get information about a specific model, identified by its unique id or slug:

var model = (await sdk.PlatformClient.ModelApi.Get(idOrSlug)).Data;

Console.WriteLine($"Model id (platform): {model.Id}");
Console.WriteLine($"Title: {model.Title}");
Console.WriteLine($"Slug: {model.Slug}");
Console.WriteLine($"Description: {model.Description}");

The slug is the last part of the URL of your model's view page on the Platform. As an example, if the URL to your model would be https://shapediver.com/app/m/my-model, then the slug is my-model. This also works for private (obfuscated) links to models.

In case you are the owner of a model, you can get more information, an example:

var model = (await sdk.PlatformClient.ModelApi.Get<PDTO.ModelDto>(idOrSlug)).Data;

Console.WriteLine($"Status: {model.Status}");
Console.WriteLine($"Created at: {model.CreatedAt}");
Console.WriteLine($"Updated at: {model.UpdatedAt}");
Console.WriteLine($"Embedding enabled: {model.UseGlobalAccessdomains}");
Console.WriteLine($"Private link sharing slug: {model.LinkSharingSlug}");
Console.WriteLine($"Backend access enabled: {model.BackendAccess}");
Console.WriteLine($"JWT required: {model.RequireToken}");

Check out the examples on github to see how you can list models, upload new ones, etc. The SDK can be used to do anything that you can also do on the ShapeDiver Platform Frontend.

Use case 2 - Trigger computations

Continuing from use case 1, now we want to trigger a computation of a model and download the data resulting from its outputs. Using the authenticated SDK, first we get a so-called session context object:

var context = await sdk.GeometryBackendClient.GetSessionContext(idOrSlug, sdk.PlatformClient)

The context wraps all the functionality to make working with your models really simple. It takes care about details like token refresh, rate limiting, long running computations, download of the resulting assets, etc. You can create as many context objects for your models as you wish. It's possible to create multiple context objects for a single model, although there is no benefit to it. Note that creating a context involves a little overhead, therefore it's good practice to reuse it. Once you don't need a context anymore, it's good practice to dispose it.

context.Dispose();

The context contains information about the model's parameters, let's inspect them:

foreach (var p in context.ModelData.Parameters.Values)
    Console.WriteLine($"Id: {p.Id}, Name: {p.Name}, Type: {p.Type}");

and identify a parameter whose type is String:

var textParameter = context.ModelData.Parameters.Values
    .Where(p => p.Type == GDTO.ParameterTypeEnum.String)
    .FirstOrDefault();
if (textParameter == null)
    throw new Exception("Model does not expose a parameter of type 'String'");

Note: You can find detailed documentation on context.ModelData in our help section Understanding the Geometry Backend API and the Swagger documentation. of the Geometry Backend API.

Now let's prepare for sending a request for computing the outputs. First we need to define a dictionary containing the stringified parameter values:

var paramDict = new Dictionary<string, string>();
paramDict.Add(textParameter.Id, "my input text");

Note that any parameter for which we don't include a specific value will use its default value.

We are ready to send the computation request and wait for its result:

var result = await context.GeometryBackendClient.ComputeOutputs(context, paramDict);
if (result.HasFailed)
    throw new Exception($"Computation failed: {result.Message}");

Finally we can download the resulting asset(s):

var format = "gltf"; // <-- an alternative would be "sdtf", see below
var asset = context.GeometryBackendClient.GetAllOutputAssetsForFormat(context, result, "gltf")
    .FirstOrDefault(); // <-- we pick the first asset only
if (asset == null)
    throw new Exception($"Expected to find a {format} asset");

var fileName = $"{asset.OutputId}.{format}";

using (var fileStream = File.Create(fileName))
{
    (await asset.GetStream()).CopyTo(fileStream);
}

The typical asset formats resulting from outputs are gltf and sdtf.

Use case 3 - Trigger exports

In case your model also defines exports, those can be triggered as well. For an explanation on how to define outputs and exports in your Grasshopper models please see this section of our help center. Section Understanding the Geometry Backend API explains the differences between outputs and exports on the API.

To begin with, we need to extend the call for creating a session context by scopes which allow us to trigger exports:

var context = await sdk.GeometryBackendClient.GetSessionContext(idOrSlug, sdk.PlatformClient, 
    new List<PDTO.ModelTokenScopeEnum>() { 
        PDTO.ModelTokenScopeEnum.GroupView, 
        PDTO.ModelTokenScopeEnum.GroupExport });

By default, the context would be created using a token that only includes scope GroupView, which wouldn't allow us to trigger exports.

We are also looking for a downloadable export that we can trigger:

var textExport = context.ModelData.Exports.Values
    .Where(e => e.Type == GDTO.ExportTypeEnum.Download)
    .FirstOrDefault();
if (textExport == null)
   throw new Exception("Model does not expose an export of type 'download'");

Now we are ready to trigger the export request:

var result = await context.GeometryBackendClient.ComputeExport(context, textExport.Id, paramDict);
if (result.HasFailed)
    throw new Exception($"Export failed: {result.Message}");

and download the resulting asset(s):

var asset = context.GeometryBackendClient.GetAllExportAssets(context, result).FirstOrDefault();
if (asset == null)
    throw new Exception("Expected to find an export asset");

var fileName = String.IsNullOrEmpty(myPreferredFilename) ? asset.Filename : myPreferredFilename;
if (String.IsNullOrEmpty(fileName))
    throw new Exception("Expected a file name to save results to");

using (var fileStream = File.Create(fileName))
{
    (await asset.GetStream()).CopyTo(fileStream);
}

Note: asset.Filename is the filename that was provided to the Download Export component.

Use case 4 - No user-based authentication

In case your model was configured to allow access without strong authorization using JSON Web Tokens, you can create a session context based on a backend ticket and a model view URL:

await sdk.GeometryBackendClient.GetSessionContext(BackendTicket, ModelViewUrl, 
    new List<GDTO.TokenScopeEnum>() { GDTO.TokenScopeEnum.GroupView, GDTO.TokenScopeEnum.GroupExport });

Warning: Access without strong authorization should only be used in case this is absolutely necessary due to the design of your application. We suggest to use strong authorization whenever possible.

Use case 5 - Authorization using token generator

In case your ShapeDiver subscription includes a dedicated ShapeDiver Geometry Backend system, you can get access to its token generator. The token generator is a lambda function that can be called to create JSON Web Tokens for your Geometry Backend system. Because the dedicated Geometry Backend system is all yours, we provide you with access to its token generator, and therefore allow you to bypass user-based authentication to the ShapeDiver Platform. This provides you with full flexibility on the scopes of the tokens you create, their lifetime, etc. The precise scopes required for each Geometry Backend API call can be found in the Swagger documentation.

Code example coming soon... (requires a separate nuget package)

Use case 6 - Low level Geometry Backend API access

The concept of context objects as introduced above provides an additional layer of abstraction and comfort when working with ShapeDiver models. You can also get direct access to the underlying Geometry Backend API. As an example, you can use this to get information about the plugins used by a model:

var token = await sdk.PlatformClient.TokenApi.Create(model.Id, new List<PDTO.ModelTokenScopeEnum>() { PDTO.ModelTokenScopeEnum.GroupOwner });
var client = sdk.GeometryBackendClient.CreateLowLevelApi(token.Data.ModelViewUrl, token.Data.AccessToken);

var modelInfo = await client.Model.Get(model.GeometryBackendId);

foreach (var library in modelInfo.Plugins.Libraries)
{
    Console.WriteLine($"{library.Name}, {library.Version}");
}

Notes

In case you want to use the SDK with ShapeDiver's IOC container (optional), check out ShapeDiver.ContainerInterfaces and ShapeDiver.ContainerCastleWindsor.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on ShapeDiver.SDK:

Package Downloads
ShapeDiver.SDK.TokenGenerator

This package provides an implementation for calling the token generator lambda of a ShapeDiver Geometry Backend system.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.17.1 621 4/5/2024
1.17.0 714 1/8/2024
1.17.0-beta 180 11/30/2023
1.16.1 318 9/15/2023
1.16.0 143 6/26/2023
1.16.0-beta 137 6/23/2023
1.15.0 148 5/24/2023
1.14.0 179 4/17/2023
1.11.6 390 10/17/2022
1.11.5 386 10/14/2022
1.11.4 392 10/13/2022
1.11.3 382 10/12/2022
1.11.2 373 10/6/2022
1.11.1 358 10/6/2022
1.11.0 396 9/28/2022
1.11.0-beta.4 156 9/8/2022
1.11.0-beta.3 93 9/7/2022
1.11.0-beta.2 98 9/7/2022
1.11.0-beta.1 98 9/7/2022
1.11.0-beta 156 9/6/2022
1.10.0-beta 157 8/10/2022