Microsoft Azure REST API

Hello all,

I have been recently using Azure Blob Storage to store and access data in an Ignition project. I have had success using a GET request to access the stored data. The issue I am having however is using a PUT request to upload data from Ignition. I believe I am having difficulty in constructing the authorization header, but I am not completely sure. I am currently receiving a 403 HTTP response code (meaning Client authorization is not acceptable I believe). Has anyone been able to successfully accomplish something similar?


What Ignition version are you using? Can you share any of your script so far?
For a variety of reasons, I highly recommend for interacting with REST/web APIs.

The is definitely something I have been using. The PUT request has been providing a 403 HTTP error as well as a compiling error that states ‘Content-Length’ is a restricted header (when included). The exact code I am using is included below:

import datetime
import hmac
import hashlib
import base64

storage_account_name = '...'
storage_account_key = '...'
api_version = '2016-05-31'
request_time = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')

string_params = {
    'verb': 'PUT',
    'Content-Encoding': '',
    'Content-Language': '',
    'Content-Length': '11',
    'Content-MD5': '',
    'Content-Type': 'text/plain; charset=UTF-8',
    'Date': '',
    'If-Modified-Since': '',
    'If-Match': '',
    'If-None-Match': '',
    'If-Unmodified-Since': '',
    'Range': '',
    'CanonicalizedHeaders': 'x-ms-blob-type:BlockBlob' + '\nx-ms-date:' + request_time + '\nx-ms-version:' + api_version + '\n',
    'CanonicalizedResource': '/' + storage_account_name +'/'+container_name+ '/' +'fname'

string_to_sign = (string_params['verb'] + '\n' 
                  + string_params['Content-Encoding'] + '\n'
                  + string_params['Content-Language'] + '\n'
                  + string_params['Content-Length'] + '\n'
                  + string_params['Content-MD5'] + '\n' 
                  + string_params['Content-Type'] + '\n' 
                  + string_params['Date'] + '\n' 
                  + string_params['If-Modified-Since'] + '\n'
                  + string_params['If-Match'] + '\n'
                  + string_params['If-None-Match'] + '\n'
                  + string_params['If-Unmodified-Since'] + '\n'
                  + string_params['Range'] + '\n'
                  + string_params['CanonicalizedHeaders']
                  + string_params['CanonicalizedResource'])

signed_string = base64.b64encode(, msg=string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()).decode()

headerVals = {
    'x-ms-version' : api_version,
    'x-ms-date' : request_time,
    'x-ms-blob-type': 'BlockBlob',
    'Content-Type': "text/plain; charset=UTF-8",
    'Authorization' : ('SharedKey ' + storage_account_name + ':' + signed_string),
    'Content-Length': '11'

urlCurr = ('https://' + storage_account_name + ''+container_name+'/fname')

putData = 'hello world'

# Create the JythonHttpClient
client =

response = client.put(url=urlCurr, data=putData, headers=headerVals)


I noticed that about a week ago a nightly fix was uploaded to the HTTP client POST function. The fix was aimed at resolving corruption when posting binary data. As seen in this post, I am using a PUT request and still seem to observe some data corruption on the byte arrays that I have been using (ie Content-Length is still incorrect). Has anybody been able to find a functional work-around or have any insight into how to resolve this problem? Also, is it possible that the bug identified in the POST function exists in the PUT function as well?