一、环境要求
-
Python 3
-
安装 SDK 核心库 OpenAPI ,使用pip安装包依赖:
pip install alibabacloud_tea_openapi
-
SDK 安装方式
- PyPI PIP:
pip install alibabacloud_chatbot20171011==2.0.1
- PyPI Anaconda:
conda install alibabacloud_chatbot20171011=2.0.1
- PyPI PIP:
二、实现代码
- sample demo 如下(涉及具体个人核心配置数据处,请对应自行修改填充)
# -*- coding: utf-8 -*-
# @ Date : 2022/1/27 16:27
# @ Author : RichardLau_Cx
# @ Project: Chatbot
# @ File : API_sample_new.py
# @ IDE : PyCharm
import ssl
import time
import uuid
import hmac
import base64
import requests
import urllib.parse
from hashlib import sha1
from Chatbot import configs # 自定义的配置数据信息文件
# 解决访问ssl网站证书的问题
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
protocol = 'https://'
domain_name = 'chatbot.cn-shanghai.aliyuncs.com/'
Parameters = {
'Format': 'JSON',
'Version': '2017-10-11',
'AccessKeyId': configs.AccessKeyId,
'SignatureMethod': 'HMAC-SHA1',
'SignatureVersion': 1.0
}
def percent_encode(code):
"""
名称和值要使用 UTF-8 字符集进行 URL 编码,URL 编码的编码规则是:
1.字符 A-Z、a-z、0-9 以及字符“-”、“_”、“.”、“~”,不进行编码;
2.对于其他字符编码成“%XY”的格式,其中 XY 是字符对应 ASCII 码的 16 进制表示。比如英文的双引号对应的编码就是 “%22”;
3.对于扩展的 UTF-8 字符,编码成“%XY%ZA…”的格式;
4.注意英文空格要被编码成 “%20”,而不是加号“+”。
:param code: 待编码串
:return: 编码字符串
"""
# result = urllib.parse.quote(str(code))
encode = str(code)
result = urllib.parse.quote(encode)
result = result.replace('+', '%20')
result = result.replace('/', '%2F')
result = result.replace('*', '%2A')
result = result.replace('%7E', '~')
return result
# print("/: " + percent_encode('/'))
def signature(params):
"""
签名机制
:param params: 公共请求参数
:return: 签名结果串
"""
# 1. 使用请求参数来构造规范化的请求字符串(Canonicalized Query String)
# 1.1 按照参数名称的字母顺序对请求中所有的请求参数进行排序
sorted_params = sorted(params.items(), key=lambda params: params[0])
print("sorted_params: " + str(sorted_params))
# 1.2 对每个请求参数的名称和值进行编码
canonicalize_query_string = ''
for (k, v) in sorted_params:
# 1.3 对编码后的参数名称和值使用英文等号“=”进行连接
# 1.4 再把英文等号连接得到的字符串按参数名称的字母顺序依次使用“&”符号连接,即得到规范化请求字符串
canonicalize_query_string += '&' + percent_encode(k) + '=' + percent_encode(v)
# print("canonicalize_query_string: " + str(canonicalize_query_string))
# 2. 使用上一步构造的规范化字符串,按照下面的规则构造用于计算签名的字符串
http_method = 'GET'
string_to_sign = http_method + '&' + percent_encode('/') + '&' + percent_encode(canonicalize_query_string[1:])
# print("string_to_sign: " + str(string_to_sign))
string_to_sign = bytes(string_to_sign, encoding='utf8')
# print("string_to_sign: " + str(string_to_sign))
# 3. 按照 RFC2104 的定义,使用上面的用于签名的字符串计算签名 HMAC 值
sign_key = bytes((configs.AccessKeySecret + '&'), encoding='utf8')
hmacs = hmac.new(key=sign_key, msg=string_to_sign, digestmod=sha1)
# 4. 按照 Base64 编码规则把上面的 HMAC 值编码成字符串,即得到签名值(Signature)
sign = base64.b64encode(hmacs.digest()).strip()
return sign
formats = "%Y-%m-%dT%H:%M:%SZ"
timestamp = time.strftime(formats, time.gmtime()) # 函数用于格式化时间,返回以可读字符串表示的当地时间,格式由参数 format 决定
Parameters['Timestamp'] = timestamp
Parameters['SignatureNonce'] = str(uuid.uuid1())
Parameters['Action'] = "Chat"
Parameters['InstanceId'] = configs.InstanceId
Parameters['Utterance'] = "你能够解决什么问题?" # 想AI机器人进行提问
Parameters['Signature'] = signature(Parameters) # 其函数操作包含了之前的一些属性值,因此理应放置到最后计算赋值
sorted_params = sorted(Parameters.items(), key=lambda Parameters: Parameters[0])
url = protocol + domain_name + '?' + urllib.parse.urlencode(sorted_params)
print("url: " + str(url))
r = requests.get(url) # 进行接口访问
print('r.text: ' + str(r.text))
- 优化封装版(基于class)
# -*- coding: utf-8 -*-
# @ Date : 2022/1/27 16:27
# @ Author : RichardLau_Cx
# @ Project: Python
# @ File : API_sample_new.py
# @ IDE : PyCharm
import ssl
import time
import uuid
import hmac
import base64
import requests
import urllib.parse
from hashlib import sha1
from Chatbot.configs import Configs # 自定义的配置数据信息文件
def percent_encode(code):
"""
名称和值要使用 UTF-8 字符集进行 URL 编码,URL 编码的编码规则是:
1.字符 A-Z、a-z、0-9 以及字符“-”、“_”、“.”、“~”,不进行编码;
2.对于其他字符编码成“%XY”的格式,其中 XY 是字符对应 ASCII 码的 16 进制表示。比如英文的双引号对应的编码就是 “%22”;
3.对于扩展的 UTF-8 字符,编码成“%XY%ZA…”的格式;
4.注意英文空格要被编码成 “%20”,而不是加号“+”。
:param code: 待编码串
:return: 编码字符串
"""
encode = str(code)
result = urllib.parse.quote(encode)
result = result.replace('+', '%20')
result = result.replace('/', '%2F')
result = result.replace('*', '%2A')
result = result.replace('%7E', '~')
return result
class ChatBot:
def __init__(self):
self.configs = Configs()
def signature(self, params):
"""
签名机制
:param params: 公共请求参数
:return: 签名结果串
"""
# 1. 使用请求参数来构造规范化的请求字符串(Canonicalized Query String)
# 1.1 按照参数名称的字母顺序对请求中所有的请求参数进行排序
sorted_params = sorted(params.items(), key=lambda params: params[0])
# print("sorted_params: " + str(sorted_params))
# 1.2 对每个请求参数的名称和值进行编码
canonicalize_query_string = ''
for (k, v) in sorted_params:
# 1.3 对编码后的参数名称和值使用英文等号“=”进行连接
# 1.4 再把英文等号连接得到的字符串按参数名称的字母顺序依次使用“&”符号连接,即得到规范化请求字符串
canonicalize_query_string += '&' + percent_encode(k) + '=' + percent_encode(v)
# print("canonicalize_query_string: " + str(canonicalize_query_string))
# 2. 使用上一步构造的规范化字符串,按照下面的规则构造用于计算签名的字符串
http_method = 'GET'
string_to_sign = http_method + '&' + percent_encode('/') + '&' + percent_encode(canonicalize_query_string[1:])
# print("string_to_sign: " + str(string_to_sign))
string_to_sign = bytes(string_to_sign, encoding='utf8')
# print("string_to_sign: " + str(string_to_sign))
# 3. 按照 RFC2104 的定义,使用上面的用于签名的字符串计算签名 HMAC 值
sign_key = bytes((self.configs.AccessKeySecret + '&'), encoding='utf8')
hmacs = hmac.new(key=sign_key, msg=string_to_sign, digestmod=sha1)
# 4. 按照 Base64 编码规则把上面的 HMAC 值编码成字符串,即得到签名值(Signature)
sign = base64.b64encode(hmacs.digest()).strip()
return sign
def send(self, utterance):
"""
向服务器发出请求
:param utterance: 向AI机器人进行发话
:return: 响应结果(json数据)
"""
# 解决访问ssl网站证书的问题
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
self.configs = Configs()
protocol = 'https://'
domain_name = 'chatbot.cn-shanghai.aliyuncs.com/'
Parameters = {
'Format': 'JSON',
'Version': '2017-10-11',
'AccessKeyId': self.configs.AccessKeyId,
'SignatureMethod': 'HMAC-SHA1',
'SignatureVersion': 1.0
}
formats = "%Y-%m-%dT%H:%M:%SZ"
timestamp = time.strftime(formats, time.gmtime()) # 函数用于格式化时间,返回以可读字符串表示的当地时间,格式由参数 formats 决定
Parameters['Timestamp'] = timestamp
Parameters['SignatureNonce'] = str(uuid.uuid1())
Parameters['Action'] = "Chat"
Parameters['InstanceId'] = self.configs.InstanceId
Parameters['Utterance'] = utterance
Parameters['Signature'] = self.signature(Parameters) # 其函数操作包含了之前的一些属性值,因此理应放置到最后计算赋值
sorted_params = sorted(Parameters.items(), key=lambda Parameters: Parameters[0])
url = protocol + domain_name + '?' + urllib.parse.urlencode(sorted_params)
# print("url: " + str(url))
response = requests.get(url).json() # 进行接口访问处
# print('response: ' + str(type(response)))
# print('response.content: ' + str(response["Messages"][0]["Text"]["Content"])) # 获取应答内容))
return response
if '__main__' == __name__:
data = "你是谁?" # 言论内容
chatbot = ChatBot()
response = chatbot.send(utterance=data)
print('response.content: ' + str(response["Messages"][0]["Text"]["Content"]))