基于Python的阿里云API签名算法及邮件推送服务
2017-09-30 15:18
627 查看
因为TalkingCoder的服务都是部署在阿里云ECS上的,而之前一直用SMTP来发邮件遇到种种问题,正好最近阿里云在推邮件推送服务,就尝试把它迁移过去。阿里云的推送速度、数量和监控会更好一点。邮件推送服务其实就是一个简单的API调用,但在和Celery集成过程中,却遇到几个很头疼的小问题。下面一一说明我遇到的一些坑。
签名算法
阿里云有提供SDK,但是签名算法目前只有JAVA、PHP、C#支持,其他需要自己写。在查了一些资料后,基于这篇文章,最终实现了邮件推送。
先看一下这个核心类:
# coding=utf-8
import base64
import hmac
from hashlib import sha1
import urllib
import time
import uuid
from config.base import ALIYUN_ACCESS_KEY_ID, ALIYUN_ACCESS_KEY_SECRET
class AliyunMonitor:
def __init__(self, url):
self.access_id = ALIYUN_ACCESS_KEY_ID
self.access_secret = ALIYUN_ACCESS_KEY_SECRET
self.url = url
# 签名
def sign(self, accessKeySecret, parameters):
sortedParameters = sorted(parameters.items(), key=lambda parameters: parameters[0])
canonicalizedQueryString = ''
for (k, v) in sortedParameters:
canonicalizedQueryString += '&' + self.percent_encode(k) + '=' + self.percent_encode(v)
stringToSign = 'GET&%2F&' + self.percent_encode(canonicalizedQueryString[1:]) # 使用get请求方法
h = hmac.new(accessKeySecret + "&", stringToSign, sha1)
signature = base64.encodestring(h.digest()).strip()
return signature
def percent_encode(self, encodeStr):
encodeStr = str(encodeStr)
# 下面这行挺坑的,使用上面文章中的方法会在某些情况下报错,后面详细说明
res = urllib.quote(encodeStr.decode('utf-8').encode('utf-8'), '')
res = res.replace('+', '%20')
res = res.replace('*', '%2A')
res = res.replace('%7E', '~')
return res
def make_url(self, params):
timestamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
parameters = {
'Format': 'JSON',
'Version': '2015-11-23',
'AccessKeyId': self.access_id,
'SignatureVersion': '1.0',
'SignatureMethod': 'HMAC-SHA1',
'SignatureNonce': str(uuid.uuid1()),
'Timestamp': timestamp,
}
for key in params.keys():
parameters[key] = params[key]
signature = self.sign(self.access_secret, parameters)
parameters['Signature'] = signature
# return parameters成都男性阴茎短小的原因有哪些?
url = self.url + "/?" + urllib.urlencode(parameters)
return url
然后,我们写一个send_email的方法来调用:
# coding=utf-8
import requests
from lib.aliyun_monitor import AliyunMonitor
def send_email(email_address, subject, text):
payload = {
'Action': 'SingleSendMail',
'AccountName': 'mail@mail.xxx.com',
'ReplyToAddress': 'true',
'AddressType': 0,
'ToAddress': email_address,
'FromAlias': 'TalkingCoder',
'Subject': subject,
'HtmlBody': text
}男性射出的精子是黄色的怎么办?
aliyun = AliyunMonitor("http://dm.aliyuncs.com")
url = aliyun.make_url(payload)
request = requests.get(url)
print request.text
send_email('test@test.com', '标题', '内容')
这里使用了requests来get请求。
注意
代码写到这里,在本机环境测试都OK的,然后就往Celery上集成。这里要说明一下,因为之前是用SMTP来发邮件,平均发一封2秒左右吧,这样同步发的话是一件很恐怖的事情,所以就丢给Celery异步去执行任务了。现在集成了阿里的云邮件服务后,其实是可以同步发了,因为本身一个API请求也很快,但Celery闲着也是闲着,为什么不用起来呢,所以后面问题就来了。
就是第一段签名代码里写道的,原文中使用的是res = urllib.quote(encodeStr.decode(sys.stdin.encoding).encode('utf8'), ''),这样普通执行任务可以,但是nohup后和使用Celery都会报一个错误,大致意思是decode的第一个参数必须是String,因为当时nohup后就比较难看到Celery的日志,最后在本机模拟相同环境才知道原因,改为了res = urllib.quote(encodeStr.decode('utf-8').encode('utf-8'),
'') 之后才可以。
最后,通过环境变量,在开发环境不使用Celery,在生成环境再使用
签名算法
阿里云有提供SDK,但是签名算法目前只有JAVA、PHP、C#支持,其他需要自己写。在查了一些资料后,基于这篇文章,最终实现了邮件推送。
先看一下这个核心类:
# coding=utf-8
import base64
import hmac
from hashlib import sha1
import urllib
import time
import uuid
from config.base import ALIYUN_ACCESS_KEY_ID, ALIYUN_ACCESS_KEY_SECRET
class AliyunMonitor:
def __init__(self, url):
self.access_id = ALIYUN_ACCESS_KEY_ID
self.access_secret = ALIYUN_ACCESS_KEY_SECRET
self.url = url
# 签名
def sign(self, accessKeySecret, parameters):
sortedParameters = sorted(parameters.items(), key=lambda parameters: parameters[0])
canonicalizedQueryString = ''
for (k, v) in sortedParameters:
canonicalizedQueryString += '&' + self.percent_encode(k) + '=' + self.percent_encode(v)
stringToSign = 'GET&%2F&' + self.percent_encode(canonicalizedQueryString[1:]) # 使用get请求方法
h = hmac.new(accessKeySecret + "&", stringToSign, sha1)
signature = base64.encodestring(h.digest()).strip()
return signature
def percent_encode(self, encodeStr):
encodeStr = str(encodeStr)
# 下面这行挺坑的,使用上面文章中的方法会在某些情况下报错,后面详细说明
res = urllib.quote(encodeStr.decode('utf-8').encode('utf-8'), '')
res = res.replace('+', '%20')
res = res.replace('*', '%2A')
res = res.replace('%7E', '~')
return res
def make_url(self, params):
timestamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
parameters = {
'Format': 'JSON',
'Version': '2015-11-23',
'AccessKeyId': self.access_id,
'SignatureVersion': '1.0',
'SignatureMethod': 'HMAC-SHA1',
'SignatureNonce': str(uuid.uuid1()),
'Timestamp': timestamp,
}
for key in params.keys():
parameters[key] = params[key]
signature = self.sign(self.access_secret, parameters)
parameters['Signature'] = signature
# return parameters成都男性阴茎短小的原因有哪些?
url = self.url + "/?" + urllib.urlencode(parameters)
return url
然后,我们写一个send_email的方法来调用:
# coding=utf-8
import requests
from lib.aliyun_monitor import AliyunMonitor
def send_email(email_address, subject, text):
payload = {
'Action': 'SingleSendMail',
'AccountName': 'mail@mail.xxx.com',
'ReplyToAddress': 'true',
'AddressType': 0,
'ToAddress': email_address,
'FromAlias': 'TalkingCoder',
'Subject': subject,
'HtmlBody': text
}男性射出的精子是黄色的怎么办?
aliyun = AliyunMonitor("http://dm.aliyuncs.com")
url = aliyun.make_url(payload)
request = requests.get(url)
print request.text
send_email('test@test.com', '标题', '内容')
这里使用了requests来get请求。
注意
代码写到这里,在本机环境测试都OK的,然后就往Celery上集成。这里要说明一下,因为之前是用SMTP来发邮件,平均发一封2秒左右吧,这样同步发的话是一件很恐怖的事情,所以就丢给Celery异步去执行任务了。现在集成了阿里的云邮件服务后,其实是可以同步发了,因为本身一个API请求也很快,但Celery闲着也是闲着,为什么不用起来呢,所以后面问题就来了。
就是第一段签名代码里写道的,原文中使用的是res = urllib.quote(encodeStr.decode(sys.stdin.encoding).encode('utf8'), ''),这样普通执行任务可以,但是nohup后和使用Celery都会报一个错误,大致意思是decode的第一个参数必须是String,因为当时nohup后就比较难看到Celery的日志,最后在本机模拟相同环境才知道原因,改为了res = urllib.quote(encodeStr.decode('utf-8').encode('utf-8'),
'') 之后才可以。
最后,通过环境变量,在开发环境不使用Celery,在生成环境再使用
相关文章推荐
- Python Web中REST API使用示例——基于云平台+云服务打造自己的在线翻译工具
- [Python]python3.5下的阿里云邮件推送集成
- 调用阿里云api获取阿里云数据同步服务(DTS)并且作图发送邮件的整个流程
- Python基于smtplib实现异步发送邮件服务
- 基于webservice的邮件消息推送服务
- 解决.NET Core中MailKit无法使用阿里云邮件推送服务的问题
- 阿里云API网关(17)签名算法
- Laravel 下结合阿里云邮件推送服务
- 阿里云API网关(13)请求身份识别:客户端请求签名和服务网关请求签名
- .net Core WebApi发布到Docker并推送到阿里云容器服务
- 解决.NET Core中MailKit无法使用阿里云邮件推送服务的问题
- Python基于smtplib实现异步发送邮件服务
- 试用阿里云邮件推送服务
- 阿里云邮件推送服务
- 阿里云短信服务API中接口签名的测试
- 基于小波变换的多聚焦图像融合算法——Python实现
- JavaMail(JAVA邮件服务) API详解
- 阿里云开放服务oss的api
- 【Python】基于候选数的解数独算法 + 使用wxPython编写程序界面
- 无需复杂深度学习算法,基于计算机视觉使用Python和OpenCV计算道路交通