python3.6 通过调用 阿里云 API (非SDK方式) 查询 账单 例子

特别注意:

报错:
b'{"Recommend":"https://error-center.aliyun.com/status/search?Keyword=MissingTimestamp&source=PopGw","Message":"Timestamp is mandatory for this action.","RequestId":"03C305CD-F5C2-4B32-BA0B-696063E3E3A5","HostId":"business.aliyuncs.com","Code":"MissingTimestamp"}'
HTTP Error 400: Bad Request

代码77行 Timestamp ,   部分API 字段是 TimeStamp 大写, 账单 需要是小写 Timestamp。 

大小写API 阿里云没有统一,这个要特别注意。 

具体大小写 看API 文档。

代码

#!/usr/bin/env python3.6
# -*- coding:utf8 -*-
try:
    import httplib
except ImportError:
    import http.client as httplib
import sys, datetime
import urllib
import urllib.request
import urllib.error
import urllib.parse
import time
import json
import base64
import hmac, ssl
import uuid
from hashlib import sha1

# 解决 访问ssl网站证书的问题

try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    # Legacy Python that doesn't verify HTTPS certificates by default
    pass
else:
    # Handle target environment that doesn't support HTTPS verification
    ssl._create_default_https_context = _create_unverified_https_context

class AliyunClient(object):
    def __init__(self, access_id, access_secret, region, url,case=0):
        self.access_id = access_id
        self.access_secret = access_secret
        self.RegionId = region
        self.url = url
        self.case = case

    # #签名

    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请求方法
        bs = accessKeySecret + '&'
        bs = bytes(bs, encoding='utf8')
        stringToSign = bytes(stringToSign, encoding='utf8')
        h = hmac.new(bs, stringToSign, sha1)
        # 进行编码
        signature = base64.b64encode(h.digest()).strip()
        return signature

    def percent_encode(self, encodeStr):
        encodeStr = str(encodeStr)
        res = urllib.request.quote(encodeStr)
        res = res.replace('+', '%20')
        res = res.replace('*', '%2A')
        res = res.replace('%7E', '~')
        return res

    # 构建除共公参数外的所有URL

    def make_url(self, params):
        timestamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
        parameters = {
            'Format': 'JSON',
            'Version': '2017-12-14',
            'AccessKeyId': self.access_id,
            'SignatureVersion': '1.0',
            'SignatureMethod': 'HMAC-SHA1',
            'SignatureNonce': str(uuid.uuid1()),
        }
        if self.case == 1:
            parameters['TimeStamp']=timestamp
        else:
            parameters['Timestamp'] = timestamp

        for key in params.keys():
            parameters[key] = params[key]
        signature = self.sign(self.access_secret, parameters)
        parameters['Signature'] = signature
        url = self.url + "/?" + urllib.parse.urlencode(parameters)
        return url

    def do_action(self, params):
        url = self.make_url(params)
        request = urllib.request.Request(url)
        try:
            conn = urllib.request.urlopen(request)
            response = conn.read().decode()
        except urllib.error.HTTPError as e:
            print(e.read().strip())
            raise SystemExit(e)
        try:
            res = json.loads(response)
        except ValueError as e:
            raise SystemExit(e)
        return res

# 继承原始类
class client(AliyunClient):
    def __init__(self,access_id,access_secret,region,url,case=0):
        super().__init__(access_id,access_secret,region,url,case)

    def DescribeInstanceMonitorData(self):
        action_dict = {"Action": "QueryMonthlyBill", "RegionId": self.RegionId,'BillingCycle': '2018-08'}
        result = self.do_action(action_dict)
        return result

if __name__ == "__main__":
    a = client('xxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxx','cn-beijing','https://business.aliyuncs.com')
    b = a.DescribeInstanceMonitorData()
    print(b)

结果

{'Data': {'Items': {'Item': [{'SubscriptionType': 'PayAsYouGo', 'ProductCode': 'arms', 'DeductedByPrepaidCard': 0.0, 'PretaxAmount': 0.0, 'DeductedByCoupons': 0.0, 'Item': 'PayAsYouGoBill', 'PaymentAmount': 0.0, 'OutstandingAmount': 0.0, 'ProductType': 'arms_web_post', 'DeductedByCashCoupons': 0.0, 'PretaxGrossAmount': 0.0, 'Currency': 'CNY', 'InvoiceDiscount': 0.0}]}, 'BillingCycle': '2018-08', 'OutstandingAmount': 0.0, 'TotalOutstandingAmount': 0, 'NewInvoiceAmount': 0}, 'Message': 'Successful!', 'RequestId': '4153510B-9D5D-41FB-8D67-1E86D163B928', 'Success': True, 'Code': 'Success'}

参考

https://www.cnblogs.com/IPYQ/p/5996868.html

转载于:https://blog.51cto.com/hequan/2176032

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值