Image upload & download to Azure Storage. With Python + requests + REST API

We have summarized how to save and retrieve images with the REST API of Azure Storage with Python + requests. Normally, it is better to use the following SDK for Python than to implement it using the REST API. https://docs.microsoft.com/ja-jp/azure/python-how-to-install

Development environment

Windows 10 Home Python 3.5.2

Azure Storage https://azure.microsoft.com/ja-jp/services/storage/ Storage with API, like Amazon s3. Get an account in advance.

class

upload → upload image download → Download image is. I think it can be used for data other than images, but I haven't experimented.

azure_storage_sample.py


import base64
import sys
import datetime
import hmac
import hashlib
import requests

class AzureStorage:
    storage_account = ""
    storage_container = ""
    access_key = ""
    api_ver = "2014-02-14"
    response = None
    
    def __init__(self, storage_account, storage_container, access_key):
        self.storage_account = storage_account
        self.storage_container = storage_container
        self.access_key = access_key
        pass

    def upload(self, filename, body, type, metadata = {}):
        date = self.get_date()
        size = str(len(body))
        string_to_sign = [
            'PUT',
            '',
            type,
            date,
        ]
        
        #meta data
        ar_metadata = []
        for k, v in metadata.items():
            ar_metadata.append(k+":"+v)

        #Authentication string creation
        authorization = self.get_authorization(filename, string_to_sign, ar_metadata)

        #http header creation
        http_headers = {
            'x-ms-blob-type': 'BlockBlob',
            'x-ms-version': self.api_ver,
            'Authorization': authorization,
            'Date': date,
            'Content-Type': type,
            'Content-Length': size,
        }
        
        #Combine metadata
        for k, v in metadata.items():
            http_headers[k] = v
        
        #http communication
        url = "https://%s.blob.core.windows.net/%s/%s" % (self.storage_account, self.storage_container, filename)
        try:
            self.response = requests.put(url, data=body, headers=http_headers)
            if (self.response.status_code == 201):
                #ok
                return True
            else:
                #ng
                return False
        except requests.exceptions.RequestException as e:
            return False

    def download(self, filename):
        date = self.get_date()
        string_to_sign = [
            'GET',
            '',
            '',
            date,
        ]

        #Authentication string creation
        authorization = self.get_authorization(filename, string_to_sign)

        #http header creation
        http_headers = {
            'x-ms-blob-type': 'BlockBlob',
            'x-ms-version': self.api_ver,
            'Authorization': authorization,
            'Date': date,
        }
        
        #http communication
        url = "https://%s.blob.core.windows.net/%s/%s" % (self.storage_account, self.storage_container, filename)
        try:
            self.response = requests.get(url, headers=http_headers)
            if (self.response.status_code == 200):
                #ok
                return True
            else:
                #ng
                return False
        except requests.exceptions.RequestException as e:
            return False

    def get_authorization(self, filename, string_to_sign, ar_metadata = None):
        sign_str = "/%s/%s/%s" % (self.storage_account, self.storage_container, filename)
        string_to_sign.extend(['x-ms-blob-type:BlockBlob'])
        if (ar_metadata != None):
            string_to_sign.extend(ar_metadata)
        string_to_sign.extend(['x-ms-version:'+self.api_ver])
        string_to_sign.extend([sign_str])
        string_to_sign = "\n".join(string_to_sign)
        signature = self.make_hash(self.access_key, string_to_sign)
        authorization = "SharedKeyLite %s:%s" % (self.storage_account, signature)
        return authorization

    def get_date(self):
        now = datetime.datetime.now()
        #rfc2822_format = "%a, %d %b %Y %H:%M:%S %z" # ex: Thu, 02 Aug 2001 10:45:23 GMT
        rfc2822_format = "%a, %d %b %Y %H:%M:%S" #Last%Because z is uneasy
        date = now.strftime(rfc2822_format)
        date = date + " GMT"
        return date

    def get_last_response(self):
        return self.response

    def encode_base64(self, data):
        encoded = base64.b64encode(data)
        return encoded.decode('utf-8')

    def decode_base64(self, data):
        return base64.b64decode(data)

    def make_hash(self, key, str):
        key = self.decode_base64(key)
        str = str.encode('utf-8')
        str_hashed = hmac.HMAC(key, str, hashlib.sha256).digest()
        str_enc = self.encode_base64(str_hashed)
        return str_enc

How to use (upload)

#Authentication information
storage_account = "xxxxxx"
storage_container = "xxxxxx"
access_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

#upload
data_filename = "sample.jpg "
data_body = open("sample.jpg ", "rb").read()
data_type = "image/jpeg"
metadata = {
    #'x-ms-meta-m1': 'aaaaaaaa',
    #'x-ms-meta-m2': 'bbbbbbbb',
}
AzureStorage = AzureStorage(storage_account, storage_container, access_key)
result = AzureStorage.upload(data_filename, data_body, data_type, metadata)
if (result == True):
    print("upload ok\n")
else:
    print("upload ng\n")
    response = AzureStorage.get_last_response()
    print(response.text)

How to use (download)

#Authentication information
storage_account = "xxxxxx"
storage_container = "xxxxxx"
access_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

#download
data_filename = "sample.jpg "
AzureStorage = AzureStorage(storage_account, storage_container, access_key)
result = AzureStorage.download(data_filename)
if (result == True):
    print("download ok\n")
    response = AzureStorage.get_last_response()
    
    #Save the downloaded file
    with open("download.jpg ", "wb") as f:
        data = bytearray(response.content)
        f.write(data)
else:
    print("download ng\n")

You can add any metadata when uploading. When I experimented, uploading sometimes failed for some reason with metadata.

reference

I referred to the following. http://qiita.com/ngyuki/items/eb9b890801e49171a0c6 https://docs.microsoft.com/ja-jp/rest/api/storageservices/put-blob

Recommended Posts

Image upload & download to Azure Storage. With Python + requests + REST API
File upload to Azure Storage (Python)
Get users belonging to your organization from Garoon REST API with Python + Requests
The first API to make with python Djnago REST framework
How to upload files to Cloud Storage with Firebase's python SDK
Operate Jupyter with REST API to extract and save Python code
A story about adding a REST API to a daemon made with Python
Upload file to GCP's Cloud Storage (GCS) ~ Load with local Python
HTML email with image to send with python
Introduction to Python Image Inflating Image inflating with ImageDataGenerator
Upload images to Google Drive with Python
Sample to convert image to Wavelet with Python
Upload & download wav file to X server (X-Server) by FTP with Python
How to upload with Heroku, Flask, Python, Git (4)
Convert PDF to image (JPEG / PNG) with Python
How to crop an image with Python + OpenCV
Upload files to Google Drive with Lambda (Python)
[WP REST API v2] Upload images in Python
[Azure Functions / Python] Chain functions with Queue Storage binding
[Python] Mention to multiple people with Slack API
Post an article with an image to WordPress with Python
GAE --With Python, rotate the image based on the rotation information of EXIF and upload it to Cloud Storage.
Resize multipart.File type image with golang ~ Upload to S3
Upload the image downloaded by requests directly to S3
[First API] Try to get Qiita articles with Python
How to scrape image data from flickr with python
How to upload with Heroku, Flask, Python, Git (Part 3)
[Python] How to specify the download location with youtube-dl
Convert the image in .zip to PDF with Python
How to upload with Heroku, Flask, Python, Git (Part 1)
Image processing with Python
How to upload with Heroku, Flask, Python, Git (Part 2)
Storage I / O notes in Python with Azure Functions
Retry with python requests
Upload to a shared drive with Google Drive API V3
How to operate Discord API with Python (bot registration)
Text extraction (Read API) with Azure Computer Vision API (Python3.6)
I tried to find the entropy of the image with python
Easy to use Nifty Cloud API with botocore and python
[Ev3dev] How to display bmp image on LCD with python
How to specify Cache-Control for blob storage in Azure Storage in Python
Image analysis with Object Detection API to try in 1 hour
How to deal with UnicodeDecodeError when executing google image download
Image processing with Python (Part 2)
Connect to BigQuery with Python
Use Trello API with python
Use Twitter API with Python
Image editing with python OpenCV
Post to slack with Python 3
Sorting image files with Python (2)
Sorting image files with Python (3)
Image processing with Python (Part 1)
Web API with Python + Falcon
Tweet with image in Python
Sorting image files with Python
Image processing with Python (Part 3)
Play RocketChat with API / Python
Switch python to 2.7 with alternatives
Write to csv with Python
Call the API with python3.
Use subsonic API with python3