How to Apply API Gateway for DirectMail in Python

My favorite language for rapid prototyping and learning a new cloud service is Python. Python makes most tasks so simple that I can test a new API in minutes. This allows me to focus on learning and not on the details of how an API works in a particular language. However, for enterprise level code where a mistake could cost millions of dollars, I use C++.

The Alibaba SDK for DirectMail does not support Python. It does support PHP, Java and C#. A very common use case for DirectMail is delivering emails for dynamic and static websites. For dynamic websites PHP is perfect. For static websites, integrating Function Compute with DirectMail is perfect. However, Function Compute does not support PHP. This means that you develop in one language on your desktop and another in the cloud.

This led me to the idea of using the DirectMail REST API. This means that I can use Python and learn how to use the REST API and in particular how to create the Signature that is not documented very well. Nothing like picking a difficult challenge to really learn a new service.

In this article I will focus on the DirectMail REST API and include a real working example in Python.

Calculating the correct dates

# Date used by the HTTP "Date" header
date = now.strftime("%a, %d %b %Y %H:%M:%S GMT")
# Date used by the API parameter "Timestamp"
utc = now.isoformat(timespec='seconds') + 'Z'

Complete Program to Call DirectMail REST API and Send an Email


""" Alibaba Cloud DirectMail REST API With Signing """import base64
import datetime
import hmac
import hashlib
import urllib
import uuid
import json
import requests
# My library for processing Alibaba Cloud Services (ACS) credentials
import mycred_acs
# From the DirectMail Console
dm_account = "<enter your value here>"
dm_alias = "<enter your value here>"
debug = 0def set_connection_logging():
""" Enable HTTP connection logging """
if debug is 0:
import logging
import http.client as http_client
http_client.HTTPConnection.debuglevel = 1 # You must initialize logging, otherwise you'll not see debug output.
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.propagate = True
def get_uuid():
""" return a uuid as a signing nonce """
return str(uuid.uuid4())
def percentEncode(path):
""" Encode a URL """
res = urllib.parse.quote(path)
res = res.replace('+', '%20')
res = res.replace('*', '%2A')
res = res.replace('%7E', '~')
return res
def my_urlencode(query):
""" Encode a Query """
res = urllib.parse.urlencode(query)
res = res.replace('+', '%20')
res = res.replace('*', '%2A')
res = res.replace('%7E', '~')
return res
def build_request_string(table):
""" Build canonical list """
items = sorted(iter(table.items()), key=lambda d: d[0])
enc = my_urlencode(items)
return enc
def sign(string, secret):
""" Sign REST API Request """
nsecret = secret + '&'
h =
bytes(nsecret, "utf-8"),
bytes(string, "utf-8"),
#sig = base64.b64encode(h.digest())
sig = str(base64.encodebytes(h.digest()).strip(), "utf-8")
return sig
def sendEmail(credentials, subject, body, body_text, to_list):
""" Send an email using Alibaba DirectMail """
# HTTP Method
method = "POST"
# Correctly formatted date and time
now = datetime.datetime.utcnow()
date = now.strftime("%a, %d %b %Y %H:%M:%S GMT")
utc = now.isoformat(timespec='seconds') + 'Z'
# HTTP Host header
host = ""
# URL for POST
url = ""
parameters = {} # Add the DirectMail public request parameters
parameters["Format"] = "json"
parameters["AccessKeyId"] = credentials['AccessKey']
parameters["SignatureMethod"] = "HMAC-SHA1"
parameters["SignatureType"] = ""
parameters["SignatureVersion"] = "1.0"
parameters["SignatureNonce"] = get_uuid()
parameters["Timestamp"] = utc
#parameters["Version"] = "2015-11-23"
parameters["Version"] = "2017-06-22"
parameters["RegionId"] = "ap-southeast-1"
# Add parameters that are always set
parameters["Action"] = "SingleSendMail"
parameters["AddressType"] = "1"
parameters["ReplyToAddress"] = "true"
# Add the DirectMail API parameters
parameters["AccountName"] = dm_account
parameters["FromAlias"] = dm_alias
parameters["ToAddress"] = to_list
parameters["Subject"] = subject
parameters["HtmlBody"] = body
parameters["textBody"] = body_text
# Build the request string for the signing process
params = build_request_string(parameters)
# Create the actual string to sign
stringToSign = method + "&%2F&" + percentEncode(params)
#print("String to Sign")
Signature = sign(stringToSign, credentials['AccessKeySecret'])
#print("Signature", Signature)
parameters["Signature"] = Signature headers = {
'Date': date,
'Host': host
set_connection_logging() print("Sending Email to", parameters["ToAddress"])
r =, data=parameters, headers=headers)
if r.status_code != 200:
print("Error: Email Send Failed:", r.status_code)
return 1
#print(r.text) result = json.loads(r.text)
print("Success: Request ID:", result['RequestId'])
return 0# Load the Alibaba Cloud Credentials (AccessKey)
cred = mycred_acs.LoadCredentials()
dm_subject = "Welcome to Alibaba Cloud DirectMail"dm_body = "<h2>Welcome to Alibaba Cloud DirectMail<h2>You are receiving this email as part of a test program.<br /><br />Click for <a href=''>more information<a>.<br /><br /><a href=''><img src='' alt='Alibaba' width='700'><a>"dm_body_text = "Welcome to Alibaba Cloud DirectMail\nYou are receiving this email as part of a test program."dm_to_list = ", test2@test.comsendEmail(cred, dm_subject, dm_body, dm_body_text, dm_to_list)

Execute with Python 3.x: python

For details, please go to Cloud DevOps Cookbook Part 4 — API Gateway and DirectMail with Python 3.0.

Related Blog Posts

Alibaba Cloud DevOps Cookbook Part 1 — CLI, SDK, SSH, SFTP

Now that I have a test website that is load balanced and has auto scaling, I would like to learn more about the Alibaba Cloud CLI and Python SDK. During development I often need to make changes to files that I publish on my ECS instances. Since the auto scaling group is built from an image, changing the image takes effort and time. During testing, I want to do rapid-fire edit / deploy / debug / improve. This means that I need a quick way to upload files to my ECS instances all at once.

Alibaba Cloud DevOps Cookbook Part 3 — Function Compute with Python 3.0

In today’s article we will be exploring Alibaba Cloud Function Compute for DevOps with some example programs using Python 3. Our ultimate goal is to combine API Gateway, Function Compute, and Direct Mail to provide a contact form suitable for a static website hosted on OSS.

Related Market Product

Spark Mllib Hadoop Core powered by Miri Infotech

Spark is a general-purpose and quick cluster computing system that provides high-level APIs in Scala, Java, Python, and R, and an optimized engine, which supports general execution graphs.

Related Documentation

SMTP — Python

This page shows how to send an email through SMTP using Python.

Set HTTPS requests

Alibaba Cloud Python SDK supports using HTTP and HTTPS protocols to send API requests. Most Alibaba Cloud products use the HTTP protocol, whereas Resource Access Manager (RAM), Security Token Service (STS), and Key Management Service (KMS) use the HTTPS protocol.

Related Products

Direct Mail

DirectMail is a simple and efficient service to send email notifications and batch email quickly and efficiently without the need to build your own email server. DirectMail is a key product for serving Alibaba’s own e-commerce platforms, which includes servicing Alibaba’s record-breaking annual sales festival. Tens of millions of emails are sent every day through DirectMail by Alibaba and Alibaba Cloud customers.

Elastic Compute Service

Alibaba Cloud Elastic Compute Service (ECS) provides fast memory and the latest Intel CPUs to help you to power your cloud applications and achieve faster results with low latency. All ECS instances come with Anti-DDoS protection to safeguard your data and applications from DDoS and Trojan attacks.

Related Course

A Quick Guide to Process Structured Data with Python

The data set of this course is from virtual blog site, we are going to use the data to solve business problems,for example what countries do your customers come from;Which day of the week gets the most online traffic; Which region contributes the most clickstream data etc. Basic functions for data cleaning, data analysis and visualization will be coverd in this course. It is also the foundation for programming on distributed system like Spark SQL,or with Alibaba cloud MaxCompute Python SDK.


Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store