├── .gitignore
├── LICENSE
├── MANIFEST.in
├── README.md
├── README.rst
├── aliyunsdkcore
├── QuerySendDetailsRequest.py
├── SendSmsRequest.py
├── __init__.py
├── acs_exception
│ ├── __init__.py
│ ├── error_code.py
│ ├── error_msg.py
│ ├── error_type.py
│ └── exceptions.py
├── auth
│ ├── __init__.py
│ ├── md5_tool.py
│ ├── oss_signature_composer.py
│ ├── roa_signature_composer.py
│ ├── rpc_signature_composer.py
│ ├── sha_hmac1.py
│ ├── sha_hmac256.py
│ └── url_encoder.py
├── client.py
├── endpoints.xml
├── http_service
│ ├── __init__.py
│ ├── format_type.py
│ ├── http_request.py
│ ├── http_response.py
│ ├── method_type.py
│ └── protocol_type.py
├── profile
│ ├── __init__.py
│ ├── location_service.py
│ └── region_provider.py
├── request.py
└── utils
│ ├── __init__.py
│ └── parameter_helper.py
├── setup.cfg
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | .idea/
28 | .DS_Store/
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | .hypothesis/
50 |
51 | # Translations
52 | *.mo
53 | *.pot
54 |
55 | # Django stuff:
56 | *.log
57 | local_settings.py
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # dotenv
85 | .env
86 |
87 | # virtualenv
88 | .venv
89 | venv/
90 | ENV/
91 |
92 | # Spyder project settings
93 | .spyderproject
94 | .spyproject
95 |
96 | # Rope project settings
97 | .ropeproject
98 |
99 | # mkdocs documentation
100 | /site
101 |
102 | # mypy
103 | .mypy_cache/
104 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include aliyunsdkcore *.xml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 阿里云python sdk文档地址
2 | [阿里云python sdk最新文档地址](https://help.aliyun.com/zh/sdk/developer-reference/v2-python-integrated-sdk?spm=a2c4g.11186623.0.0.3c15795et8ipN5)
3 |
4 | 阿里将sdk接入分为特化调用和泛化调用,特化调用安装地址为:
5 |
6 | ```pip install alibabacloud_dysmsapi20170525==2.0.24```,
7 |
8 | 泛化地址为:
9 |
10 | ```pip install alibabacloud-tea-openapi```
11 |
12 | ---
13 | # Deprecated
14 |
15 | 目前阿里云好像官方出了aliyun-python-sdk-core-v3的Python3的支持包,地址是[https://pypi.org/project/aliyun-python-sdk-core-v3/](https://pypi.org/project/aliyun-python-sdk-core-v3/),经过测试可以正常发送短信,所以推荐大家安装这个新的包。[官方文档](https://help.aliyun.com/document_detail/55491.html?spm=a2c4g.11186623.6.570.dfgplP)
16 |
17 | # 安装方式
18 | ```
19 | pip install aliyun-python-sdk-core-v3
20 |
21 | ```
22 |
23 | # 官方文档中的发送例子 demo_sms_send.py
24 | ```python
25 | # -*- coding: utf-8 -*-
26 | import sys
27 | from aliyunsdkdysmsapi.request.v20170525 import SendSmsRequest
28 | from aliyunsdkdysmsapi.request.v20170525 import QuerySendDetailsRequest
29 | from aliyunsdkcore.client import AcsClient
30 | import uuid
31 | from aliyunsdkcore.profile import region_provider
32 | from aliyunsdkcore.http import method_type as MT
33 | from aliyunsdkcore.http import format_type as FT
34 |
35 | """
36 | 短信业务调用接口示例,版本号:v20170525
37 |
38 | Created on 2017-06-12
39 |
40 | """
41 | try:
42 | reload(sys)
43 | sys.setdefaultencoding('utf8')
44 | except NameError:
45 | pass
46 | except Exception as err:
47 | raise err
48 |
49 | # 注意:不要更改
50 | REGION = "cn-hangzhou"
51 | PRODUCT_NAME = "Dysmsapi"
52 | DOMAIN = "dysmsapi.aliyuncs.com"
53 |
54 | # ACCESS_KEY_ID/ACCESS_KEY_SECRET 根据实际申请的账号信息进行替换
55 | ACCESS_KEY_ID = "yourAccessKeyId"
56 | ACCESS_KEY_SECRET = "yourAccessKeySecret"
57 |
58 | acs_client = AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, REGION)
59 | region_provider.add_endpoint(PRODUCT_NAME, REGION, DOMAIN)
60 |
61 | def send_sms(business_id, phone_numbers, sign_name, template_code, template_param=None):
62 | smsRequest = SendSmsRequest.SendSmsRequest()
63 | # 申请的短信模板编码,必填
64 | smsRequest.set_TemplateCode(template_code)
65 |
66 | # 短信模板变量参数
67 | if template_param is not None:
68 | smsRequest.set_TemplateParam(template_param)
69 |
70 | # 设置业务请求流水号,必填。
71 | smsRequest.set_OutId(business_id)
72 |
73 | # 短信签名
74 | smsRequest.set_SignName(sign_name)
75 |
76 | # 数据提交方式
77 | # smsRequest.set_method(MT.POST)
78 |
79 | # 数据提交格式
80 | # smsRequest.set_accept_format(FT.JSON)
81 |
82 | # 短信发送的号码列表,必填。
83 | smsRequest.set_PhoneNumbers(phone_numbers)
84 |
85 | # 调用短信发送接口,返回json
86 | smsResponse = acs_client.do_action_with_exception(smsRequest)
87 |
88 | # TODO 业务处理
89 |
90 | return smsResponse
91 |
92 |
93 | if __name__ == '__main__':
94 | __business_id = uuid.uuid1()
95 | #print(__business_id)
96 | params = "{\"code\":\"12345\",\"product\":\"云通信\"}"
97 | #params = u'{"name":"wqb","code":"12345678","address":"bz","phone":"13000000000"}'
98 | print(send_sms(__business_id, "13000000000", "云通信测试", "SMS_5250008", params))
99 | ```
100 |
101 | 文档中将ACCESS_KEY_ID和ACCESS_KEY_SECRET放在了const.py的文件中,此处直接放在了测试代码里。
102 |
103 |
104 |
105 | ----
106 |
107 | # **Deprecated**
108 |
109 | # aliyunsdkcore
110 | 阿里短信Python3 API,基于[阿里官网](https://help.aliyun.com/document_detail/55491.html?spm=5176.sms-account.109.3.66e36217NuxCf) Python2 API的翻版,
111 | 主要修改为Python2转Python3时不兼容包的替换。
112 |
113 | # Requirements
114 | - Python (3.3, 3.4, 3.5, 3.6)
115 |
116 | # Installation
117 | ```python
118 | $ pip install aliyunsdkcore
119 | ```
120 |
121 | # Sample
122 | ```python
123 | import sys
124 | from aliyunsdkcore import SendSmsRequest, QuerySendDetailsRequest
125 | from aliyunsdkcore.client import AcsClient
126 | import uuid
127 |
128 |
129 | REGION = "cn-hangzhou"
130 | # ACCESS_KEY_ID/ACCESS_KEY_SECRET 根据实际申请的账号信息进行替换
131 | ACCESS_KEY_ID = "YOUR ACCESS_KEY_ID"
132 | ACCESS_KEY_SECRET = "YOUR ACCESS_KEY_SECRET"
133 |
134 | acs_client = AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, REGION)
135 |
136 |
137 | def send_sms(business_id, phone_numbers, sign_name, template_code, template_param=None):
138 | smsRequest = SendSmsRequest.SendSmsRequest()
139 | # 申请的短信模板编码,必填
140 | smsRequest.set_TemplateCode(template_code)
141 |
142 | # 短信模板变量参数
143 | if template_param is not None:
144 | smsRequest.set_TemplateParam(template_param)
145 |
146 | # 设置业务请求流水号,必填。
147 | smsRequest.set_OutId(business_id)
148 |
149 | # 短信签名
150 | smsRequest.set_SignName(sign_name);
151 |
152 | # 短信发送的号码列表,必填。
153 | smsRequest.set_PhoneNumbers(phone_numbers)
154 |
155 | # 调用短信发送接口,返回json
156 | smsResponse = acs_client.do_action_with_exception(smsRequest)
157 |
158 | # TODO 业务处理
159 |
160 | return smsResponse
161 |
162 |
163 | def query_send_detail(biz_id, phone_number, page_size, current_page, send_date):
164 | queryRequest = QuerySendDetailsRequest.QuerySendDetailsRequest()
165 | # 查询的手机号码
166 | queryRequest.set_PhoneNumber(phone_number)
167 | # 可选 - 流水号
168 | queryRequest.set_BizId(biz_id)
169 | # 必填 - 发送日期 支持30天内记录查询,格式yyyyMMdd
170 | queryRequest.set_SendDate(send_date)
171 | # 必填-当前页码从1开始计数
172 | queryRequest.set_CurrentPage(current_page)
173 | # 必填-页大小
174 | queryRequest.set_PageSize(page_size)
175 |
176 | # 调用短信记录查询接口,返回json
177 | queryResponse = acs_client.do_action_with_exception(queryRequest)
178 |
179 | # TODO 业务处理
180 |
181 | return queryResponse
182 |
183 |
184 | __name__ = 'send'
185 | if __name__ == 'send':
186 | __business_id = uuid.uuid1()
187 | print(__business_id)
188 | params = {"code": "456789"}
189 | print(send_sms(__business_id, "13000000000", "测试", "SMS_1234567", params))
190 |
191 | ```
192 |
193 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ======================
2 | aliyun-python-sdk-core
3 | ======================
4 |
5 |
6 | This is the core module of Aliyun Python SDK.
7 |
8 | Aliyun Python SDK is the official software development kit. It makes things easy to integrate your Python application,
9 | library, or script with Aliyun services.
10 |
11 | This module works on Python versions:
12 |
13 | * 3.0 and greater
14 |
15 |
16 | Documentation:
17 |
18 | Please visit https://github.com/duangy/aliyunsdkcore
--------------------------------------------------------------------------------
/aliyunsdkcore/QuerySendDetailsRequest.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | from .request import RpcRequest
21 | class QuerySendDetailsRequest(RpcRequest):
22 |
23 | def __init__(self):
24 | RpcRequest.__init__(self, 'Dysmsapi', '2017-05-25', 'QuerySendDetails')
25 |
26 | def get_SendDate(self):
27 | return self.get_query_params().get('SendDate')
28 |
29 | def set_SendDate(self,SendDate):
30 | self.add_query_param('SendDate',SendDate)
31 |
32 | def get_PageSize(self):
33 | return self.get_query_params().get('PageSize')
34 |
35 | def set_PageSize(self,PageSize):
36 | self.add_query_param('PageSize',PageSize)
37 |
38 | def get_ResourceOwnerId(self):
39 | return self.get_query_params().get('ResourceOwnerId')
40 |
41 | def set_ResourceOwnerId(self,ResourceOwnerId):
42 | self.add_query_param('ResourceOwnerId',ResourceOwnerId)
43 |
44 | def get_OwnerId(self):
45 | return self.get_query_params().get('OwnerId')
46 |
47 | def set_OwnerId(self,OwnerId):
48 | self.add_query_param('OwnerId',OwnerId)
49 |
50 | def get_PhoneNumber(self):
51 | return self.get_query_params().get('PhoneNumber')
52 |
53 | def set_PhoneNumber(self,PhoneNumber):
54 | self.add_query_param('PhoneNumber',PhoneNumber)
55 |
56 | def get_CurrentPage(self):
57 | return self.get_query_params().get('CurrentPage')
58 |
59 | def set_CurrentPage(self,CurrentPage):
60 | self.add_query_param('CurrentPage',CurrentPage)
61 |
62 | def get_BizId(self):
63 | return self.get_query_params().get('BizId')
64 |
65 | def set_BizId(self,BizId):
66 | self.add_query_param('BizId',BizId)
67 |
68 | def get_ResourceOwnerAccount(self):
69 | return self.get_query_params().get('ResourceOwnerAccount')
70 |
71 | def set_ResourceOwnerAccount(self,ResourceOwnerAccount):
72 | self.add_query_param('ResourceOwnerAccount',ResourceOwnerAccount)
--------------------------------------------------------------------------------
/aliyunsdkcore/SendSmsRequest.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | from .request import RpcRequest
21 | class SendSmsRequest(RpcRequest):
22 |
23 | def __init__(self):
24 | RpcRequest.__init__(self, 'Dysmsapi', '2017-05-25', 'SendSms')
25 |
26 | def get_OutId(self):
27 | return self.get_query_params().get('OutId')
28 |
29 | def set_OutId(self,OutId):
30 | self.add_query_param('OutId',OutId)
31 |
32 | def get_SignName(self):
33 | return self.get_query_params().get('SignName')
34 |
35 | def set_SignName(self,SignName):
36 | self.add_query_param('SignName',SignName)
37 |
38 | def get_ResourceOwnerId(self):
39 | return self.get_query_params().get('ResourceOwnerId')
40 |
41 | def set_ResourceOwnerId(self,ResourceOwnerId):
42 | self.add_query_param('ResourceOwnerId',ResourceOwnerId)
43 |
44 | def get_OwnerId(self):
45 | return self.get_query_params().get('OwnerId')
46 |
47 | def set_OwnerId(self,OwnerId):
48 | self.add_query_param('OwnerId',OwnerId)
49 |
50 | def get_TemplateCode(self):
51 | return self.get_query_params().get('TemplateCode')
52 |
53 | def set_TemplateCode(self,TemplateCode):
54 | self.add_query_param('TemplateCode',TemplateCode)
55 |
56 | def get_PhoneNumbers(self):
57 | return self.get_query_params().get('PhoneNumbers')
58 |
59 | def set_PhoneNumbers(self,PhoneNumbers):
60 | self.add_query_param('PhoneNumbers',PhoneNumbers)
61 |
62 | def get_ResourceOwnerAccount(self):
63 | return self.get_query_params().get('ResourceOwnerAccount')
64 |
65 | def set_ResourceOwnerAccount(self,ResourceOwnerAccount):
66 | self.add_query_param('ResourceOwnerAccount',ResourceOwnerAccount)
67 |
68 | def get_TemplateParam(self):
69 | return self.get_query_params().get('TemplateParam')
70 |
71 | def set_TemplateParam(self,TemplateParam):
72 | self.add_query_param('TemplateParam',TemplateParam)
--------------------------------------------------------------------------------
/aliyunsdkcore/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'guangyao'
2 | __version__ = '1.0.3'
3 |
--------------------------------------------------------------------------------
/aliyunsdkcore/acs_exception/__init__.py:
--------------------------------------------------------------------------------
1 | __author__='guangyao'
2 |
--------------------------------------------------------------------------------
/aliyunsdkcore/acs_exception/error_code.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | #coding=utf-8
21 |
22 | """
23 | Acs ERROR CODE module.
24 |
25 | Created on 9/19/2017
26 |
27 | @author: guangyao
28 | """
29 |
30 | SDK_INVALID_REGION_ID = 'SDK.InvalidRegionId'
31 | SDK_SERVER_UNREACHABLE = 'SDK.ServerUnreachable'
32 | SDK_INVALID_REQUEST = 'SDK.InvalidRequest'
33 | SDK_MISSING_ENDPOINTS_FILER = 'SDK.MissingEndpointsFiler'
34 | SDK_UNKNOWN_SERVER_ERROR = 'SDK.UnknownServerError'
35 |
--------------------------------------------------------------------------------
/aliyunsdkcore/acs_exception/error_msg.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | #coding=utf-8
21 |
22 | """
23 | Acs error message module.
24 |
25 | Created on 9/19/2017
26 |
27 | @author: guangyao
28 | """
29 |
30 | __dict = dict(SDK_INVALID_REGION_ID='Can not find endpoint to access.',
31 | SDK_SERVER_UNREACHABLE='Unable to connect server',
32 | SDK_INVALID_REQUEST='The request is not a valid AcsRequest.',
33 | SDK_MISSING_ENDPOINTS_FILER='Internal endpoints info is missing.',
34 | SDK_UNKNOWN_SERVER_ERROR="Can not parse error message from server response.")
35 |
36 |
37 | def get_msg(code):
38 | return __dict.get(code)
39 |
--------------------------------------------------------------------------------
/aliyunsdkcore/acs_exception/error_type.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | #coding=utf-8
21 |
22 | """
23 | SDK exception error type module.
24 |
25 | Created on 9/19/2017
26 |
27 | @author: guangyao
28 | """
29 |
30 | ERROR_TYPE_CLIENT = 'Client'
31 | ERROR_TYPE_SERVER = 'Server'
32 | ERROR_TYPE_THROTTLING = 'Throttling'
33 | ERROR_TYPE_UNKNOWN = 'Unknown'
--------------------------------------------------------------------------------
/aliyunsdkcore/acs_exception/exceptions.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | #coding=utf-8
21 |
22 | """
23 | SDK exception module.
24 |
25 | Created on 9/19/2017
26 |
27 | @author: guangyao
28 | """
29 |
30 | from . import error_type
31 |
32 |
33 | class ClientException(Exception):
34 | """client exception"""
35 |
36 | def __init__(self, code, msg):
37 | """
38 |
39 | :param code: error code
40 | :param message: error message
41 | :return:
42 | """
43 | Exception.__init__(self)
44 | self.__error_type = error_type.ERROR_TYPE_CLIENT
45 | self.message = msg
46 | self.error_code = code
47 |
48 | def __str__(self):
49 | return "%s %s" % (
50 | self.error_code,
51 | self.message,
52 | )
53 |
54 | def set_error_code(self, code):
55 | self.error_code = code
56 |
57 | def set_error_msg(self, msg):
58 | self.message = msg
59 |
60 | def get_error_type(self):
61 | return self.__error_type
62 |
63 | def get_error_code(self):
64 | return self.error_code
65 |
66 | def get_error_msg(self):
67 | return self.message
68 |
69 |
70 | class ServerException(Exception):
71 | """
72 | server exception
73 | """
74 |
75 | def __init__(self, code, msg, http_status=None, request_id=None):
76 | Exception.__init__(self)
77 | self.error_code = code
78 | self.message = msg
79 | self.__error_type = error_type.ERROR_TYPE_SERVER
80 | self.http_status = http_status
81 | self.request_id = request_id
82 |
83 | def __str__(self):
84 | return "HTTP Status: %s Error:%s %s RequestID: %s" % (
85 | str(self.http_status),
86 | self.error_code,
87 | self.message,
88 | self.request_id
89 | )
90 |
91 | def set_error_code(self, code):
92 | self.error_code = code
93 |
94 | def set_error_msg(self, msg):
95 | self.message = msg
96 |
97 | def get_error_type(self):
98 | return self.__error_type
99 |
100 | def get_error_code(self):
101 | return self.error_code
102 |
103 | def get_error_msg(self):
104 | return self.message
105 |
106 | def get_http_status(self):
107 | return self.http_status
108 |
109 | def get_request_id(self):
110 | return self.request_id
111 |
112 |
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/__init__.py:
--------------------------------------------------------------------------------
1 | __author__='guangyao'
2 |
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/md5_tool.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | """
21 | MD5 tools module.
22 |
23 | Created on 9/19/2017
24 |
25 | @author: guangyao
26 | """
27 |
28 | import hashlib
29 | import base64
30 |
31 |
32 |
33 | def _get_md5(content):
34 | m = hashlib.md5()
35 | m.update(memoryview(content))
36 | return m.digest()
37 |
38 | def get_md5_base64_str(content):
39 | return base64.encodestring(_get_md5(content)).strip()
40 |
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/oss_signature_composer.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 | import os
22 | import sys
23 |
24 | parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
25 | sys.path.insert(0,parentdir)
26 | from . import roa_signature_composer
27 | from . import sha_hmac1 as mac1
28 | from ..utils import parameter_helper as helper
29 | from urllib import parse
30 |
31 | ACCEPT = "Accept"
32 | CONTENT_MD5 = "Content-MD5"
33 | CONTENT_TYPE = "Content-Type"
34 | DATE = "Date"
35 | QUERY_SEPARATOR = "&"
36 | HEADER_SEPARATOR = "\n"
37 |
38 | def __init__():
39 | pass
40 |
41 | def refresh_sign_parameters(parameters, access_key_id, format="JSON", signer=mac1):
42 | parameters["Date"] = helper.get_rfc_2616_date()
43 | return parameters
44 |
45 | def __build_query_string(uri, queries):
46 | sorted_map = sorted(queries.items(), key=lambda queries:queries[0])
47 | if len(sorted_map) > 0:
48 | uri += "?"
49 | for (k,v) in sorted_map:
50 | uri += k
51 | if v is not None:
52 | uri += "="
53 | uri += v
54 | uri += roa_signature_composer.QUERY_SEPARATOR
55 | if uri.find(roa_signature_composer.QUERY_SEPARATOR) >= 0:
56 | uri = uri[0:(len(uri)-1)]
57 | return uri
58 |
59 | def compose_string_to_sign(method, queries, uri_pattern=None, headers=None, paths=None, signer=mac1):
60 | sign_to_string = ""
61 | sign_to_string += method
62 | sign_to_string += HEADER_SEPARATOR
63 | if headers.has_key(CONTENT_MD5) and headers[CONTENT_MD5] is not None:
64 | sign_to_string += headers[CONTENT_MD5]
65 | sign_to_string += HEADER_SEPARATOR
66 | if headers.has_key(CONTENT_TYPE) and headers[CONTENT_TYPE] is not None:
67 | sign_to_string += headers[CONTENT_TYPE]
68 | sign_to_string += HEADER_SEPARATOR
69 | if headers.has_key(DATE) and headers[DATE] is not None:
70 | sign_to_string += headers[DATE]
71 | sign_to_string += HEADER_SEPARATOR
72 | sign_to_string += roa_signature_composer.build_canonical_headers(headers, "x-oss-")
73 | sign_to_string += __build_query_string(uri_pattern, queries)
74 | return sign_to_string
75 |
76 | def get_signature(queries, access_key, secret, format, headers, uri_pattern, paths, method, signer=mac1, bucket_name=None):
77 | headers = refresh_sign_parameters(parameters=headers, access_key_id=access_key,format=format)
78 | uri = uri_pattern
79 | if bucket_name is not None:
80 | uri = "/"+bucket_name+uri
81 | sign_to_string = compose_string_to_sign(method=method, queries=queries, headers=headers, uri_pattern=uri, paths=paths)
82 | signature = signer.get_sign_string(sign_to_string, secret=secret)
83 | return signature
84 |
85 | def get_signature_headers(queries, access_key, secret, format, headers, uri_pattern, paths, method, bucket_name, signer=mac1):
86 | signature = get_signature(queries, access_key, secret, format, headers, uri_pattern, paths, method, signer, bucket_name)
87 | headers["Authorization"] = "OSS "+access_key+":"+signature
88 | return headers
89 |
90 | def get_url(queries, uri_pattern, path_parameters):
91 | url = ""
92 | url += roa_signature_composer.replace_occupied_parameters(uri_pattern, path_parameters)
93 | if not url.endswith("?"):
94 | url += "?"
95 | url += parse.urlencode(queries)
96 | if url.endswith("?"):
97 | url = url[0:(len(url)-1)]
98 | return url
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/roa_signature_composer.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 | import os
22 | import sys
23 |
24 | parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
25 | sys.path.insert(0, parentdir)
26 | from . import sha_hmac1 as mac1
27 | from ..utils import parameter_helper as helper
28 | from ..http_service import format_type as FormatType
29 | from urllib import parse
30 |
31 | ACCEPT = "Accept"
32 | CONTENT_MD5 = "Content-MD5"
33 | CONTENT_TYPE = "Content-Type"
34 | DATE = "Date"
35 | QUERY_SEPARATOR = "&"
36 | HEADER_SEPARATOR = "\n"
37 |
38 | def __init__():
39 | pass
40 |
41 | # this function will append the necessary parameters for signer process.
42 | # parameters: the orignal parameters
43 | # signer: sha_hmac1 or sha_hmac256
44 | # accessKeyId: this is aliyun_access_key_id
45 | # format: XML or JSON
46 | # input parameters is headers
47 | def refresh_sign_parameters(parameters, access_key_id, format, signer=mac1):
48 | if parameters is None or not isinstance(parameters, dict):
49 | parameters = dict()
50 | if format is None:
51 | format = FormatType.RAW
52 | parameters["Date"] = helper.get_rfc_2616_date()
53 | parameters["Accept"] = FormatType.map_format_to_accept(format)
54 | parameters["x-acs-signature-method"] = signer.get_signer_name()
55 | parameters["x-acs-signature-version"] = signer.get_singer_version()
56 | return parameters
57 |
58 |
59 | def compose_string_to_sign(method, queries, uri_pattern=None, headers=None, paths=None, signer=mac1):
60 | sign_to_string = ""
61 | sign_to_string += method
62 | sign_to_string += HEADER_SEPARATOR
63 | if headers.has_key(ACCEPT) and headers[ACCEPT] is not None:
64 | sign_to_string += headers[ACCEPT]
65 | sign_to_string += HEADER_SEPARATOR
66 | if headers.has_key(CONTENT_MD5) and headers[CONTENT_MD5] is not None:
67 | sign_to_string += headers[CONTENT_MD5]
68 | sign_to_string += HEADER_SEPARATOR
69 | if headers.has_key(CONTENT_TYPE) and headers[CONTENT_TYPE] is not None:
70 | sign_to_string += headers[CONTENT_TYPE]
71 | sign_to_string += HEADER_SEPARATOR
72 | if headers.has_key(DATE) and headers[DATE] is not None:
73 | sign_to_string += headers[DATE]
74 | sign_to_string += HEADER_SEPARATOR
75 | uri = replace_occupied_parameters(uri_pattern, paths)
76 | sign_to_string += build_canonical_headers(headers, "x-acs-")
77 | sign_to_string += __build_query_string(uri, queries)
78 | return sign_to_string
79 |
80 | def replace_occupied_parameters(uri_pattern, paths):
81 | result = uri_pattern
82 | if paths is not None:
83 | for (key, value) in paths.items():
84 | target = "[" + key + "]"
85 | result = result.replace(target, value)
86 | return result
87 |
88 | # change the give headerBegin to the lower() which in the headers
89 | # and change it to key.lower():value
90 | def build_canonical_headers(headers, header_begin):
91 | result = ""
92 | unsort_map = dict()
93 | for (key, value) in headers.iteritems():
94 | if key.lower().find(header_begin) >= 0:
95 | unsort_map[key.lower()] = value
96 | sort_map = sorted(unsort_map.items(), key=lambda d: d[0])
97 | for (key, value) in sort_map:
98 | result += key + ":" +value
99 | result += HEADER_SEPARATOR
100 | return result
101 |
102 | def split_sub_resource(uri):
103 | return uri.split("?")
104 |
105 | def __build_query_string(uri, queries):
106 | uri_parts = split_sub_resource(uri)
107 | if len(uri_parts) >1 and uri_parts[1] is not None:
108 | queries[uri_parts[1]] = None
109 | query_builder = uri_parts[0]
110 | sorted_map = sorted(queries.items(), key=lambda queries:queries[0])
111 | if len(sorted_map) > 0:
112 | query_builder += "?"
113 | for (k,v) in sorted_map:
114 | query_builder += k
115 | if v is not None:
116 | query_builder += "="
117 | query_builder += str(v)
118 | query_builder += QUERY_SEPARATOR
119 | if query_builder.endswith(QUERY_SEPARATOR):
120 | query_builder = query_builder[0:(len(query_builder)-1)]
121 | return query_builder
122 |
123 | def get_signature(queries, access_key, secret, format, headers, uri_pattern, paths, method, signer=mac1):
124 | headers = refresh_sign_parameters(parameters=headers, access_key_id=access_key,format=format)
125 | sign_to_string = compose_string_to_sign(method=method, queries=queries, headers=headers, uri_pattern=uri_pattern, paths=paths)
126 | signature = signer.get_sign_string(sign_to_string, secret=secret)
127 | return signature
128 |
129 | def get_signature_headers(queries, access_key, secret, format, headers, uri_pattern, paths, method, signer=mac1):
130 | signature = get_signature(queries, access_key, secret, format, headers, uri_pattern, paths, method, signer)
131 | headers["Authorization"] = "acs "+access_key+":"+signature
132 | return headers
133 |
134 | def get_url(uri_pattern, queries, path_parameters):
135 | url = ""
136 | url += replace_occupied_parameters(uri_pattern, path_parameters)
137 | if not url.endswith("?"):
138 | url += "?"
139 | url += parse.urlencode(queries)
140 | if url.endswith("?"):
141 | url = url[0:(len(url)-1)]
142 | return url
143 |
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/rpc_signature_composer.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 | import os
22 | import sys
23 |
24 | parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
25 | sys.path.insert(0, parentdir)
26 | from . import sha_hmac1 as mac1
27 | from urllib import parse, request
28 | from ..utils import parameter_helper as helper
29 |
30 |
31 |
32 | def __init__():
33 | pass
34 |
35 |
36 | # this function will append the necessary parameters for signer process.
37 | # parameters: the orignal parameters
38 | # signer: sha_hmac1 or sha_hmac256
39 | # accessKeyId: this is aliyun_access_key_id
40 | # format: XML or JSON
41 | def __refresh_sign_parameters(parameters, access_key_id, accept_format="JSON", signer=mac1):
42 | if parameters is None or not isinstance(parameters, dict):
43 | parameters = dict()
44 | parameters["Timestamp"] = helper.get_iso_8061_date()
45 | parameters["SignatureMethod"] = signer.get_signer_name()
46 | parameters["SignatureVersion"] = signer.get_singer_version()
47 | parameters["SignatureNonce"] = helper.get_uuid()
48 | parameters["AccessKeyId"] = access_key_id
49 | if accept_format is not None:
50 | parameters["Format"] = accept_format
51 | return parameters
52 |
53 |
54 | def __pop_standard_urlencode(query):
55 | ret = parse.urlencode(query)
56 | ret = ret.replace('+', '%20')
57 | ret = ret.replace('*', '%2A')
58 | ret = ret.replace('%7E', '~')
59 | return ret
60 |
61 |
62 | def __compose_string_to_sign(method, queries):
63 | canonicalized_query_string = ""
64 | sorted_parameters = sorted(queries.items(), key=lambda queries: queries[0])
65 | string_to_sign = method + "&%2F&" + request.pathname2url(__pop_standard_urlencode(sorted_parameters))
66 | return string_to_sign.encode('utf-8')
67 |
68 |
69 | def __get_signature(string_to_sign, secret, signer=mac1):
70 | return signer.get_sign_string(string_to_sign, secret + '&')
71 |
72 |
73 | def get_signed_url(params, ak, secret, accept_format, method, signer=mac1):
74 | sign_params = __refresh_sign_parameters(params, ak, accept_format, signer)
75 | string_to_sign = __compose_string_to_sign(method, sign_params)
76 | signature = __get_signature(string_to_sign, secret, signer)
77 | sign_params['Signature'] = signature
78 | url = '/?' + __pop_standard_urlencode(sign_params)
79 | return url
80 |
81 |
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/sha_hmac1.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 |
22 | import hashlib
23 | import hmac
24 | import base64
25 |
26 |
27 | def get_sign_string(source, secret):
28 | h = hmac.new(bytes(secret, 'utf-8'), source, hashlib.sha1)
29 | signature = base64.encodebytes(h.digest()).strip()
30 | return signature
31 |
32 |
33 | def get_signer_name():
34 | return "HMAC-SHA1"
35 |
36 |
37 | def get_singer_version():
38 | return "1.0"
39 |
40 |
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/sha_hmac256.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 |
22 | import hmac
23 | import hashlib
24 | import base64
25 |
26 | class ShaHmac256:
27 | def __init__(self):
28 | pass
29 |
30 | def get_sign_string(self, source, accessSecret):
31 | h = hmac.new(accessSecret, source, hashlib.sha256)
32 | signature = base64.encodestring(h.digest()).strip()
33 | return signature
34 |
35 | def get_signer_name(self):
36 | return "HMAC-SHA256"
37 |
38 | def get_singer_version(self):
39 | return "1.0"
40 |
--------------------------------------------------------------------------------
/aliyunsdkcore/auth/url_encoder.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | #coding=utf-8
21 | from urllib import parse
22 | import sys
23 |
24 | """
25 | Acs url encoder module.
26 |
27 | Created on 9/19/2017
28 |
29 | @author: guangyao
30 | """
31 |
32 |
33 | def get_encode_str(params):
34 | """
35 | transforms parameters to encoded string
36 | :param params: dict parameters
37 | :return: string
38 | """
39 | list_params = sorted(params.iteritems(), key=lambda d: d[0])
40 | encode_str = parse.urlencode(list_params)
41 | if sys.stdin.encoding is None:
42 | res = parse.quote(encode_str.decode('cp936').encode('utf8'), '')
43 | else:
44 | res = parse.quote(encode_str.decode(sys.stdin.encoding).encode('utf8'), '')
45 | res = res.replace("+","%20")
46 | res = res.replace("*","%2A")
47 | res = res.replace("%7E","~")
48 | return res
--------------------------------------------------------------------------------
/aliyunsdkcore/client.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | # coding=utf-8
21 | import os
22 | import sys
23 | import http.client as httplib
24 | import warnings
25 | warnings.filterwarnings("once", category=DeprecationWarning)
26 |
27 | try:
28 | import json
29 | except ImportError:
30 | import simplejson as json
31 |
32 | from .profile import region_provider
33 | from .profile.location_service import LocationService
34 | from .acs_exception.exceptions import ClientException
35 | from .acs_exception.exceptions import ServerException
36 | from .acs_exception import error_code, error_msg
37 | from .http_service.http_response import HttpResponse
38 | from .request import AcsRequest
39 |
40 | """
41 | Acs default client module.
42 |
43 | Created on 9/19/2017
44 |
45 | @author: guangyao
46 | """
47 |
48 |
49 | class AcsClient:
50 | def __init__(self, ak, secret, region_id, auto_retry=True, max_retry_time=3, user_agent=None, port=80):
51 | """
52 | constructor for AcsClient
53 | :param ak: String, access key id
54 | :param secret: String, access key secret
55 | :param region_id: String, region id
56 | :param auto_retry: Boolean
57 | :param max_retry_time: Number
58 | :return:
59 | """
60 | self.__max_retry_num = max_retry_time
61 | self.__auto_retry = auto_retry
62 | self.__ak = ak
63 | self.__secret = secret
64 | self.__region_id = region_id
65 | self.__user_agent = user_agent
66 | self._port = port
67 | self._location_service = LocationService(self)
68 | self._url_test_flag = False # if true, do_action() will throw a ClientException that contains URL
69 |
70 | def get_region_id(self):
71 | """
72 |
73 | :return: String
74 | """
75 | return self.__region_id
76 |
77 | def get_access_key(self):
78 | """
79 |
80 | :return: String
81 | """
82 | return self.__ak
83 |
84 | def get_access_secret(self):
85 | """
86 |
87 | :return: String
88 | """
89 | return self.__secret
90 |
91 | def is_auto_retry(self):
92 | """
93 |
94 | :return:Boolean
95 | """
96 | return self.__auto_retry
97 |
98 | def get_max_retry_num(self):
99 | """
100 |
101 | :return: Number
102 | """
103 | return self.__max_retry_num
104 |
105 | def get_user_agent(self):
106 | return self.__user_agent
107 |
108 | def set_region_id(self, region):
109 | self.__region_id = region
110 |
111 | def set_access_key(self, ak):
112 | self.__ak = ak
113 |
114 | def set_access_secret(self, secret):
115 | self.__secret = secret
116 |
117 | def set_max_retry_num(self, num):
118 | """
119 | set auto retry number
120 | :param num: Numbers
121 | :return: None
122 | """
123 | self.__max_retry_num = num
124 |
125 | def set_auto_retry(self, flag):
126 | """
127 | set whether or not the client perform auto-retry
128 | :param flag: Booleans
129 | :return: None
130 | """
131 | self.__auto_retry = flag
132 |
133 | def set_user_agent(self, agent):
134 | """
135 | User agent set to client will overwrite the request setting.
136 | :param agent:
137 | :return:
138 | """
139 | self.__user_agent = agent
140 |
141 | def get_location_service(self):
142 | return self._location_service
143 |
144 | def get_port(self):
145 | return self._port
146 |
147 | def _resolve_endpoint(self, request):
148 | endpoint = None
149 | if request.get_location_service_code() is not None:
150 | endpoint = self._location_service.find_product_domain(self.get_region_id(), request.get_location_service_code())
151 | if endpoint is None:
152 | endpoint = region_provider.find_product_domain(self.get_region_id(), request.get_product())
153 | if endpoint is None:
154 | raise ClientException(error_code.SDK_INVALID_REGION_ID, error_msg.get_msg('SDK_INVALID_REGION_ID'))
155 | if not isinstance(request, AcsRequest):
156 | raise ClientException(error_code.SDK_INVALID_REQUEST, error_msg.get_msg('SDK_INVALID_REQUEST'))
157 | return endpoint
158 |
159 | def _make_http_response(self, endpoint, request):
160 | content = request.get_content()
161 | method = request.get_method()
162 | header = request.get_signed_header(self.get_region_id(), self.get_access_key(),
163 | self.get_access_secret())
164 | if self.get_user_agent() is not None:
165 | header['User-Agent'] = self.get_user_agent()
166 | header['x-sdk-client'] = 'python/2.0.0'
167 | if header is None:
168 | header = {}
169 |
170 | protocol = request.get_protocol_type()
171 | url = request.get_url(self.get_region_id(), self.get_access_key(), self.get_access_secret())
172 | response = HttpResponse(endpoint, url, method, header, protocol, content,
173 | self._port)
174 | return response
175 |
176 | def _implementation_of_do_action(self, request):
177 | endpoint = self._resolve_endpoint(request)
178 | http_response = self._make_http_response(endpoint, request)
179 | if self._url_test_flag:
180 | raise ClientException("URLTestFlagIsSet", http_response.get_url())
181 |
182 | # Do the actual network thing
183 | try:
184 | status, headers, body = http_response.get_response_object()
185 | return status, headers, body
186 | except IOError as e:
187 | raise ClientException(error_code.SDK_SERVER_UNREACHABLE, error_msg.get_msg('SDK_SERVER_UNREACHABLE') + ': ' + str(e))
188 | except AttributeError:
189 | raise ClientException(error_code.SDK_INVALID_REQUEST, error_msg.get_msg('SDK_INVALID_REQUEST'))
190 |
191 | def _parse_error_info_from_response_body(self, response_body):
192 | try:
193 | body_obj = json.loads(response_body)
194 | if 'Code' in body_obj and 'Message' in body_obj:
195 | return (body_obj['Code'], body_obj['Message'])
196 | else:
197 | return (error_code.SDK_UNKNOWN_SERVER_ERROR, error_msg.get_msg('SDK_UNKNOWN_SERVER_ERROR'))
198 | except ValueError:
199 | # failed to parse body as json format
200 | return (error_code.SDK_UNKNOWN_SERVER_ERROR, error_msg.get_msg('SDK_UNKNOWN_SERVER_ERROR'))
201 |
202 | def do_action_with_exception(self, acs_request):
203 |
204 | # set server response format as json, because thie function will
205 | # parse the response so which format doesn't matter
206 | acs_request.set_accept_format('json')
207 |
208 | status, headers, body = self._implementation_of_do_action(acs_request)
209 |
210 | request_id = None
211 | ret = body
212 |
213 | try:
214 | body_obj = json.loads(str(body))
215 | request_id = body_obj.get('RequestId')
216 | ret = body_obj
217 | except ValueError:
218 | # in case the response body is not a json string, return the raw data instead
219 | pass
220 |
221 | if status != 200:
222 | server_error_code, server_error_message = self._parse_error_info_from_response_body(body)
223 | raise ServerException(server_error_code, server_error_message, http_status=status, request_id=request_id)
224 |
225 | return body
226 |
227 | def do_action(self, acs_request):
228 | warnings.warn("do_action() method is deprecated, please use do_action_with_exception() instead.", DeprecationWarning)
229 | status, headers, body = self._implementation_of_do_action(acs_request)
230 | return body
231 |
232 | def get_response(self, acs_request):
233 | warnings.warn("get_response() method is deprecated, please use do_action_with_exception() instead.", DeprecationWarning)
234 | return self._implementation_of_do_action(acs_request)
235 |
236 |
--------------------------------------------------------------------------------
/aliyunsdkcore/http_service/__init__.py:
--------------------------------------------------------------------------------
1 | __author__='guangyao'
2 |
--------------------------------------------------------------------------------
/aliyunsdkcore/http_service/format_type.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 |
22 | XML = 'XML'
23 | JSON = 'JSON'
24 | RAW = 'RAW'
25 | APPLICATION_XML = 'application/xml'
26 | APPLICATION_JSON = 'application/json'
27 | APPLICATION_OCTET_STREAM = 'application/octet-stream'
28 | TEXT_XML = 'text/xml'
29 |
30 | def map_format_to_accept(format):
31 | if format == XML:
32 | return APPLICATION_XML
33 | if format == JSON:
34 | return APPLICATION_JSON
35 | return APPLICATION_OCTET_STREAM
36 |
37 | def map_accept_to_format(accept):
38 | if accept.lower() == APPLICATION_XML or accept.lower() == TEXT_XML:
39 | return XML
40 | if accept.lower() == APPLICATION_JSON:
41 | return JSON
42 | return RAW
43 |
44 | if __name__ == "__main__":
45 | print(map_format_to_accept(XML))
46 | print(map_format_to_accept(JSON))
47 | print(map_format_to_accept(RAW))
48 | print(map_accept_to_format("application/xml"))
49 | print(map_accept_to_format("text/xml"))
50 | print(map_accept_to_format("application/json"))
51 |
52 |
53 |
--------------------------------------------------------------------------------
/aliyunsdkcore/http_service/http_request.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 | import os
22 | import sys
23 |
24 | parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
25 | sys.path.insert(0,parentdir)
26 | from . import format_type
27 | from ..utils import parameter_helper as helper
28 |
29 |
30 | class HttpRequest:
31 |
32 | content_md5 = "Content-MD5"
33 | content_length = "Content-Length"
34 | content_type = "Content-Type"
35 |
36 | def __init__(self, host="", url="/", method=None, headers={}):
37 | self.__host = host
38 | self.__url = url
39 | self.__method = method
40 | self.__content_type = ""
41 | self.__content = ""
42 | self.__encoding = ""
43 | self.__headers = headers
44 | self.__body = None
45 |
46 | def get_host(self):
47 | return self.__host
48 |
49 | def set_host(self, host):
50 | self.__host = host
51 |
52 | def get_body(self):
53 | return self.__body
54 |
55 | def set_body(self, body):
56 | self.__body = body
57 |
58 | def get_url(self):
59 | return self.__url
60 |
61 | def set_url(self, url):
62 | self.__url = url
63 |
64 | def get_encoding(self):
65 | return self.__encoding
66 |
67 | def set_encoding(self, encoding):
68 | self.__encoding = encoding
69 |
70 | def get_content_type(self):
71 | return self.__content_type
72 |
73 | def set_content_type(self, content_type):
74 | self.__content_type = content_type
75 |
76 | def get_method(self):
77 | return self.__method
78 |
79 | def set_method(self, method):
80 | self.__method = method
81 |
82 | def get_content(self):
83 | return self.__content
84 |
85 | def get_header_value(self, name):
86 | return self.__headers[name]
87 |
88 | def put_header_parameter(self, key, value):
89 | if key is not None and value is not None:
90 | self.__headers[key] = value
91 |
92 | def md5_sum(self, content):
93 | return helper.md5_sum(content)
94 |
95 | def set_content(self, content, encoding, format):
96 | tmp = dict()
97 | if content is None:
98 | self.__headers.pop(self.content_md5)
99 | self.__headers.pop(self.content_length)
100 | self.__headers.pop(self.content_type)
101 | self.__content_type = None
102 | self.__content = None
103 | self.__encoding = None
104 | return
105 | str_md5 = self.md5_sum(content)
106 | content_length = len(content)
107 | content_type = format_type.RAW
108 | if format is None:
109 | content_type = format
110 | self.__headers[self.content_md5] = str_md5
111 | self.__headers[self.content_length] = content_length
112 | self.__headers[self.content_type] = content_type
113 | self.__content = content
114 | self.__encoding = encoding
115 |
116 | def get_headers(self):
117 | return self.__headers
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/aliyunsdkcore/http_service/http_response.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 | __author__='guangyao'
20 | import http.client as httplib
21 |
22 | from .http_request import HttpRequest
23 | from . import protocol_type as PT
24 |
25 |
26 | class HttpResponse(HttpRequest):
27 | def __init__(self,host="",url="/",method="GET",headers={},protocol=PT.HTTP,content= None, port=None,key_file=None,cert_file=None):
28 | HttpRequest.__init__(self,host=host,url=url,method=method,headers=headers)
29 | self.__ssl_enable=False
30 | if protocol is PT.HTTPS:
31 | self.__ssl_enable=True
32 | self.__key_file=key_file
33 | self.__cert_file=cert_file
34 | self.__port=port
35 | self.__connection=None
36 | self.set_body(content)
37 |
38 | def set_ssl_enable(self,enable):
39 | self.__ssl_enable=enable
40 |
41 | def get_ssl_enabled(self):
42 | return self.__ssl_enable
43 |
44 | def get_response(self):
45 | if self.get_ssl_enabled():
46 | return self.get_https_response()
47 | else:
48 | return self.get_http_response()
49 |
50 |
51 | def get_response_object(self):
52 | if self.get_ssl_enabled():
53 | return self.get_https_response_object()
54 | else:
55 | return self.get_http_response_object()
56 |
57 |
58 | def get_http_response(self):
59 | if self.__port is None or self.__port == "":
60 | self.__port = 80
61 | try:
62 | self.__connection=httplib.HTTPConnection(self.get_host(),self.__port)
63 | self.__connection.connect()
64 | self.__connection.request(method=self.get_method(),url=self.get_url(),body=self.get_body(),
65 | headers=self.get_headers())
66 | response=self.__connection.getresponse()
67 | return response.getheaders(), response.read()
68 | finally:
69 | self.__close_connection()
70 |
71 |
72 | def get_http_response_object(self):
73 | if self.__port is None or self.__port == "":
74 | self.__port = 80
75 | try:
76 | self.__connection=httplib.HTTPConnection(self.get_host(),self.__port)
77 | self.__connection.connect()
78 | self.__connection.request(method=self.get_method(),url=self.get_url(),body=self.get_body(),
79 | headers=self.get_headers())
80 | response=self.__connection.getresponse()
81 | return response.status, response.getheaders(), response.read()
82 | finally:
83 | self.__close_connection()
84 |
85 |
86 | def get_https_response(self):
87 | if self.__port is None or self.__port == "":
88 | self.__port = 443
89 | try:
90 | self.__port = 443
91 | self.__connection=httplib.HTTPSConnection(self.get_host(),self.__port,cert_file=self.__cert_file,
92 | key_file=self.__key_file)
93 | self.__connection.connect()
94 | self.__connection.request(method=self.get_method(),url=self.get_url(),body=self.get_body(),
95 | headers=self.get_headers())
96 | response=self.__connection.getresponse()
97 | return response.getheaders(), response.read()
98 | finally:
99 | self.__close_connection()
100 |
101 |
102 | def get_https_response_object(self):
103 | if self.__port is None or self.__port == "":
104 | self.__port = 443
105 | try:
106 | self.__port = 443
107 | self.__connection=httplib.HTTPSConnection(self.get_host(),self.__port,cert_file=self.__cert_file,
108 | key_file=self.__key_file)
109 | self.__connection.connect()
110 | self.__connection.request(method=self.get_method(),url=self.get_url(),body=self.get_body(),
111 | headers=self.get_headers())
112 | response=self.__connection.getresponse()
113 | return response.status, response.getheaders(), response.read()
114 | finally:
115 | self.__close_connection()
116 |
117 |
118 | def __close_connection(self):
119 | if self.__connection is not None:
120 | self.__connection.close()
121 | self.__connection = None
122 |
123 |
124 |
--------------------------------------------------------------------------------
/aliyunsdkcore/http_service/method_type.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 |
22 | GET = "GET"
23 | PUT = "PUT"
24 | POST = "POST"
25 | DELETE = "DELETE"
26 | HEAD = "HEAD"
27 | OPTIONS = "OPTIONS"
28 |
--------------------------------------------------------------------------------
/aliyunsdkcore/http_service/protocol_type.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 |
22 | HTTP = "http"
23 | HTTPS = "https"
24 |
--------------------------------------------------------------------------------
/aliyunsdkcore/profile/__init__.py:
--------------------------------------------------------------------------------
1 | __author__='guangyao'
2 |
--------------------------------------------------------------------------------
/aliyunsdkcore/profile/location_service.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | #coding=utf-8
21 |
22 | import os
23 | import sys
24 | import json
25 | parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
26 | sys.path.insert(0, parent_dir)
27 |
28 | from ..request import RpcRequest
29 | from ..http_service.http_response import HttpResponse
30 | from ..acs_exception import exceptions as exs
31 | from ..acs_exception import error_code, error_msg
32 |
33 | LOCATION_SERVICE_PRODUCT_NAME="Location"
34 | LOCATION_SERVICE_DOMAIN="location.aliyuncs.com"
35 | LOCATION_SERVICE_VERSION="2015-06-12"
36 | LOCATION_SERVICE_DESCRIBE_ENDPOINT_ACTION="DescribeEndpoint"
37 | LOCATION_SERVICE_REGION="cn-hangzhou"
38 |
39 | class DescribeEndpointRequest(RpcRequest):
40 |
41 | def __init__(self, product_name, version, action_name, region_id, service_code):
42 | RpcRequest.__init__(self, product_name, version, action_name, 'hhh')
43 |
44 | self.add_query_param("Id", region_id)
45 | self.add_query_param("ServiceCode", service_code)
46 | self.set_accept_format("JSON")
47 |
48 |
49 | class LocationService:
50 |
51 | def __init__(self, client):
52 | self.__clinetRef = client
53 | self.__cache = {}
54 | self.__service_product_name = LOCATION_SERVICE_PRODUCT_NAME
55 | self.__service_domain = LOCATION_SERVICE_DOMAIN
56 | self.__service_version = LOCATION_SERVICE_VERSION
57 | self.__service_region = LOCATION_SERVICE_REGION
58 | self.__service_action = LOCATION_SERVICE_DESCRIBE_ENDPOINT_ACTION
59 |
60 | def set_location_service_attr(self, region=None, product_name=None, domain=None,version=None):
61 | if region is not None:
62 | self.__service_region = region
63 |
64 | if product_name is not None:
65 | self.__service_product_name = product_name
66 |
67 | if domain is not None:
68 | self.__service_domain = domain
69 |
70 | if version is not None:
71 | self.__service_version = version
72 |
73 | def find_product_domain(self, region_id, service_code):
74 | key = "%s_&_%s" %(region_id, service_code)
75 | domain = self.__cache.get(key)
76 | if domain is None:
77 | domain = self.find_product_domain_from_location_service(region_id, service_code)
78 | if domain is not None:
79 | self.__cache[key] = domain
80 |
81 | return domain
82 |
83 |
84 | def find_product_domain_from_location_service(self, region_id, service_code):
85 |
86 | request = DescribeEndpointRequest(self.__service_product_name,
87 | self.__service_version,
88 | self.__service_action,
89 | region_id,
90 | service_code)
91 | try:
92 | content = request.get_content()
93 | method = request.get_method()
94 | header = request.get_signed_header(self.__service_region, self.__clinetRef.get_access_key(),
95 | self.__clinetRef.get_access_secret())
96 | if self.__clinetRef.get_user_agent() is not None:
97 | header['User-Agent'] = self.__clinetRef.get_user_agent()
98 | header['x-sdk-client'] = 'python/2.0.0'
99 | protocol = request.get_protocol_type()
100 | url = request.get_url(self.__service_region, self.__clinetRef.get_access_key(),
101 | self.__clinetRef.get_access_secret())
102 | response = HttpResponse(self.__service_domain, url, method, {} if header is None else header, protocol, content,
103 | self.__clinetRef.get_port())
104 |
105 | status, header, body = response.get_response_object()
106 | result = json.loads(body)
107 | if status == 200:
108 | return result.get('Endpoint')
109 | elif status >= 400 and status < 500:
110 | # print "serviceCode=" + service_code + " get location error! code=" + result.get('Code') +", message =" + result.get('Message')
111 | return None
112 | elif status >= 500:
113 | raise exs.ServerException(result.get('Code'), result.get('Message'))
114 | else:
115 | raise exs.ClientException(result.get('Code'), result.get('Message'))
116 | except IOError:
117 | raise exs.ClientException(error_code.SDK_SERVER_UNREACHABLE, error_msg.get_msg('SDK_SERVER_UNREACHABLE'))
118 | except AttributeError:
119 | raise exs.ClientException(error_code.SDK_INVALID_REQUEST, error_msg.get_msg('SDK_INVALID_REQUEST'))
120 |
--------------------------------------------------------------------------------
/aliyunsdkcore/profile/region_provider.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | #coding=utf-8
21 |
22 | import os
23 | import sys
24 |
25 | parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
26 | sys.path.insert(0, parent_dir)
27 | from ..acs_exception import error_code, error_msg
28 | from ..acs_exception.exceptions import ClientException
29 | from xml.dom.minidom import parse
30 |
31 |
32 | """
33 | Region&Endpoint provider module.
34 |
35 | Created on 9/19/2017
36 |
37 | @author: guangyao
38 | """
39 |
40 | #endpoint list
41 | __endpoints = dict()
42 |
43 | #load endpoints info from endpoints.xml file and parse to dict.
44 | __endpoints_file = os.path.join(parent_dir, 'endpoints.xml')
45 | try:
46 | DOMTree = parse(__endpoints_file)
47 | root = DOMTree.documentElement
48 | eps = root.getElementsByTagName('Endpoint')
49 | for endpoint in eps:
50 | region_list = []
51 | product_list = []
52 | regions = endpoint.getElementsByTagName('RegionId')
53 | products = endpoint.getElementsByTagName('Product')
54 | for region in regions:
55 | region_list.append(region.childNodes[0].nodeValue)
56 | for product in products:
57 | name_node = product.getElementsByTagName('ProductName')[0]
58 | name = name_node.childNodes[0].nodeValue
59 | domain_node = product.getElementsByTagName('DomainName')[0]
60 | domain = domain_node.childNodes[0].nodeValue
61 | product_list.append({name: domain})
62 |
63 | __endpoints[endpoint.getAttribute('name')] = dict(regions=region_list, products=product_list)
64 |
65 | except Exception as ex:
66 | raise ClientException(error_code.SDK_MISSING_ENDPOINTS_FILER, error_msg.get_msg('SDK_MISSING_ENDPOINTS_FILER'))
67 |
68 |
69 | def find_product_domain(regionid, prod_name):
70 | """
71 | Fetch endpoint url with given region id, product name and endpoint list
72 | :param regionid: region id
73 | :param product: product name
74 | :param endpoints: product list
75 | :return: endpoint url
76 | """
77 | if regionid is not None and product is not None:
78 | for point in __endpoints:
79 | point_info = __endpoints.get(point)
80 | if regionid in point_info.get('regions'):
81 | prod_info = point_info.get('products')
82 | for prod in prod_info:
83 | if prod_name in prod:
84 | return prod.get(prod_name)
85 | return None
86 |
87 | def modify_point(product_name, region_id, end_point):
88 | for point in __endpoints:
89 | point_info = __endpoints.get(point)
90 | region_list = point_info.get('regions')
91 | products = point_info.get('products')
92 |
93 | if region_id is not None and region_id not in region_list:
94 | region_list.append(region_id)
95 |
96 | if end_point is not None:
97 | product_exit = 0
98 | for prod in products:
99 | if product_name in prod:
100 | prod[product_name] = end_point
101 | product_exit = 1
102 | if product_exit == 0:
103 | item = dict()
104 | item[product_name] = end_point
105 | products.append(item)
106 |
107 | __mdict = dict()
108 | __mdict['regions'] = region_list
109 | __mdict['products'] = products
110 | __endpoints[point] = __mdict
111 | convert_dict_to_endpointsxml(__endpoints)
112 |
113 | def convert_dict_to_endpointsxml(mdict):
114 | regions = list()
115 | products = list()
116 | for point in mdict:
117 | point_info = mdict.get(point)
118 | regions = point_info.get('regions')
119 | products = point_info.get('products')
120 | content = ''
121 | prefix = '\n\n\n'
122 | endfix = '\n\n'
123 | content += prefix
124 | content += '\n'
125 | for item in regions:
126 | content += ''+item+'\n'
127 | content += '\n'+'\n'
128 | for item in products:
129 | content += '\n'
130 | content += ''+list(item.keys())[0]+'\n'
131 | content += ''+item[list(item.keys())[0]]+'\n'
132 | content += '\n'
133 | content += ''
134 | content += endfix
135 | #print content
136 | if not os.path.isfile(__endpoints_file):
137 | _createFile(__endpoints_file)
138 | f = open(__endpoints_file, 'w')
139 | try:
140 | f.write(''.join(content))
141 | except Exception as e:
142 | print(e)
143 | print("Please confirm you has use sudo + cmd")
144 | finally:
145 | f.close()
146 |
147 | def _createFile(filename):
148 | namePath = os.path.split(filename)[0]
149 | if not os.path.isdir(namePath):
150 | os.makedirs(namePath)
151 | with os.fdopen(os.open(filename,
152 | os.O_WRONLY | os.O_CREAT, 0o600), 'w'):
153 | pass
154 |
155 | if __name__ == '__main__':
156 | print(find_product_domain('cn-hangzhou', 'Rds'))
157 | modify_point('ecs', 'cn-beijing-2', 'ecs.aliyuncs.com')
158 |
--------------------------------------------------------------------------------
/aliyunsdkcore/request.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | #
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 |
20 | # coding=utf-8
21 |
22 | import os
23 | import sys
24 |
25 | parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
26 | sys.path.insert(0, parent_dir)
27 |
28 | from .http_service import protocol_type as PT
29 | from .http_service import method_type as MT
30 | from .http_service import format_type as FT
31 | from .auth import rpc_signature_composer as rpc_signer
32 | from .auth import roa_signature_composer as roa_signer
33 | from .auth import oss_signature_composer as oss_signer
34 | from .auth import md5_tool
35 | import abc
36 | import base64
37 |
38 | """
39 | Acs request model.
40 |
41 | Created on 9/19/2017
42 |
43 | @author: guangyao
44 | """
45 |
46 | STYLE_RPC = 'RPC'
47 | STYLE_ROA = 'ROA'
48 | STYLE_OSS = 'OSS'
49 |
50 |
51 | class AcsRequest:
52 | """
53 | Acs request base class. This class wraps up common parameters for a request.
54 | """
55 | __metaclass__ = abc.ABCMeta
56 |
57 | def __init__(self, product, version=None,
58 | action_name=None,
59 | location_service_code=None,
60 | accept_format=None,
61 | protocol_type=PT.HTTP,
62 | method=None):
63 | """
64 |
65 | :param product:
66 | :param version:
67 | :param action_name:
68 | :param params:
69 | :param resource_owner_account:
70 | :param protocol_type:
71 | :param accept_format:
72 | :return:
73 | """
74 | self.__version = version
75 | self.__product = product
76 | self.__action_name = action_name
77 | self.__protocol_type = protocol_type
78 | self.__accept_format = accept_format
79 | self.__params = {}
80 | self.__method = method
81 | self.__header = {}
82 | self.__uri_pattern = None
83 | self.__uri_params = None
84 | self.__content = None
85 | self.__location_service_code = location_service_code
86 |
87 | def add_query_param(self, k, v):
88 | if self.__params is None:
89 | self.__params = {}
90 | self.__params[k] = v
91 |
92 | def get_uri_pattern(self):
93 | return self.__uri_pattern
94 |
95 | def get_uri_params(self):
96 | return self.__uri_params
97 |
98 | def get_product(self):
99 | return self.__product
100 |
101 | def get_version(self):
102 | return self.__version
103 |
104 | def get_action_name(self):
105 | return self.__action_name
106 |
107 | def get_accept_format(self):
108 | return self.__accept_format
109 |
110 | def get_protocol_type(self):
111 | return self.__protocol_type
112 |
113 | def get_query_params(self):
114 | return self.__params
115 |
116 | def get_method(self):
117 | return self.__method
118 |
119 | def set_uri_pattern(self, pattern):
120 | self.__uri_pattern = pattern
121 |
122 | def set_uri_params(self, params):
123 | self.__uri_params = params
124 |
125 | def set_method(self, method):
126 | self.__method = method
127 |
128 | def set_product(self, product):
129 | self.__product = product
130 |
131 | def set_version(self, version):
132 | self.__version = version
133 |
134 | def set_action_name(self, action_name):
135 | self.__action_name = action_name
136 |
137 | def set_accept_format(self, accept_format):
138 | self.__accept_format = accept_format
139 |
140 | def set_protocol_type(self, protocol_type):
141 | self.__protocol_type = protocol_type
142 |
143 | def set_query_params(self, params):
144 | self.__params = params
145 |
146 | def set_content(self, content):
147 | """
148 |
149 | :param content: ByteArray
150 | :return:
151 | """
152 | self.__content = content
153 |
154 | def get_content(self):
155 | """
156 |
157 | :return: ByteArray
158 | """
159 | return self.__content
160 |
161 | def get_headers(self):
162 | """
163 |
164 | :return: Dict
165 | """
166 | return self.__header
167 |
168 | def set_headers(self, headers):
169 | """
170 |
171 | :param headers: Dict
172 | :return:
173 | """
174 | self.__header = headers
175 |
176 | def add_header(self, k, v):
177 | if self.__header is None:
178 | self.__header = dict(k=v)
179 | else:
180 | self.__header[k] = v
181 |
182 | def set_user_agent(self, agent):
183 | self.add_header('User-Agent', agent)
184 |
185 | def set_location_service_code(self, location_service_code):
186 | self.__location_service_code = location_service_code
187 |
188 | def get_location_service_code(self):
189 | return self.__location_service_code
190 |
191 | @abc.abstractmethod
192 | def get_style(self):
193 | pass
194 |
195 | @abc.abstractmethod
196 | def get_url(self, region_id, ak, secret):
197 | pass
198 |
199 | @abc.abstractmethod
200 | def get_signed_header(self, region_id, ak, secret):
201 | pass
202 |
203 |
204 | class RpcRequest(AcsRequest):
205 | """
206 | Class to compose an RPC style request with.
207 | """
208 |
209 | def __init__(self, product, version, action_name, location_service_code=None, format=None, protocol=None):
210 | AcsRequest.__init__(self, product, version, action_name, location_service_code, format, protocol, MT.GET)
211 | self.__style = STYLE_RPC
212 |
213 | def get_style(self):
214 | return self.__style
215 |
216 | def __get_sign_params(self):
217 | req_params = self.get_query_params()
218 | if req_params is None:
219 | req_params = {}
220 | req_params['Version'] = self.get_version()
221 | req_params['Action'] = self.get_action_name()
222 | req_params['Format'] = self.get_accept_format()
223 | return req_params
224 |
225 | def get_url(self, region_id, ak, secret):
226 | sign_params = self.__get_sign_params()
227 | if 'RegionId' not in sign_params.keys():
228 | sign_params['RegionId'] = region_id
229 | url = rpc_signer.get_signed_url(sign_params, ak, secret, self.get_accept_format(), self.get_method())
230 | return url
231 |
232 | def get_signed_header(self, region_id=None, ak=None, secret=None):
233 | return {}
234 |
235 |
236 | class RoaRequest(AcsRequest):
237 | """
238 | Class to compose an ROA style request with.
239 | """
240 |
241 | def __init__(self, product, version, action_name, location_service_code=None, method=None, headers=None, uri_pattern=None, path_params=None,
242 | protocol=None):
243 | """
244 |
245 | :param product: String, mandatory
246 | :param version: String, mandatory
247 | :param action_name: String, mandatory
248 | :param method: String
249 | :param headers: Dict
250 | :param uri_pattern: String
251 | :param path_params: Dict
252 | :param protocol: String
253 | :return:
254 | """
255 | AcsRequest.__init__(self, product, version, action_name, location_service_code, FT.RAW, protocol, method)
256 | self.__style = STYLE_ROA
257 | self.__method = method
258 | self.__header = headers
259 | self.__uri_pattern = uri_pattern
260 | self.__path_params = path_params
261 |
262 | def get_style(self):
263 | """
264 |
265 | :return: String
266 | """
267 | return self.__style
268 |
269 | def get_path_params(self):
270 | return self.__path_params
271 |
272 | def set_path_params(self, path_params):
273 | self.__path_params = path_params
274 |
275 | def add_path_param(self, k, v):
276 | if self.__path_params is None:
277 | self.__path_params = {}
278 | self.__path_params[k] = v
279 |
280 | def __get_sign_params(self):
281 | req_params = self.get_query_params()
282 | if req_params is None:
283 | req_params = {}
284 | req_params['Version'] = self.get_version()
285 | req_params['Action'] = self.get_action_name()
286 | req_params['Format'] = self.get_accept_format()
287 | return req_params
288 |
289 | def get_signed_header(self, region_id, ak, secret):
290 | """
291 | Generate signed header
292 | :param region_id: String
293 | :param ak: String
294 | :param secret: String
295 | :return: Dict
296 | """
297 | sign_params = self.get_query_params()
298 | if (self.get_content() is not None):
299 | md5_str = md5_tool.get_md5_base64_str(self.get_content())
300 | self.add_header('Content-MD5', md5_str)
301 | if 'RegionId' not in sign_params.keys():
302 | sign_params['RegionId'] = region_id
303 | signed_headers = roa_signer.get_signature_headers(sign_params, ak, secret,
304 | self.get_accept_format(),
305 | self.get_headers(),
306 | self.get_uri_pattern(),
307 | self.get_path_params(),
308 | self.get_method())
309 | return signed_headers
310 |
311 | def get_url(self, region_id, ak=None, secret=None):
312 | """
313 | Compose request url without domain
314 | :param region_id: String
315 | :return: String
316 | """
317 | sign_params = self.get_query_params()
318 | if region_id not in sign_params.keys():
319 | sign_params['RegionId'] = region_id
320 | url = roa_signer.get_url(self.get_uri_pattern(), sign_params, self.get_path_params())
321 | return url
322 |
323 |
324 | class OssRequest(AcsRequest):
325 | def __init__(self, product, version, action_name, location_service_code, bucket=None, method=None,
326 | headers=None, uri_pattern=None, path_params=None, protocol=None):
327 | """
328 |
329 | :param product: String, mandatory
330 | :param version: String, mandatory
331 | :param action_name: String, mandatory
332 | :param bucket: String
333 | :param method: String
334 | :param headers: Dict
335 | :param uri_pattern: String
336 | :param path_params: Dict
337 | :param protocol: String
338 | :return:
339 | """
340 | AcsRequest.__init__(self, product, version, action_name, location_service_code, FT.XML, protocol, method)
341 | self.__style = STYLE_OSS
342 | self.__bucket = bucket
343 | self.__method = method
344 | self.__header = headers
345 | self.__uri_pattern = uri_pattern
346 | self.__path_params = path_params
347 |
348 | def get_style(self):
349 | return self.__style
350 |
351 | def get_path_params(self):
352 | """
353 |
354 | :return: dict
355 | """
356 | return self.__path_params
357 |
358 | def set_path_params(self, path_params):
359 | self.__path_params = path_params
360 |
361 | def add_path_param(self, k, v):
362 | if self.__path_params is None:
363 | self.__path_params = {}
364 | self.__path_params[k] = v
365 |
366 | def __get_sign_params(self):
367 | req_params = self.get_query_params()
368 | if req_params is None:
369 | req_params = {}
370 | req_params['Version'] = self.get_version()
371 | req_params['Action'] = self.get_action_name()
372 | req_params['Format'] = self.get_accept_format()
373 | return req_params
374 |
375 | def get_signed_header(self, region_id, ak, secret, ):
376 | """
377 | Compose signed headers.
378 | :param region_id: String
379 | :param ak: String
380 | :param secret: String
381 | :return:
382 | """
383 | sign_params = self.get_query_params()
384 | if 'RegionId' not in sign_params.keys():
385 | sign_params['RegionId'] = region_id
386 | signed_headers = oss_signer.get_signature_headers(sign_params, ak, secret, self.get_accept_format(),
387 | self.get_headers(),
388 | self.get_uri_pattern(), self.get_path_params(),
389 | self.get_method(), self.__bucket)
390 | return signed_headers
391 |
392 | def get_url(self, region_id, ak=None, secret=None):
393 | """
394 | Generate request url without domain
395 | :param region_id: String
396 | :return: String
397 | """
398 | sign_params = self.get_query_params()
399 | if 'RegionId' not in sign_params.keys():
400 | sign_params['RegionId'] = region_id
401 | url = oss_signer.get_url(sign_params, self.get_uri_pattern(), self.get_path_params())
402 | return url
403 |
--------------------------------------------------------------------------------
/aliyunsdkcore/utils/__init__.py:
--------------------------------------------------------------------------------
1 | __author__='guangyao'
2 |
--------------------------------------------------------------------------------
/aliyunsdkcore/utils/parameter_helper.py:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 |
18 | #coding=utf-8
19 |
20 | __author__ = 'guangyao'
21 |
22 | import hashlib
23 | import base64
24 | import uuid
25 | import time
26 | from urllib import parse
27 | import sys
28 |
29 | TIME_ZONE = "GMT"
30 | FORMAT_ISO_8601 = "%Y-%m-%dT%H:%M:%SZ"
31 | FORMAT_RFC_2616 = "%a, %d %b %Y %X GMT"
32 |
33 | def get_uuid():
34 | return str(uuid.uuid4())
35 |
36 | def get_iso_8061_date():
37 | return time.strftime(FORMAT_ISO_8601, time.gmtime())
38 |
39 | def get_rfc_2616_date():
40 | return time.strftime(FORMAT_RFC_2616, time.gmtime())
41 |
42 | def md5_sum(content):
43 | return base64.standard_b64encode(hashlib.md5(content).digest())
44 |
45 | def percent_encode(encodeStr):
46 | encodeStr = str(encodeStr)
47 | if sys.stdin.encoding is None:
48 | res = parse.quote(encodeStr.decode('cp936').encode('utf8'), '')
49 | else:
50 | res = parse.quote(encodeStr.decode(sys.stdin.encoding).encode('utf8'), '')
51 | res = res.replace('+', '%20')
52 | res = res.replace('*', '%2A')
53 | res = res.replace('%7E', '~')
54 | return res
55 |
56 | if __name__ == "__main__":
57 | print(get_uuid())
58 | print(get_iso_8061_date())
59 | print(get_rfc_2616_date())
60 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [egg_info]
2 | tag_build =
3 | tag_date = 0
4 |
5 | [bdist_wheel]
6 | universal=1
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | '''
3 | Apache License
4 | Version 2.0, January 2004
5 | http://www.apache.org/licenses/
6 |
7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8 |
9 | 1. Definitions.
10 |
11 | "License" shall mean the terms and conditions for use, reproduction,
12 | and distribution as defined by Sections 1 through 9 of this document.
13 |
14 | "Licensor" shall mean the copyright owner or entity authorized by
15 | the copyright owner that is granting the License.
16 |
17 | "Legal Entity" shall mean the union of the acting entity and all
18 | other entities that control, are controlled by, or are under common
19 | control with that entity. For the purposes of this definition,
20 | "control" means (i) the power, direct or indirect, to cause the
21 | direction or management of such entity, whether by contract or
22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
23 | outstanding shares, or (iii) beneficial ownership of such entity.
24 |
25 | "You" (or "Your") shall mean an individual or Legal Entity
26 | exercising permissions granted by this License.
27 |
28 | "Source" form shall mean the preferred form for making modifications,
29 | including but not limited to software source code, documentation
30 | source, and configuration files.
31 |
32 | "Object" form shall mean any form resulting from mechanical
33 | transformation or translation of a Source form, including but
34 | not limited to compiled object code, generated documentation,
35 | and conversions to other media types.
36 |
37 | "Work" shall mean the work of authorship, whether in Source or
38 | Object form, made available under the License, as indicated by a
39 | copyright notice that is included in or attached to the work
40 | (an example is provided in the Appendix below).
41 |
42 | "Derivative Works" shall mean any work, whether in Source or Object
43 | form, that is based on (or derived from) the Work and for which the
44 | editorial revisions, annotations, elaborations, or other modifications
45 | represent, as a whole, an original work of authorship. For the purposes
46 | of this License, Derivative Works shall not include works that remain
47 | separable from, or merely link (or bind by name) to the interfaces of,
48 | the Work and Derivative Works thereof.
49 |
50 | "Contribution" shall mean any work of authorship, including
51 | the original version of the Work and any modifications or additions
52 | to that Work or Derivative Works thereof, that is intentionally
53 | submitted to Licensor for inclusion in the Work by the copyright owner
54 | or by an individual or Legal Entity authorized to submit on behalf of
55 | the copyright owner. For the purposes of this definition, "submitted"
56 | means any form of electronic, verbal, or written communication sent
57 | to the Licensor or its representatives, including but not limited to
58 | communication on electronic mailing lists, source code control systems,
59 | and issue tracking systems that are managed by, or on behalf of, the
60 | Licensor for the purpose of discussing and improving the Work, but
61 | excluding communication that is conspicuously marked or otherwise
62 | designated in writing by the copyright owner as "Not a Contribution."
63 |
64 | "Contributor" shall mean Licensor and any individual or Legal Entity
65 | on behalf of whom a Contribution has been received by Licensor and
66 | subsequently incorporated within the Work.
67 |
68 | 2. Grant of Copyright License. Subject to the terms and conditions of
69 | this License, each Contributor hereby grants to You a perpetual,
70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
71 | copyright license to reproduce, prepare Derivative Works of,
72 | publicly display, publicly perform, sublicense, and distribute the
73 | Work and such Derivative Works in Source or Object form.
74 |
75 | 3. Grant of Patent License. Subject to the terms and conditions of
76 | this License, each Contributor hereby grants to You a perpetual,
77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78 | (except as stated in this section) patent license to make, have made,
79 | use, offer to sell, sell, import, and otherwise transfer the Work,
80 | where such license applies only to those patent claims licensable
81 | by such Contributor that are necessarily infringed by their
82 | Contribution(s) alone or by combination of their Contribution(s)
83 | with the Work to which such Contribution(s) was submitted. If You
84 | institute patent litigation against any entity (including a
85 | cross-claim or counterclaim in a lawsuit) alleging that the Work
86 | or a Contribution incorporated within the Work constitutes direct
87 | or contributory patent infringement, then any patent licenses
88 | granted to You under this License for that Work shall terminate
89 | as of the date such litigation is filed.
90 |
91 | 4. Redistribution. You may reproduce and distribute copies of the
92 | Work or Derivative Works thereof in any medium, with or without
93 | modifications, and in Source or Object form, provided that You
94 | meet the following conditions:
95 |
96 | (a) You must give any other recipients of the Work or
97 | Derivative Works a copy of this License; and
98 |
99 | (b) You must cause any modified files to carry prominent notices
100 | stating that You changed the files; and
101 |
102 | (c) You must retain, in the Source form of any Derivative Works
103 | that You distribute, all copyright, patent, trademark, and
104 | attribution notices from the Source form of the Work,
105 | excluding those notices that do not pertain to any part of
106 | the Derivative Works; and
107 |
108 | (d) If the Work includes a "NOTICE" text file as part of its
109 | distribution, then any Derivative Works that You distribute must
110 | include a readable copy of the attribution notices contained
111 | within such NOTICE file, excluding those notices that do not
112 | pertain to any part of the Derivative Works, in at least one
113 | of the following places: within a NOTICE text file distributed
114 | as part of the Derivative Works; within the Source form or
115 | documentation, if provided along with the Derivative Works; or,
116 | within a display generated by the Derivative Works, if and
117 | wherever such third-party notices normally appear. The contents
118 | of the NOTICE file are for informational purposes only and
119 | do not modify the License. You may add Your own attribution
120 | notices within Derivative Works that You distribute, alongside
121 | or as an addendum to the NOTICE text from the Work, provided
122 | that such additional attribution notices cannot be construed
123 | as modifying the License.
124 |
125 | You may add Your own copyright statement to Your modifications and
126 | may provide additional or different license terms and conditions
127 | for use, reproduction, or distribution of Your modifications, or
128 | for any such Derivative Works as a whole, provided Your use,
129 | reproduction, and distribution of the Work otherwise complies with
130 | the conditions stated in this License.
131 |
132 | 5. Submission of Contributions. Unless You explicitly state otherwise,
133 | any Contribution intentionally submitted for inclusion in the Work
134 | by You to the Licensor shall be under the terms and conditions of
135 | this License, without any additional terms or conditions.
136 | Notwithstanding the above, nothing herein shall supersede or modify
137 | the terms of any separate license agreement you may have executed
138 | with Licensor regarding such Contributions.
139 |
140 | 6. Trademarks. This License does not grant permission to use the trade
141 | names, trademarks, service marks, or product names of the Licensor,
142 | except as required for reasonable and customary use in describing the
143 | origin of the Work and reproducing the content of the NOTICE file.
144 |
145 | 7. Disclaimer of Warranty. Unless required by applicable law or
146 | agreed to in writing, Licensor provides the Work (and each
147 | Contributor provides its Contributions) on an "AS IS" BASIS,
148 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
149 | implied, including, without limitation, any warranties or conditions
150 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
151 | PARTICULAR PURPOSE. You are solely responsible for determining the
152 | appropriateness of using or redistributing the Work and assume any
153 | risks associated with Your exercise of permissions under this License.
154 |
155 | 8. Limitation of Liability. In no event and under no legal theory,
156 | whether in tort (including negligence), contract, or otherwise,
157 | unless required by applicable law (such as deliberate and grossly
158 | negligent acts) or agreed to in writing, shall any Contributor be
159 | liable to You for damages, including any direct, indirect, special,
160 | incidental, or consequential damages of any character arising as a
161 | result of this License or out of the use or inability to use the
162 | Work (including but not limited to damages for loss of goodwill,
163 | work stoppage, computer failure or malfunction, or any and all
164 | other commercial damages or losses), even if such Contributor
165 | has been advised of the possibility of such damages.
166 |
167 | 9. Accepting Warranty or Additional Liability. While redistributing
168 | the Work or Derivative Works thereof, You may choose to offer,
169 | and charge a fee for, acceptance of support, warranty, indemnity,
170 | or other liability obligations and/or rights consistent with this
171 | License. However, in accepting such obligations, You may act only
172 | on Your own behalf and on Your sole responsibility, not on behalf
173 | of any other Contributor, and only if You agree to indemnify,
174 | defend, and hold each Contributor harmless for any liability
175 | incurred by, or claims asserted against, such Contributor by reason
176 | of your accepting any such warranty or additional liability.
177 |
178 | END OF TERMS AND CONDITIONS
179 |
180 | APPENDIX: How to apply the Apache License to your work.
181 |
182 | To apply the Apache License to your work, attach the following
183 | boilerplate notice, with the fields enclosed by brackets "{}"
184 | replaced with your own identifying information. (Don't include
185 | the brackets!) The text should be enclosed in the appropriate
186 | comment syntax for the file format. We also recommend that a
187 | file or class name and description of purpose be included on the
188 | same "printed page" as the copyright notice for easier
189 | identification within third-party archives.
190 |
191 | Copyright {yyyy} {name of copyright owner}
192 |
193 | Licensed under the Apache License, Version 2.0 (the "License");
194 | you may not use this file except in compliance with the License.
195 | You may obtain a copy of the License at
196 |
197 | http://www.apache.org/licenses/LICENSE-2.0
198 |
199 | Unless required by applicable law or agreed to in writing, software
200 | distributed under the License is distributed on an "AS IS" BASIS,
201 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
202 | See the License for the specific language governing permissions and
203 | limitations under the License.
204 |
205 | '''
206 |
207 | from setuptools import setup, find_packages
208 | import os
209 |
210 | """
211 | setup module for core.
212 |
213 | Created on 1/26/2018
214 |
215 | @author: guangyao
216 | """
217 | PACKAGE = "aliyunsdkcore"
218 | NAME = "aliyunsdkcore"
219 | DESCRIPTION = "The core module of Aliyun Python SDK."
220 | AUTHOR = "guangyao"
221 | AUTHOR_EMAIL = "duanguangyao@gmail.com"
222 | URL = "https://github.com/duangy/aliyunsdkcore"
223 |
224 | TOPDIR = os.path.dirname(__file__) or "."
225 | VERSION = __import__(PACKAGE).__version__
226 |
227 | desc_file = open("README.rst")
228 | try:
229 | LONG_DESCRIPTION = desc_file.read()
230 | finally:
231 | desc_file.close()
232 |
233 | setup(
234 | name=NAME,
235 | version=VERSION,
236 | description=DESCRIPTION,
237 | long_description=LONG_DESCRIPTION,
238 | author=AUTHOR,
239 | author_email=AUTHOR_EMAIL,
240 | license="Apache",
241 | url=URL,
242 | keywords=["aliyun", "sdk", "core"],
243 | packages=find_packages(exclude=["tests*"]),
244 | include_package_data=True,
245 | python_requires='>=3',
246 | platforms='any',
247 | install_requires=[
248 | 'pycrypto>=2.6.1'
249 | ],
250 | classifiers=(
251 | 'Development Status :: 5 - Production/Stable',
252 | 'Intended Audience :: Developers',
253 | 'License :: OSI Approved :: Apache Software License',
254 | 'Programming Language :: Python',
255 | 'Programming Language :: Python :: 3',
256 | 'Programming Language :: Python :: 3.3',
257 | 'Programming Language :: Python :: 3.5',
258 | 'Programming Language :: Python :: 3.6',
259 | 'Topic :: Software Development',
260 | )
261 | )
262 |
--------------------------------------------------------------------------------