Add blobs to objects in Azure Digital Twins

Important

A new version of the Azure Digital Twins service has been released. In light of the new service's expanded capabilities, the original Azure Digital Twins service (described in this documentation set) has been retired.

To view the documentation for the new service, visit the active Azure Digital Twins Documentation.

Blobs are unstructured representations of common file types, like pictures and logs. Blobs track what kind of data they represent by using a MIME type (for example: "image/jpeg") and metadata (name, description, type, and so on).

Azure Digital Twins supports attaching blobs to devices, spaces, and users. Blobs can represent a profile picture for a user, a device photo, a video, a map, a firmware zip, JSON data, a log, etc.

This article assumes some familiarity with authenticating to your Azure Digital Twins Management APIs.

Uploading blobs overview

You can use multipart requests to upload blobs to specific endpoints and their respective functionalities.

Note

Multipart requests typically require three pieces:

  • A Content-Type header:
    • application/json; charset=utf-8
    • multipart/form-data; boundary="USER_DEFINED_BOUNDARY"
  • A Content-Disposition:
    • form-data; name="metadata"
  • The file content to upload

Content-Type and Content-Disposition will vary depending on use scenario.

Multipart requests can be made programmatically (through C#), through a REST client, or tool such as Postman. REST client tools may have varying levels of support for complex multipart requests. Configuration settings may also vary slightly from tool to tool. Verify which tool is best suited for your needs.

Important

Multipart requests made to the Azure Digital Twins Management APIs typically have two parts:

  • Blob metadata (such as an associated MIME type) that's declared by Content-Type and/or Content-Disposition
  • Blob contents which include the unstructured contents of a file to be uploaded

Neither of the two parts is required for PATCH requests. Both are required for POST or create operations.

The Occupancy Quickstart source code contains complete C# examples demonstrating how to make multipart requests against the Azure Digital Twins Management APIs.

Blob metadata

In addition to Content-Type and Content-Disposition, Azure Digital Twins blob multipart requests must specify the correct JSON body. Which JSON body to submit depends on the kind of HTTP request operation that's being performed.

The four main JSON schemas are:

JSON schemas

JSON blob metadata conforms to the following model:

{
    "parentId": "00000000-0000-0000-0000-000000000000",
    "name": "My First Blob",
    "type": "Map",
    "subtype": "GenericMap",
    "description": "A well chosen description",
    "sharing": "None"
  }
Attribute Type Description
parentId String The parent entity to associate the blob with (spaces, devices, or users)
name String A human-friendly name for the blob
type String The type of blob - cannot use type and typeId
typeId Integer The blob type ID - cannot use type and typeId
subtype String The blob subtype - cannot use subtype and subtypeId
subtypeId Integer The subtype ID for the blob - cannot use subtype and subtypeId
description String Customized description of the blob
sharing String Whether the blob can be shared - enum [None, Tree, Global]

Blob metadata is always supplied as the first chunk with Content-Type application/json or as a .json file. File data is supplied in the second chunk and can be of any supported MIME type.

The Swagger documentation describes these model schemas in full detail.

Tip

A Swagger sneak preview is provided to demonstrate the API feature set. It's hosted at docs.westcentralus.azuresmartspaces.net/management/swagger.

You can access your own generated Management API Swagger documentation at:

https://YOUR_INSTANCE_NAME.YOUR_LOCATION.azuresmartspaces.net/management/swagger
Name Replace with
YOUR_INSTANCE_NAME The name of your Azure Digital Twins instance
YOUR_LOCATION Which server region your instance is hosted on

Learn about using the reference documentation by reading How to use Swagger.

Blobs response data

Individually returned blobs conform to the following JSON schema:

{
  "id": "00000000-0000-0000-0000-000000000000",
  "name": "string",
  "parentId": "00000000-0000-0000-0000-000000000000",
  "type": "string",
  "subtype": "string",
  "typeId": 0,
  "subtypeId": 0,
  "sharing": "None",
  "description": "string",
  "contentInfos": [
    {
      "type": "string",
      "sizeBytes": 0,
      "mD5": "string",
      "version": "string",
      "lastModifiedUtc": "2019-01-12T00:58:08.689Z",
      "metadata": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
      }
    }
  ],
  "fullName": "string",
  "spacePaths": [
    "string"
  ]
}
Attribute Type Description
id String The unique identifier for the blob
name String A human-friendly name for the blob
parentId String The parent entity to associate the blob with (spaces, devices, or users)
type String The type of blob - cannot use type and typeId
typeId Integer The blob type ID - cannot use type and typeId
subtype String The blob subtype - cannot use subtype and subtypeId
subtypeId Integer The subtype ID for the blob - cannot use subtype and subtypeId
sharing String Whether the blob can be shared - enum [None, Tree, Global]
description String Customized description of the blob
contentInfos Array Specifies unstructured metadata information including version
fullName String The full name of the blob
spacePaths String The space path

Blob metadata is always supplied as the first chunk with Content-Type application/json or as a .json file. File data is supplied in the second chunk and can be of any supported MIME type.

Blob multipart request examples

In the examples below, YOUR_MANAGEMENT_API_URL refers to the URI of the Digital Twins APIs:

https://YOUR_INSTANCE_NAME.YOUR_LOCATION.azuresmartspaces.net/management/api/v1.0
Name Replace with
YOUR_INSTANCE_NAME The name of your Azure Digital Twins instance
YOUR_LOCATION The region your instance is hosted on

To upload a text file as a blob and associate it with a space, make an authenticated HTTP POST request to:

YOUR_MANAGEMENT_API_URL/spaces/blobs

With the following body:

--USER_DEFINED_BOUNDARY
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name="metadata"

{
  "ParentId": "54213cf5-285f-e611-80c3-000d3a320e1e",
  "Name": "My First Blob",
  "Type": "Map",
  "SubType": "GenericMap",
  "Description": "A well chosen description",
  "Sharing": "None"
}
--USER_DEFINED_BOUNDARY
Content-Disposition: form-data; name="contents"; filename="myblob.txt"
Content-Type: text/plain

This is my blob content. In this case, some text, but I could also be uploading a picture, an JSON file, a firmware zip, etc.

--USER_DEFINED_BOUNDARY--
Value Replace with
USER_DEFINED_BOUNDARY A multipart content boundary name

The following code is a .NET implementation of the same blob upload, using the class MultipartFormDataContent:

//Supply your metadata in a suitable format
var multipartContent = new MultipartFormDataContent("USER_DEFINED_BOUNDARY");

var metadataContent = new StringContent(JsonConvert.SerializeObject(metaData), Encoding.UTF8, "application/json");
metadataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
multipartContent.Add(metadataContent, "metadata");

//MY_BLOB.txt is the String representation of your text file
var fileContents = new StringContent("MY_BLOB.txt");
fileContents.Headers.ContentType = MediaTypeHeaderValue.Parse("text/plain");
multipartContent.Add(fileContents, "contents");

var response = await httpClient.PostAsync("spaces/blobs", multipartContent);

Lastly, cURL users can make multipart form requests in the same manner:

curl -X POST "YOUR_MANAGEMENT_API_URL/spaces/blobs" \
 -H "Authorization: Bearer YOUR_TOKEN" \
 -H "Accept: application/json" \
 -H "Content-Type: multipart/form-data" \
 -F "meta={\"ParentId\":\"YOUR_SPACE_ID\",\"Name\":\"My CURL Blob\",\"Type\":\"Map\",\"SubType\":\"GenericMap\",\"Description\":\"A well chosen description\",\"Sharing\":\"None\"};type=application/json" \
 -F "text=PATH_TO_FILE;type=text/plain"
Value Replace with
YOUR_TOKEN Your valid OAuth 2.0 token
YOUR_SPACE_ID The ID of the space to associate the blob with
PATH_TO_FILE The path to your text file

cURL example

A successful POST returns the ID of the new the blob.

API endpoints

The following sections describe the core blob-related API endpoints and their functionalities.

Devices

You can attach blobs to devices. The following image shows the Swagger reference documentation for your Management APIs. It specifies device-related API endpoints for blob consumption and any required path parameters to pass into them.

Device blobs

For example, to update or create a blob and attach the blob to a device, make an authenticated HTTP PATCH request to:

YOUR_MANAGEMENT_API_URL/devices/blobs/YOUR_BLOB_ID
Parameter Replace with
YOUR_BLOB_ID The desired blob ID

Successful requests return a JSON object as described earlier.

Spaces

You can also attach blobs to spaces. The following image lists all space API endpoints responsible for handling blobs. It also lists any path parameters to pass into those endpoints.

Space blobs

For example, to return a blob attached to a space, make an authenticated HTTP GET request to:

YOUR_MANAGEMENT_API_URL/spaces/blobs/YOUR_BLOB_ID
Parameter Replace with
YOUR_BLOB_ID The desired blob ID

Successful requests return a JSON object as described earlier.

A PATCH request to the same endpoint updates metadata descriptions and creates versions of the blob. The HTTP request is made through the PATCH method, along with any necessary meta, and multipart form data.

Users

You can attach blobs to user models (for example, to associate a profile picture). The following image shows relevant user API endpoints and any required path parameters, like id:

User blobs

For example, to fetch a blob attached to a user, make an authenticated HTTP GET request with any required form data to:

YOUR_MANAGEMENT_API_URL/users/blobs/YOUR_BLOB_ID
Parameter Replace with
YOUR_BLOB_ID The desired blob ID

Successful requests return a JSON object as described earlier.

Common errors

  • A common error involves not supplying the correct header information:

    {
        "error": {
            "code": "400.600.000.000",
            "message": "Invalid media type in first section."
        }
    }
    

    To resolve this error, verify that the overall request has an appropriate Content-Type header:

    • multipart/mixed
    • multipart/form-data

    Also, verify that each multipart chunk has an appropriate corresponding Content-Type.

  • A second common error arises when multiple blobs are assigned to the same resource in your spatial intelligence graph:

    {
        "error": {
            "code": "400.600.000.000",
            "message": "SpaceBlobMetadata already exists."
        }
    }
    

    Note

    The message attribute will vary based on the resource.

    Only one blob (of each kind) may be attached to each resource within your spatial graph.

    To resolve this error, update the existing blob by using the appropriate API HTTP PATCH operation. Doing so will replace the existing blob data with the desired data.

Next steps