@@ -77,25 +67,19 @@ def _encrypt_message(self,
pc = crypto_class(self.key)
encrypt = to_text(pc.encrypt(msg, self._id))
signature = _get_signature(self.token, timestamp, nonce, encrypt)
- return to_text(xml.format(
- encrypt=encrypt,
- signature=signature,
- timestamp=timestamp,
- nonce=nonce
- ))
-
- def _decrypt_message(self,
- msg,
- signature,
- timestamp,
- nonce,
- crypto_class=None):
+ return to_text(
+ xml.format(
+ encrypt=encrypt, signature=signature, timestamp=timestamp, nonce=nonce
+ )
+ )
+
+ def _decrypt_message(self, msg, signature, timestamp, nonce, crypto_class=None):
if not isinstance(msg, dict):
import xmltodict
- msg = xmltodict.parse(to_text(msg))['xml']
+ msg = xmltodict.parse(to_text(msg))["xml"]
- encrypt = msg['Encrypt']
+ encrypt = msg["Encrypt"]
_signature = _get_signature(self.token, timestamp, nonce, encrypt)
if _signature != signature:
raise InvalidSignatureException()
@@ -113,13 +97,7 @@ def encrypt_message(self, msg, nonce, timestamp=None):
return self._encrypt_message(msg, nonce, timestamp, PrpCrypto)
def decrypt_message(self, msg, signature, timestamp, nonce):
- return self._decrypt_message(
- msg,
- signature,
- timestamp,
- nonce,
- PrpCrypto
- )
+ return self._decrypt_message(msg, signature, timestamp, nonce, PrpCrypto)
class WeChatWxaCrypto(object):
@@ -132,6 +110,6 @@ def decrypt_message(self, msg):
decrypted = self.cipher.decrypt(raw_data)
plaintext = PKCS7Encoder.decode(decrypted)
decrypted_msg = json.loads(to_text(plaintext))
- if decrypted_msg['watermark']['appid'] != self.app_id:
+ if decrypted_msg["watermark"]["appid"] != self.app_id:
raise InvalidAppIdException()
return decrypted_msg
diff --git a/chapter14/booking_system/exts/wechatpy/crypto/base.py b/chapter14/booking_system/exts/wechatpy/crypto/base.py
index e12300e..a6f60d3 100644
--- a/chapter14/booking_system/exts/wechatpy/crypto/base.py
+++ b/chapter14/booking_system/exts/wechatpy/crypto/base.py
@@ -6,13 +6,14 @@
from exts.wechatpy.utils import to_text, to_binary, random_string, byte2int
from exts.wechatpy.crypto.pkcs7 import PKCS7Encoder
+
try:
from exts.wechatpy.crypto.cryptography import WeChatCipher
except ImportError:
try:
from exts.wechatpy.crypto.pycrypto import WeChatCipher
except ImportError:
- raise Exception('You must install either cryptography or pycryptodome!')
+ raise Exception("You must install either cryptography or pycryptodome!")
class BasePrpCrypto(object):
@@ -27,12 +28,12 @@ def _encrypt(self, text, _id):
text = to_binary(text)
tmp_list = []
tmp_list.append(to_binary(self.get_random_string()))
- length = struct.pack(b'I', socket.htonl(len(text)))
+ length = struct.pack(b"I", socket.htonl(len(text)))
tmp_list.append(length)
tmp_list.append(text)
tmp_list.append(to_binary(_id))
- text = b''.join(tmp_list)
+ text = b"".join(tmp_list)
text = PKCS7Encoder.encode(text)
ciphertext = to_binary(self.cipher.encrypt(text))
@@ -43,9 +44,9 @@ def _decrypt(self, text, _id, exception=None):
plain_text = self.cipher.decrypt(base64.b64decode(text))
padding = byte2int(plain_text[-1])
content = plain_text[16:-padding]
- xml_length = socket.ntohl(struct.unpack(b'I', content[:4])[0])
- xml_content = to_text(content[4:xml_length + 4])
- from_id = to_text(content[xml_length + 4:])
+ xml_length = socket.ntohl(struct.unpack(b"I", content[:4])[0])
+ xml_content = to_text(content[4 : xml_length + 4])
+ from_id = to_text(content[xml_length + 4 :])
if from_id != _id:
exception = exception or Exception
raise exception()
diff --git a/chapter14/booking_system/exts/wechatpy/crypto/cryptography.py b/chapter14/booking_system/exts/wechatpy/crypto/cryptography.py
index e63917f..944923e 100644
--- a/chapter14/booking_system/exts/wechatpy/crypto/cryptography.py
+++ b/chapter14/booking_system/exts/wechatpy/crypto/cryptography.py
@@ -9,11 +9,7 @@ class WeChatCipher(object):
def __init__(self, key, iv=None):
iv = iv or key[:16]
backend = default_backend()
- self.cipher = Cipher(
- algorithms.AES(key),
- modes.CBC(iv),
- backend=backend
- )
+ self.cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
def encrypt(self, plaintext):
encryptor = self.cipher.encryptor()
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/__init__.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/__init__.py
index 89b19c6..94d6b23 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/__init__.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/__init__.py
@@ -6,7 +6,7 @@
class WeChatClient(BaseWeChatClient):
- API_BASE_URL = 'https://qyapi.weixin.qq.com/cgi-bin/'
+ API_BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin/"
agent = api.WeChatAgent()
appchat = api.WeChatAppChat()
@@ -25,8 +25,15 @@ class WeChatClient(BaseWeChatClient):
tag = api.WeChatTag()
user = api.WeChatUser()
- def __init__(self, corp_id, secret, access_token=None,
- session=None, timeout=None, auto_retry=True):
+ def __init__(
+ self,
+ corp_id,
+ secret,
+ access_token=None,
+ session=None,
+ timeout=None,
+ auto_retry=True,
+ ):
super(WeChatClient, self).__init__(
corp_id, access_token, session, timeout, auto_retry
)
@@ -35,14 +42,11 @@ def __init__(self, corp_id, secret, access_token=None,
@property
def access_token_key(self):
- return '{0}_{1}_access_token'.format(self.corp_id, self.secret[:10])
+ return "{0}_{1}_access_token".format(self.corp_id, self.secret[:10])
def fetch_access_token(self):
- """ Fetch access token"""
+ """Fetch access token"""
return self._fetch_access_token(
- url='https://qyapi.weixin.qq.com/cgi-bin/gettoken',
- params={
- 'corpid': self.corp_id,
- 'corpsecret': self.secret
- }
+ url="https://qyapi.weixin.qq.com/cgi-bin/gettoken",
+ params={"corpid": self.corp_id, "corpsecret": self.secret},
)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/agent.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/agent.py
index 2ba1d4c..d969d72 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/agent.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/agent.py
@@ -19,12 +19,7 @@ def get(self, agent_id):
:param agent_id: 应用id
:return: 返回的 JSON 数据包
"""
- return self._get(
- 'agent/get',
- params={
- 'agentid': agent_id
- }
- )
+ return self._get("agent/get", params={"agentid": agent_id})
def list(self):
"""
@@ -33,18 +28,20 @@ def list(self):
:return: 应用概况列表
"""
- res = self._get('agent/list')
- return res['agentlist']
+ res = self._get("agent/list")
+ return res["agentlist"]
- def set(self,
- agent_id,
- name=None,
- description=None,
- redirect_domain=None,
- logo_media_id=None,
- report_location_flag=0,
- is_report_user=True,
- is_report_enter=True):
+ def set(
+ self,
+ agent_id,
+ name=None,
+ description=None,
+ redirect_domain=None,
+ logo_media_id=None,
+ report_location_flag=0,
+ is_report_user=True,
+ is_report_enter=True,
+ ):
"""
设置应用
https://work.weixin.qq.com/api/doc#90000/90135/90228
@@ -60,15 +57,12 @@ def set(self,
:return: 返回的 JSON 数据包
"""
agent_data = optionaldict()
- agent_data['agentid'] = agent_id
- agent_data['name'] = name
- agent_data['description'] = description
- agent_data['redirect_domain'] = redirect_domain
- agent_data['logo_mediaid'] = logo_media_id
- agent_data['report_location_flag'] = report_location_flag
- agent_data['isreportenter'] = 1 if is_report_enter else 0
- agent_data['isreportuser'] = 1 if is_report_user else 0
- return self._post(
- 'agent/set',
- data=agent_data
- )
+ agent_data["agentid"] = agent_id
+ agent_data["name"] = name
+ agent_data["description"] = description
+ agent_data["redirect_domain"] = redirect_domain
+ agent_data["logo_mediaid"] = logo_media_id
+ agent_data["report_location_flag"] = report_location_flag
+ agent_data["isreportenter"] = 1 if is_report_enter else 0
+ agent_data["isreportuser"] = 1 if is_report_user else 0
+ return self._post("agent/set", data=agent_data)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/appchat.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/appchat.py
index e6a5b46..1feb9e6 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/appchat.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/appchat.py
@@ -35,7 +35,7 @@ def create(self, chat_id=None, name=None, owner=None, user_list=None):
owner=owner,
userlist=user_list,
)
- return self._post('appchat/create', data=data)
+ return self._post("appchat/create", data=data)
def get(self, chat_id):
"""
@@ -47,11 +47,12 @@ def get(self, chat_id):
:param chat_id: 群聊id
:return: 会话信息
"""
- res = self._get('appchat/get', params={'chatid': chat_id})
- return res['chat_info']
+ res = self._get("appchat/get", params={"chatid": chat_id})
+ return res["chat_info"]
- def update(self, chat_id, name=None, owner=None,
- add_user_list=None, del_user_list=None):
+ def update(
+ self, chat_id, name=None, owner=None, add_user_list=None, del_user_list=None
+ ):
"""
修改群聊会话
@@ -72,7 +73,7 @@ def update(self, chat_id, name=None, owner=None,
add_user_list=add_user_list,
del_user_list=del_user_list,
)
- return self._post('appchat/update', data=data)
+ return self._post("appchat/update", data=data)
def send(self, chat_id, msg_type, **kwargs):
"""
@@ -84,16 +85,13 @@ def send(self, chat_id, msg_type, **kwargs):
:param kwargs: 具体消息类型的扩展参数
:return:
"""
- data = {
- 'chatid': chat_id,
- 'safe': kwargs.get('safe') or 0
- }
+ data = {"chatid": chat_id, "safe": kwargs.get("safe") or 0}
data.update(self._build_msg_content(msg_type, **kwargs))
- return self._post('appchat/send', data=data)
+ return self._post("appchat/send", data=data)
def send_msg(self, chat_id, msg_type, **kwargs):
- """ deprecated, use `send` instead """
+ """deprecated, use `send` instead"""
return self.send(chat_id, msg_type, **kwargs)
def send_text(self, chat_id, content, safe=0):
@@ -107,9 +105,9 @@ def send_text(self, chat_id, content, safe=0):
:param safe: 表示是否是保密消息,0表示否,1表示是,默认0
:return:
"""
- return self.send(chat_id, 'text', safe=safe, content=content)
+ return self.send(chat_id, "text", safe=safe, content=content)
- def _build_msg_content(self, msgtype='text', **kwargs):
+ def _build_msg_content(self, msgtype="text", **kwargs):
"""
构造消息内容
@@ -118,25 +116,25 @@ def _build_msg_content(self, msgtype='text', **kwargs):
:param kwargs: 具体消息类型的扩展参数
:return:
"""
- data = {'msgtype': msgtype}
- if msgtype == 'text':
- data[msgtype] = {'content': kwargs.get('content')}
- elif msgtype == 'image' or msgtype == 'voice' or msgtype == 'file':
- data[msgtype] = {'media_id': kwargs.get('media_id')}
- elif msgtype == 'video':
+ data = {"msgtype": msgtype}
+ if msgtype == "text":
+ data[msgtype] = {"content": kwargs.get("content")}
+ elif msgtype == "image" or msgtype == "voice" or msgtype == "file":
+ data[msgtype] = {"media_id": kwargs.get("media_id")}
+ elif msgtype == "video":
data[msgtype] = {
- 'media_id': kwargs.get('media_id'),
- 'title': kwargs.get('title'),
- 'description': kwargs.get('description')
+ "media_id": kwargs.get("media_id"),
+ "title": kwargs.get("title"),
+ "description": kwargs.get("description"),
}
- elif msgtype == 'textcard':
+ elif msgtype == "textcard":
data[msgtype] = {
- 'title': kwargs.get('title'),
- 'description': kwargs.get('description'),
- 'url': kwargs.get('url'),
- 'btntxt': kwargs.get('btntxt'),
+ "title": kwargs.get("title"),
+ "description": kwargs.get("description"),
+ "url": kwargs.get("url"),
+ "btntxt": kwargs.get("btntxt"),
}
- elif msgtype == 'news':
+ elif msgtype == "news":
# {
# "articles" :
# [
@@ -149,7 +147,7 @@ def _build_msg_content(self, msgtype='text', **kwargs):
# ]
# }
data[msgtype] = kwargs
- elif msgtype == 'mpnews':
+ elif msgtype == "mpnews":
# {
# "articles":[
# {
@@ -163,7 +161,7 @@ def _build_msg_content(self, msgtype='text', **kwargs):
# ]
# }
data[msgtype] = kwargs
- elif msgtype == 'markdown':
+ elif msgtype == "markdown":
# {
# "content": "您的会议室已经预定,稍后会同步到`邮箱`
# >**事项详情**
@@ -181,5 +179,5 @@ def _build_msg_content(self, msgtype='text', **kwargs):
# }
data[msgtype] = kwargs
else:
- raise TypeError('不能识别的msgtype: %s' % msgtype)
+ raise TypeError("不能识别的msgtype: %s" % msgtype)
return data
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/batch.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/batch.py
index 8ed88d5..268ebf3 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/batch.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/batch.py
@@ -30,16 +30,16 @@ def sync_user(self, url, token, encoding_aes_key, media_id, to_invite=True):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'batch/syncuser',
+ "batch/syncuser",
data={
- 'media_id': media_id,
- 'to_invite': to_invite,
- 'callback': {
- 'url': url,
- 'token': token,
- 'encodingaeskey': encoding_aes_key
- }
- }
+ "media_id": media_id,
+ "to_invite": to_invite,
+ "callback": {
+ "url": url,
+ "token": token,
+ "encodingaeskey": encoding_aes_key,
+ },
+ },
)
def replace_user(self, url, token, encoding_aes_key, media_id, to_invite=True):
@@ -56,16 +56,16 @@ def replace_user(self, url, token, encoding_aes_key, media_id, to_invite=True):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'batch/replaceuser',
+ "batch/replaceuser",
data={
- 'media_id': media_id,
- 'to_invite': to_invite,
- 'callback': {
- 'url': url,
- 'token': token,
- 'encodingaeskey': encoding_aes_key
- }
- }
+ "media_id": media_id,
+ "to_invite": to_invite,
+ "callback": {
+ "url": url,
+ "token": token,
+ "encodingaeskey": encoding_aes_key,
+ },
+ },
)
def replace_party(self, url, token, encoding_aes_key, media_id):
@@ -81,15 +81,15 @@ def replace_party(self, url, token, encoding_aes_key, media_id):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'batch/replaceparty',
+ "batch/replaceparty",
data={
- 'media_id': media_id,
- 'callback': {
- 'url': url,
- 'token': token,
- 'encodingaeskey': encoding_aes_key
- }
- }
+ "media_id": media_id,
+ "callback": {
+ "url": url,
+ "token": token,
+ "encodingaeskey": encoding_aes_key,
+ },
+ },
)
def get_result(self, job_id):
@@ -101,7 +101,7 @@ def get_result(self, job_id):
:param job_id: 异步任务id,最大长度为64字符
:return: 返回的 JSON 数据包
"""
- return self._get('batch/getresult', params={'jobid': job_id})
+ return self._get("batch/getresult", params={"jobid": job_id})
def invite(self, user=None, party=None, tag=None):
"""
@@ -117,10 +117,18 @@ def invite(self, user=None, party=None, tag=None):
:return: 返回的 JSON 数据包
"""
data = optionaldict(user=user, party=party, tag=tag)
- return self._post('batch/invite', data=data)
-
- def invite_user(self, url, token, encoding_aes_key, user_ids=None,
- party_ids=None, tag_ids=None, invite_tips=None):
+ return self._post("batch/invite", data=data)
+
+ def invite_user(
+ self,
+ url,
+ token,
+ encoding_aes_key,
+ user_ids=None,
+ party_ids=None,
+ tag_ids=None,
+ invite_tips=None,
+ ):
"""
邀请成员关注(deprecated)
https://qydev.weixin.qq.com/wiki/index.php?title=异步任务接口
@@ -135,19 +143,19 @@ def invite_user(self, url, token, encoding_aes_key, user_ids=None,
:return: 返回的 JSON 数据包
"""
data = optionaldict()
- data['callback'] = {
- 'url': url,
- 'token': token,
- 'encodingaeskey': encoding_aes_key
+ data["callback"] = {
+ "url": url,
+ "token": token,
+ "encodingaeskey": encoding_aes_key,
}
if isinstance(user_ids, (tuple, list)):
- user_ids = '|'.join(map(to_text, user_ids))
+ user_ids = "|".join(map(to_text, user_ids))
if isinstance(party_ids, (tuple, list)):
- party_ids = '|'.join(map(to_text, party_ids))
+ party_ids = "|".join(map(to_text, party_ids))
if isinstance(tag_ids, (tuple, list)):
- tag_ids = '|'.join(map(to_text, tag_ids))
- data['touser'] = user_ids
- data['toparty'] = party_ids
- data['totag'] = tag_ids
- data['invite_tips'] = invite_tips
- return self._post('batch/inviteuser', data=data)
+ tag_ids = "|".join(map(to_text, tag_ids))
+ data["touser"] = user_ids
+ data["toparty"] = party_ids
+ data["totag"] = tag_ids
+ data["invite_tips"] = invite_tips
+ return self._post("batch/inviteuser", data=data)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/chat.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/chat.py
index da16e5c..a71f53c 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/chat.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/chat.py
@@ -27,13 +27,13 @@ def create(self, chat_id, name, owner, user_list):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'chat/create',
+ "chat/create",
data={
- 'chatid': chat_id,
- 'name': name,
- 'owner': owner,
- 'userlist': user_list,
- }
+ "chatid": chat_id,
+ "name": name,
+ "owner": owner,
+ "userlist": user_list,
+ },
)
def get(self, chat_id):
@@ -46,11 +46,18 @@ def get(self, chat_id):
:param chat_id: 会话 ID
:return: 会话信息
"""
- res = self._get('chat/get', params={'chatid': chat_id})
- return res['chat_info']
-
- def update(self, chat_id, op_user, name=None, owner=None,
- add_user_list=None, del_user_list=None):
+ res = self._get("chat/get", params={"chatid": chat_id})
+ return res["chat_info"]
+
+ def update(
+ self,
+ chat_id,
+ op_user,
+ name=None,
+ owner=None,
+ add_user_list=None,
+ del_user_list=None,
+ ):
"""
修改会话
@@ -73,7 +80,7 @@ def update(self, chat_id, op_user, name=None, owner=None,
add_user_list=add_user_list,
del_user_list=del_user_list,
)
- return self._post('chat/update', data=data)
+ return self._post("chat/update", data=data)
def quit(self, chat_id, op_user):
"""
@@ -87,11 +94,11 @@ def quit(self, chat_id, op_user):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'chat/quit',
+ "chat/quit",
data={
- 'chatid': chat_id,
- 'op_user': op_user,
- }
+ "chatid": chat_id,
+ "op_user": op_user,
+ },
)
def clear_notify(self, op_user, type, id):
@@ -107,14 +114,14 @@ def clear_notify(self, op_user, type, id):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'chat/clearnotify',
+ "chat/clearnotify",
data={
- 'op_user': op_user,
- 'chat': {
- 'type': type,
- 'id': id,
- }
- }
+ "op_user": op_user,
+ "chat": {
+ "type": type,
+ "id": id,
+ },
+ },
)
def set_mute(self, user_mute_list):
@@ -127,10 +134,7 @@ def set_mute(self, user_mute_list):
:param user_mute_list: 成员新消息免打扰参数,数组,最大支持10000个成员
:return: 返回的 JSON 数据包
"""
- return self._post(
- 'chat/setmute',
- data={'user_mute_list': user_mute_list}
- )
+ return self._post("chat/setmute", data={"user_mute_list": user_mute_list})
def send_text(self, sender, receiver_type, receiver_id, content):
"""
@@ -146,17 +150,17 @@ def send_text(self, sender, receiver_type, receiver_id, content):
:return: 返回的 JSON 数据包
"""
data = {
- 'receiver': {
- 'type': receiver_type,
- 'id': receiver_id,
+ "receiver": {
+ "type": receiver_type,
+ "id": receiver_id,
+ },
+ "sender": sender,
+ "msgtype": "text",
+ "text": {
+ "content": content,
},
- 'sender': sender,
- 'msgtype': 'text',
- 'text': {
- 'content': content,
- }
}
- return self._post('chat/send', data=data)
+ return self._post("chat/send", data=data)
def send_single_text(self, sender, receiver, content):
"""
@@ -167,7 +171,7 @@ def send_single_text(self, sender, receiver, content):
:param content: 消息内容
:return: 返回的 JSON 数据包
"""
- return self.send_text(sender, 'single', receiver, content)
+ return self.send_text(sender, "single", receiver, content)
def send_group_text(self, sender, receiver, content):
"""
@@ -178,7 +182,7 @@ def send_group_text(self, sender, receiver, content):
:param content: 消息内容
:return: 返回的 JSON 数据包
"""
- return self.send_text(sender, 'group', receiver, content)
+ return self.send_text(sender, "group", receiver, content)
def send_image(self, sender, receiver_type, receiver_id, media_id):
"""
@@ -194,17 +198,17 @@ def send_image(self, sender, receiver_type, receiver_id, media_id):
:return: 返回的 JSON 数据包
"""
data = {
- 'receiver': {
- 'type': receiver_type,
- 'id': receiver_id,
+ "receiver": {
+ "type": receiver_type,
+ "id": receiver_id,
+ },
+ "sender": sender,
+ "msgtype": "image",
+ "image": {
+ "media_id": media_id,
},
- 'sender': sender,
- 'msgtype': 'image',
- 'image': {
- 'media_id': media_id,
- }
}
- return self._post('chat/send', data=data)
+ return self._post("chat/send", data=data)
def send_single_image(self, sender, receiver, media_id):
"""
@@ -215,7 +219,7 @@ def send_single_image(self, sender, receiver, media_id):
:param media_id: 图片媒体文件id,可以调用上传素材文件接口获取
:return: 返回的 JSON 数据包
"""
- return self.send_image(sender, 'single', receiver, media_id)
+ return self.send_image(sender, "single", receiver, media_id)
def send_group_image(self, sender, receiver, media_id):
"""
@@ -226,7 +230,7 @@ def send_group_image(self, sender, receiver, media_id):
:param media_id: 图片媒体文件id,可以调用上传素材文件接口获取
:return: 返回的 JSON 数据包
"""
- return self.send_image(sender, 'group', receiver, media_id)
+ return self.send_image(sender, "group", receiver, media_id)
def send_file(self, sender, receiver_type, receiver_id, media_id):
"""
@@ -242,17 +246,17 @@ def send_file(self, sender, receiver_type, receiver_id, media_id):
:return: 返回的 JSON 数据包
"""
data = {
- 'receiver': {
- 'type': receiver_type,
- 'id': receiver_id,
+ "receiver": {
+ "type": receiver_type,
+ "id": receiver_id,
+ },
+ "sender": sender,
+ "msgtype": "file",
+ "file": {
+ "media_id": media_id,
},
- 'sender': sender,
- 'msgtype': 'file',
- 'file': {
- 'media_id': media_id,
- }
}
- return self._post('chat/send', data=data)
+ return self._post("chat/send", data=data)
def send_single_file(self, sender, receiver, media_id):
"""
@@ -263,7 +267,7 @@ def send_single_file(self, sender, receiver, media_id):
:param media_id: 文件id,可以调用上传素材文件接口获取, 文件须大于4字节
:return: 返回的 JSON 数据包
"""
- return self.send_file(sender, 'single', receiver, media_id)
+ return self.send_file(sender, "single", receiver, media_id)
def send_group_file(self, sender, receiver, media_id):
"""
@@ -274,4 +278,4 @@ def send_group_file(self, sender, receiver, media_id):
:param media_id: 文件id,可以调用上传素材文件接口获取, 文件须大于4字节
:return: 返回的 JSON 数据包
"""
- return self.send_file(sender, 'group', receiver, media_id)
+ return self.send_file(sender, "group", receiver, media_id)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/department.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/department.py
index d36893c..603c2ae 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/department.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/department.py
@@ -23,13 +23,8 @@ def create(self, name, parent_id=1, order=None, id=None):
:param id: 部门id,32位整型,指定时必须大于1。若不填该参数,将自动生成id
:return: 返回的 JSON 数据包
"""
- data = optionaldict(
- name=name,
- parentid=parent_id,
- order=order,
- id=id
- )
- return self._post('department/create', data=data)
+ data = optionaldict(name=name, parentid=parent_id, order=order, id=id)
+ return self._post("department/create", data=data)
def update(self, id, name=None, parent_id=None, order=None):
"""
@@ -43,13 +38,8 @@ def update(self, id, name=None, parent_id=None, order=None):
:param order: 在父部门中的次序值。order值大的排序靠前。有效的值范围是[0, 2^32)
:return: 返回的 JSON 数据包
"""
- data = optionaldict(
- id=id,
- name=name,
- parentid=parent_id,
- order=order
- )
- return self._post('department/update', data=data)
+ data = optionaldict(id=id, name=name, parentid=parent_id, order=order)
+ return self._post("department/update", data=data)
def delete(self, id):
"""
@@ -60,7 +50,7 @@ def delete(self, id):
:param id: 部门id。(注:不能删除根部门;不能删除含有子部门、成员的部门)
:return: 返回的 JSON 数据包
"""
- return self._get('department/delete', params={'id': id})
+ return self._get("department/delete", params={"id": id})
def get(self, id=None):
"""
@@ -75,10 +65,10 @@ def get(self, id=None):
:return: 部门列表
"""
if id is None:
- res = self._get('department/list')
+ res = self._get("department/list")
else:
- res = self._get('department/list', params={'id': id})
- return res['department']
+ res = self._get("department/list", params={"id": id})
+ return res["department"]
def get_users(self, id, status=0, fetch_child=0, simple=True):
"""
@@ -92,13 +82,13 @@ def get_users(self, id, status=0, fetch_child=0, simple=True):
:param simple: True 获取部门成员,False 获取部门成员详情
:return: 部门成员列表
"""
- url = 'order/simplelist' if simple else 'order/list'
+ url = "order/simplelist" if simple else "order/list"
res = self._get(
url,
params={
- 'department_id': id,
- 'status': status,
- 'fetch_child': 1 if fetch_child else 0
- }
+ "department_id": id,
+ "status": status,
+ "fetch_child": 1 if fetch_child else 0,
+ },
)
- return res['userlist']
+ return res["userlist"]
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/jsapi.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/jsapi.py
index 59571df..d0b7be6 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/jsapi.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/jsapi.py
@@ -20,7 +20,7 @@ def get_ticket(self):
:return: 返回的 JSON 数据包
"""
- return self._get('get_jsapi_ticket')
+ return self._get("get_jsapi_ticket")
def get_jsapi_signature(self, noncestr, ticket, timestamp, url):
"""
@@ -35,12 +35,12 @@ def get_jsapi_signature(self, noncestr, ticket, timestamp, url):
:return: 签名
"""
data = [
- 'noncestr={noncestr}'.format(noncestr=noncestr),
- 'jsapi_ticket={ticket}'.format(ticket=ticket),
- 'timestamp={timestamp}'.format(timestamp=timestamp),
- 'url={url}'.format(url=url),
+ "noncestr={noncestr}".format(noncestr=noncestr),
+ "jsapi_ticket={ticket}".format(ticket=ticket),
+ "timestamp={timestamp}".format(timestamp=timestamp),
+ "url={url}".format(url=url),
]
- signer = WeChatSigner(delimiter=b'&')
+ signer = WeChatSigner(delimiter=b"&")
signer.add_data(*data)
return signer.signature
@@ -52,7 +52,7 @@ def get_agent_ticket(self):
:return: 返回的 JSON 数据包
"""
- return self._get('ticket/get', params={'type': 'agent_config'})
+ return self._get("ticket/get", params={"type": "agent_config"})
def get_jsapi_ticket(self):
"""
@@ -62,14 +62,14 @@ def get_jsapi_ticket(self):
:return: ticket
"""
- ticket_key = '{}_jsapi_ticket'.format(self._client.corp_id)
- expires_at_key = '{}_jsapi_ticket_expires_at'.format(self._client.corp_id)
+ ticket_key = "{}_jsapi_ticket".format(self._client.corp_id)
+ expires_at_key = "{}_jsapi_ticket_expires_at".format(self._client.corp_id)
ticket = self.session.get(ticket_key)
expires_at = self.session.get(expires_at_key, 0)
if not ticket or expires_at < int(time.time()):
jsapi_ticket = self.get_ticket()
- ticket = jsapi_ticket['ticket']
- expires_at = int(time.time()) + int(jsapi_ticket['expires_in'])
+ ticket = jsapi_ticket["ticket"]
+ expires_at = int(time.time()) + int(jsapi_ticket["expires_in"])
self.session.set(ticket_key, ticket)
self.session.set(expires_at_key, expires_at)
return ticket
@@ -82,14 +82,14 @@ def get_agent_jsapi_ticket(self):
:return: ticket
"""
- ticket_key = '{}_agent_jsapi_ticket'.format(self._client.corp_id)
- expires_at_key = '{}_agent_jsapi_ticket_expires_at'.format(self._client.corp_id)
+ ticket_key = "{}_agent_jsapi_ticket".format(self._client.corp_id)
+ expires_at_key = "{}_agent_jsapi_ticket_expires_at".format(self._client.corp_id)
ticket = self.session.get(ticket_key)
expires_at = self.session.get(expires_at_key, 0)
if not ticket or expires_at < int(time.time()):
jsapi_ticket = self.get_agent_ticket()
- ticket = jsapi_ticket['ticket']
- expires_at = int(time.time()) + int(jsapi_ticket['expires_in'])
+ ticket = jsapi_ticket["ticket"]
+ expires_at = int(time.time()) + int(jsapi_ticket["expires_in"])
self.session.set(ticket_key, ticket)
self.session.set(expires_at_key, expires_at)
return ticket
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/material.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/material.py
index 9de5fef..2c23f37 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/material.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/material.py
@@ -19,22 +19,19 @@ def add_articles(self, articles):
"""
articles_data = []
for article in articles:
- articles_data.append({
- 'thumb_media_id': article['thumb_media_id'],
- 'title': article['title'],
- 'content': article['content'],
- 'author': article.get('author', ''),
- 'content_source_url': article.get('content_source_url', ''),
- 'digest': article.get('digest', ''),
- 'show_cover_pic': article.get('show_cover_pic', 0)
- })
- return self._post(
- 'material/add_mpnews',
- data={
- "mpnews": {
- "articles": articles_data
+ articles_data.append(
+ {
+ "thumb_media_id": article["thumb_media_id"],
+ "title": article["title"],
+ "content": article["content"],
+ "author": article.get("author", ""),
+ "content_source_url": article.get("content_source_url", ""),
+ "digest": article.get("digest", ""),
+ "show_cover_pic": article.get("show_cover_pic", 0),
}
- }
+ )
+ return self._post(
+ "material/add_mpnews", data={"mpnews": {"articles": articles_data}}
)
def add(self, agent_id, media_type, media_file):
@@ -49,15 +46,11 @@ def add(self, agent_id, media_type, media_file):
:return: 返回的 JSON 数据包
"""
params = {
- 'agentid': agent_id,
- 'type': media_type,
+ "agentid": agent_id,
+ "type": media_type,
}
return self._post(
- url='material/add_material',
- params=params,
- files={
- 'media': media_file
- }
+ url="material/add_material", params=params, files={"media": media_file}
)
def get_url(self, agent_id, media_id):
@@ -71,15 +64,15 @@ def get_url(self, agent_id, media_id):
:return: 临时素材下载地址
"""
parts = (
- 'https://qyapi.weixin.qq.com/cgi-bin/material/get',
- '?access_token=',
+ "https://qyapi.weixin.qq.com/cgi-bin/material/get",
+ "?access_token=",
self.access_token,
- '&media_id=',
+ "&media_id=",
media_id,
- '&agentid=',
+ "&agentid=",
agent_id,
)
- return ''.join(parts)
+ return "".join(parts)
def get(self, agent_id, media_id):
"""
@@ -104,11 +97,11 @@ def get_articles(self, agent_id, media_id):
:return: 返回的 JSON 数据包
"""
return self._get(
- 'material/get',
+ "material/get",
params={
- 'agentid': agent_id,
- 'media_id': media_id,
- }
+ "agentid": agent_id,
+ "media_id": media_id,
+ },
)
def delete(self, agent_id, media_id):
@@ -122,11 +115,11 @@ def delete(self, agent_id, media_id):
:return: 返回的 JSON 数据包
"""
return self._get(
- 'material/del',
+ "material/del",
params={
- 'agentid': agent_id,
- 'media_id': media_id,
- }
+ "agentid": agent_id,
+ "media_id": media_id,
+ },
)
def update_articles(self, agent_id, media_id, articles):
@@ -142,22 +135,20 @@ def update_articles(self, agent_id, media_id, articles):
"""
articles_data = []
for article in articles:
- articles_data.append({
- 'thumb_media_id': article['thumb_media_id'],
- 'title': article['title'],
- 'content': article['content'],
- 'author': article.get('author', ''),
- 'content_source_url': article.get('content_source_url', ''),
- 'digest': article.get('digest', ''),
- 'show_cover_pic': article.get('show_cover_pic', 0)
- })
+ articles_data.append(
+ {
+ "thumb_media_id": article["thumb_media_id"],
+ "title": article["title"],
+ "content": article["content"],
+ "author": article.get("author", ""),
+ "content_source_url": article.get("content_source_url", ""),
+ "digest": article.get("digest", ""),
+ "show_cover_pic": article.get("show_cover_pic", 0),
+ }
+ )
return self._post(
- 'material/update_news',
- data={
- 'agentid': agent_id,
- 'media_id': media_id,
- 'articles': articles_data
- }
+ "material/update_news",
+ data={"agentid": agent_id, "media_id": media_id, "articles": articles_data},
)
def get_count(self, agent_id):
@@ -170,10 +161,10 @@ def get_count(self, agent_id):
:return: 返回的 JSON 数据包
"""
return self._get(
- 'material/get_count',
+ "material/get_count",
params={
- 'agent_id': agent_id,
- }
+ "agent_id": agent_id,
+ },
)
def batchget(self, agent_id, media_type, offset=0, count=20):
@@ -190,11 +181,11 @@ def batchget(self, agent_id, media_type, offset=0, count=20):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'material/batchget',
+ "material/batchget",
data={
- 'agent_id': agent_id,
- 'type': media_type,
- 'offset': offset,
- 'count': count
- }
+ "agent_id": agent_id,
+ "type": media_type,
+ "offset": offset,
+ "count": count,
+ },
)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/media.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/media.py
index 15762f3..4705bbf 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/media.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/media.py
@@ -23,7 +23,9 @@ def upload(self, media_type, media_file):
:param media_file: 要上传的文件,一个 File-object
:return: 返回的 JSON 数据包
"""
- return self._post('media/upload', params={'type': media_type}, files={'media': media_file})
+ return self._post(
+ "media/upload", params={"type": media_type}, files={"media": media_file}
+ )
def upload_img(self, image_file):
"""
@@ -38,7 +40,7 @@ def upload_img(self, image_file):
:return: 返回的 JSON 数据包
"""
- return self._post('media/uploadimg', files={'media': image_file})
+ return self._post("media/uploadimg", files={"media": image_file})
def get_url(self, media_id):
"""
@@ -50,13 +52,13 @@ def get_url(self, media_id):
:return: 临时素材下载地址
"""
parts = (
- 'https://qyapi.weixin.qq.com/cgi-bin/media/get',
- '?access_token=',
+ "https://qyapi.weixin.qq.com/cgi-bin/media/get",
+ "?access_token=",
self.access_token,
- '&media_id=',
- media_id
+ "&media_id=",
+ media_id,
)
- return ''.join(parts)
+ return "".join(parts)
def get_jssdk_url(self, media_id):
"""
@@ -68,13 +70,13 @@ def get_jssdk_url(self, media_id):
:return: 高清语音素材下载地址
"""
parts = (
- 'https://qyapi.weixin.qq.com/cgi-bin/media/get/jssdk',
- '?access_token=',
+ "https://qyapi.weixin.qq.com/cgi-bin/media/get/jssdk",
+ "?access_token=",
self.access_token,
- '&media_id=',
- media_id
+ "&media_id=",
+ media_id,
)
- return ''.join(parts)
+ return "".join(parts)
def download(self, media_id):
"""
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/menu.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/menu.py
index 612fb25..41aabd2 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/menu.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/menu.py
@@ -19,13 +19,7 @@ def create(self, agent_id, menu_data):
:param agent_id: 应用id
"""
- return self._post(
- 'menu/create',
- params={
- 'agentid': agent_id
- },
- data=menu_data
- )
+ return self._post("menu/create", params={"agentid": agent_id}, data=menu_data)
def get(self, agent_id):
"""
@@ -35,12 +29,7 @@ def get(self, agent_id):
:param agent_id: 应用id
"""
- return self._get(
- 'menu/get',
- params={
- 'agentid': agent_id
- }
- )
+ return self._get("menu/get", params={"agentid": agent_id})
def delete(self, agent_id):
"""
@@ -50,12 +39,7 @@ def delete(self, agent_id):
:param agent_id: 应用id
"""
- return self._get(
- 'menu/delete',
- params={
- 'agentid': agent_id
- }
- )
+ return self._get("menu/delete", params={"agentid": agent_id})
def update(self, agent_id, menu_data):
self.delete(agent_id)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/message.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/message.py
index 21b2988..9952ebc 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/message.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/message.py
@@ -25,8 +25,7 @@ class WeChatMessage(BaseWeChatAPI):
* 小程序通知消息
"""
- def send(self, agent_id, user_ids, party_ids='',
- tag_ids='', msg=None):
+ def send(self, agent_id, user_ids, party_ids="", tag_ids="", msg=None):
"""
通用的消息发送接口。msg 内需要指定 msgtype 和对应类型消息必须的字段。
如果部分接收人无权限或不存在,发送仍然执行,但会返回无效的部分(即invaliduser或invalidparty或invalidtag),常见的原因是接收人不在应用的可见范围内。
@@ -42,38 +41,42 @@ def send(self, agent_id, user_ids, party_ids='',
"""
msg = msg or {}
if isinstance(user_ids, (tuple, list)):
- user_ids = '|'.join(user_ids)
+ user_ids = "|".join(user_ids)
if isinstance(party_ids, (tuple, list)):
- party_ids = '|'.join(party_ids)
+ party_ids = "|".join(party_ids)
if isinstance(tag_ids, (tuple, list)):
- tag_ids = '|'.join(tag_ids)
+ tag_ids = "|".join(tag_ids)
data = {
- 'touser': user_ids,
- 'toparty': party_ids,
- 'totag': tag_ids,
- 'agentid': agent_id
+ "touser": user_ids,
+ "toparty": party_ids,
+ "totag": tag_ids,
+ "agentid": agent_id,
}
data.update(msg)
- return self._post('message/send', data=data)
+ return self._post("message/send", data=data)
- def send_text(self, agent_id, user_ids, content,
- party_ids='', tag_ids='', safe=0):
+ def send_text(self, agent_id, user_ids, content, party_ids="", tag_ids="", safe=0):
return self.send(
agent_id,
user_ids,
party_ids,
tag_ids,
- msg={
- 'msgtype': 'text',
- 'text': {'content': content},
- 'safe': safe
- }
+ msg={"msgtype": "text", "text": {"content": content}, "safe": safe},
)
- def send_text_card(self, agent_id, user_ids, title, description, url, btntxt='详情',
- party_ids='', tag_ids=''):
- """ 文本卡片消息
+ def send_text_card(
+ self,
+ agent_id,
+ user_ids,
+ title,
+ description,
+ url,
+ btntxt="详情",
+ party_ids="",
+ tag_ids="",
+ ):
+ """文本卡片消息
https://work.weixin.qq.com/api/doc#90000/90135/90236/文本卡片消息
@@ -113,129 +116,114 @@ def send_text_card(self, agent_id, user_ids, title, description, url, btntxt='
party_ids,
tag_ids,
msg={
- 'msgtype': 'textcard',
- 'textcard': {
- 'title': title,
- 'description': description,
- 'url': url,
- 'btntxt': btntxt,
+ "msgtype": "textcard",
+ "textcard": {
+ "title": title,
+ "description": description,
+ "url": url,
+ "btntxt": btntxt,
},
- }
+ },
)
- def send_image(self, agent_id, user_ids, media_id,
- party_ids='', tag_ids='', safe=0):
+ def send_image(
+ self, agent_id, user_ids, media_id, party_ids="", tag_ids="", safe=0
+ ):
return self.send(
agent_id,
user_ids,
party_ids,
tag_ids,
- msg={
- 'msgtype': 'image',
- 'image': {
- 'media_id': media_id
- },
- 'safe': safe
- }
+ msg={"msgtype": "image", "image": {"media_id": media_id}, "safe": safe},
)
- def send_voice(self, agent_id, user_ids, media_id,
- party_ids='', tag_ids='', safe=0):
+ def send_voice(
+ self, agent_id, user_ids, media_id, party_ids="", tag_ids="", safe=0
+ ):
return self.send(
agent_id,
user_ids,
party_ids,
tag_ids,
- msg={
- 'msgtype': 'voice',
- 'voice': {
- 'media_id': media_id
- },
- 'safe': safe
- }
+ msg={"msgtype": "voice", "voice": {"media_id": media_id}, "safe": safe},
)
- def send_video(self, agent_id, user_ids, media_id, title=None,
- description=None, party_ids='', tag_ids='', safe=0):
+ def send_video(
+ self,
+ agent_id,
+ user_ids,
+ media_id,
+ title=None,
+ description=None,
+ party_ids="",
+ tag_ids="",
+ safe=0,
+ ):
video_data = optionaldict()
- video_data['media_id'] = media_id
- video_data['title'] = title
- video_data['description'] = description
+ video_data["media_id"] = media_id
+ video_data["title"] = title
+ video_data["description"] = description
return self.send(
agent_id,
user_ids,
party_ids,
tag_ids,
- msg={
- 'msgtype': 'video',
- 'video': dict(video_data),
- 'safe': safe
- }
+ msg={"msgtype": "video", "video": dict(video_data), "safe": safe},
)
- def send_file(self, agent_id, user_ids, media_id,
- party_ids='', tag_ids='', safe=0):
+ def send_file(self, agent_id, user_ids, media_id, party_ids="", tag_ids="", safe=0):
return self.send(
agent_id,
user_ids,
party_ids,
tag_ids,
- msg={
- 'msgtype': 'file',
- 'file': {
- 'media_id': media_id
- },
- 'safe': safe
- }
+ msg={"msgtype": "file", "file": {"media_id": media_id}, "safe": safe},
)
- def send_articles(self, agent_id, user_ids, articles,
- party_ids='', tag_ids=''):
+ def send_articles(self, agent_id, user_ids, articles, party_ids="", tag_ids=""):
articles_data = []
for article in articles:
- articles_data.append({
- 'title': article['title'],
- 'description': article['description'],
- 'url': article['url'],
- 'picurl': article['image']
- })
+ articles_data.append(
+ {
+ "title": article["title"],
+ "description": article["description"],
+ "url": article["url"],
+ "picurl": article["image"],
+ }
+ )
return self.send(
agent_id,
user_ids,
party_ids,
tag_ids,
- msg={
- 'msgtype': 'news',
- 'news': {
- 'articles': articles_data
- }
- }
+ msg={"msgtype": "news", "news": {"articles": articles_data}},
)
- def send_mp_articles(self, agent_id, user_ids, articles,
- party_ids='', tag_ids='', safe=0):
+ def send_mp_articles(
+ self, agent_id, user_ids, articles, party_ids="", tag_ids="", safe=0
+ ):
articles_data = []
for article in articles:
- articles_data.append({
- 'thumb_media_id': article['thumb_media_id'],
- 'author': article['author'],
- 'title': article['title'],
- 'content': article['content'],
- 'content_source_url': article['content_source_url'],
- 'digest': article['digest'],
- 'show_cover_pic': article['show_cover_pic']
- })
+ articles_data.append(
+ {
+ "thumb_media_id": article["thumb_media_id"],
+ "author": article["author"],
+ "title": article["title"],
+ "content": article["content"],
+ "content_source_url": article["content_source_url"],
+ "digest": article["digest"],
+ "show_cover_pic": article["show_cover_pic"],
+ }
+ )
return self.send(
agent_id,
user_ids,
party_ids,
tag_ids,
msg={
- 'msgtype': 'mpnews',
- 'mpnews': {
- 'articles': articles_data
- },
- 'safe': safe
- }
+ "msgtype": "mpnews",
+ "mpnews": {"articles": articles_data},
+ "safe": safe,
+ },
)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/misc.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/misc.py
index 54c356c..34c9e2f 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/misc.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/misc.py
@@ -14,5 +14,5 @@ def get_wechat_ips(self):
:return: 企业微信回调的IP段
"""
- res = self._get('getcallbackip')
- return res['ip_list']
+ res = self._get("getcallbackip")
+ return res["ip_list"]
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/oauth.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/oauth.py
index cffe7ca..9bb913a 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/oauth.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/oauth.py
@@ -7,7 +7,7 @@
class WeChatOAuth(BaseWeChatAPI):
- OAUTH_BASE_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize'
+ OAUTH_BASE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize"
def authorize_url(self, redirect_uri, state=None):
"""
@@ -19,19 +19,19 @@ def authorize_url(self, redirect_uri, state=None):
:param state: 重定向后会带上 state 参数
:return: 返回的 JSON 数据包
"""
- redirect_uri = six.moves.urllib.parse.quote(redirect_uri, safe=b'')
+ redirect_uri = six.moves.urllib.parse.quote(redirect_uri, safe=b"")
url_list = [
self.OAUTH_BASE_URL,
- '?appid=',
+ "?appid=",
self._client.corp_id,
- '&redirect_uri=',
+ "&redirect_uri=",
redirect_uri,
- '&response_type=code&scope=snsapi_base',
+ "&response_type=code&scope=snsapi_base",
]
if state:
- url_list.extend(['&state=', state])
- url_list.append('#wechat_redirect')
- return ''.join(url_list)
+ url_list.extend(["&state=", state])
+ url_list.append("#wechat_redirect")
+ return "".join(url_list)
def get_user_info(self, code):
"""
@@ -44,8 +44,8 @@ def get_user_info(self, code):
"""
return self._get(
- 'order/getuserinfo',
+ "order/getuserinfo",
params={
- 'code': code,
- }
+ "code": code,
+ },
)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/service.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/service.py
index 75ba8ee..2b4d083 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/service.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/service.py
@@ -23,11 +23,11 @@ def get_provider_token(self, provider_secret):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'service/get_provider_token',
+ "service/get_provider_token",
data={
- 'corpid': self._client.corp_id,
- 'provider_secret': provider_secret,
- }
+ "corpid": self._client.corp_id,
+ "provider_secret": provider_secret,
+ },
)
def get_suite_token(self, suite_id, suite_secret, suite_ticket):
@@ -42,12 +42,12 @@ def get_suite_token(self, suite_id, suite_secret, suite_ticket):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'service/get_suite_token',
+ "service/get_suite_token",
data={
- 'suite_id': suite_id,
- 'suite_secret': suite_secret,
- 'suite_ticket': suite_ticket
- }
+ "suite_id": suite_id,
+ "suite_secret": suite_secret,
+ "suite_ticket": suite_ticket,
+ },
)
def get_login_info(self, auth_code, provider_access_token=None):
@@ -62,16 +62,18 @@ def get_login_info(self, auth_code, provider_access_token=None):
:return: 返回的 JSON 数据包
"""
return self._post(
- 'service/get_login_info',
+ "service/get_login_info",
params={
- 'provider_access_token': provider_access_token,
+ "provider_access_token": provider_access_token,
},
data={
- 'auth_code': auth_code,
- }
+ "auth_code": auth_code,
+ },
)
- def get_login_url(self, login_ticket, target, agentid=None, provider_access_token=None):
+ def get_login_url(
+ self, login_ticket, target, agentid=None, provider_access_token=None
+ ):
"""
获取登录企业号官网的url
@@ -85,13 +87,13 @@ def get_login_url(self, login_ticket, target, agentid=None, provider_access_toke
:return: 返回的 JSON 数据包
"""
return self._post(
- 'service/get_login_url',
+ "service/get_login_url",
params={
- 'provider_access_token': provider_access_token,
+ "provider_access_token": provider_access_token,
},
data={
- 'login_ticket': login_ticket,
- 'target': target,
- 'agentid': agentid,
- }
+ "login_ticket": login_ticket,
+ "target": target,
+ "agentid": agentid,
+ },
)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/shakearound.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/shakearound.py
index 0155576..047ebbc 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/shakearound.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/shakearound.py
@@ -15,10 +15,5 @@ def get_shake_info(self, ticket):
:param ticket: 摇周边业务的ticket,可在摇到的 URL 中得到,ticket 生效时间为30分钟
:return: 设备及用户信息
"""
- res = self._post(
- 'shakearound/getshakeinfo',
- data={
- 'ticket': ticket
- }
- )
- return res['data']
+ res = self._post("shakearound/getshakeinfo", data={"ticket": ticket})
+ return res["data"]
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/tag.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/tag.py
index dce5dd5..8db6f66 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/tag.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/tag.py
@@ -12,56 +12,27 @@ class WeChatTag(BaseWeChatAPI):
"""
def create(self, name):
- return self._post(
- 'tag/create',
- data={
- 'tagname': name
- }
- )
+ return self._post("tag/create", data={"tagname": name})
def update(self, tag_id, name):
- return self._post(
- 'tag/update',
- data={
- 'tagid': tag_id,
- 'tagname': name
- }
- )
+ return self._post("tag/update", data={"tagid": tag_id, "tagname": name})
def delete(self, tag_id):
- return self._get(
- 'tag/delete',
- params={
- 'tagid': tag_id
- }
- )
+ return self._get("tag/delete", params={"tagid": tag_id})
def get_users(self, tag_id):
- return self._get(
- 'tag/get',
- params={
- 'tagid': tag_id
- }
- )
+ return self._get("tag/get", params={"tagid": tag_id})
def add_users(self, tag_id, user_ids):
return self._post(
- 'tag/addtagusers',
- data={
- 'tagid': tag_id,
- 'userlist': user_ids
- }
+ "tag/addtagusers", data={"tagid": tag_id, "userlist": user_ids}
)
def delete_users(self, tag_id, user_ids):
return self._post(
- 'tag/deltagusers',
- data={
- 'tagid': tag_id,
- 'userlist': user_ids
- }
+ "tag/deltagusers", data={"tagid": tag_id, "userlist": user_ids}
)
def list(self):
- res = self._get('tag/list')
- return res['taglist']
+ res = self._get("tag/list")
+ return res["taglist"]
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/user.py b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/user.py
index bd5e367..e94404c 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/client/api/user.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/client/api/user.py
@@ -15,30 +15,37 @@ class WeChatUser(BaseWeChatAPI):
邀请成员接口位于 `WeChatBatch.invite`
"""
- def create(self, user_id, name, department=None, position=None,
- mobile=None, gender=0, tel=None, email=None,
- weixin_id=None, extattr=None):
+ def create(
+ self,
+ user_id,
+ name,
+ department=None,
+ position=None,
+ mobile=None,
+ gender=0,
+ tel=None,
+ email=None,
+ weixin_id=None,
+ extattr=None,
+ ):
"""
创建成员
https://work.weixin.qq.com/api/doc#90000/90135/90195
"""
user_data = optionaldict()
- user_data['userid'] = user_id
- user_data['name'] = name
- user_data['gender'] = gender
- user_data['department'] = department
- user_data['position'] = position
- user_data['mobile'] = mobile
- user_data['tel'] = tel
- user_data['email'] = email
- user_data['weixinid'] = weixin_id
- user_data['extattr'] = extattr
-
- return self._post(
- 'order/create',
- data=user_data
- )
+ user_data["userid"] = user_id
+ user_data["name"] = name
+ user_data["gender"] = gender
+ user_data["department"] = department
+ user_data["position"] = position
+ user_data["mobile"] = mobile
+ user_data["tel"] = tel
+ user_data["email"] = email
+ user_data["weixinid"] = weixin_id
+ user_data["extattr"] = extattr
+
+ return self._post("order/create", data=user_data)
def get(self, user_id):
"""
@@ -46,38 +53,41 @@ def get(self, user_id):
https://work.weixin.qq.com/api/doc#90000/90135/90196
"""
- return self._get(
- 'order/get',
- params={
- 'userid': user_id
- }
- )
-
- def update(self, user_id, name=None, department=None, position=None,
- mobile=None, gender=None, tel=None, email=None,
- weixin_id=None, enable=None, extattr=None):
+ return self._get("order/get", params={"userid": user_id})
+
+ def update(
+ self,
+ user_id,
+ name=None,
+ department=None,
+ position=None,
+ mobile=None,
+ gender=None,
+ tel=None,
+ email=None,
+ weixin_id=None,
+ enable=None,
+ extattr=None,
+ ):
"""
更新成员
https://work.weixin.qq.com/api/doc#90000/90135/90197
"""
user_data = optionaldict()
- user_data['userid'] = user_id
- user_data['name'] = name
- user_data['gender'] = gender
- user_data['department'] = department
- user_data['position'] = position
- user_data['mobile'] = mobile
- user_data['tel'] = tel
- user_data['email'] = email
- user_data['weixinid'] = weixin_id
- user_data['extattr'] = extattr
- user_data['enable'] = enable
-
- return self._post(
- 'order/update',
- data=user_data
- )
+ user_data["userid"] = user_id
+ user_data["name"] = name
+ user_data["gender"] = gender
+ user_data["department"] = department
+ user_data["position"] = position
+ user_data["mobile"] = mobile
+ user_data["tel"] = tel
+ user_data["email"] = email
+ user_data["weixinid"] = weixin_id
+ user_data["extattr"] = extattr
+ user_data["enable"] = enable
+
+ return self._post("order/update", data=user_data)
def delete(self, user_id):
"""
@@ -85,12 +95,7 @@ def delete(self, user_id):
https://work.weixin.qq.com/api/doc#90000/90135/90198
"""
- return self._get(
- 'order/delete',
- params={
- 'userid': user_id
- }
- )
+ return self._get("order/delete", params={"userid": user_id})
def batch_delete(self, user_ids):
"""
@@ -98,12 +103,7 @@ def batch_delete(self, user_ids):
https://work.weixin.qq.com/api/doc#90000/90135/90199
"""
- return self._post(
- 'order/batchdelete',
- data={
- 'useridlist': user_ids
- }
- )
+ return self._post("order/batchdelete", data={"useridlist": user_ids})
def list(self, department_id, fetch_child=False, status=0, simple=False):
"""
@@ -114,16 +114,16 @@ def list(self, department_id, fetch_child=False, status=0, simple=False):
此接口和 `WeChatDepartment.get_users` 是同一个接口,区别为 simple 的默认值不同。
"""
- url = 'order/simplelist' if simple else 'order/list'
+ url = "order/simplelist" if simple else "order/list"
res = self._get(
url,
params={
- 'department_id': department_id,
- 'fetch_child': 1 if fetch_child else 0,
- 'status': status
- }
+ "department_id": department_id,
+ "fetch_child": 1 if fetch_child else 0,
+ "status": status,
+ },
)
- return res['userlist']
+ return res["userlist"]
def convert_to_openid(self, user_id, agent_id=None):
"""
@@ -135,11 +135,8 @@ def convert_to_openid(self, user_id, agent_id=None):
:param agent_id: 可选,需要发送红包的应用ID,若只是使用微信支付和企业转账,则无需该参数
:return: 返回的 JSON 数据包
"""
- data = optionaldict(
- userid=user_id,
- agentid=agent_id
- )
- return self._post('order/convert_to_openid', data=data)
+ data = optionaldict(userid=user_id, agentid=agent_id)
+ return self._post("order/convert_to_openid", data=data)
def convert_to_user_id(self, openid):
"""
@@ -150,8 +147,8 @@ def convert_to_user_id(self, openid):
:param openid: 在使用微信支付、微信红包和企业转账之后,返回结果的openid
:return: 该 openid 在企业微信中对应的成员 user_id
"""
- res = self._post('order/convert_to_userid', data={'openid': openid})
- return res['userid']
+ res = self._post("order/convert_to_userid", data={"openid": openid})
+ return res["userid"]
def verify(self, user_id):
"""
@@ -161,18 +158,9 @@ def verify(self, user_id):
:param user_id: 成员UserID。对应管理端的帐号
"""
- return self._get(
- 'order/authsucc',
- params={
- 'userid': user_id
- }
- )
+ return self._get("order/authsucc", params={"userid": user_id})
def get_info(self, agent_id, code):
return self._get(
- 'order/getuserinfo',
- params={
- 'agentid': agent_id,
- 'code': code
- }
+ "order/getuserinfo", params={"agentid": agent_id, "code": code}
)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/crypto.py b/chapter14/booking_system/exts/wechatpy/enterprise/crypto.py
index 9b14bd6..90e6f4a 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/crypto.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/crypto.py
@@ -20,27 +20,10 @@ def __init__(self, token, encoding_aes_key, corp_id):
self.corp_id = corp_id
def check_signature(self, signature, timestamp, nonce, echo_str):
- return self._check_signature(
- signature,
- timestamp,
- nonce,
- echo_str,
- PrpCrypto
- )
+ return self._check_signature(signature, timestamp, nonce, echo_str, PrpCrypto)
def encrypt_message(self, msg, nonce, timestamp=None):
- return self._encrypt_message(
- msg,
- nonce,
- timestamp,
- PrpCrypto
- )
+ return self._encrypt_message(msg, nonce, timestamp, PrpCrypto)
def decrypt_message(self, msg, signature, timestamp, nonce):
- return self._decrypt_message(
- msg,
- signature,
- timestamp,
- nonce,
- PrpCrypto
- )
+ return self._decrypt_message(msg, signature, timestamp, nonce, PrpCrypto)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/exceptions.py b/chapter14/booking_system/exts/wechatpy/enterprise/exceptions.py
index a4ac5ee..13cd7f5 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/exceptions.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/exceptions.py
@@ -6,5 +6,5 @@
class InvalidCorpIdException(WeChatException):
- def __init__(self, errcode=-40005, errmsg='Invalid corp_id'):
+ def __init__(self, errcode=-40005, errmsg="Invalid corp_id"):
super(InvalidCorpIdException, self).__init__(errcode, errmsg)
diff --git a/chapter14/booking_system/exts/wechatpy/enterprise/parser.py b/chapter14/booking_system/exts/wechatpy/enterprise/parser.py
index 31fa199..7d1040d 100644
--- a/chapter14/booking_system/exts/wechatpy/enterprise/parser.py
+++ b/chapter14/booking_system/exts/wechatpy/enterprise/parser.py
@@ -12,10 +12,10 @@
def parse_message(xml):
if not xml:
return
- message = xmltodict.parse(to_text(xml))['xml']
- message_type = message['MsgType'].lower()
- if message_type == 'event':
- event_type = message['Event'].lower()
+ message = xmltodict.parse(to_text(xml))["xml"]
+ message_type = message["MsgType"].lower()
+ if message_type == "event":
+ event_type = message["Event"].lower()
message_class = EVENT_TYPES.get(event_type, UnknownMessage)
else:
message_class = MESSAGE_TYPES.get(message_type, UnknownMessage)
diff --git a/chapter14/booking_system/exts/wechatpy/events.py b/chapter14/booking_system/exts/wechatpy/events.py
index eeb03db..a1ba320 100644
--- a/chapter14/booking_system/exts/wechatpy/events.py
+++ b/chapter14/booking_system/exts/wechatpy/events.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.events
- ~~~~~~~~~~~~~~~~
+wechatpy.events
+~~~~~~~~~~~~~~~~
- This module contains all the events WeChat callback uses.
+This module contains all the events WeChat callback uses.
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
@@ -16,7 +16,7 @@
IntegerField,
BaseField,
Base64DecodeField,
- DateTimeField
+ DateTimeField,
)
from exts.wechatpy.messages import BaseMessage
@@ -30,19 +30,22 @@ def register_event(event_type):
:param event_type: Event type
"""
+
def register(cls):
EVENT_TYPES[event_type] = cls
return cls
+
return register
class BaseEvent(BaseMessage):
"""Base class for all events"""
- type = 'event'
- event = ''
+
+ type = "event"
+ event = ""
-@register_event('subscribe')
+@register_event("subscribe")
class SubscribeEvent(BaseEvent):
"""
用户关注事件
@@ -50,11 +53,12 @@ class SubscribeEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421140454
"""
- event = 'subscribe'
- key = StringField('EventKey', '')
+ event = "subscribe"
+ key = StringField("EventKey", "")
-@register_event('unsubscribe')
+
+@register_event("unsubscribe")
class UnsubscribeEvent(BaseEvent):
"""
用户取消关注事件
@@ -62,10 +66,11 @@ class UnsubscribeEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421140454
"""
- event = 'unsubscribe'
+
+ event = "unsubscribe"
-@register_event('subscribe_scan')
+@register_event("subscribe_scan")
class SubscribeScanEvent(BaseEvent):
"""
用户扫描二维码关注事件
@@ -73,12 +78,13 @@ class SubscribeScanEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421140454
"""
- event = 'subscribe_scan'
- scene_id = StringField('EventKey')
- ticket = StringField('Ticket')
+ event = "subscribe_scan"
+ scene_id = StringField("EventKey")
+ ticket = StringField("Ticket")
-@register_event('scan')
+
+@register_event("scan")
class ScanEvent(BaseEvent):
"""
用户扫描二维码事件
@@ -86,12 +92,13 @@ class ScanEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421140454
"""
- event = 'scan'
- scene_id = StringField('EventKey')
- ticket = StringField('Ticket')
+
+ event = "scan"
+ scene_id = StringField("EventKey")
+ ticket = StringField("Ticket")
-@register_event('location')
+@register_event("location")
class LocationEvent(BaseEvent):
"""
上报地理位置事件
@@ -99,13 +106,14 @@ class LocationEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421140454
"""
- event = 'location'
- latitude = FloatField('Latitude', 0.0)
- longitude = FloatField('Longitude', 0.0)
- precision = FloatField('Precision', 0.0)
+
+ event = "location"
+ latitude = FloatField("Latitude", 0.0)
+ longitude = FloatField("Longitude", 0.0)
+ precision = FloatField("Precision", 0.0)
-@register_event('click')
+@register_event("click")
class ClickEvent(BaseEvent):
"""
点击菜单拉取消息事件
@@ -113,11 +121,12 @@ class ClickEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421140454
"""
- event = 'click'
- key = StringField('EventKey')
+ event = "click"
+ key = StringField("EventKey")
-@register_event('view')
+
+@register_event("view")
class ViewEvent(BaseEvent):
"""
点击菜单跳转链接事件
@@ -125,11 +134,12 @@ class ViewEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421140454
"""
- event = 'view'
- url = StringField('EventKey')
+
+ event = "view"
+ url = StringField("EventKey")
-@register_event('masssendjobfinish')
+@register_event("masssendjobfinish")
class MassSendJobFinishEvent(BaseEvent):
"""
群发消息任务完成事件
@@ -137,16 +147,17 @@ class MassSendJobFinishEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1481187827_i0l21
"""
- id = IntegerField('MsgID', 0)
- event = 'masssendjobfinish'
- status = StringField('Status')
- total_count = IntegerField('TotalCount', 0)
- filter_count = IntegerField('FilterCount', 0)
- sent_count = IntegerField('SentCount', 0)
- error_count = IntegerField('ErrorCount', 0)
+ id = IntegerField("MsgID", 0)
+ event = "masssendjobfinish"
+ status = StringField("Status")
+ total_count = IntegerField("TotalCount", 0)
+ filter_count = IntegerField("FilterCount", 0)
+ sent_count = IntegerField("SentCount", 0)
+ error_count = IntegerField("ErrorCount", 0)
-@register_event('templatesendjobfinish')
+
+@register_event("templatesendjobfinish")
class TemplateSendJobFinishEvent(BaseEvent):
"""
模板消息任务完成事件
@@ -154,25 +165,26 @@ class TemplateSendJobFinishEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1433751277
"""
- id = IntegerField('MsgID')
- event = 'templatesendjobfinish'
- status = StringField('Status')
+
+ id = IntegerField("MsgID")
+ event = "templatesendjobfinish"
+ status = StringField("Status")
class BaseScanCodeEvent(BaseEvent):
- key = StringField('EventKey')
- scan_code_info = BaseField('ScanCodeInfo', {})
+ key = StringField("EventKey")
+ scan_code_info = BaseField("ScanCodeInfo", {})
@property
def scan_type(self):
- return self.scan_code_info['ScanType']
+ return self.scan_code_info["ScanType"]
@property
def scan_result(self):
- return self.scan_code_info['ScanResult']
+ return self.scan_code_info["ScanResult"]
-@register_event('scancode_push')
+@register_event("scancode_push")
class ScanCodePushEvent(BaseScanCodeEvent):
"""
扫码推事件
@@ -180,10 +192,11 @@ class ScanCodePushEvent(BaseScanCodeEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421141016
"""
- event = 'scancode_push'
+
+ event = "scancode_push"
-@register_event('scancode_waitmsg')
+@register_event("scancode_waitmsg")
class ScanCodeWaitMsgEvent(BaseScanCodeEvent):
"""
扫码推事件且弹出“消息接收中”提示框的事件
@@ -191,28 +204,29 @@ class ScanCodeWaitMsgEvent(BaseScanCodeEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421141016
"""
- event = 'scancode_waitmsg'
+
+ event = "scancode_waitmsg"
class BasePictureEvent(BaseEvent):
- key = StringField('EventKey')
- pictures_info = BaseField('SendPicsInfo', {})
+ key = StringField("EventKey")
+ pictures_info = BaseField("SendPicsInfo", {})
@property
def count(self):
- return int(self.pictures_info['Count'])
+ return int(self.pictures_info["Count"])
@property
def pictures(self):
- if self.pictures_info['PicList']:
- items = self.pictures_info['PicList']['item']
+ if self.pictures_info["PicList"]:
+ items = self.pictures_info["PicList"]["item"]
if self.count > 1:
return items
return [items]
return []
-@register_event('pic_sysphoto')
+@register_event("pic_sysphoto")
class PicSysPhotoEvent(BasePictureEvent):
"""
弹出系统拍照发图的事件
@@ -220,10 +234,11 @@ class PicSysPhotoEvent(BasePictureEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421141016
"""
- event = 'pic_sysphoto'
+
+ event = "pic_sysphoto"
-@register_event('pic_photo_or_album')
+@register_event("pic_photo_or_album")
class PicPhotoOrAlbumEvent(BasePictureEvent):
"""
弹出拍照或者相册发图的事件
@@ -231,10 +246,11 @@ class PicPhotoOrAlbumEvent(BasePictureEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421141016
"""
- event = 'pic_photo_or_album'
+ event = "pic_photo_or_album"
-@register_event('pic_weixin')
+
+@register_event("pic_weixin")
class PicWeChatEvent(BasePictureEvent):
"""
弹出微信相册发图器的事件
@@ -242,10 +258,11 @@ class PicWeChatEvent(BasePictureEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421141016
"""
- event = 'pic_weixin'
+
+ event = "pic_weixin"
-@register_event('location_select')
+@register_event("location_select")
class LocationSelectEvent(BaseEvent):
"""
弹出地理位置选择器的事件
@@ -253,17 +270,18 @@ class LocationSelectEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1421141016
"""
- event = 'location_select'
- key = StringField('EventKey')
- location_info = BaseField('SendLocationInfo', {})
+
+ event = "location_select"
+ key = StringField("EventKey")
+ location_info = BaseField("SendLocationInfo", {})
@property
def location_x(self):
- return self.location_info['Location_X']
+ return self.location_info["Location_X"]
@property
def location_y(self):
- return self.location_info['Location_Y']
+ return self.location_info["Location_Y"]
@property
def location(self):
@@ -271,30 +289,30 @@ def location(self):
@property
def scale(self):
- return self.location_info['Scale']
+ return self.location_info["Scale"]
@property
def label(self):
- return self.location_info['Label']
+ return self.location_info["Label"]
@property
def poiname(self):
- return self.location_info['Poiname']
+ return self.location_info["Poiname"]
-@register_event('card_pass_check')
+@register_event("card_pass_check")
class CardPassCheckEvent(BaseEvent):
- event = 'card_pass_check'
- card_id = StringField('CardId')
+ event = "card_pass_check"
+ card_id = StringField("CardId")
-@register_event('card_not_pass_check')
+@register_event("card_not_pass_check")
class CardNotPassCheckEvent(BaseEvent):
- event = 'card_not_pass_check'
- card_id = StringField('CardId')
+ event = "card_not_pass_check"
+ card_id = StringField("CardId")
-@register_event('user_get_card')
+@register_event("user_get_card")
class UserGetCardEvent(BaseEvent):
"""
领取事件推送
@@ -302,16 +320,17 @@ class UserGetCardEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1451025274
"""
- event = 'user_get_card'
- card_id = StringField('CardId')
- is_given_by_friend = IntegerField('IsGiveByFriend')
- friend = StringField('FriendUserName')
- code = StringField('UserCardCode')
- old_code = StringField('OldUserCardCode')
- outer_id = StringField('OuterId')
+
+ event = "user_get_card"
+ card_id = StringField("CardId")
+ is_given_by_friend = IntegerField("IsGiveByFriend")
+ friend = StringField("FriendUserName")
+ code = StringField("UserCardCode")
+ old_code = StringField("OldUserCardCode")
+ outer_id = StringField("OuterId")
-@register_event('user_del_card')
+@register_event("user_del_card")
class UserDeleteCardEvent(BaseEvent):
"""
卡券删除事件推送
@@ -319,12 +338,13 @@ class UserDeleteCardEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1451025274
"""
- event = 'user_del_card'
- card_id = StringField('CardId')
- code = StringField('UserCardCode')
+ event = "user_del_card"
+ card_id = StringField("CardId")
+ code = StringField("UserCardCode")
-@register_event('user_consume_card')
+
+@register_event("user_consume_card")
class UserConsumeCardEvent(BaseEvent):
"""
卡券核销事件推送
@@ -332,95 +352,96 @@ class UserConsumeCardEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1451025274
"""
- event = 'user_consume_card'
- card_id = StringField('CardId')
- code = StringField('UserCardCode')
- consume_source = StringField('ConsumeSource')
- location_id = StringField('LocationId')
- staff = StringField('StaffOpenId')
+
+ event = "user_consume_card"
+ card_id = StringField("CardId")
+ code = StringField("UserCardCode")
+ consume_source = StringField("ConsumeSource")
+ location_id = StringField("LocationId")
+ staff = StringField("StaffOpenId")
-@register_event('merchant_order')
+@register_event("merchant_order")
class MerchantOrderEvent(BaseEvent):
- event = 'merchant_order'
- order_id = StringField('OrderId')
- order_status = IntegerField('OrderStatus')
- product_id = StringField('ProductId')
- sku_info = StringField('SkuInfo')
+ event = "merchant_order"
+ order_id = StringField("OrderId")
+ order_status = IntegerField("OrderStatus")
+ product_id = StringField("ProductId")
+ sku_info = StringField("SkuInfo")
-@register_event('kf_create_session')
+@register_event("kf_create_session")
class KfCreateSessionEvent(BaseEvent):
- event = 'kf_create_session'
- account = StringField('KfAccount')
+ event = "kf_create_session"
+ account = StringField("KfAccount")
-@register_event('kf_close_session')
+@register_event("kf_close_session")
class KfCloseSessionEvent(BaseEvent):
- event = 'kf_close_session'
- account = StringField('KfAccount')
+ event = "kf_close_session"
+ account = StringField("KfAccount")
-@register_event('kf_switch_session')
+@register_event("kf_switch_session")
class KfSwitchSessionEvent(BaseEvent):
- event = 'kf_switch_session'
- from_account = StringField('FromKfAccount')
- to_account = StringField('ToKfAccount')
+ event = "kf_switch_session"
+ from_account = StringField("FromKfAccount")
+ to_account = StringField("ToKfAccount")
-@register_event('device_text')
+@register_event("device_text")
class DeviceTextEvent(BaseEvent):
- event = 'device_text'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64DecodeField('Content')
- open_id = StringField('OpenID')
+ event = "device_text"
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ session_id = StringField("SessionID")
+ content = Base64DecodeField("Content")
+ open_id = StringField("OpenID")
-@register_event('device_bind')
+@register_event("device_bind")
class DeviceBindEvent(BaseEvent):
- event = 'device_bind'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64DecodeField('Content')
- open_id = StringField('OpenID')
+ event = "device_bind"
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ session_id = StringField("SessionID")
+ content = Base64DecodeField("Content")
+ open_id = StringField("OpenID")
-@register_event('device_unbind')
+@register_event("device_unbind")
class DeviceUnbindEvent(BaseEvent):
- event = 'device_unbind'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64DecodeField('Content')
- open_id = StringField('OpenID')
+ event = "device_unbind"
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ session_id = StringField("SessionID")
+ content = Base64DecodeField("Content")
+ open_id = StringField("OpenID")
-@register_event('device_subscribe_status')
+@register_event("device_subscribe_status")
class DeviceSubscribeStatusEvent(BaseEvent):
- event = 'device_subscribe_status'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- open_id = StringField('OpenID')
- op_type = IntegerField('OpType')
+ event = "device_subscribe_status"
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ open_id = StringField("OpenID")
+ op_type = IntegerField("OpType")
-@register_event('device_unsubscribe_status')
+@register_event("device_unsubscribe_status")
class DeviceUnsubscribeStatusEvent(BaseEvent):
- event = 'device_unsubscribe_status'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- open_id = StringField('OpenID')
- op_type = IntegerField('OpType')
+ event = "device_unsubscribe_status"
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ open_id = StringField("OpenID")
+ op_type = IntegerField("OpType")
-@register_event('shakearoundusershake')
+@register_event("shakearoundusershake")
class ShakearoundUserShakeEvent(BaseEvent):
- event = 'shakearound_user_shake'
- _chosen_beacon = BaseField('ChosenBeacon', {})
- _around_beacons = BaseField('AroundBeacons', {})
+ event = "shakearound_user_shake"
+ _chosen_beacon = BaseField("ChosenBeacon", {})
+ _around_beacons = BaseField("AroundBeacons", {})
@property
def chosen_beacon(self):
@@ -428,10 +449,10 @@ def chosen_beacon(self):
if not beacon:
return {}
return {
- 'uuid': beacon['Uuid'],
- 'major': beacon['Major'],
- 'minor': beacon['Minor'],
- 'distance': float(beacon['Distance']),
+ "uuid": beacon["Uuid"],
+ "major": beacon["Major"],
+ "minor": beacon["Minor"],
+ "distance": float(beacon["Distance"]),
}
@property
@@ -441,39 +462,41 @@ def around_beacons(self):
return []
ret = []
- for beacon in beacons['AroundBeacon']:
- ret.append({
- 'uuid': beacon['Uuid'],
- 'major': beacon['Major'],
- 'minor': beacon['Minor'],
- 'distance': float(beacon['Distance']),
- })
+ for beacon in beacons["AroundBeacon"]:
+ ret.append(
+ {
+ "uuid": beacon["Uuid"],
+ "major": beacon["Major"],
+ "minor": beacon["Minor"],
+ "distance": float(beacon["Distance"]),
+ }
+ )
return ret
-@register_event('poi_check_notify')
+@register_event("poi_check_notify")
class PoiCheckNotifyEvent(BaseEvent):
- event = 'poi_check_notify'
- poi_id = StringField('PoiId')
- uniq_id = StringField('UniqId')
- result = StringField('Result')
- message = StringField('Msg')
+ event = "poi_check_notify"
+ poi_id = StringField("PoiId")
+ uniq_id = StringField("UniqId")
+ result = StringField("Result")
+ message = StringField("Msg")
-@register_event('wificonnected')
+@register_event("wificonnected")
class WiFiConnectedEvent(BaseEvent):
- event = 'wificconnected'
- connect_time = IntegerField('ConnectTime')
- expire_time = IntegerField('ExpireTime')
- vendor_id = StringField('VendorId')
- shop_id = StringField('PlaceId')
- bssid = StringField('DeviceNo')
+ event = "wificconnected"
+ connect_time = IntegerField("ConnectTime")
+ expire_time = IntegerField("ExpireTime")
+ vendor_id = StringField("VendorId")
+ shop_id = StringField("PlaceId")
+ bssid = StringField("DeviceNo")
# ============================================================================
# 微信认证事件推送
# ============================================================================
-@register_event('qualification_verify_success')
+@register_event("qualification_verify_success")
class QualificationVerifySuccessEvent(BaseEvent):
"""
资质认证成功事件
@@ -481,11 +504,12 @@ class QualificationVerifySuccessEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1455785130
"""
- event = 'qualification_verify_success'
- expired_time = DateTimeField('ExpiredTime')
+
+ event = "qualification_verify_success"
+ expired_time = DateTimeField("ExpiredTime")
-@register_event('qualification_verify_fail')
+@register_event("qualification_verify_fail")
class QualificationVerifyFailEvent(BaseEvent):
"""
资质认证失败事件
@@ -493,12 +517,13 @@ class QualificationVerifyFailEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1455785130
"""
- event = 'qualification_verify_fail'
- fail_time = DateTimeField('FailTime')
- fail_reason = StringField('FailReason')
+ event = "qualification_verify_fail"
+ fail_time = DateTimeField("FailTime")
+ fail_reason = StringField("FailReason")
-@register_event('naming_verify_success')
+
+@register_event("naming_verify_success")
class NamingVerifySuccessEvent(BaseEvent):
"""
名称认证成功事件
@@ -506,11 +531,12 @@ class NamingVerifySuccessEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1455785130
"""
- event = 'naming_verify_success'
- expired_time = DateTimeField('ExpiredTime')
+
+ event = "naming_verify_success"
+ expired_time = DateTimeField("ExpiredTime")
-@register_event('naming_verify_fail')
+@register_event("naming_verify_fail")
class NamingVerifyFailEvent(BaseEvent):
"""
名称认证失败事件
@@ -518,12 +544,13 @@ class NamingVerifyFailEvent(BaseEvent):
客户端不打勾,但仍有接口权限。详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1455785130
"""
- event = 'naming_verify_fail'
- fail_time = DateTimeField('FailTime')
- fail_reason = StringField('FailReason')
+ event = "naming_verify_fail"
+ fail_time = DateTimeField("FailTime")
+ fail_reason = StringField("FailReason")
-@register_event('annual_renew')
+
+@register_event("annual_renew")
class AnnualRenewEvent(BaseEvent):
"""
年审通知事件
@@ -531,11 +558,12 @@ class AnnualRenewEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1455785130
"""
- event = 'annual_renew'
- expired_time = DateTimeField('ExpiredTime')
+
+ event = "annual_renew"
+ expired_time = DateTimeField("ExpiredTime")
-@register_event('verify_expired')
+@register_event("verify_expired")
class VerifyExpiredEvent(BaseEvent):
"""
认证过期失效通知
@@ -543,11 +571,12 @@ class VerifyExpiredEvent(BaseEvent):
详情请参阅
https://mp.weixin.qq.com/wiki?id=mp1455785130
"""
- event = 'verify_expired'
- expired_time = DateTimeField('ExpiredTime')
+ event = "verify_expired"
+ expired_time = DateTimeField("ExpiredTime")
-@register_event('user_scan_product')
+
+@register_event("user_scan_product")
class UserScanProductEvent(BaseEvent):
"""
打开商品主页事件
@@ -555,17 +584,18 @@ class UserScanProductEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1455872179
"""
- event = 'user_scan_product'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
- country = StringField('Country')
- province = StringField('Province')
- city = StringField('City')
- sex = IntegerField('Sex')
- scene = IntegerField('Scene')
+
+ event = "user_scan_product"
+ standard = StringField("KeyStandard")
+ key = StringField("KeyStr")
+ country = StringField("Country")
+ province = StringField("Province")
+ city = StringField("City")
+ sex = IntegerField("Sex")
+ scene = IntegerField("Scene")
-@register_event('user_scan_product_enter_session')
+@register_event("user_scan_product_enter_session")
class UserScanProductEnterSessionEvent(BaseEvent):
"""
进入公众号事件
@@ -573,12 +603,13 @@ class UserScanProductEnterSessionEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1455872179
"""
- event = 'user_scan_product_enter_session'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
+ event = "user_scan_product_enter_session"
+ standard = StringField("KeyStandard")
+ key = StringField("KeyStr")
-@register_event('user_scan_product_async')
+
+@register_event("user_scan_product_async")
class UserScanProductAsyncEvent(BaseEvent):
"""
地理位置信息异步推送事件
@@ -586,13 +617,14 @@ class UserScanProductAsyncEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1455872179
"""
- event = 'user_scan_product_async'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
- region_code = StringField('RegionCode')
+
+ event = "user_scan_product_async"
+ standard = StringField("KeyStandard")
+ key = StringField("KeyStr")
+ region_code = StringField("RegionCode")
-@register_event('user_scan_product_verify_action')
+@register_event("user_scan_product_verify_action")
class UserScanProductVerifyActionEvent(BaseEvent):
"""
商品审核结果事件
@@ -600,14 +632,15 @@ class UserScanProductVerifyActionEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1455872179
"""
- event = 'user_scan_product_verify_action'
- standard = StringField('KeyStandard')
- key = StringField('KeyStr')
- result = StringField('Result')
- reason = StringField('ReasonMsg')
+
+ event = "user_scan_product_verify_action"
+ standard = StringField("KeyStandard")
+ key = StringField("KeyStr")
+ result = StringField("Result")
+ reason = StringField("ReasonMsg")
-@register_event('subscribe_scan_product')
+@register_event("subscribe_scan_product")
class SubscribeScanProductEvent(BaseEvent):
"""
用户在商品主页中关注公众号事件
@@ -615,23 +648,24 @@ class SubscribeScanProductEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1455872179
"""
- event = 'subscribe_scan_product'
- event_key = StringField('EventKey')
+
+ event = "subscribe_scan_product"
+ event_key = StringField("EventKey")
@property
def scene(self):
- return self.event_key.split('|', 1)[0]
+ return self.event_key.split("|", 1)[0]
@property
def standard(self):
- return self.event_key.split('|')[1]
+ return self.event_key.split("|")[1]
@property
def key(self):
- return self.event_key.split('|')[2]
+ return self.event_key.split("|")[2]
-@register_event('user_authorize_invoice')
+@register_event("user_authorize_invoice")
class UserAuthorizeInvoiceEvent(BaseEvent):
"""
用户授权发票事件
@@ -640,14 +674,15 @@ class UserAuthorizeInvoiceEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1497082828_r1cI2
"""
- event = 'user_authorize_invoice'
- success_order_id = StringField('SuccOrderId') # 授权成功的订单号
- fail_order_id = StringField('FailOrderId') # 授权失败的订单号
- app_id = StringField('AppId') # 用于接收事件推送的公众号的AppId
- auth_source = StringField('Source') # 授权来源,web表示来自微信内H5,app标识来自app
+
+ event = "user_authorize_invoice"
+ success_order_id = StringField("SuccOrderId") # 授权成功的订单号
+ fail_order_id = StringField("FailOrderId") # 授权失败的订单号
+ app_id = StringField("AppId") # 用于接收事件推送的公众号的AppId
+ auth_source = StringField("Source") # 授权来源,web表示来自微信内H5,app标识来自app
-@register_event('update_invoice_status')
+@register_event("update_invoice_status")
class UpdateInvoiceStatusEvent(BaseEvent):
"""
发票状态更新事件
@@ -655,13 +690,14 @@ class UpdateInvoiceStatusEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1497082828_r1cI2
"""
- event = 'update_invoice_status'
- status = StringField('Status') # 发票报销状态
- card_id = StringField('CardId') # 发票 Card ID
- code = StringField('Code') # 发票 Code
+ event = "update_invoice_status"
+ status = StringField("Status") # 发票报销状态
+ card_id = StringField("CardId") # 发票 Card ID
+ code = StringField("Code") # 发票 Code
-@register_event('submit_invoice_title')
+
+@register_event("submit_invoice_title")
class SubmitInvoiceTitleEvent(BaseEvent):
"""
用户提交发票抬头事件
@@ -669,33 +705,38 @@ class SubmitInvoiceTitleEvent(BaseEvent):
详情请参考
https://mp.weixin.qq.com/wiki?id=mp1496554912_vfWU0
"""
- event = 'submit_invoice_title'
- title = StringField('title') # 抬头
- phone = StringField('phone') # 联系方式
- tax_no = StringField('tax_no') # 税号
- addr = StringField('addr') # 地址
- bank_type = StringField('bank_type') # 银行类型
- bank_no = StringField('bank_no') # 银行号码
- attach = StringField('attach') # 附加字段
- title_type = StringField('title_type') # 抬头类型,个人InvoiceUserTitlePersonType, 公司InvoiceUserTitleBusinessType
+
+ event = "submit_invoice_title"
+ title = StringField("title") # 抬头
+ phone = StringField("phone") # 联系方式
+ tax_no = StringField("tax_no") # 税号
+ addr = StringField("addr") # 地址
+ bank_type = StringField("bank_type") # 银行类型
+ bank_no = StringField("bank_no") # 银行号码
+ attach = StringField("attach") # 附加字段
+ title_type = StringField(
+ "title_type"
+ ) # 抬头类型,个人InvoiceUserTitlePersonType, 公司InvoiceUserTitleBusinessType
-@register_event('user_enter_tempsession')
+@register_event("user_enter_tempsession")
class UserEnterTempSessionEvent(BaseEvent):
"""
小程序用户进入客服消息
详情请参阅
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/receive.html
"""
- event = 'user_enter_tempsession'
- session_from = StringField('SessionFrom')
+ event = "user_enter_tempsession"
+ session_from = StringField("SessionFrom")
-@register_event('view_miniprogram')
+
+@register_event("view_miniprogram")
class ViewMiniProgramEvent(BaseEvent):
"""
从菜单进入小程序事件
"""
- event = 'view_miniprogram'
- page_path = StringField('EventKey') # 小程序路径
- menu_id = StringField('MenuId') # 菜单ID
+
+ event = "view_miniprogram"
+ page_path = StringField("EventKey") # 小程序路径
+ menu_id = StringField("MenuId") # 菜单ID
diff --git a/chapter14/booking_system/exts/wechatpy/exceptions.py b/chapter14/booking_system/exts/wechatpy/exceptions.py
index 683da28..f347485 100644
--- a/chapter14/booking_system/exts/wechatpy/exceptions.py
+++ b/chapter14/booking_system/exts/wechatpy/exceptions.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.exceptions
- ~~~~~~~~~~~~~~~~~~~~
+wechatpy.exceptions
+~~~~~~~~~~~~~~~~~~~~
- Basic exceptions definition.
+Basic exceptions definition.
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
@@ -27,9 +27,8 @@ def __init__(self, errcode, errmsg):
self.errmsg = errmsg
def __str__(self):
- _repr = 'Error code: {code}, message: {msg}'.format(
- code=self.errcode,
- msg=self.errmsg
+ _repr = "Error code: {code}, message: {msg}".format(
+ code=self.errcode, msg=self.errmsg
)
if six.PY2:
return to_binary(_repr)
@@ -37,10 +36,8 @@ def __str__(self):
return to_text(_repr)
def __repr__(self):
- _repr = '{klass}({code}, {msg})'.format(
- klass=self.__class__.__name__,
- code=self.errcode,
- msg=self.errmsg
+ _repr = "{klass}({code}, {msg})".format(
+ klass=self.__class__.__name__, code=self.errcode, msg=self.errmsg
)
if six.PY2:
return to_binary(_repr)
@@ -51,8 +48,7 @@ def __repr__(self):
class WeChatClientException(WeChatException):
"""WeChat API client exception class"""
- def __init__(self, errcode, errmsg, client=None,
- request=None, response=None):
+ def __init__(self, errcode, errmsg, client=None, request=None, response=None):
super(WeChatClientException, self).__init__(errcode, errmsg)
self.client = client
self.request = request
@@ -62,38 +58,49 @@ def __init__(self, errcode, errmsg, client=None,
class InvalidSignatureException(WeChatException):
"""Invalid signature exception class"""
- def __init__(self, errcode=-40001, errmsg='Invalid signature'):
+ def __init__(self, errcode=-40001, errmsg="Invalid signature"):
super(InvalidSignatureException, self).__init__(errcode, errmsg)
class APILimitedException(WeChatClientException):
"""WeChat API call limited exception class"""
+
pass
class InvalidAppIdException(WeChatException):
"""Invalid app_id exception class"""
- def __init__(self, errcode=-40005, errmsg='Invalid AppId'):
+ def __init__(self, errcode=-40005, errmsg="Invalid AppId"):
super(InvalidAppIdException, self).__init__(errcode, errmsg)
class WeChatOAuthException(WeChatClientException):
"""WeChat OAuth API exception class"""
+
pass
class WeChatComponentOAuthException(WeChatClientException):
"""WeChat Component OAuth API exception class"""
+
pass
class WeChatPayException(WeChatClientException):
"""WeChat Pay API exception class"""
- def __init__(self, return_code, result_code=None, return_msg=None,
- errcode=None, errmsg=None, client=None,
- request=None, response=None):
+ def __init__(
+ self,
+ return_code,
+ result_code=None,
+ return_msg=None,
+ errcode=None,
+ errmsg=None,
+ client=None,
+ request=None,
+ response=None,
+ ):
"""
:param return_code: 返回状态码
:param result_code: 业务结果
@@ -102,11 +109,7 @@ def __init__(self, return_code, result_code=None, return_msg=None,
:param errmsg: 错误代码描述
"""
super(WeChatPayException, self).__init__(
- errcode,
- errmsg,
- client,
- request,
- response
+ errcode, errmsg, client, request, response
)
self.return_code = return_code
self.result_code = result_code
@@ -114,27 +117,31 @@ def __init__(self, return_code, result_code=None, return_msg=None,
def __str__(self):
if six.PY2:
- return to_binary('Error code: {code}, message: {msg}. Pay Error code: {pay_code}, message: {pay_msg}'.format(
- code=self.return_code,
- msg=self.return_msg,
- pay_code=self.errcode,
- pay_msg=self.errmsg
- ))
+ return to_binary(
+ "Error code: {code}, message: {msg}. Pay Error code: {pay_code}, message: {pay_msg}".format(
+ code=self.return_code,
+ msg=self.return_msg,
+ pay_code=self.errcode,
+ pay_msg=self.errmsg,
+ )
+ )
else:
- return to_text('Error code: {code}, message: {msg}. Pay Error code: {pay_code}, message: {pay_msg}'.format(
- code=self.return_code,
- msg=self.return_msg,
- pay_code=self.errcode,
- pay_msg=self.errmsg
- ))
+ return to_text(
+ "Error code: {code}, message: {msg}. Pay Error code: {pay_code}, message: {pay_msg}".format(
+ code=self.return_code,
+ msg=self.return_msg,
+ pay_code=self.errcode,
+ pay_msg=self.errmsg,
+ )
+ )
def __repr__(self):
- _repr = '{klass}({code}, {msg}). Pay({pay_code}, {pay_msg})'.format(
+ _repr = "{klass}({code}, {msg}). Pay({pay_code}, {pay_msg})".format(
klass=self.__class__.__name__,
code=self.return_code,
msg=self.return_msg,
pay_code=self.errcode,
- pay_msg=self.errmsg
+ pay_msg=self.errmsg,
)
if six.PY2:
return to_binary(_repr)
diff --git a/chapter14/booking_system/exts/wechatpy/fields.py b/chapter14/booking_system/exts/wechatpy/fields.py
index 8db6847..9a4bdf9 100644
--- a/chapter14/booking_system/exts/wechatpy/fields.py
+++ b/chapter14/booking_system/exts/wechatpy/fields.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.fields
- ~~~~~~~~~~~~~~~~
+wechatpy.fields
+~~~~~~~~~~~~~~~~
- This module defines some useful field types for parse WeChat messages
+This module defines some useful field types for parse WeChat messages
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
import time
@@ -19,7 +19,7 @@
from exts.wechatpy.utils import to_text, to_binary, ObjectDict, timezone
-default_timezone = timezone('Asia/Shanghai')
+default_timezone = timezone("Asia/Shanghai")
class FieldDescriptor(object):
@@ -36,8 +36,11 @@ def __get__(self, instance, instance_type=None):
instance._data[self.attr_name] = value
if isinstance(value, dict):
value = ObjectDict(value)
- if value and not isinstance(value, (dict, list, tuple)) and \
- six.callable(self.field.converter):
+ if (
+ value
+ and not isinstance(value, (dict, list, tuple))
+ and six.callable(self.field.converter)
+ ):
value = self.field.converter(value)
return value
return self.field
@@ -61,9 +64,8 @@ def from_xml(cls, value):
raise NotImplementedError()
def __repr__(self):
- _repr = '{klass}({name})'.format(
- klass=self.__class__.__name__,
- name=repr(self.name)
+ _repr = "{klass}({name})".format(
+ klass=self.__class__.__name__, name=repr(self.name)
)
if six.PY2:
return to_binary(_repr)
@@ -85,7 +87,7 @@ def __to_text(self, value):
def to_xml(self, value):
value = self.converter(value)
- tpl = '<{name}>{name}>'
+ tpl = "<{name}>{name}>"
return tpl.format(name=self.name, value=value)
@classmethod
@@ -98,7 +100,7 @@ class IntegerField(BaseField):
def to_xml(self, value):
value = self.converter(value) if value is not None else self.default
- tpl = '<{name}>{value}{name}>'
+ tpl = "<{name}>{value}{name}>"
return tpl.format(name=self.name, value=value)
@classmethod
@@ -110,12 +112,13 @@ class DateTimeField(BaseField):
def __converter(self, value):
v = int(value)
return datetime.fromtimestamp(v, tz=default_timezone)
+
converter = __converter
def to_xml(self, value):
value = time.mktime(datetime.timetuple(value))
value = int(value)
- tpl = '<{name}>{value}{name}>'
+ tpl = "<{name}>{value}{name}>"
return tpl.format(name=self.name, value=value)
@classmethod
@@ -128,7 +131,7 @@ class FloatField(BaseField):
def to_xml(self, value):
value = self.converter(value) if value is not None else self.default
- tpl = '<{name}>{value}{name}>'
+ tpl = "<{name}>{value}{name}>"
return tpl.format(name=self.name, value=value)
@classmethod
@@ -167,62 +170,66 @@ def from_xml(cls, value):
class VideoField(StringField):
def to_xml(self, value):
- kwargs = dict(media_id=self.converter(value['media_id']))
- content = ''
- if 'title' in value:
- kwargs['title'] = self.converter(value['title'])
- content += ''
- if 'description' in value:
- kwargs['description'] = self.converter(value['description'])
- content += ''
+ kwargs = dict(media_id=self.converter(value["media_id"]))
+ content = ""
+ if "title" in value:
+ kwargs["title"] = self.converter(value["title"])
+ content += ""
+ if "description" in value:
+ kwargs["description"] = self.converter(value["description"])
+ content += ""
tpl = """""".format(content=content)
+ """.format(
+ content=content
+ )
return tpl.format(**kwargs)
@classmethod
def from_xml(cls, value):
- rv = dict(media_id=value['MediaId'])
- if 'Title' in value:
- rv["title"] = value['Title']
- if 'Description' in value:
- rv['description'] = value['Description']
+ rv = dict(media_id=value["MediaId"])
+ if "Title" in value:
+ rv["title"] = value["Title"]
+ if "Description" in value:
+ rv["description"] = value["Description"]
return rv
class MusicField(StringField):
def to_xml(self, value):
- kwargs = dict(thumb_media_id=self.converter(value['thumb_media_id']))
- content = ''
- if 'title' in value:
- kwargs['title'] = self.converter(value['title'])
- content += ''
- if 'description' in value:
- kwargs['description'] = self.converter(value['description'])
- content += ''
- if 'music_url' in value:
- kwargs['music_url'] = self.converter(value['music_url'])
- content += ''
- if 'hq_music_url' in value:
- kwargs['hq_music_url'] = self.converter(value['hq_music_url'])
- content += ''
+ kwargs = dict(thumb_media_id=self.converter(value["thumb_media_id"]))
+ content = ""
+ if "title" in value:
+ kwargs["title"] = self.converter(value["title"])
+ content += ""
+ if "description" in value:
+ kwargs["description"] = self.converter(value["description"])
+ content += ""
+ if "music_url" in value:
+ kwargs["music_url"] = self.converter(value["music_url"])
+ content += ""
+ if "hq_music_url" in value:
+ kwargs["hq_music_url"] = self.converter(value["hq_music_url"])
+ content += ""
tpl = """
{content}
- """.format(content=content)
+ """.format(
+ content=content
+ )
return tpl.format(**kwargs)
@classmethod
def from_xml(cls, value):
- rv = dict(thumb_media_id=value['ThumbMediaId'])
- if 'Title' in value:
- rv['title'] = value['Title']
- if 'Description' in value:
- rv['description'] = value['Description']
- if 'MusicUrl' in value:
- rv['music_url'] = value['MusicUrl']
- if 'HQMusicUrl' in value:
- rv['hq_music_url'] = value['HQMusicUrl']
+ rv = dict(thumb_media_id=value["ThumbMediaId"])
+ if "Title" in value:
+ rv["title"] = value["Title"]
+ if "Description" in value:
+ rv["description"] = value["Description"]
+ if "MusicUrl" in value:
+ rv["music_url"] = value["MusicUrl"]
+ if "HQMusicUrl" in value:
+ rv["hq_music_url"] = value["HQMusicUrl"]
return rv
@@ -232,10 +239,10 @@ def to_xml(self, articles):
article_count = len(articles)
items = []
for article in articles:
- title = self.converter(article.get('title', ''))
- description = self.converter(article.get('description', ''))
- image = self.converter(article.get('image', ''))
- url = self.converter(article.get('url', ''))
+ title = self.converter(article.get("title", ""))
+ description = self.converter(article.get("description", ""))
+ image = self.converter(article.get("image", ""))
+ url = self.converter(article.get("url", ""))
item_tpl = """-
@@ -243,28 +250,25 @@ def to_xml(self, articles):
"""
item = item_tpl.format(
- title=title,
- description=description,
- image=image,
- url=url
+ title=title, description=description, image=image, url=url
)
items.append(item)
- items_str = '\n'.join(items)
+ items_str = "\n".join(items)
tpl = """{article_count}
{items}"""
- return tpl.format(
- article_count=article_count,
- items=items_str
- )
+ return tpl.format(article_count=article_count, items=items_str)
@classmethod
def from_xml(cls, value):
- return [dict(
- title=item["Title"],
- description=item["Description"],
- image=item["PicUrl"],
- url=item["Url"]
- ) for item in value["item"]]
+ return [
+ dict(
+ title=item["Title"],
+ description=item["Description"],
+ image=item["PicUrl"],
+ url=item["Url"],
+ )
+ for item in value["item"]
+ ]
class Base64EncodeField(StringField):
@@ -286,13 +290,11 @@ def __base64_decode(self, text):
class HardwareField(StringField):
def to_xml(self, value=None):
- value = value or {'view': 'myrank', 'action': 'ranklist'}
+ value = value or {"view": "myrank", "action": "ranklist"}
tpl = """<{name}>
{name}>"""
return tpl.format(
- name=self.name,
- view=value.get('view'),
- action=value.get('action')
+ name=self.name, view=value.get("view"), action=value.get("action")
)
diff --git a/chapter14/booking_system/exts/wechatpy/messages.py b/chapter14/booking_system/exts/wechatpy/messages.py
index 04f4d0c..9e33666 100644
--- a/chapter14/booking_system/exts/wechatpy/messages.py
+++ b/chapter14/booking_system/exts/wechatpy/messages.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.messages
- ~~~~~~~~~~~~~~~~~~
+wechatpy.messages
+~~~~~~~~~~~~~~~~~~
- This module defines all the messages you can get from WeChat server
+This module defines all the messages you can get from WeChat server
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
import copy
@@ -17,7 +17,7 @@
StringField,
IntegerField,
DateTimeField,
- FieldDescriptor
+ FieldDescriptor,
)
from exts.wechatpy.utils import to_text, to_binary
@@ -29,14 +29,16 @@ def register_message(msg_type):
def register(cls):
MESSAGE_TYPES[msg_type] = cls
return cls
+
return register
class MessageMetaClass(type):
"""Metaclass for all messages"""
+
def __new__(cls, name, bases, attrs):
for b in bases:
- if not hasattr(b, '_fields'):
+ if not hasattr(b, "_fields"):
continue
for k, v in b.__dict__.items():
@@ -56,20 +58,20 @@ def __new__(cls, name, bases, attrs):
class BaseMessage(six.with_metaclass(MessageMetaClass)):
"""Base class for all messages and events"""
- type = 'unknown'
- id = IntegerField('MsgId', 0)
- source = StringField('FromUserName')
- target = StringField('ToUserName')
- create_time = DateTimeField('CreateTime')
- time = IntegerField('CreateTime')
+
+ type = "unknown"
+ id = IntegerField("MsgId", 0)
+ source = StringField("FromUserName")
+ target = StringField("ToUserName")
+ create_time = DateTimeField("CreateTime")
+ time = IntegerField("CreateTime")
def __init__(self, message):
self._data = message
def __repr__(self):
_repr = "{klass}({msg})".format(
- klass=self.__class__.__name__,
- msg=repr(self._data)
+ klass=self.__class__.__name__, msg=repr(self._data)
)
if six.PY2:
return to_binary(_repr)
@@ -77,97 +79,105 @@ def __repr__(self):
return to_text(_repr)
-@register_message('text')
+@register_message("text")
class TextMessage(BaseMessage):
"""
文本消息
详情请参阅
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
"""
- type = 'text'
- content = StringField('Content')
+ type = "text"
+ content = StringField("Content")
-@register_message('image')
+
+@register_message("image")
class ImageMessage(BaseMessage):
"""
图片消息
详情请参阅
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
"""
- type = 'image'
- media_id = StringField('MediaId')
- image = StringField('PicUrl')
+
+ type = "image"
+ media_id = StringField("MediaId")
+ image = StringField("PicUrl")
-@register_message('voice')
+@register_message("voice")
class VoiceMessage(BaseMessage):
"""
语音消息
详情请参阅
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
"""
- type = 'voice'
- media_id = StringField('MediaId')
- format = StringField('Format')
- recognition = StringField('Recognition')
+
+ type = "voice"
+ media_id = StringField("MediaId")
+ format = StringField("Format")
+ recognition = StringField("Recognition")
-@register_message('shortvideo')
+@register_message("shortvideo")
class ShortVideoMessage(BaseMessage):
"""
短视频消息
详情请参阅
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
"""
- type = 'shortvideo'
- media_id = StringField('MediaId')
- thumb_media_id = StringField('ThumbMediaId')
+ type = "shortvideo"
+ media_id = StringField("MediaId")
+ thumb_media_id = StringField("ThumbMediaId")
-@register_message('video')
+
+@register_message("video")
class VideoMessage(BaseMessage):
"""
视频消息
详情请参阅
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
"""
- type = 'video'
- media_id = StringField('MediaId')
- thumb_media_id = StringField('ThumbMediaId')
+
+ type = "video"
+ media_id = StringField("MediaId")
+ thumb_media_id = StringField("ThumbMediaId")
-@register_message('location')
+@register_message("location")
class LocationMessage(BaseMessage):
"""
地理位置消息
详情请参阅
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
"""
- type = 'location'
- location_x = StringField('Location_X')
- location_y = StringField('Location_Y')
- scale = StringField('Scale')
- label = StringField('Label')
+
+ type = "location"
+ location_x = StringField("Location_X")
+ location_y = StringField("Location_Y")
+ scale = StringField("Scale")
+ label = StringField("Label")
@property
def location(self):
return self.location_x, self.location_y
-@register_message('link')
+@register_message("link")
class LinkMessage(BaseMessage):
"""
链接消息
详情请参阅
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
"""
- type = 'link'
- title = StringField('Title')
- description = StringField('Description')
- url = StringField('Url')
+
+ type = "link"
+ title = StringField("Title")
+ description = StringField("Description")
+ url = StringField("Url")
class UnknownMessage(BaseMessage):
"""未知消息类型"""
+
pass
diff --git a/chapter14/booking_system/exts/wechatpy/oauth.py b/chapter14/booking_system/exts/wechatpy/oauth.py
index db5743a..984cffa 100644
--- a/chapter14/booking_system/exts/wechatpy/oauth.py
+++ b/chapter14/booking_system/exts/wechatpy/oauth.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.oauth
- ~~~~~~~~~~~~~~~
+wechatpy.oauth
+~~~~~~~~~~~~~~~
- This module provides OAuth2 library for WeChat
+This module provides OAuth2 library for WeChat
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
@@ -18,16 +18,16 @@
class WeChatOAuth(object):
- """ 微信公众平台 OAuth 网页授权
+ """微信公众平台 OAuth 网页授权
详情请参考
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505
"""
- API_BASE_URL = 'https://api.weixin.qq.com/'
- OAUTH_BASE_URL = 'https://open.weixin.qq.com/connect/'
+ API_BASE_URL = "https://api.weixin.qq.com/"
+ OAUTH_BASE_URL = "https://open.weixin.qq.com/connect/"
- def __init__(self, app_id, secret, redirect_uri, scope='snsapi_base', state=''):
+ def __init__(self, app_id, secret, redirect_uri, scope="snsapi_base", state=""):
"""
:param app_id: 微信公众号 app_id
@@ -44,24 +44,19 @@ def __init__(self, app_id, secret, redirect_uri, scope='snsapi_base', state=''):
self._http = requests.Session()
def _request(self, method, url_or_endpoint, **kwargs):
- if not url_or_endpoint.startswith(('http://', 'https://')):
- url = '{base}{endpoint}'.format(
- base=self.API_BASE_URL,
- endpoint=url_or_endpoint
+ if not url_or_endpoint.startswith(("http://", "https://")):
+ url = "{base}{endpoint}".format(
+ base=self.API_BASE_URL, endpoint=url_or_endpoint
)
else:
url = url_or_endpoint
- if isinstance(kwargs.get('data', ''), dict):
- body = json.dumps(kwargs['data'], ensure_ascii=False)
- body = body.encode('utf-8')
- kwargs['data'] = body
+ if isinstance(kwargs.get("data", ""), dict):
+ body = json.dumps(kwargs["data"], ensure_ascii=False)
+ body = body.encode("utf-8")
+ kwargs["data"] = body
- res = self._http.request(
- method=method,
- url=url,
- **kwargs
- )
+ res = self._http.request(method=method, url=url, **kwargs)
try:
res.raise_for_status()
except requests.RequestException as reqe:
@@ -70,29 +65,21 @@ def _request(self, method, url_or_endpoint, **kwargs):
errmsg=None,
client=self,
request=reqe.request,
- response=reqe.response
+ response=reqe.response,
)
- result = json.loads(res.content.decode('utf-8', 'ignore'), strict=False)
+ result = json.loads(res.content.decode("utf-8", "ignore"), strict=False)
- if 'errcode' in result and result['errcode'] != 0:
- errcode = result['errcode']
- errmsg = result['errmsg']
+ if "errcode" in result and result["errcode"] != 0:
+ errcode = result["errcode"]
+ errmsg = result["errmsg"]
raise WeChatOAuthException(
- errcode,
- errmsg,
- client=self,
- request=res.request,
- response=res
+ errcode, errmsg, client=self, request=res.request, response=res
)
return result
def _get(self, url, **kwargs):
- return self._request(
- method='get',
- url_or_endpoint=url,
- **kwargs
- )
+ return self._request(method="get", url_or_endpoint=url, **kwargs)
@property
def authorize_url(self):
@@ -100,20 +87,20 @@ def authorize_url(self):
:return: URL 地址
"""
- redirect_uri = quote(self.redirect_uri, safe=b'')
+ redirect_uri = quote(self.redirect_uri, safe=b"")
url_list = [
self.OAUTH_BASE_URL,
- 'oauth2/authorize?appid=',
+ "oauth2/authorize?appid=",
self.app_id,
- '&redirect_uri=',
+ "&redirect_uri=",
redirect_uri,
- '&response_type=code&scope=',
- self.scope
+ "&response_type=code&scope=",
+ self.scope,
]
if self.state:
- url_list.extend(['&state=', self.state])
- url_list.append('#wechat_redirect')
- return ''.join(url_list)
+ url_list.extend(["&state=", self.state])
+ url_list.append("#wechat_redirect")
+ return "".join(url_list)
@property
def qrconnect_url(self):
@@ -121,20 +108,20 @@ def qrconnect_url(self):
:return: URL 地址
"""
- redirect_uri = quote(self.redirect_uri, safe=b'')
+ redirect_uri = quote(self.redirect_uri, safe=b"")
url_list = [
self.OAUTH_BASE_URL,
- 'qrconnect?appid=',
+ "qrconnect?appid=",
self.app_id,
- '&redirect_uri=',
+ "&redirect_uri=",
redirect_uri,
- '&response_type=code&scope=',
- 'snsapi_login' # scope
+ "&response_type=code&scope=",
+ "snsapi_login", # scope
]
if self.state:
- url_list.extend(['&state=', self.state])
- url_list.append('#wechat_redirect')
- return ''.join(url_list)
+ url_list.extend(["&state=", self.state])
+ url_list.append("#wechat_redirect")
+ return "".join(url_list)
def fetch_access_token(self, code):
"""获取 access_token
@@ -143,18 +130,18 @@ def fetch_access_token(self, code):
:return: JSON 数据包
"""
res = self._get(
- 'sns/oauth2/access_token',
+ "sns/oauth2/access_token",
params={
- 'appid': self.app_id,
- 'secret': self.secret,
- 'code': code,
- 'grant_type': 'authorization_code'
- }
+ "appid": self.app_id,
+ "secret": self.secret,
+ "code": code,
+ "grant_type": "authorization_code",
+ },
)
- self.access_token = res['access_token']
- self.open_id = res['openid']
- self.refresh_token = res['refresh_token']
- self.expires_in = res['expires_in']
+ self.access_token = res["access_token"]
+ self.open_id = res["openid"]
+ self.refresh_token = res["refresh_token"]
+ self.expires_in = res["expires_in"]
return res
def refresh_access_token(self, refresh_token):
@@ -164,20 +151,20 @@ def refresh_access_token(self, refresh_token):
:return: JSON 数据包
"""
res = self._get(
- 'sns/oauth2/refresh_token',
+ "sns/oauth2/refresh_token",
params={
- 'appid': self.app_id,
- 'grant_type': 'refresh_token',
- 'refresh_token': refresh_token
- }
+ "appid": self.app_id,
+ "grant_type": "refresh_token",
+ "refresh_token": refresh_token,
+ },
)
- self.access_token = res['access_token']
- self.open_id = res['openid']
- self.refresh_token = res['refresh_token']
- self.expires_in = res['expires_in']
+ self.access_token = res["access_token"]
+ self.open_id = res["openid"]
+ self.refresh_token = res["refresh_token"]
+ self.expires_in = res["expires_in"]
return res
- def get_user_info(self, openid=None, access_token=None, lang='zh_CN'):
+ def get_user_info(self, openid=None, access_token=None, lang="zh_CN"):
"""获取用户信息
:param openid: 可选,微信 openid,默认获取当前授权用户信息
@@ -188,12 +175,8 @@ def get_user_info(self, openid=None, access_token=None, lang='zh_CN'):
openid = openid or self.open_id
access_token = access_token or self.access_token
return self._get(
- 'sns/userinfo',
- params={
- 'access_token': access_token,
- 'openid': openid,
- 'lang': lang
- }
+ "sns/userinfo",
+ params={"access_token": access_token, "openid": openid, "lang": lang},
)
def check_access_token(self, openid=None, access_token=None):
@@ -206,12 +189,8 @@ def check_access_token(self, openid=None, access_token=None):
openid = openid or self.open_id
access_token = access_token or self.access_token
res = self._get(
- 'sns/auth',
- params={
- 'access_token': access_token,
- 'openid': openid
- }
+ "sns/auth", params={"access_token": access_token, "openid": openid}
)
- if res['errcode'] == 0:
+ if res["errcode"] == 0:
return True
return False
diff --git a/chapter14/booking_system/exts/wechatpy/parser.py b/chapter14/booking_system/exts/wechatpy/parser.py
index 11f3af7..0706fae 100644
--- a/chapter14/booking_system/exts/wechatpy/parser.py
+++ b/chapter14/booking_system/exts/wechatpy/parser.py
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.parser
- ~~~~~~~~~~~~~~~~
- This module provides functions for parsing WeChat messages
+wechatpy.parser
+~~~~~~~~~~~~~~~~
+This module provides functions for parsing WeChat messages
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
import xmltodict
@@ -24,28 +24,28 @@ def parse_message(xml):
"""
if not xml:
return
- message = xmltodict.parse(to_text(xml))['xml']
- message_type = message['MsgType'].lower()
+ message = xmltodict.parse(to_text(xml))["xml"]
+ message_type = message["MsgType"].lower()
event_type = None
- if message_type == 'event' or message_type.startswith('device_'):
- if 'Event' in message:
- event_type = message['Event'].lower()
+ if message_type == "event" or message_type.startswith("device_"):
+ if "Event" in message:
+ event_type = message["Event"].lower()
# special event type for device_event
- if event_type is None and message_type.startswith('device_'):
+ if event_type is None and message_type.startswith("device_"):
event_type = message_type
- elif message_type.startswith('device_'):
- event_type = 'device_{event}'.format(event=event_type)
+ elif message_type.startswith("device_"):
+ event_type = "device_{event}".format(event=event_type)
- if event_type == 'subscribe' and message.get('EventKey'):
- event_key = message['EventKey']
- if event_key.startswith(('scanbarcode|', 'scanimage|')):
- event_type = 'subscribe_scan_product'
- message['Event'] = event_type
- elif event_key.startswith('qrscene_'):
+ if event_type == "subscribe" and message.get("EventKey"):
+ event_key = message["EventKey"]
+ if event_key.startswith(("scanbarcode|", "scanimage|")):
+ event_type = "subscribe_scan_product"
+ message["Event"] = event_type
+ elif event_key.startswith("qrscene_"):
# Scan to subscribe with scene id event
- event_type = 'subscribe_scan'
- message['Event'] = event_type
- message['EventKey'] = event_key[len('qrscene_'):]
+ event_type = "subscribe_scan"
+ message["Event"] = event_type
+ message["EventKey"] = event_key[len("qrscene_") :]
message_class = EVENT_TYPES.get(event_type, UnknownMessage)
else:
message_class = MESSAGE_TYPES.get(message_type, UnknownMessage)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/__init__.py b/chapter14/booking_system/exts/wechatpy/pay/__init__.py
index ff9dc96..e7ce60d 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/__init__.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/__init__.py
@@ -11,7 +11,10 @@
from exts.wechatpy.utils import random_string
from exts.wechatpy.exceptions import WeChatPayException, InvalidSignatureException
from exts.wechatpy.pay.utils import (
- calculate_signature, calculate_signature_hmac, _check_signature, dict_to_xml
+ calculate_signature,
+ calculate_signature_hmac,
+ _check_signature,
+ dict_to_xml,
)
from exts.wechatpy.pay.base import BaseWeChatPayAPI
from exts.wechatpy.pay import api
@@ -57,7 +60,7 @@ class WeChatPay(object):
withhold = api.WeChatWithhold()
"""代扣接口"""
- API_BASE_URL = 'https://api.mch.weixin.qq.com/'
+ API_BASE_URL = "https://api.mch.weixin.qq.com/"
def __new__(cls, *args, **kwargs):
self = super(WeChatPay, cls).__new__(cls)
@@ -68,8 +71,18 @@ def __new__(cls, *args, **kwargs):
setattr(self, name, _api)
return self
- def __init__(self, appid, api_key, mch_id, sub_mch_id=None,
- mch_cert=None, mch_key=None, timeout=None, sandbox=False, sub_appid=None):
+ def __init__(
+ self,
+ appid,
+ api_key,
+ mch_id,
+ sub_mch_id=None,
+ mch_cert=None,
+ mch_key=None,
+ timeout=None,
+ sandbox=False,
+ sub_appid=None,
+ ):
self.appid = appid
self.sub_appid = sub_appid
self.api_key = api_key
@@ -84,56 +97,58 @@ def __init__(self, appid, api_key, mch_id, sub_mch_id=None,
def _fetch_sandbox_api_key(self):
nonce_str = random_string(32)
- sign = calculate_signature({'mch_id': self.mch_id, 'nonce_str': nonce_str}, self.api_key)
- payload = dict_to_xml({
- 'mch_id': self.mch_id,
- 'nonce_str': nonce_str,
- }, sign=sign)
- headers = {'Content-Type': 'text/xml'}
- api_url = '{base}sandboxnew/pay/getsignkey'.format(base=self.API_BASE_URL)
+ sign = calculate_signature(
+ {"mch_id": self.mch_id, "nonce_str": nonce_str}, self.api_key
+ )
+ payload = dict_to_xml(
+ {
+ "mch_id": self.mch_id,
+ "nonce_str": nonce_str,
+ },
+ sign=sign,
+ )
+ headers = {"Content-Type": "text/xml"}
+ api_url = "{base}sandboxnew/pay/getsignkey".format(base=self.API_BASE_URL)
response = self._http.post(api_url, data=payload, headers=headers)
- return xmltodict.parse(response.text)['xml'].get('sandbox_signkey')
+ return xmltodict.parse(response.text)["xml"].get("sandbox_signkey")
def _request(self, method, url_or_endpoint, **kwargs):
- if not url_or_endpoint.startswith(('http://', 'https://')):
- api_base_url = kwargs.pop('api_base_url', self.API_BASE_URL)
+ if not url_or_endpoint.startswith(("http://", "https://")):
+ api_base_url = kwargs.pop("api_base_url", self.API_BASE_URL)
if self.sandbox:
- api_base_url = '{url}sandboxnew/'.format(url=api_base_url)
- url = '{base}{endpoint}'.format(
- base=api_base_url,
- endpoint=url_or_endpoint
- )
+ api_base_url = "{url}sandboxnew/".format(url=api_base_url)
+ url = "{base}{endpoint}".format(base=api_base_url, endpoint=url_or_endpoint)
else:
url = url_or_endpoint
- if isinstance(kwargs.get('data', ''), dict):
- data = kwargs['data']
- if 'mchid' not in data:
+ if isinstance(kwargs.get("data", ""), dict):
+ data = kwargs["data"]
+ if "mchid" not in data:
# Fuck Tencent
- data.setdefault('mch_id', self.mch_id)
- data.setdefault('sub_mch_id', self.sub_mch_id)
- data.setdefault('nonce_str', random_string(32))
+ data.setdefault("mch_id", self.mch_id)
+ data.setdefault("sub_mch_id", self.sub_mch_id)
+ data.setdefault("nonce_str", random_string(32))
data = optionaldict(data)
- if data.get('sign_type', 'MD5') == 'HMAC-SHA256':
- sign = calculate_signature_hmac(data, self.sandbox_api_key if self.sandbox else self.api_key)
+ if data.get("sign_type", "MD5") == "HMAC-SHA256":
+ sign = calculate_signature_hmac(
+ data, self.sandbox_api_key if self.sandbox else self.api_key
+ )
else:
- sign = calculate_signature(data, self.sandbox_api_key if self.sandbox else self.api_key)
+ sign = calculate_signature(
+ data, self.sandbox_api_key if self.sandbox else self.api_key
+ )
body = dict_to_xml(data, sign)
- body = body.encode('utf-8')
- kwargs['data'] = body
+ body = body.encode("utf-8")
+ kwargs["data"] = body
# 商户证书
if self.mch_cert and self.mch_key:
- kwargs['cert'] = (self.mch_cert, self.mch_key)
-
- kwargs['timeout'] = kwargs.get('timeout', self.timeout)
- logger.debug('Request to WeChat API: %s %s\n%s', method, url, kwargs)
- res = self._http.request(
- method=method,
- url=url,
- **kwargs
- )
+ kwargs["cert"] = (self.mch_cert, self.mch_key)
+
+ kwargs["timeout"] = kwargs.get("timeout", self.timeout)
+ logger.debug("Request to WeChat API: %s %s\n%s", method, url, kwargs)
+ res = self._http.request(method=method, url=url, **kwargs)
try:
res.raise_for_status()
except requests.RequestException as reqe:
@@ -141,28 +156,28 @@ def _request(self, method, url_or_endpoint, **kwargs):
return_code=None,
client=self,
request=reqe.request,
- response=reqe.response
+ response=reqe.response,
)
return self._handle_result(res)
def _handle_result(self, res):
- res.encoding = 'utf-8'
+ res.encoding = "utf-8"
xml = res.text
- logger.debug('Response from WeChat API \n %s', xml)
+ logger.debug("Response from WeChat API \n %s", xml)
try:
- data = xmltodict.parse(xml)['xml']
+ data = xmltodict.parse(xml)["xml"]
except (xmltodict.ParsingInterrupted, ExpatError):
# 解析 XML 失败
- logger.debug('WeChat payment result xml parsing error', exc_info=True)
+ logger.debug("WeChat payment result xml parsing error", exc_info=True)
return xml
- return_code = data['return_code']
- return_msg = data.get('return_msg')
- result_code = data.get('result_code')
- errcode = data.get('err_code')
- errmsg = data.get('err_code_des')
- if return_code != 'SUCCESS' or result_code != 'SUCCESS':
+ return_code = data["return_code"]
+ return_msg = data.get("return_msg")
+ result_code = data.get("result_code")
+ errcode = data.get("err_code")
+ errmsg = data.get("err_code_des")
+ if return_code != "SUCCESS" or result_code != "SUCCESS":
# 返回状态码不为成功
raise WeChatPayException(
return_code,
@@ -172,26 +187,20 @@ def _handle_result(self, res):
errmsg,
client=self,
request=res.request,
- response=res
+ response=res,
)
return data
def get(self, url, **kwargs):
- return self._request(
- method='get',
- url_or_endpoint=url,
- **kwargs
- )
+ return self._request(method="get", url_or_endpoint=url, **kwargs)
def post(self, url, **kwargs):
- return self._request(
- method='post',
- url_or_endpoint=url,
- **kwargs
- )
+ return self._request(method="post", url_or_endpoint=url, **kwargs)
def check_signature(self, params):
- return _check_signature(params, self.api_key if not self.sandbox else self.sandbox_api_key)
+ return _check_signature(
+ params, self.api_key if not self.sandbox else self.sandbox_api_key
+ )
def parse_payment_result(self, xml):
"""解析微信支付结果通知"""
@@ -200,22 +209,30 @@ def parse_payment_result(self, xml):
except (xmltodict.ParsingInterrupted, ExpatError):
raise InvalidSignatureException()
- if not data or 'xml' not in data:
+ if not data or "xml" not in data:
raise InvalidSignatureException()
- data = data['xml']
- sign = data.pop('sign', None)
- if '#text' in data.keys():
+ data = data["xml"]
+ sign = data.pop("sign", None)
+ if "#text" in data.keys():
pass
- del data['#text']
- real_sign = calculate_signature(data, self.api_key if not self.sandbox else self.sandbox_api_key)
+ del data["#text"]
+ real_sign = calculate_signature(
+ data, self.api_key if not self.sandbox else self.sandbox_api_key
+ )
if sign != real_sign:
raise InvalidSignatureException()
- for key in ('total_fee', 'settlement_total_fee', 'cash_fee', 'coupon_fee', 'coupon_count'):
+ for key in (
+ "total_fee",
+ "settlement_total_fee",
+ "cash_fee",
+ "coupon_fee",
+ "coupon_count",
+ ):
if key in data:
data[key] = int(data[key])
- data['sign'] = sign
+ data["sign"] = sign
return data
@property
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/coupon.py b/chapter14/booking_system/exts/wechatpy/pay/api/coupon.py
index 53cd0bc..fe97cfd 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/coupon.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/coupon.py
@@ -8,8 +8,9 @@
class WeChatCoupon(BaseWeChatPayAPI):
- def send(self, user_id, stock_id, op_user_id=None, device_info=None,
- out_trade_no=None):
+ def send(
+ self, user_id, stock_id, op_user_id=None, device_info=None, out_trade_no=None
+ ):
"""
发放代金券
@@ -22,23 +23,21 @@ def send(self, user_id, stock_id, op_user_id=None, device_info=None,
"""
if not out_trade_no:
now = datetime.now()
- out_trade_no = '{0}{1}{2}'.format(
- self.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ out_trade_no = "{0}{1}{2}".format(
+ self.mch_id, now.strftime("%Y%m%d%H%M%S"), random.randint(1000, 10000)
)
data = {
- 'appid': self.appid,
- 'coupon_stock_id': stock_id,
- 'openid': user_id,
- 'openid_count': 1,
- 'partner_trade_no': out_trade_no,
- 'op_user_id': op_user_id,
- 'device_info': device_info,
- 'version': '1.0',
- 'type': 'XML',
+ "appid": self.appid,
+ "coupon_stock_id": stock_id,
+ "openid": user_id,
+ "openid_count": 1,
+ "partner_trade_no": out_trade_no,
+ "op_user_id": op_user_id,
+ "device_info": device_info,
+ "version": "1.0",
+ "type": "XML",
}
- return self._post('mmpaymkttransfers/send_coupon', data=data)
+ return self._post("mmpaymkttransfers/send_coupon", data=data)
def query_stock(self, stock_id, op_user_id=None, device_info=None):
"""
@@ -50,17 +49,16 @@ def query_stock(self, stock_id, op_user_id=None, device_info=None):
:return: 返回的结果信息
"""
data = {
- 'appid': self.appid,
- 'coupon_stock_id': stock_id,
- 'op_user_id': op_user_id,
- 'device_info': device_info,
- 'version': '1.0',
- 'type': 'XML',
+ "appid": self.appid,
+ "coupon_stock_id": stock_id,
+ "op_user_id": op_user_id,
+ "device_info": device_info,
+ "version": "1.0",
+ "type": "XML",
}
- return self._post('mmpaymkttransfers/query_coupon_stock', data=data)
+ return self._post("mmpaymkttransfers/query_coupon_stock", data=data)
- def query_coupon(self, coupon_id, user_id,
- op_user_id=None, device_info=None):
+ def query_coupon(self, coupon_id, user_id, op_user_id=None, device_info=None):
"""
查询代金券信息
@@ -71,12 +69,12 @@ def query_coupon(self, coupon_id, user_id,
:return: 返回的结果信息
"""
data = {
- 'coupon_id': coupon_id,
- 'openid': user_id,
- 'appid': self.appid,
- 'op_user_id': op_user_id,
- 'device_info': device_info,
- 'version': '1.0',
- 'type': 'XML',
+ "coupon_id": coupon_id,
+ "openid": user_id,
+ "appid": self.appid,
+ "op_user_id": op_user_id,
+ "device_info": device_info,
+ "version": "1.0",
+ "type": "XML",
}
- return self._post('promotion/query_coupon', data=data)
+ return self._post("promotion/query_coupon", data=data)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/jsapi.py b/chapter14/booking_system/exts/wechatpy/pay/api/jsapi.py
index 79ed209..a818fe8 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/jsapi.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/jsapi.py
@@ -8,6 +8,7 @@
logger = logging.getLogger(__name__)
+
class WeChatJSAPI(BaseWeChatPayAPI):
def get_jsapi_signature(self, prepay_id, timestamp=None, nonce_str=None):
@@ -20,15 +21,19 @@ def get_jsapi_signature(self, prepay_id, timestamp=None, nonce_str=None):
:return: 签名
"""
data = {
- 'appId': self.sub_appid or self.appid,
- 'timeStamp': timestamp or to_text(int(time.time())),
- 'nonceStr': nonce_str or random_string(32),
- 'signType': 'MD5',
- 'package': 'prepay_id={0}'.format(prepay_id),
+ "appId": self.sub_appid or self.appid,
+ "timeStamp": timestamp or to_text(int(time.time())),
+ "nonceStr": nonce_str or random_string(32),
+ "signType": "MD5",
+ "package": "prepay_id={0}".format(prepay_id),
}
return calculate_signature(
data,
- self._client.api_key if not self._client.sandbox else self._client.sandbox_api_key
+ (
+ self._client.api_key
+ if not self._client.sandbox
+ else self._client.sandbox_api_key
+ ),
)
def get_jsapi_params(self, prepay_id, timestamp=None, nonce_str=None, jssdk=False):
@@ -44,18 +49,22 @@ def get_jsapi_params(self, prepay_id, timestamp=None, nonce_str=None, jssdk=Fals
:return: 参数
"""
data = {
- 'appId': self.sub_appid or self.appid,
- 'timeStamp': timestamp or to_text(int(time.time())),
- 'nonceStr': nonce_str or random_string(32),
- 'signType': 'MD5',
- 'package': 'prepay_id={0}'.format(prepay_id),
+ "appId": self.sub_appid or self.appid,
+ "timeStamp": timestamp or to_text(int(time.time())),
+ "nonceStr": nonce_str or random_string(32),
+ "signType": "MD5",
+ "package": "prepay_id={0}".format(prepay_id),
}
sign = calculate_signature(
data,
- self._client.api_key if not self._client.sandbox else self._client.sandbox_api_key
+ (
+ self._client.api_key
+ if not self._client.sandbox
+ else self._client.sandbox_api_key
+ ),
)
- logger.debug('JSAPI payment parameters: data = %s, sign = %s', data, sign)
- data['paySign'] = sign
+ logger.debug("JSAPI payment parameters: data = %s, sign = %s", data, sign)
+ data["paySign"] = sign
if jssdk:
- data['timestamp'] = data.pop('timeStamp')
+ data["timestamp"] = data.pop("timeStamp")
return data
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/micropay.py b/chapter14/booking_system/exts/wechatpy/pay/api/micropay.py
index 30e8714..439cf19 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/micropay.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/micropay.py
@@ -8,8 +8,20 @@
class WeChatMicroPay(BaseWeChatPayAPI):
- def create(self, body, total_fee, auth_code, client_ip=None, out_trade_no=None, detail=None, attach=None,
- fee_type='CNY', goods_tag=None, device_info=None, limit_pay=None):
+ def create(
+ self,
+ body,
+ total_fee,
+ auth_code,
+ client_ip=None,
+ out_trade_no=None,
+ detail=None,
+ attach=None,
+ fee_type="CNY",
+ goods_tag=None,
+ device_info=None,
+ limit_pay=None,
+ ):
"""
刷卡支付接口
:param device_info: 可选,终端设备号(商户自定义,如门店编号)
@@ -27,26 +39,24 @@ def create(self, body, total_fee, auth_code, client_ip=None, out_trade_no=None,
"""
now = datetime.now()
if not out_trade_no:
- out_trade_no = '{0}{1}{2}'.format(
- self.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ out_trade_no = "{0}{1}{2}".format(
+ self.mch_id, now.strftime("%Y%m%d%H%M%S"), random.randint(1000, 10000)
)
data = {
- 'appid': self.appid,
- 'device_info': device_info,
- 'body': body,
- 'detail': detail,
- 'attach': attach,
- 'out_trade_no': out_trade_no,
- 'total_fee': total_fee,
- 'fee_type': fee_type,
- 'spbill_create_ip': client_ip or get_external_ip(),
- 'goods_tag': goods_tag,
- 'limit_pay': limit_pay,
- 'auth_code': auth_code,
+ "appid": self.appid,
+ "device_info": device_info,
+ "body": body,
+ "detail": detail,
+ "attach": attach,
+ "out_trade_no": out_trade_no,
+ "total_fee": total_fee,
+ "fee_type": fee_type,
+ "spbill_create_ip": client_ip or get_external_ip(),
+ "goods_tag": goods_tag,
+ "limit_pay": limit_pay,
+ "auth_code": auth_code,
}
- return self._post('pay/micropay', data=data)
+ return self._post("pay/micropay", data=data)
def query(self, transaction_id=None, out_trade_no=None):
"""
@@ -57,8 +67,8 @@ def query(self, transaction_id=None, out_trade_no=None):
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'transaction_id': transaction_id,
- 'out_trade_no': out_trade_no,
+ "appid": self.appid,
+ "transaction_id": transaction_id,
+ "out_trade_no": out_trade_no,
}
- return self._post('pay/orderquery', data=data)
+ return self._post("pay/orderquery", data=data)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/order.py b/chapter14/booking_system/exts/wechatpy/pay/api/order.py
index ebc3549..68005fd 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/order.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/order.py
@@ -13,10 +13,27 @@
class WeChatOrder(BaseWeChatPayAPI):
- def create(self, trade_type, body, total_fee, notify_url, client_ip=None,
- user_id=None, out_trade_no=None, detail=None, attach=None,
- fee_type='CNY', time_start=None, time_expire=None, goods_tag=None,
- product_id=None, device_info=None, limit_pay=None, scene_info=None, sub_user_id=None):
+ def create(
+ self,
+ trade_type,
+ body,
+ total_fee,
+ notify_url,
+ client_ip=None,
+ user_id=None,
+ out_trade_no=None,
+ detail=None,
+ attach=None,
+ fee_type="CNY",
+ time_start=None,
+ time_expire=None,
+ goods_tag=None,
+ product_id=None,
+ device_info=None,
+ limit_pay=None,
+ scene_info=None,
+ sub_user_id=None,
+ ):
"""
统一下单接口
@@ -41,43 +58,41 @@ def create(self, trade_type, body, total_fee, notify_url, client_ip=None,
:type scene_info: dict
:return: 返回的结果数据
"""
- now = datetime.fromtimestamp(time.time(), tz=timezone('Asia/Shanghai'))
+ now = datetime.fromtimestamp(time.time(), tz=timezone("Asia/Shanghai"))
hours_later = now + timedelta(hours=2)
if time_start is None:
time_start = now
if time_expire is None:
time_expire = hours_later
if not out_trade_no:
- out_trade_no = '{0}{1}{2}'.format(
- self.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ out_trade_no = "{0}{1}{2}".format(
+ self.mch_id, now.strftime("%Y%m%d%H%M%S"), random.randint(1000, 10000)
)
if scene_info is not None:
scene_info = json.dumps(scene_info, ensure_ascii=False)
data = {
- 'appid': self.appid,
- 'sub_appid': self.sub_appid,
- 'device_info': device_info,
- 'body': body,
- 'detail': detail,
- 'attach': attach,
- 'out_trade_no': out_trade_no,
- 'fee_type': fee_type,
- 'total_fee': total_fee,
- 'spbill_create_ip': client_ip or get_external_ip(),
- 'time_start': time_start.strftime('%Y%m%d%H%M%S'),
- 'time_expire': time_expire.strftime('%Y%m%d%H%M%S'),
- 'goods_tag': goods_tag,
- 'notify_url': notify_url,
- 'trade_type': trade_type,
- 'limit_pay': limit_pay,
- 'product_id': product_id,
- 'openid': user_id,
- 'sub_openid': sub_user_id,
- 'scene_info': scene_info,
+ "appid": self.appid,
+ "sub_appid": self.sub_appid,
+ "device_info": device_info,
+ "body": body,
+ "detail": detail,
+ "attach": attach,
+ "out_trade_no": out_trade_no,
+ "fee_type": fee_type,
+ "total_fee": total_fee,
+ "spbill_create_ip": client_ip or get_external_ip(),
+ "time_start": time_start.strftime("%Y%m%d%H%M%S"),
+ "time_expire": time_expire.strftime("%Y%m%d%H%M%S"),
+ "goods_tag": goods_tag,
+ "notify_url": notify_url,
+ "trade_type": trade_type,
+ "limit_pay": limit_pay,
+ "product_id": product_id,
+ "openid": user_id,
+ "sub_openid": sub_user_id,
+ "scene_info": scene_info,
}
- return self._post('pay/unifiedorder', data=data)
+ return self._post("pay/unifiedorder", data=data)
def query(self, transaction_id=None, out_trade_no=None):
"""
@@ -88,11 +103,11 @@ def query(self, transaction_id=None, out_trade_no=None):
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'transaction_id': transaction_id,
- 'out_trade_no': out_trade_no,
+ "appid": self.appid,
+ "transaction_id": transaction_id,
+ "out_trade_no": out_trade_no,
}
- return self._post('pay/orderquery', data=data)
+ return self._post("pay/orderquery", data=data)
def close(self, out_trade_no):
"""
@@ -102,10 +117,10 @@ def close(self, out_trade_no):
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'out_trade_no': out_trade_no,
+ "appid": self.appid,
+ "out_trade_no": out_trade_no,
}
- return self._post('pay/closeorder', data=data)
+ return self._post("pay/closeorder", data=data)
def get_appapi_params(self, prepay_id, timestamp=None, nonce_str=None):
"""
@@ -117,15 +132,15 @@ def get_appapi_params(self, prepay_id, timestamp=None, nonce_str=None):
:return: 签名
"""
data = {
- 'appid': self.appid,
- 'partnerid': self.mch_id,
- 'prepayid': prepay_id,
- 'package': 'Sign=WXPay',
- 'timestamp': timestamp or to_text(int(time.time())),
- 'noncestr': nonce_str or random_string(32)
+ "appid": self.appid,
+ "partnerid": self.mch_id,
+ "prepayid": prepay_id,
+ "package": "Sign=WXPay",
+ "timestamp": timestamp or to_text(int(time.time())),
+ "noncestr": nonce_str or random_string(32),
}
sign = calculate_signature(data, self._client.api_key)
- data['sign'] = sign
+ data["sign"] = sign
return data
def get_appapi_params_xiugai(self, prepay_id, timestamp=None, nonce_str=None):
@@ -138,14 +153,14 @@ def get_appapi_params_xiugai(self, prepay_id, timestamp=None, nonce_str=None):
:return: 签名
"""
data = {
- 'appId': self.appid,
- 'timeStamp': timestamp or to_text(int(time.time())),
- 'nonceStr': nonce_str or random_string(32),
- 'package': 'prepay_id='+prepay_id,
- 'signType': 'MD5'
+ "appId": self.appid,
+ "timeStamp": timestamp or to_text(int(time.time())),
+ "nonceStr": nonce_str or random_string(32),
+ "package": "prepay_id=" + prepay_id,
+ "signType": "MD5",
}
sign = calculate_signature(data, self._client.api_key)
- data['paySign'] = sign
+ data["paySign"] = sign
return data
def reverse(self, transaction_id=None, out_trade_no=None):
@@ -159,8 +174,8 @@ def reverse(self, transaction_id=None, out_trade_no=None):
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'transaction_id': transaction_id,
- 'out_trade_no': out_trade_no,
+ "appid": self.appid,
+ "transaction_id": transaction_id,
+ "out_trade_no": out_trade_no,
}
- return self._post('secapi/pay/reverse', data=data)
+ return self._post("secapi/pay/reverse", data=data)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/redpack.py b/chapter14/booking_system/exts/wechatpy/pay/api/redpack.py
index c888b97..5a779f7 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/redpack.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/redpack.py
@@ -9,9 +9,20 @@
class WeChatRedpack(BaseWeChatPayAPI):
- def send(self, user_id, total_amount, send_name, act_name,
- wishing, remark, total_num=1, client_ip=None,
- out_trade_no=None, scene_id=None, consume_mch_id=None):
+ def send(
+ self,
+ user_id,
+ total_amount,
+ send_name,
+ act_name,
+ wishing,
+ remark,
+ total_num=1,
+ client_ip=None,
+ out_trade_no=None,
+ scene_id=None,
+ consume_mch_id=None,
+ ):
"""
发送现金红包
@@ -30,31 +41,41 @@ def send(self, user_id, total_amount, send_name, act_name,
"""
if not out_trade_no:
now = datetime.now()
- out_trade_no = '{0}{1}{2}'.format(
- self.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ out_trade_no = "{0}{1}{2}".format(
+ self.mch_id, now.strftime("%Y%m%d%H%M%S"), random.randint(1000, 10000)
)
data = {
- 'wxappid': self.appid,
- 're_openid': user_id,
- 'total_amount': total_amount,
- 'send_name': send_name,
- 'act_name': act_name,
- 'wishing': wishing,
- 'remark': remark,
- 'client_ip': client_ip or get_external_ip(),
- 'total_num': total_num,
- 'mch_billno': out_trade_no,
- 'scene_id': scene_id,
- 'risk_info': None,
- 'consume_mch_id': consume_mch_id
+ "wxappid": self.appid,
+ "re_openid": user_id,
+ "total_amount": total_amount,
+ "send_name": send_name,
+ "act_name": act_name,
+ "wishing": wishing,
+ "remark": remark,
+ "client_ip": client_ip or get_external_ip(),
+ "total_num": total_num,
+ "mch_billno": out_trade_no,
+ "scene_id": scene_id,
+ "risk_info": None,
+ "consume_mch_id": consume_mch_id,
}
- return self._post('mmpaymkttransfers/sendredpack', data=data)
+ return self._post("mmpaymkttransfers/sendredpack", data=data)
- def send_group(self, user_id, total_amount, send_name, act_name, wishing,
- remark, total_num, client_ip=None, amt_type="ALL_RAND",
- out_trade_no=None, scene_id=None, consume_mch_id=None):
+ def send_group(
+ self,
+ user_id,
+ total_amount,
+ send_name,
+ act_name,
+ wishing,
+ remark,
+ total_num,
+ client_ip=None,
+ amt_type="ALL_RAND",
+ out_trade_no=None,
+ scene_id=None,
+ consume_mch_id=None,
+ ):
"""
发送裂变红包
@@ -75,30 +96,30 @@ def send_group(self, user_id, total_amount, send_name, act_name, wishing,
"""
if not out_trade_no:
now = datetime.now()
- out_trade_no = '{0}{1}{2}'.format(
+ out_trade_no = "{0}{1}{2}".format(
self._client.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ now.strftime("%Y%m%d%H%M%S"),
+ random.randint(1000, 10000),
)
data = {
- 'wxappid': self.appid,
- 're_openid': user_id,
- 'total_amount': total_amount,
- 'send_name': send_name,
- 'act_name': act_name,
- 'wishing': wishing,
- 'remark': remark,
- 'total_num': total_num,
- 'client_ip': client_ip or get_external_ip(),
- 'amt_type': amt_type,
- 'mch_billno': out_trade_no,
- 'scene_id': scene_id,
- 'risk_info': None,
- 'consume_mch_id': consume_mch_id
+ "wxappid": self.appid,
+ "re_openid": user_id,
+ "total_amount": total_amount,
+ "send_name": send_name,
+ "act_name": act_name,
+ "wishing": wishing,
+ "remark": remark,
+ "total_num": total_num,
+ "client_ip": client_ip or get_external_ip(),
+ "amt_type": amt_type,
+ "mch_billno": out_trade_no,
+ "scene_id": scene_id,
+ "risk_info": None,
+ "consume_mch_id": consume_mch_id,
}
- return self._post('mmpaymkttransfers/sendgroupredpack', data=data)
+ return self._post("mmpaymkttransfers/sendgroupredpack", data=data)
- def query(self, out_trade_no, bill_type='MCHT'):
+ def query(self, out_trade_no, bill_type="MCHT"):
"""
查询红包发放记录
@@ -107,8 +128,8 @@ def query(self, out_trade_no, bill_type='MCHT'):
:return: 返回的红包发放记录信息
"""
data = {
- 'mch_billno': out_trade_no,
- 'bill_type': bill_type,
- 'appid': self.appid,
+ "mch_billno": out_trade_no,
+ "bill_type": bill_type,
+ "appid": self.appid,
}
- return self._post('mmpaymkttransfers/gethbinfo', data=data)
+ return self._post("mmpaymkttransfers/gethbinfo", data=data)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/refund.py b/chapter14/booking_system/exts/wechatpy/pay/api/refund.py
index 8d9a5d1..9dec65b 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/refund.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/refund.py
@@ -6,10 +6,19 @@
class WeChatRefund(BaseWeChatPayAPI):
- def apply(self, total_fee, refund_fee, out_refund_no, transaction_id=None,
- out_trade_no=None, fee_type='CNY', op_user_id=None,
- device_info=None, refund_account='REFUND_SOURCE_UNSETTLED_FUNDS',
- notify_url=None):
+ def apply(
+ self,
+ total_fee,
+ refund_fee,
+ out_refund_no,
+ transaction_id=None,
+ out_trade_no=None,
+ fee_type="CNY",
+ op_user_id=None,
+ device_info=None,
+ refund_account="REFUND_SOURCE_UNSETTLED_FUNDS",
+ notify_url=None,
+ ):
"""
申请退款
@@ -26,22 +35,28 @@ def apply(self, total_fee, refund_fee, out_refund_no, transaction_id=None,
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'device_info': device_info,
- 'transaction_id': transaction_id,
- 'out_trade_no': out_trade_no,
- 'out_refund_no': out_refund_no,
- 'total_fee': total_fee,
- 'refund_fee': refund_fee,
- 'refund_fee_type': fee_type,
- 'op_user_id': op_user_id if op_user_id else self.mch_id,
- 'refund_account': refund_account,
- 'notify_url': notify_url,
+ "appid": self.appid,
+ "device_info": device_info,
+ "transaction_id": transaction_id,
+ "out_trade_no": out_trade_no,
+ "out_refund_no": out_refund_no,
+ "total_fee": total_fee,
+ "refund_fee": refund_fee,
+ "refund_fee_type": fee_type,
+ "op_user_id": op_user_id if op_user_id else self.mch_id,
+ "refund_account": refund_account,
+ "notify_url": notify_url,
}
- return self._post('secapi/pay/refund', data=data)
+ return self._post("secapi/pay/refund", data=data)
- def query(self, refund_id=None, out_refund_no=None, transaction_id=None,
- out_trade_no=None, device_info=None):
+ def query(
+ self,
+ refund_id=None,
+ out_refund_no=None,
+ transaction_id=None,
+ out_trade_no=None,
+ device_info=None,
+ ):
"""
查询退款
@@ -53,11 +68,11 @@ def query(self, refund_id=None, out_refund_no=None, transaction_id=None,
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'device_info': device_info,
- 'transaction_id': transaction_id,
- 'out_trade_no': out_trade_no,
- 'out_refund_no': out_refund_no,
- 'refund_id': refund_id,
+ "appid": self.appid,
+ "device_info": device_info,
+ "transaction_id": transaction_id,
+ "out_trade_no": out_trade_no,
+ "out_refund_no": out_refund_no,
+ "refund_id": refund_id,
}
- return self._post('pay/refundquery', data=data)
+ return self._post("pay/refundquery", data=data)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/tools.py b/chapter14/booking_system/exts/wechatpy/pay/api/tools.py
index 75ffc33..1c76797 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/tools.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/tools.py
@@ -15,12 +15,12 @@ def short_url(self, long_url):
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'long_url': long_url,
+ "appid": self.appid,
+ "long_url": long_url,
}
- return self._post('tools/shorturl', data=data)
+ return self._post("tools/shorturl", data=data)
- def download_bill(self, bill_date, bill_type='ALL', device_info=None):
+ def download_bill(self, bill_date, bill_type="ALL", device_info=None):
"""
下载对账单
@@ -33,18 +33,17 @@ def download_bill(self, bill_date, bill_type='ALL', device_info=None):
:return: 返回的结果数据
"""
if isinstance(bill_date, (datetime, date)):
- bill_date = bill_date.strftime('%Y%m%d')
+ bill_date = bill_date.strftime("%Y%m%d")
data = {
- 'appid': self.appid,
- 'bill_date': bill_date,
- 'bill_type': bill_type,
- 'device_info': device_info,
+ "appid": self.appid,
+ "bill_date": bill_date,
+ "bill_type": bill_type,
+ "device_info": device_info,
}
- return self._post('pay/downloadbill', data=data)
+ return self._post("pay/downloadbill", data=data)
- def download_fundflow(self, bill_date, account_type='Basic',
- tar_type=None):
+ def download_fundflow(self, bill_date, account_type="Basic", tar_type=None):
"""
下载资金账单
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_18&index=7
@@ -58,17 +57,17 @@ def download_fundflow(self, bill_date, account_type='Basic',
不传则默认为数据流形式。
"""
if isinstance(bill_date, (datetime, date)):
- bill_date = bill_date.strftime('%Y%m%d')
+ bill_date = bill_date.strftime("%Y%m%d")
data = {
- 'appid': self.appid,
- 'bill_date': bill_date,
- 'account_type': account_type,
- 'sign_type': 'HMAC-SHA256'
+ "appid": self.appid,
+ "bill_date": bill_date,
+ "account_type": account_type,
+ "sign_type": "HMAC-SHA256",
}
if tar_type is not None:
- data['tar_type'] = tar_type
- return self._post('pay/downloadfundflow', data=data)
+ data["tar_type"] = tar_type
+ return self._post("pay/downloadfundflow", data=data)
def auto_code_to_openid(self, auth_code):
"""
@@ -78,7 +77,7 @@ def auto_code_to_openid(self, auth_code):
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'auth_code': auth_code,
+ "appid": self.appid,
+ "auth_code": auth_code,
}
- return self._post('tools/authcodetoopenid', data=data)
+ return self._post("tools/authcodetoopenid", data=data)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/transfer.py b/chapter14/booking_system/exts/wechatpy/pay/api/transfer.py
index 0b49951..13701fe 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/transfer.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/transfer.py
@@ -9,9 +9,17 @@
class WeChatTransfer(BaseWeChatPayAPI):
- def transfer(self, user_id, amount, desc, client_ip=None,
- check_name='OPTION_CHECK', real_name=None,
- out_trade_no=None, device_info=None):
+ def transfer(
+ self,
+ user_id,
+ amount,
+ desc,
+ client_ip=None,
+ check_name="OPTION_CHECK",
+ real_name=None,
+ out_trade_no=None,
+ device_info=None,
+ ):
"""
企业付款接口
@@ -32,24 +40,22 @@ def transfer(self, user_id, amount, desc, client_ip=None,
"""
if not out_trade_no:
now = datetime.now()
- out_trade_no = '{0}{1}{2}'.format(
- self.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ out_trade_no = "{0}{1}{2}".format(
+ self.mch_id, now.strftime("%Y%m%d%H%M%S"), random.randint(1000, 10000)
)
data = {
- 'mch_appid': self.appid,
- 'mchid': self.mch_id,
- 'device_info': device_info,
- 'partner_trade_no': out_trade_no,
- 'openid': user_id,
- 'check_name': check_name,
- 're_user_name': real_name,
- 'amount': amount,
- 'desc': desc,
- 'spbill_create_ip': client_ip or get_external_ip(),
+ "mch_appid": self.appid,
+ "mchid": self.mch_id,
+ "device_info": device_info,
+ "partner_trade_no": out_trade_no,
+ "openid": user_id,
+ "check_name": check_name,
+ "re_user_name": real_name,
+ "amount": amount,
+ "desc": desc,
+ "spbill_create_ip": client_ip or get_external_ip(),
}
- return self._post('mmpaymkttransfers/promotion/transfers', data=data)
+ return self._post("mmpaymkttransfers/promotion/transfers", data=data)
def query(self, out_trade_no):
"""
@@ -59,12 +65,14 @@ def query(self, out_trade_no):
:return: 返回的结果数据
"""
data = {
- 'appid': self.appid,
- 'partner_trade_no': out_trade_no,
+ "appid": self.appid,
+ "partner_trade_no": out_trade_no,
}
- return self._post('mmpaymkttransfers/gettransferinfo', data=data)
+ return self._post("mmpaymkttransfers/gettransferinfo", data=data)
- def transfer_bankcard(self, true_name, bank_card_no, bank_code, amount, desc=None, out_trade_no=None):
+ def transfer_bankcard(
+ self, true_name, bank_card_no, bank_code, amount, desc=None, out_trade_no=None
+ ):
"""
企业付款到银行卡接口
@@ -78,21 +86,19 @@ def transfer_bankcard(self, true_name, bank_card_no, bank_code, amount, desc=Non
"""
if not out_trade_no:
now = datetime.now()
- out_trade_no = '{0}{1}{2}'.format(
- self.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ out_trade_no = "{0}{1}{2}".format(
+ self.mch_id, now.strftime("%Y%m%d%H%M%S"), random.randint(1000, 10000)
)
data = {
- 'mch_id': self.mch_id,
- 'partner_trade_no': out_trade_no,
- 'amount': amount,
- 'desc': desc,
- 'enc_bank_no': self._rsa_encrypt(bank_card_no),
- 'enc_true_name': self._rsa_encrypt(true_name),
- 'bank_code': bank_code,
+ "mch_id": self.mch_id,
+ "partner_trade_no": out_trade_no,
+ "amount": amount,
+ "desc": desc,
+ "enc_bank_no": self._rsa_encrypt(bank_card_no),
+ "enc_true_name": self._rsa_encrypt(true_name),
+ "bank_code": bank_code,
}
- return self._post('mmpaysptrans/pay_bank', data=data)
+ return self._post("mmpaysptrans/pay_bank", data=data)
def query_bankcard(self, out_trade_no):
"""
@@ -102,19 +108,21 @@ def query_bankcard(self, out_trade_no):
:return: 返回的结果数据
"""
data = {
- 'mch_id': self.mch_id,
- 'partner_trade_no': out_trade_no,
+ "mch_id": self.mch_id,
+ "partner_trade_no": out_trade_no,
}
- return self._post('mmpaysptrans/query_bank', data=data)
+ return self._post("mmpaysptrans/query_bank", data=data)
def get_rsa_public_key(self):
data = {
- 'mch_id': self.mch_id,
- 'sign_type': 'MD5',
+ "mch_id": self.mch_id,
+ "sign_type": "MD5",
}
- return self._post('https://fraud.mch.weixin.qq.com/risk/getpublickey', data=data)
+ return self._post(
+ "https://fraud.mch.weixin.qq.com/risk/getpublickey", data=data
+ )
def _rsa_encrypt(self, data):
- if not getattr(self, '_rsa_public_key', None):
- self._rsa_public_key = self.get_rsa_public_key()['pub_key']
+ if not getattr(self, "_rsa_public_key", None):
+ self._rsa_public_key = self.get_rsa_public_key()["pub_key"]
return rsa_encrypt(data, self._rsa_public_key)
diff --git a/chapter14/booking_system/exts/wechatpy/pay/api/withhold.py b/chapter14/booking_system/exts/wechatpy/pay/api/withhold.py
index 3e9f2e7..e629d80 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/api/withhold.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/api/withhold.py
@@ -13,9 +13,23 @@
class WeChatWithhold(BaseWeChatPayAPI):
- def apply_signing(self, plan_id, contract_code, contract_display_account, notify_url,
- version="1.0", clientip=None, deviceid=None, mobile=None, email=None, qq=None,
- request_serial=None, openid=None, creid=None, outerid=None):
+ def apply_signing(
+ self,
+ plan_id,
+ contract_code,
+ contract_display_account,
+ notify_url,
+ version="1.0",
+ clientip=None,
+ deviceid=None,
+ mobile=None,
+ email=None,
+ qq=None,
+ request_serial=None,
+ openid=None,
+ creid=None,
+ outerid=None,
+ ):
"""
申请签约 api
@@ -65,10 +79,17 @@ def apply_signing(self, plan_id, contract_code, contract_display_account, notify
data["sign"] = sign
return {
"base_url": "{}papay/entrustweb".format(self._client.API_BASE_URL),
- "data": data
+ "data": data,
}
- def query_signing(self, contract_id=None, plan_id=None, contract_code=None, openid=None, version="1.0"):
+ def query_signing(
+ self,
+ contract_id=None,
+ plan_id=None,
+ contract_code=None,
+ openid=None,
+ version="1.0",
+ ):
"""
查询签约关系 api
@@ -79,8 +100,14 @@ def query_signing(self, contract_id=None, plan_id=None, contract_code=None, open
:param version: 版本号 固定值1.0
:return: 返回的结果信息
"""
- if not contract_id and not (plan_id and contract_code) and not (plan_id and openid):
- raise ValueError("contract_id and (plan_id, contract_code) and (plan_id, openid) must be a choice.")
+ if (
+ not contract_id
+ and not (plan_id and contract_code)
+ and not (plan_id and openid)
+ ):
+ raise ValueError(
+ "contract_id and (plan_id, contract_code) and (plan_id, openid) must be a choice."
+ )
data = {
"appid": self.appid,
"mch_id": self.mch_id,
@@ -91,11 +118,28 @@ def query_signing(self, contract_id=None, plan_id=None, contract_code=None, open
"version": version,
"nonce_str": None,
}
- return self._post('papay/querycontract', data=data)
-
- def apply_deduct(self, body, total_fee, contract_id, notify_url, out_trade_no=None,
- detail=None, attach=None, fee_type='CNY', goods_tag=None, clientip=None, deviceid=None,
- mobile=None, email=None, qq=None, openid=None, creid=None, outerid=None):
+ return self._post("papay/querycontract", data=data)
+
+ def apply_deduct(
+ self,
+ body,
+ total_fee,
+ contract_id,
+ notify_url,
+ out_trade_no=None,
+ detail=None,
+ attach=None,
+ fee_type="CNY",
+ goods_tag=None,
+ clientip=None,
+ deviceid=None,
+ mobile=None,
+ email=None,
+ qq=None,
+ openid=None,
+ creid=None,
+ outerid=None,
+ ):
"""
申请扣款 api
@@ -118,15 +162,13 @@ def apply_deduct(self, body, total_fee, contract_id, notify_url, out_trade_no=No
:param outerid: 可选 商户侧用户标识 用户在商户侧的标识
:return: 返回的结果信息
"""
- trade_type = 'PAP' # 交易类型 交易类型PAP-微信委托代扣支付
+ trade_type = "PAP" # 交易类型 交易类型PAP-微信委托代扣支付
timestamp = int(time.time()) # 10位时间戳
spbill_create_ip = get_external_ip() # 终端IP 调用微信支付API的机器IP
if not out_trade_no:
- now = datetime.fromtimestamp(time.time(), tz=timezone('Asia/Shanghai'))
- out_trade_no = '{0}{1}{2}'.format(
- self.mch_id,
- now.strftime('%Y%m%d%H%M%S'),
- random.randint(1000, 10000)
+ now = datetime.fromtimestamp(time.time(), tz=timezone("Asia/Shanghai"))
+ out_trade_no = "{0}{1}{2}".format(
+ self.mch_id, now.strftime("%Y%m%d%H%M%S"), random.randint(1000, 10000)
)
data = {
@@ -173,8 +215,14 @@ def query_order(self, transaction_id=None, out_trade_no=None):
}
return self._post("pay/paporderquery", data=data)
- def apply_cancel_signing(self, contract_id=None, plan_id=None, contract_code=None,
- contract_termination_remark=None, version="1.0"):
+ def apply_cancel_signing(
+ self,
+ contract_id=None,
+ plan_id=None,
+ contract_code=None,
+ contract_termination_remark=None,
+ version="1.0",
+ ):
"""
申请解约
@@ -188,7 +236,9 @@ def apply_cancel_signing(self, contract_id=None, plan_id=None, contract_code=Non
:return:
"""
if not (contract_id or (plan_id and contract_code)):
- raise ValueError("contract_id and (plan_id, contract_code) must be a choice.")
+ raise ValueError(
+ "contract_id and (plan_id, contract_code) must be a choice."
+ )
data = {
"appid": self.appid,
"mch_id": self.mch_id,
diff --git a/chapter14/booking_system/exts/wechatpy/pay/base.py b/chapter14/booking_system/exts/wechatpy/pay/base.py
index 6184fa9..25c7830 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/base.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/base.py
@@ -3,18 +3,19 @@
class BaseWeChatPayAPI(object):
- """ WeChat Pay API base class """
+ """WeChat Pay API base class"""
+
def __init__(self, client=None):
self._client = client
def _get(self, url, **kwargs):
- if getattr(self, 'API_BASE_URL', None):
- kwargs['api_base_url'] = self.API_BASE_URL
+ if getattr(self, "API_BASE_URL", None):
+ kwargs["api_base_url"] = self.API_BASE_URL
return self._client.get(url, **kwargs)
def _post(self, url, **kwargs):
- if getattr(self, 'API_BASE_URL', None):
- kwargs['api_base_url'] = self.API_BASE_URL
+ if getattr(self, "API_BASE_URL", None):
+ kwargs["api_base_url"] = self.API_BASE_URL
return self._client.post(url, **kwargs)
@property
diff --git a/chapter14/booking_system/exts/wechatpy/pay/utils.py b/chapter14/booking_system/exts/wechatpy/pay/utils.py
index 4c1d05d..194be89 100644
--- a/chapter14/booking_system/exts/wechatpy/pay/utils.py
+++ b/chapter14/booking_system/exts/wechatpy/pay/utils.py
@@ -13,19 +13,22 @@
logger = logging.getLogger(__name__)
+
def format_url(params, api_key=None):
# if '#text' in params:
# print(params['#text'])
# del params['#text']
# print( params['#text'])
- data = [to_binary('{0}={1}'.format(k, params[k])) for k in sorted(params) if params[k]]
+ data = [
+ to_binary("{0}={1}".format(k, params[k])) for k in sorted(params) if params[k]
+ ]
# 微信支付回调的验证签名的修改!!!!zyxyuanxiao del data[0]
# 微信支付回调的验证签名的修改!!!!zyxyuanxiao del data[0]
# 微信支付回调的验证签名的修改!!!!zyxyuanxiao del data[0]
# del data[0]
if api_key:
- data.append(to_binary('key={0}'.format(api_key)))
+ data.append(to_binary("key={0}".format(api_key)))
return b"&".join(data)
@@ -37,42 +40,45 @@ def calculate_signature(params, api_key):
def calculate_signature_hmac(params, api_key):
url = format_url(params, api_key)
- sign = to_text(hmac.new(api_key.encode(), msg=url,
- digestmod=hashlib.sha256).hexdigest().upper())
+ sign = to_text(
+ hmac.new(api_key.encode(), msg=url, digestmod=hashlib.sha256)
+ .hexdigest()
+ .upper()
+ )
return sign
def _check_signature(params, api_key):
_params = copy.deepcopy(params)
- sign = _params.pop('sign', '')
+ sign = _params.pop("sign", "")
return sign == calculate_signature(_params, api_key)
def dict_to_xml(d, sign):
- xml = ['\n']
+ xml = ["\n"]
for k in sorted(d):
# use sorted to avoid test error on Py3k
v = d[k]
- if isinstance(v, six.integer_types) or (isinstance(v, six.string_types) and v.isdigit()):
- xml.append('<{0}>{1}{0}>\n'.format(to_text(k), to_text(v)))
+ if isinstance(v, six.integer_types) or (
+ isinstance(v, six.string_types) and v.isdigit()
+ ):
+ xml.append("<{0}>{1}{0}>\n".format(to_text(k), to_text(v)))
else:
- xml.append(
- '<{0}>{0}>\n'.format(to_text(k), to_text(v))
- )
- xml.append('\n'.format(to_text(sign)))
- return ''.join(xml)
+ xml.append("<{0}>{0}>\n".format(to_text(k), to_text(v)))
+ xml.append("\n".format(to_text(sign)))
+ return "".join(xml)
def get_external_ip():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
- wechat_ip = socket.gethostbyname('api.mch.weixin.qq.com')
+ wechat_ip = socket.gethostbyname("api.mch.weixin.qq.com")
sock.connect((wechat_ip, 80))
addr, port = sock.getsockname()
sock.close()
return addr
except socket.error:
- return '127.0.0.1'
+ return "127.0.0.1"
def rsa_encrypt(data, pem, b64_encode=True):
@@ -87,6 +93,7 @@ def rsa_encrypt(data, pem, b64_encode=True):
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
+
encoded_data = to_binary(data)
pem = to_binary(pem)
public_key = serialization.load_pem_public_key(pem, backend=default_backend())
@@ -96,10 +103,10 @@ def rsa_encrypt(data, pem, b64_encode=True):
mgf=padding.MGF1(hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None,
- )
+ ),
)
if b64_encode:
- encrypted_data = base64.b64encode(encrypted_data).decode('utf-8')
+ encrypted_data = base64.b64encode(encrypted_data).decode("utf-8")
return encrypted_data
@@ -118,13 +125,15 @@ def rsa_decrypt(encrypted_data, pem, password=None):
encrypted_data = to_binary(encrypted_data)
pem = to_binary(pem)
- private_key = serialization.load_pem_private_key(pem, password, backend=default_backend())
+ private_key = serialization.load_pem_private_key(
+ pem, password, backend=default_backend()
+ )
data = private_key.decrypt(
encrypted_data,
padding=padding.OAEP(
mgf=padding.MGF1(hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None,
- )
+ ),
)
return data
diff --git a/chapter14/booking_system/exts/wechatpy/replies.py b/chapter14/booking_system/exts/wechatpy/replies.py
index 9a48d71..3365edc 100644
--- a/chapter14/booking_system/exts/wechatpy/replies.py
+++ b/chapter14/booking_system/exts/wechatpy/replies.py
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.replies
- ~~~~~~~~~~~~~~~~~~
- This module defines all kinds of replies you can send to WeChat
+wechatpy.replies
+~~~~~~~~~~~~~~~~~~
+This module defines all kinds of replies you can send to WeChat
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
import time
@@ -34,28 +34,30 @@ def register_reply(reply_type):
def register(cls):
REPLY_TYPES[reply_type] = cls
return cls
+
return register
class BaseReply(six.with_metaclass(MessageMetaClass)):
"""Base class for all replies"""
- source = StringField('FromUserName')
- target = StringField('ToUserName')
- time = IntegerField('CreateTime', time.time())
- type = 'unknown'
+
+ source = StringField("FromUserName")
+ target = StringField("ToUserName")
+ time = IntegerField("CreateTime", time.time())
+ type = "unknown"
def __init__(self, **kwargs):
self._data = {}
- message = kwargs.pop('message', None)
+ message = kwargs.pop("message", None)
if message and isinstance(message, BaseMessage):
- if 'source' not in kwargs:
- kwargs['source'] = message.target
- if 'target' not in kwargs:
- kwargs['target'] = message.source
- if hasattr(message, 'agent') and 'agent' not in kwargs:
- kwargs['agent'] = message.agent
- if 'time' not in kwargs:
- kwargs['time'] = time.time()
+ if "source" not in kwargs:
+ kwargs["source"] = message.target
+ if "target" not in kwargs:
+ kwargs["target"] = message.source
+ if hasattr(message, "agent") and "agent" not in kwargs:
+ kwargs["agent"] = message.agent
+ if "time" not in kwargs:
+ kwargs["time"] = time.time()
for name, value in kwargs.items():
field = self._fields.get(name)
if field:
@@ -65,9 +67,9 @@ def __init__(self, **kwargs):
def render(self):
"""Render reply from Python object to XML string"""
- tpl = '\n{data}\n'
+ tpl = "\n{data}\n"
nodes = []
- msg_type = ''.format(
+ msg_type = "".format(
msg_type=self.type
)
nodes.append(msg_type)
@@ -75,7 +77,7 @@ def render(self):
value = getattr(self, name, field.default)
node_xml = field.to_xml(value)
nodes.append(node_xml)
- data = '\n'.join(nodes)
+ data = "\n".join(nodes)
return tpl.format(data=data)
def __str__(self):
@@ -85,39 +87,42 @@ def __str__(self):
return to_text(self.render())
-@register_reply('empty')
+@register_reply("empty")
class EmptyReply(BaseReply):
"""
回复空串
微信服务器不会对此作任何处理,并且不会发起重试
"""
+
def __init__(self):
pass
def render(self):
- return ''
+ return ""
-@register_reply('text')
+@register_reply("text")
class TextReply(BaseReply):
"""
文本回复
详情请参阅 http://mp.weixin.qq.com/wiki/9/2c15b20a16019ae613d413e30cac8ea1.html
"""
- type = 'text'
- content = StringField('Content')
+ type = "text"
+ content = StringField("Content")
-@register_reply('image')
+
+@register_reply("image")
class ImageReply(BaseReply):
"""
图片回复
详情请参阅
http://mp.weixin.qq.com/wiki/9/2c15b20a16019ae613d413e30cac8ea1.html
"""
- type = 'image'
- image = ImageField('Image')
+
+ type = "image"
+ image = ImageField("Image")
@property
def media_id(self):
@@ -128,15 +133,16 @@ def media_id(self, value):
self.image = value
-@register_reply('voice')
+@register_reply("voice")
class VoiceReply(BaseReply):
"""
语音回复
详情请参阅
http://mp.weixin.qq.com/wiki/9/2c15b20a16019ae613d413e30cac8ea1.html
"""
- type = 'voice'
- voice = VoiceField('Voice')
+
+ type = "voice"
+ voice = VoiceField("Voice")
@property
def media_id(self):
@@ -147,169 +153,174 @@ def media_id(self, value):
self.voice = value
-@register_reply('video')
+@register_reply("video")
class VideoReply(BaseReply):
"""
视频回复
详情请参阅
http://mp.weixin.qq.com/wiki/9/2c15b20a16019ae613d413e30cac8ea1.html
"""
- type = 'video'
- video = VideoField('Video', {})
+
+ type = "video"
+ video = VideoField("Video", {})
@property
def media_id(self):
- return self.video.get('media_id')
+ return self.video.get("media_id")
@media_id.setter
def media_id(self, value):
video = self.video
- video['media_id'] = value
+ video["media_id"] = value
self.video = video
@property
def title(self):
- return self.video.get('title')
+ return self.video.get("title")
@title.setter
def title(self, value):
video = self.video
- video['title'] = value
+ video["title"] = value
self.video = video
@property
def description(self):
- return self.video.get('description')
+ return self.video.get("description")
@description.setter
def description(self, value):
video = self.video
- video['description'] = value
+ video["description"] = value
self.video = video
-@register_reply('music')
+@register_reply("music")
class MusicReply(BaseReply):
"""
音乐回复
详情请参阅
http://mp.weixin.qq.com/wiki/9/2c15b20a16019ae613d413e30cac8ea1.html
"""
- type = 'music'
- music = MusicField('Music', {})
+
+ type = "music"
+ music = MusicField("Music", {})
@property
def thumb_media_id(self):
- return self.music.get('thumb_media_id')
+ return self.music.get("thumb_media_id")
@thumb_media_id.setter
def thumb_media_id(self, value):
music = self.music
- music['thumb_media_id'] = value
+ music["thumb_media_id"] = value
self.music = music
@property
def title(self):
- return self.music.get('title')
+ return self.music.get("title")
@title.setter
def title(self, value):
music = self.music
- music['title'] = value
+ music["title"] = value
self.music = music
@property
def description(self):
- return self.music.get('description')
+ return self.music.get("description")
@description.setter
def description(self, value):
music = self.music
- music['description'] = value
+ music["description"] = value
self.music = music
@property
def music_url(self):
- return self.music.get('music_url')
+ return self.music.get("music_url")
@music_url.setter
def music_url(self, value):
music = self.music
- music['music_url'] = value
+ music["music_url"] = value
self.music = music
@property
def hq_music_url(self):
- return self.music.get('hq_music_url')
+ return self.music.get("hq_music_url")
@hq_music_url.setter
def hq_music_url(self, value):
music = self.music
- music['hq_music_url'] = value
+ music["hq_music_url"] = value
self.music = music
-@register_reply('news')
+@register_reply("news")
class ArticlesReply(BaseReply):
"""
图文回复
详情请参阅
http://mp.weixin.qq.com/wiki/9/2c15b20a16019ae613d413e30cac8ea1.html
"""
- type = 'news'
- articles = ArticlesField('Articles', [])
+
+ type = "news"
+ articles = ArticlesField("Articles", [])
def add_article(self, article):
if len(self.articles) == 10:
- raise AttributeError("Can't add more than 10 articles"
- " in an ArticlesReply")
+ raise AttributeError(
+ "Can't add more than 10 articles" " in an ArticlesReply"
+ )
articles = self.articles
articles.append(article)
self.articles = articles
-@register_reply('transfer_customer_service')
+@register_reply("transfer_customer_service")
class TransferCustomerServiceReply(BaseReply):
"""
将消息转发到多客服
详情请参阅
http://mp.weixin.qq.com/wiki/5/ae230189c9bd07a6b221f48619aeef35.html
"""
- type = 'transfer_customer_service'
+ type = "transfer_customer_service"
-@register_reply('device_text')
+
+@register_reply("device_text")
class DeviceTextReply(BaseReply):
- type = 'device_text'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64EncodeField('Content')
+ type = "device_text"
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ session_id = StringField("SessionID")
+ content = Base64EncodeField("Content")
-@register_reply('device_event')
+@register_reply("device_event")
class DeviceEventReply(BaseReply):
- type = 'device_event'
- event = StringField('Event')
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- session_id = StringField('SessionID')
- content = Base64EncodeField('Content')
+ type = "device_event"
+ event = StringField("Event")
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ session_id = StringField("SessionID")
+ content = Base64EncodeField("Content")
-@register_reply('device_status')
+@register_reply("device_status")
class DeviceStatusReply(BaseReply):
- type = 'device_status'
- device_type = StringField('DeviceType')
- device_id = StringField('DeviceID')
- status = IntegerField('DeviceStatus')
+ type = "device_status"
+ device_type = StringField("DeviceType")
+ device_id = StringField("DeviceID")
+ status = IntegerField("DeviceStatus")
-@register_reply('hardware')
+@register_reply("hardware")
class HardwareReply(BaseReply):
- type = 'hardware'
- func_flag = IntegerField('FuncFlag', 0)
- hardware = HardwareField('HardWare')
+ type = "hardware"
+ func_flag = IntegerField("FuncFlag", 0)
+ hardware = HardwareField("HardWare")
def create_reply(reply, message=None, render=False):
@@ -325,18 +336,13 @@ def create_reply(reply, message=None, render=False):
r.source = message.target
r.target = message.source
elif isinstance(reply, six.string_types):
- r = TextReply(
- message=message,
- content=reply
- )
+ r = TextReply(message=message, content=reply)
elif isinstance(reply, (tuple, list)):
if len(reply) > 10:
- raise AttributeError("Can't add more than 10 articles"
- " in an ArticlesReply")
- r = ArticlesReply(
- message=message,
- articles=reply
- )
+ raise AttributeError(
+ "Can't add more than 10 articles" " in an ArticlesReply"
+ )
+ r = ArticlesReply(message=message, articles=reply)
if r and render:
return r.render()
return r
diff --git a/chapter14/booking_system/exts/wechatpy/session/memcachedstorage.py b/chapter14/booking_system/exts/wechatpy/session/memcachedstorage.py
index e9d7b33..15bd06d 100644
--- a/chapter14/booking_system/exts/wechatpy/session/memcachedstorage.py
+++ b/chapter14/booking_system/exts/wechatpy/session/memcachedstorage.py
@@ -8,14 +8,14 @@
class MemcachedStorage(SessionStorage):
- def __init__(self, mc, prefix='wechatpy'):
- for method_name in ('get', 'set', 'delete'):
+ def __init__(self, mc, prefix="wechatpy"):
+ for method_name in ("get", "set", "delete"):
assert hasattr(mc, method_name)
self.mc = mc
self.prefix = prefix
def key_name(self, key):
- return '{0}:{1}'.format(self.prefix, key)
+ return "{0}:{1}".format(self.prefix, key)
def get(self, key, default=None):
key = self.key_name(key)
diff --git a/chapter14/booking_system/exts/wechatpy/session/redisstorage.py b/chapter14/booking_system/exts/wechatpy/session/redisstorage.py
index 7412929..c931e64 100644
--- a/chapter14/booking_system/exts/wechatpy/session/redisstorage.py
+++ b/chapter14/booking_system/exts/wechatpy/session/redisstorage.py
@@ -7,14 +7,14 @@
class RedisStorage(SessionStorage):
- def __init__(self, redis, prefix='wechatpy'):
- for method_name in ('get', 'set', 'delete'):
+ def __init__(self, redis, prefix="wechatpy"):
+ for method_name in ("get", "set", "delete"):
assert hasattr(redis, method_name)
self.redis = redis
self.prefix = prefix
def key_name(self, key):
- return '{0}:{1}'.format(self.prefix, key)
+ return "{0}:{1}".format(self.prefix, key)
def get(self, key, default=None):
key = self.key_name(key)
diff --git a/chapter14/booking_system/exts/wechatpy/session/shovestorage.py b/chapter14/booking_system/exts/wechatpy/session/shovestorage.py
index 2e0ffbf..1efda82 100644
--- a/chapter14/booking_system/exts/wechatpy/session/shovestorage.py
+++ b/chapter14/booking_system/exts/wechatpy/session/shovestorage.py
@@ -5,12 +5,12 @@
class ShoveStorage(SessionStorage):
- def __init__(self, shove, prefix='wechatpy'):
+ def __init__(self, shove, prefix="wechatpy"):
self.shove = shove
self.prefix = prefix
def key_name(self, key):
- return '{0}:{1}'.format(self.prefix, key)
+ return "{0}:{1}".format(self.prefix, key)
def get(self, key, default=None):
key = self.key_name(key)
diff --git a/chapter14/booking_system/exts/wechatpy/utils.py b/chapter14/booking_system/exts/wechatpy/utils.py
index 74480ed..ee02ada 100644
--- a/chapter14/booking_system/exts/wechatpy/utils.py
+++ b/chapter14/booking_system/exts/wechatpy/utils.py
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""
- wechatpy.utils
- ~~~~~~~~~~~~~~~
+wechatpy.utils
+~~~~~~~~~~~~~~~
- This module provides some useful utilities.
+This module provides some useful utilities.
- :copyright: (c) 2014 by messense.
- :license: MIT, see LICENSE for more details.
+:copyright: (c) 2014 by messense.
+:license: MIT, see LICENSE for more details.
"""
from __future__ import absolute_import, unicode_literals
import string
@@ -14,7 +14,7 @@
import hashlib
try:
- '''Use simplejson if we can, fallback to json otherwise.'''
+ """Use simplejson if we can, fallback to json otherwise."""
import simplejson as json
except ImportError:
import json # NOQA
@@ -24,8 +24,7 @@
class ObjectDict(dict):
- """Makes a dictionary behave like an object, with attribute-style access.
- """
+ """Makes a dictionary behave like an object, with attribute-style access."""
def __getattr__(self, key):
if key in self:
@@ -39,7 +38,7 @@ def __setattr__(self, key, value):
class WeChatSigner(object):
"""WeChat data signer"""
- def __init__(self, delimiter=b''):
+ def __init__(self, delimiter=b""):
self._data = []
self._delimiter = to_binary(delimiter)
@@ -73,14 +72,14 @@ def check_signature(token, signature, timestamp, nonce):
raise InvalidSignatureException()
-def to_text(value, encoding='utf-8'):
+def to_text(value, encoding="utf-8"):
"""Convert value to unicode, default encoding is utf-8
:param value: Value to be converted
:param encoding: Desired encoding
"""
if not value:
- return ''
+ return ""
if isinstance(value, six.text_type):
return value
if isinstance(value, six.binary_type):
@@ -88,14 +87,14 @@ def to_text(value, encoding='utf-8'):
return six.text_type(value)
-def to_binary(value, encoding='utf-8'):
+def to_binary(value, encoding="utf-8"):
"""Convert value to binary string, default encoding is utf-8
:param value: Value to be converted
:param encoding: Desired encoding
"""
if not value:
- return b''
+ return b""
if isinstance(value, six.binary_type):
return value
if isinstance(value, six.text_type):
@@ -111,11 +110,13 @@ def timezone(zone):
"""
try:
import pytz
+
return pytz.timezone(zone)
except ImportError:
pass
try:
from dateutil.tz import gettz
+
return gettz(zone)
except ImportError:
return None
@@ -124,7 +125,7 @@ def timezone(zone):
def random_string(length=16):
rule = string.ascii_letters + string.digits
rand_list = random.sample(rule, length)
- return ''.join(rand_list)
+ return "".join(rand_list)
def get_querystring(uri):
diff --git a/chapter14/booking_system/main.py b/chapter14/booking_system/main.py
index ec3f1e1..b0c5d55 100644
--- a/chapter14/booking_system/main.py
+++ b/chapter14/booking_system/main.py
@@ -1,12 +1,14 @@
from app import creat_app
-app =creat_app()
+
+app = creat_app()
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
# tree -I "node_modules|cache|test_*"
-# tree -I "__pycache__"
\ No newline at end of file
+# tree -I "__pycache__"
diff --git a/chapter14/booking_system/middlewares/loger/middleware.py b/chapter14/booking_system/middlewares/loger/middleware.py
index dca0ac5..e74aaef 100644
--- a/chapter14/booking_system/middlewares/loger/middleware.py
+++ b/chapter14/booking_system/middlewares/loger/middleware.py
@@ -15,87 +15,107 @@
request: Request = bind_contextvar(request_var)
-
-
def setup_ext_loguru(log_pro_path: str = None):
- '''
+ """
:param pro_path: 当前需要生产的日志文件的存在路径
:return:
- '''
+ """
import os
+
if not log_pro_path:
log_pro_path = os.path.split(os.path.realpath(__file__))[0]
# 定义info_log文件名称
- log_file_path = os.path.join(log_pro_path, 'log/info_{time:YYYYMMDD}.log')
+ log_file_path = os.path.join(log_pro_path, "log/info_{time:YYYYMMDD}.log")
# 定义err_log文件名称
- err_log_file_path = os.path.join(log_pro_path, 'log/error_{time:YYYYMMDD}.log')
+ err_log_file_path = os.path.join(log_pro_path, "log/error_{time:YYYYMMDD}.log")
from sys import stdout
- LOGURU_FORMAT: str = '{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <16} | {message}'
+
+ LOGURU_FORMAT: str = (
+ "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <16} | {message}"
+ )
# 这句话很关键避免多次的写入我们的日志
- logger.configure(handlers=[{'sink': stdout, 'format': LOGURU_FORMAT}])
+ logger.configure(handlers=[{"sink": stdout, "format": LOGURU_FORMAT}])
# 这个也可以启动避免多次的写入的作用,但是我们的 app:register_logger:40 -无法输出
# logger.remove()
# 错误日志不需要压缩
format = " {time:YYYY-MM-DD HH:mm:ss:SSS} | thread_id:{thread.id} thread_name:{thread.name} | {level} |\n {message}"
# 使用 rotation 参数实现定时创建 log 文件,可以实现每天 0 点新创建一个 log 文件输出了 enqueue=True表示 开启异步写入
- logger.add(err_log_file_path, format=format, rotation='00:00', encoding='utf-8', level='ERROR', enqueue=True) # Automatically rotate too big file
+ logger.add(
+ err_log_file_path,
+ format=format,
+ rotation="00:00",
+ encoding="utf-8",
+ level="ERROR",
+ enqueue=True,
+ ) # Automatically rotate too big file
# 对应不同的格式
format2 = " {time:YYYY-MM-DD HH:mm:ss:SSS} | thread_id:{thread.id} thread_name:{thread.name} | {level} | {message}"
# 使用 rotation 参数实现定时创建 log 文件,可以实现每天 0 点新创建一个 log 文件输出了 enqueue=True表示 开启异步写入
- logger.add(log_file_path, format=format2, rotation='00:00', encoding='utf-8', level='INFO', enqueue=True) # Automatically rotate too big file
-
+ logger.add(
+ log_file_path,
+ format=format2,
+ rotation="00:00",
+ encoding="utf-8",
+ level="INFO",
+ enqueue=True,
+ ) # Automatically rotate too big file
-async def async_trace_add_log_record(event_type='', msg={}, remarks=''):
- '''
+async def async_trace_add_log_record(event_type="", msg={}, remarks=""):
+ """
:param event_type: 日志记录事件描述
:param msg: 日志记录信息字典
:param remarks: 日志备注信息
:return:
- '''
+ """
# 如果没有这个标记的属性的,说明这个接口的不需要记录啦!
- if request and hasattr(request.state, 'traceid'):
+ if request and hasattr(request.state, "traceid"):
# 自增编号索引序
- trace_links_index = request.state.trace_links_index = getattr(request.state, 'trace_links_index') + 1
+ trace_links_index = request.state.trace_links_index = (
+ getattr(request.state, "trace_links_index") + 1
+ )
log = {
# 自定义一个新的参数复制到我们的请求上下文的对象中
- 'traceid': getattr(request.state, 'traceid'),
+ "traceid": getattr(request.state, "traceid"),
# 定义链路所以序号
- 'trace_index': trace_links_index,
+ "trace_index": trace_links_index,
# 时间类型描述描述
- 'event_type': event_type,
+ "event_type": event_type,
# 日志内容详情
- 'msg': msg,
+ "msg": msg,
# 日志备注信息
- 'remarks': remarks,
-
+ "remarks": remarks,
}
# 为少少相关记录,删除不必要的为空的日志内容信息,
if not remarks:
- log.pop('remarks')
+ log.pop("remarks")
if not msg:
- log.pop('msg')
+ log.pop("msg")
try:
log_msg = json_helper.dict_to_json_ensure_ascii(log) # 返回文本
logger.info(log_msg)
except:
- logger.info(getattr(request.state, 'traceid') + ':索引:' + str(getattr(request.state, 'trace_links_index')) + ':日志信息写入异常')
-
+ logger.info(
+ getattr(request.state, "traceid")
+ + ":索引:"
+ + str(getattr(request.state, "trace_links_index"))
+ + ":日志信息写入异常"
+ )
class LogerMiddleware:
def __init__(
- self,
- *,
- app: ASGIApp,
- log_pro_path: str,
- is_record_useragent=False,
- is_record_headers=False,
- nesss_access_heads_keys=[],
- ignore_url: typing.List = ['/favicon.ico', 'websocket'],
+ self,
+ *,
+ app: ASGIApp,
+ log_pro_path: str,
+ is_record_useragent=False,
+ is_record_headers=False,
+ nesss_access_heads_keys=[],
+ ignore_url: typing.List = ["/favicon.ico", "websocket"],
) -> None:
self.app = app
self.is_record_useragent = is_record_useragent
@@ -105,11 +125,11 @@ def __init__(
setup_ext_loguru(log_pro_path)
def make_traceid(self, request) -> None:
- '''
+ """
生成追踪链路ID
:param request:
:return:
- '''
+ """
request.state.traceid = shortuuid.uuid()
# 追踪索引序号
request.state.trace_links_index = 0
@@ -119,36 +139,35 @@ def make_traceid(self, request) -> None:
request.state.start_time = perf_counter()
def make_token_request(self, request):
- '''
+ """
生成当前请求上下文对象request
:param request:
:return:
- '''
+ """
return request_var.set(request)
def reset_token_request(self, token_request):
- '''
+ """
重置当前请求上下文对象request
:param request:
:return:
- '''
+ """
request_var.reset(token_request)
-
async def get_request_body(self, request) -> typing.AnyStr:
body = None
try:
body_bytes = await request.body()
if body_bytes:
try:
- body = await request.json()
+ body = await request.json()
except:
pass
if body_bytes:
try:
- body = body_bytes.decode('utf-8')
+ body = body_bytes.decode("utf-8")
except:
- body = body_bytes.decode('gb2312')
+ body = body_bytes.decode("gb2312")
except:
pass
request.state.body = body
@@ -189,77 +208,102 @@ async def make_request_log_msg(self, request) -> typing.Dict:
os_major, os_minor = 0, 0
log_msg = {
- 'headers': None if not self.is_record_headers else
- [request.headers.get(i, '') for i in
- self.nesss_access_heads_keys] if self.nesss_access_heads_keys else None,
+ "headers": (
+ None
+ if not self.is_record_headers
+ else (
+ [
+ request.headers.get(i, "")
+ for i in self.nesss_access_heads_keys
+ ]
+ if self.nesss_access_heads_keys
+ else None
+ )
+ ),
# 记录请求URL信息
- "useragent": None if not self.is_record_useragent else
- {
- "os": "{} {}".format(user_agent.os.family, user_agent.os.version_string),
- 'browser': "{} {}".format(user_agent.browser.family, user_agent.browser.version_string),
- "device": {
- "family": user_agent.device.family,
- "brand": user_agent.device.brand,
- "model": user_agent.device.model,
+ "useragent": (
+ None
+ if not self.is_record_useragent
+ else {
+ "os": "{} {}".format(
+ user_agent.os.family, user_agent.os.version_string
+ ),
+ "browser": "{} {}".format(
+ user_agent.browser.family, user_agent.browser.version_string
+ ),
+ "device": {
+ "family": user_agent.device.family,
+ "brand": user_agent.device.brand,
+ "model": user_agent.device.model,
+ },
}
- },
- 'url': url,
+ ),
+ "url": url,
# 记录请求方法
- 'method': method,
+ "method": method,
# 记录请求来源IP
- 'ip': ip,
+ "ip": ip,
# 'path': gziprequest.path,
# 记录请求提交的参数信息
- 'params': {
- 'query_params': parse_qs(str(request.query_params)),
- 'from': body_form,
- 'body': body
+ "params": {
+ "query_params": parse_qs(str(request.query_params)),
+ "from": body_form,
+ "body": body,
},
- "ts": f'{datetime.now():%Y-%m-%d %H:%M:%S%z}'
+ "ts": f"{datetime.now():%Y-%m-%d %H:%M:%S%z}",
}
# 对于没有的数据清除
- if not log_msg['headers']:
- log_msg.pop('headers')
- if not log_msg['params']['query_params']:
- log_msg['params'].pop('query_params')
- if not log_msg['params']['from']:
- log_msg['params'].pop('from')
- if not log_msg['params']['body']:
- log_msg['params'].pop('body')
+ if not log_msg["headers"]:
+ log_msg.pop("headers")
+ if not log_msg["params"]["query_params"]:
+ log_msg["params"].pop("query_params")
+ if not log_msg["params"]["from"]:
+ log_msg["params"].pop("from")
+ if not log_msg["params"]["body"]:
+ log_msg["params"].pop("body")
except:
log_msg = {
- 'headers': None if not self.is_record_headers else
- [request.headers.get(i, '') for i in
- self.nesss_access_heads_keys] if self.nesss_access_heads_keys else None,
- 'url': url,
- 'method': method,
- 'ip': ip,
- 'params': {
- 'query_params': parse_qs(str(request.query_params)),
- 'from': body_form,
- 'body': body
+ "headers": (
+ None
+ if not self.is_record_headers
+ else (
+ [
+ request.headers.get(i, "")
+ for i in self.nesss_access_heads_keys
+ ]
+ if self.nesss_access_heads_keys
+ else None
+ )
+ ),
+ "url": url,
+ "method": method,
+ "ip": ip,
+ "params": {
+ "query_params": parse_qs(str(request.query_params)),
+ "from": body_form,
+ "body": body,
},
- "ts": f'{datetime.now():%Y-%m-%d %H:%M:%S%z}'
+ "ts": f"{datetime.now():%Y-%m-%d %H:%M:%S%z}",
}
- print('log_msg', log_msg)
+ print("log_msg", log_msg)
# 对于没有的数据清除
- if 'headers' in log_msg and not log_msg['headers']:
- log_msg.pop('headers')
- if log_msg['params']:
- if 'query_params' in log_msg['params'] and not log_msg['params']['query_params']:
- log_msg['params'].pop('query_params')
- print(log_msg['params'])
- if 'from' in log_msg['params'] and not log_msg['params']['from']:
- log_msg['params'].pop('from')
- if 'body' in log_msg['params'] and not log_msg['params']['body']:
- log_msg['params'].pop('body')
+ if "headers" in log_msg and not log_msg["headers"]:
+ log_msg.pop("headers")
+ if log_msg["params"]:
+ if (
+ "query_params" in log_msg["params"]
+ and not log_msg["params"]["query_params"]
+ ):
+ log_msg["params"].pop("query_params")
+ print(log_msg["params"])
+ if "from" in log_msg["params"] and not log_msg["params"]["from"]:
+ log_msg["params"].pop("from")
+ if "body" in log_msg["params"] and not log_msg["params"]["body"]:
+ log_msg["params"].pop("body")
return log_msg
-
-
-
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
if scope["type"] != "http": # pragma: no cover
await self.app(scope, receive, send)
@@ -284,9 +328,9 @@ async def receive():
# 生成日志记录
log_msg = await self.make_request_log_msg(request)
# 开始写日志信息到文件中
- await async_trace_add_log_record(event_type='request', msg=log_msg)
+ await async_trace_add_log_record(event_type="request", msg=log_msg)
try:
response = await self.app(scope, receive, send)
return response
finally:
- self.reset_token_request(token_request)
+ self.reset_token_request(token_request)
diff --git a/chapter14/booking_system/order_consumer.py b/chapter14/booking_system/order_consumer.py
index d417a2f..88d332f 100644
--- a/chapter14/booking_system/order_consumer.py
+++ b/chapter14/booking_system/order_consumer.py
@@ -7,7 +7,7 @@
创建人 : 小钟同学
创建时间 : 2021/10/19
-------------------------------------------------
- 修改描述-2021/10/19:
+ 修改描述-2021/10/19:
-------------------------------------------------
"""
import pika
@@ -21,24 +21,33 @@
credentials = pika.PlainCredentials("guest", "guest")
# 创建连接http://47.99.189.42:30100/
connection = pika.BlockingConnection(
- pika.ConnectionParameters(host='localhost', port=5672, virtual_host='yuyueguahao', credentials=credentials))
+ pika.ConnectionParameters(
+ host="localhost", port=5672, virtual_host="yuyueguahao", credentials=credentials
+ )
+)
# 通过连接创建信道
channel = connection.channel()
# 通过信道创建我们的队列 其中名称是task_queue,并且这个队列的消息是需要持久化的!PS:持久化存储存到磁盘会占空间,
# 队列不能由持久化变为普通队列,反过来也是!否则会报错!所以队列类型创建的开始必须确定的!
-order_dead_letter_exchange_name = 'xz-dead-letter-exchange'
-order_dead_letter_exchange_type = 'fanout'
-order_dead_letter_queue_name = 'xz-dead-letter-queue'
-order_dead_letter_routing_key = 'xz-dead-letter-queue'
+order_dead_letter_exchange_name = "xz-dead-letter-exchange"
+order_dead_letter_exchange_type = "fanout"
+order_dead_letter_queue_name = "xz-dead-letter-queue"
+order_dead_letter_routing_key = "xz-dead-letter-queue"
# 相对比只要交换机名称即可接收到消息的广播模式(fanout),direct模式在其基础上,多加了一层密码限制(routingKey)
-channel.exchange_declare(exchange=order_dead_letter_exchange_name, durable=True,
- exchange_type=order_dead_letter_exchange_type)
+channel.exchange_declare(
+ exchange=order_dead_letter_exchange_name,
+ durable=True,
+ exchange_type=order_dead_letter_exchange_type,
+)
channel.queue_declare(queue=order_dead_letter_queue_name, durable=True)
-channel.queue_bind(exchange=order_dead_letter_exchange_name, queue=order_dead_letter_queue_name,
- routing_key=order_dead_letter_routing_key)
+channel.queue_bind(
+ exchange=order_dead_letter_exchange_name,
+ queue=order_dead_letter_queue_name,
+ routing_key=order_dead_letter_routing_key,
+)
-print(' [*] 死信队列里面的死信消息的消费. To exit press CTRL+C')
+print(" [*] 死信队列里面的死信消息的消费. To exit press CTRL+C")
# 初始化数据库的链接处理
@@ -50,11 +59,17 @@ def callback(ch, method, properties, body):
# 获取当前的订单支付状态信息,如果当前处于没支付的状态的话,则需要回滚我们的库存
with sync_context_get_db() as session:
- _result = session.query(DoctorSubscribeinfo).filter(and_(DoctorSubscribeinfo.dno == mesgg.get('dno'),
- DoctorSubscribeinfo.visit_uopenid == mesgg.get(
- 'visit_uopenid'),
- DoctorSubscribeinfo.orderid == mesgg.get(
- 'orderid'))).one_or_none()
+ _result = (
+ session.query(DoctorSubscribeinfo)
+ .filter(
+ and_(
+ DoctorSubscribeinfo.dno == mesgg.get("dno"),
+ DoctorSubscribeinfo.visit_uopenid == mesgg.get("visit_uopenid"),
+ DoctorSubscribeinfo.orderid == mesgg.get("orderid"),
+ )
+ )
+ .one_or_none()
+ )
if _result:
@@ -65,9 +80,12 @@ def callback(ch, method, properties, body):
pass
# 更新订单状态
print("更新状态!!!!!!!!!!!!!")
- session.query(DoctorSubscribeinfo).filter(and_(DoctorSubscribeinfo.dno == mesgg.get('dno'),DoctorSubscribeinfo.orderid == mesgg.get(
- 'orderid'))).update({DoctorSubscribeinfo.statue: 4},
- synchronize_session=False)
+ session.query(DoctorSubscribeinfo).filter(
+ and_(
+ DoctorSubscribeinfo.dno == mesgg.get("dno"),
+ DoctorSubscribeinfo.orderid == mesgg.get("orderid"),
+ )
+ ).update({DoctorSubscribeinfo.statue: 4}, synchronize_session=False)
elif _result.statue == 3:
pass
elif _result.statue == 5:
@@ -84,7 +102,7 @@ def callback(ch, method, properties, body):
channel.basic_qos(prefetch_count=1)
# await channel.set_qos(prefetch_count=1)
# 开始进行订阅消费
-ack = channel.basic_consume(queue='xz-dead-letter-queue', on_message_callback=callback)
-print('s', ack)
+ack = channel.basic_consume(queue="xz-dead-letter-queue", on_message_callback=callback)
+print("s", ack)
# 消费者会阻塞在这里,一直等待消息,队列中有消息了,就会执行消息的回调函数
channel.start_consuming()
diff --git a/chapter14/booking_system/plugins/base.py b/chapter14/booking_system/plugins/base.py
index 847db87..72827ca 100644
--- a/chapter14/booking_system/plugins/base.py
+++ b/chapter14/booking_system/plugins/base.py
@@ -3,12 +3,21 @@
import typing
import abc
+
class PluginBase(abc.ABC):
- def __init__(self,app: fastapi.FastAPI = None,config: pydantic.BaseSettings = None):
+ def __init__(
+ self, app: fastapi.FastAPI = None, config: pydantic.BaseSettings = None
+ ):
if app is not None:
self.init_app(app)
@abc.abstractmethod
- def init_app(self,app: fastapi.FastAPI,config: pydantic.BaseSettings = None,*args,**kwargs) -> None:
- raise NotImplementedError('需要实现初始化')
+ def init_app(
+ self,
+ app: fastapi.FastAPI,
+ config: pydantic.BaseSettings = None,
+ *args,
+ **kwargs
+ ) -> None:
+ raise NotImplementedError("需要实现初始化")
diff --git a/chapter14/booking_system/plugins/request_hook.py b/chapter14/booking_system/plugins/request_hook.py
index 5cc23e7..c43f5ee 100644
--- a/chapter14/booking_system/plugins/request_hook.py
+++ b/chapter14/booking_system/plugins/request_hook.py
@@ -1,4 +1,3 @@
-
from plugins.base import PluginBase
from fastapi import FastAPI
from pydantic import BaseSettings
@@ -10,15 +9,24 @@
class HookPluginClient(PluginBase):
# 设置插件默认的参数信息
- def __init__(self,
- on_before_request: typing.Sequence[typing.Callable] = None,
- on_after_request: typing.Sequence[typing.Callable] = None,
- on_teardown_appcontext: typing.Sequence[typing.Callable] = None,
- *args, **kwargs):
+ def __init__(
+ self,
+ on_before_request: typing.Sequence[typing.Callable] = None,
+ on_after_request: typing.Sequence[typing.Callable] = None,
+ on_teardown_appcontext: typing.Sequence[typing.Callable] = None,
+ *args,
+ **kwargs
+ ):
super().__init__(*args, **kwargs)
- self.on_before_request = [] if on_before_request is None else list(on_before_request)
- self.on_after_request = [] if on_after_request is None else list(on_after_request)
- self.on_teardown_appcontext = [] if on_teardown_appcontext is None else list(on_teardown_appcontext)
+ self.on_before_request = (
+ [] if on_before_request is None else list(on_before_request)
+ )
+ self.on_after_request = (
+ [] if on_after_request is None else list(on_after_request)
+ )
+ self.on_teardown_appcontext = (
+ [] if on_teardown_appcontext is None else list(on_teardown_appcontext)
+ )
def init_app(self, app: FastAPI, *args, **kwargs):
pass
@@ -50,6 +58,7 @@ def on_event(self, event_type: str) -> typing.Callable:
def decorator(func: typing.Callable) -> typing.Callable:
self.add_event_handler(event_type, func)
return func
+
return decorator
async def before_request(self, request) -> None:
@@ -72,4 +81,4 @@ async def teardown_appcontext(self, request, response) -> None:
if asyncio.iscoroutinefunction(handler):
await handler(request, response)
else:
- handler(request, response)
\ No newline at end of file
+ handler(request, response)
diff --git a/chapter14/booking_system/testcase/conftest.py b/chapter14/booking_system/testcase/conftest.py
index 4dbe611..e18c976 100644
--- a/chapter14/booking_system/testcase/conftest.py
+++ b/chapter14/booking_system/testcase/conftest.py
@@ -4,9 +4,10 @@
import asyncio
import sys
from db.async_database import async_engine
+
# 需要加载当前项目目录。sys.path.append('E://yuanxiao//code//booking_system//booking_system'),
# 不然在项目根目录执行pytest会出现ModuleNotFoundError: No module named 'app'
-sys.path.append('E://yuanxiao//code//booking_system//booking_system')
+sys.path.append("E://yuanxiao//code//booking_system//booking_system")
from app import app
# ===========================================同步使用
@@ -14,6 +15,8 @@
from typing import Dict, Generator
import pytest
from fastapi.testclient import TestClient
+
+
@pytest.fixture(scope="module")
def client() -> Generator:
with TestClient(app) as c:
@@ -25,6 +28,7 @@ def client() -> Generator:
# 修改设置优先循环事件
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
+
# 配置使用哪一种模式的异步
@pytest.fixture(
params=[
@@ -34,15 +38,21 @@ def client() -> Generator:
def anyio_backend(request):
return request.param
+
# 解决当接口中涉及到依赖注入的数据库使用
async def start_db():
async with async_engine.begin() as conn:
pass
await async_engine.dispose()
+
@pytest_asyncio.fixture
async def async_client() -> AsyncClient:
- async with AsyncClient(app=app,base_url="http://test", headers={"Content-Type": "application/json"},) as async_client:
+ async with AsyncClient(
+ app=app,
+ base_url="http://test",
+ headers={"Content-Type": "application/json"},
+ ) as async_client:
await start_db()
yield async_client
- await async_engine.dispose()
\ No newline at end of file
+ await async_engine.dispose()
diff --git a/chapter14/booking_system/testcase/test_async_api_v1.py b/chapter14/booking_system/testcase/test_async_api_v1.py
index 0464845..83a728f 100644
--- a/chapter14/booking_system/testcase/test_async_api_v1.py
+++ b/chapter14/booking_system/testcase/test_async_api_v1.py
@@ -16,8 +16,9 @@
import pytest
+
@pytest.mark.anyio
-@pytest.mark.parametrize('anyio_backend', ['asyncio'])
+@pytest.mark.parametrize("anyio_backend", ["asyncio"])
async def test_doctor_list(async_client):
res = await async_client.get("/api/v1/doctor_list")
assert res.status_code == 200
@@ -25,7 +26,7 @@ async def test_doctor_list(async_client):
@pytest.mark.anyio
-@pytest.mark.parametrize('anyio_backend', ['asyncio'])
+@pytest.mark.parametrize("anyio_backend", ["asyncio"])
async def test_hospital_info(async_client):
res = await async_client.get("/api/v1/hospital_info")
assert res.status_code == 200
diff --git a/chapter14/booking_system/testcase/test_async_api_v2.py b/chapter14/booking_system/testcase/test_async_api_v2.py
index 2c9c53a..a65f873 100644
--- a/chapter14/booking_system/testcase/test_async_api_v2.py
+++ b/chapter14/booking_system/testcase/test_async_api_v2.py
@@ -2,15 +2,17 @@
#
import pytest
from httpx import AsyncClient
+
pytestmark = pytest.mark.anyio
+
async def test_hospital_info(async_client: AsyncClient):
response = await async_client.get("/api/v1/hospital_info")
- print('response', response.text)
+ print("response", response.text)
assert response.status_code == 200
async def test_doctor_list(async_client: AsyncClient):
response = await async_client.get("/api/v1/doctor_list")
- print('response', response.text)
- assert response.status_code == 200
\ No newline at end of file
+ print("response", response.text)
+ assert response.status_code == 200
diff --git a/chapter14/booking_system/testcase/test_sync_api.py b/chapter14/booking_system/testcase/test_sync_api.py
index e6ec0fd..dc18420 100644
--- a/chapter14/booking_system/testcase/test_sync_api.py
+++ b/chapter14/booking_system/testcase/test_sync_api.py
@@ -34,15 +34,15 @@
from fastapi.testclient import TestClient
-
-def test_hospitalinfo(client:TestClient):
- res = client.get('/api/v1/hospital_info')
- print('sdsd',res.text)
+def test_hospitalinfo(client: TestClient):
+ res = client.get("/api/v1/hospital_info")
+ print("sdsd", res.text)
assert res.status_code == 200
assert type(res.status_code) == int
-def test_doctorlist(client:TestClient):
- res = client.get('/api/v1/doctor_list')
- print('dsasd',res.text)
+
+def test_doctorlist(client: TestClient):
+ res = client.get("/api/v1/doctor_list")
+ print("dsasd", res.text)
assert res.status_code == 200
- assert type(res.status_code) == int
\ No newline at end of file
+ assert type(res.status_code) == int
diff --git a/chapter14/booking_system/utils/cast_helper.py b/chapter14/booking_system/utils/cast_helper.py
index c0803c1..4693ad3 100644
--- a/chapter14/booking_system/utils/cast_helper.py
+++ b/chapter14/booking_system/utils/cast_helper.py
@@ -1,2 +1,2 @@
-def add(a,b):
- return a+b;
\ No newline at end of file
+def add(a, b):
+ return a + b
diff --git a/chapter14/booking_system/utils/datatime_helper.py b/chapter14/booking_system/utils/datatime_helper.py
index ab77882..c6e1e6c 100644
--- a/chapter14/booking_system/utils/datatime_helper.py
+++ b/chapter14/booking_system/utils/datatime_helper.py
@@ -5,48 +5,58 @@
def effectiveness_tiempm(tiempm):
- today = time.strftime('%Y-%m-%d %H:%M', time.localtime(time.time())).replace("-", "")
- todaydate = datetime.datetime.strptime(today, "%Y%m%d %H:%M") # 字符串转化为date形式
+ today = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time())).replace(
+ "-", ""
+ )
+ todaydate = datetime.datetime.strptime(
+ today, "%Y%m%d %H:%M"
+ ) # 字符串转化为date形式
# 预约时段的时间
yuyue_day = tiempm.replace("-", "")
- yuyue_daydate = datetime.datetime.strptime(yuyue_day, "%Y%m%d %H:%M:%S") # 字符串转化为date形式
+ yuyue_daydate = datetime.datetime.strptime(
+ yuyue_day, "%Y%m%d %H:%M:%S"
+ ) # 字符串转化为date形式
# 超出预约时间范围
if todaydate >= yuyue_daydate:
return False
return True
-
def get_timestamp10():
"""获取当前时间长度为10位长度的时间戳"""
return int(time.time())
def str_to_datatime(srr_time, strftime="%Y-%m-%d"):
- print('strftimestrftimestrftime',strftime)
+ print("strftimestrftimestrftime", strftime)
return datetime.datetime.strptime(srr_time, strftime)
-str_to_datatime('2021-12-27 10:00:00',strftime='%Y-%m-%d %H:%M:%S')
+
+str_to_datatime("2021-12-27 10:00:00", strftime="%Y-%m-%d %H:%M:%S")
+
def datatime_to_str(data_time: datetime.datetime, strftime="%Y-%m-%d"):
return data_time.strftime(strftime)
def diff_days_for_now_time(srr_time):
- '''
+ """
对比当前的传入日期和当前系统时间的相差的天数
:param srr_time:
:return:
- '''
- return (datetime.datetime.strptime(srr_time, "%Y-%m-%d") - datetime.datetime.combine(datetime.datetime.now().date(),
- datetime.time())).days
+ """
+ return (
+ datetime.datetime.strptime(srr_time, "%Y-%m-%d")
+ - datetime.datetime.combine(datetime.datetime.now().date(), datetime.time())
+ ).days
# 获取当前日期
# today=time.strftime('%Y-%m-%d',time.localtime(time.time()))
+
def currday_time_info():
- return time.strftime('%Y-%m-%d', time.localtime(time.time()))
+ return time.strftime("%Y-%m-%d", time.localtime(time.time()))
def currday_time_info_tochane_datetime(today):
@@ -55,11 +65,17 @@ def currday_time_info_tochane_datetime(today):
def effectiveness_tiempm(tiempm):
- today = time.strftime('%Y-%m-%d %H:%M', time.localtime(time.time())).replace("-", "")
- todaydate = datetime.datetime.strptime(today, "%Y%m%d %H:%M") # 字符串转化为date形式
+ today = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time())).replace(
+ "-", ""
+ )
+ todaydate = datetime.datetime.strptime(
+ today, "%Y%m%d %H:%M"
+ ) # 字符串转化为date形式
# 预约时段的时间
yuyue_day = tiempm.replace("-", "")
- yuyue_daydate = datetime.datetime.strptime(yuyue_day, "%Y%m%d %H:%M:%S") # 字符串转化为date形式
+ yuyue_daydate = datetime.datetime.strptime(
+ yuyue_day, "%Y%m%d %H:%M:%S"
+ ) # 字符串转化为date形式
# 超出预约时间范围
if todaydate >= yuyue_daydate:
return False
@@ -68,9 +84,9 @@ def effectiveness_tiempm(tiempm):
# 根据给定的日期,获取前n天或后n天的日期,n为正数则是以后的n天,n为负数则是以前的n天,不包括当天
def get_day_of_day(str2date, n=0):
- if (n < 0):
+ if n < 0:
n = abs(n)
- return (str2date - timedelta(days=n))
+ return str2date - timedelta(days=n)
else:
return str2date + timedelta(days=n)
@@ -83,7 +99,7 @@ def num_to_string(num):
3: "周三",
4: "周四",
5: "周五",
- 6: "周六"
+ 6: "周六",
}
return numbers.get(num, None)
@@ -93,9 +109,9 @@ def get_7day_info_list(num=6):
ditcs = dict()
for i in range(num + 1):
datatime = get_day_of_day(currday_time_info_tochane_datetime(today), i)
- ditcs[datatime.strftime('%Y-%m-%d')] = {
- 'weekday': num_to_string(datatime.isoweekday()),
- 'datetimeday': datatime.strftime('%Y-%m-%d')
+ ditcs[datatime.strftime("%Y-%m-%d")] = {
+ "weekday": num_to_string(datatime.isoweekday()),
+ "datetimeday": datatime.strftime("%Y-%m-%d"),
}
return ditcs
@@ -105,6 +121,5 @@ def get_7day_info_list_only_data(num=6):
ditcs = dict()
for i in range(num + 1):
datatime = get_day_of_day(currday_time_info_tochane_datetime(today), i)
- ditcs[datatime.strftime('%Y-%m-%d')] = {}
+ ditcs[datatime.strftime("%Y-%m-%d")] = {}
return ditcs
-
diff --git a/chapter14/booking_system/utils/json_helper.py b/chapter14/booking_system/utils/json_helper.py
index f8a3fd2..6a1de21 100644
--- a/chapter14/booking_system/utils/json_helper.py
+++ b/chapter14/booking_system/utils/json_helper.py
@@ -8,16 +8,16 @@
class CJsonEncoder(json.JSONEncoder):
def default(self, obj):
- if hasattr(obj, 'keys') and hasattr(obj, '__getitem__'):
+ if hasattr(obj, "keys") and hasattr(obj, "__getitem__"):
return dict(obj)
if isinstance(obj, datetime.datetime):
- return obj.strftime('%Y-%m-%d %H:%M:%S')
+ return obj.strftime("%Y-%m-%d %H:%M:%S")
if isinstance(obj, datetime.date):
- return obj.strftime('%Y-%m-%d')
+ return obj.strftime("%Y-%m-%d")
if isinstance(obj, decimal.Decimal):
return float(obj)
if isinstance(obj, bytes):
- return str(obj, encoding='utf-8')
+ return str(obj, encoding="utf-8")
return json.JSONEncoder.default(self, obj)
@@ -61,7 +61,7 @@ def class_to_dict(obj):
else:
dict = {}
dict.update(obj.__dict__)
- return dict.get('__data__')
+ return dict.get("__data__")
import base64
@@ -125,4 +125,4 @@ def dumps(
default=default,
sort_keys=sort_keys,
**kw
- )
\ No newline at end of file
+ )
diff --git a/chapter14/booking_system/utils/ordernum_helper.py b/chapter14/booking_system/utils/ordernum_helper.py
index 6723543..80ec95c 100644
--- a/chapter14/booking_system/utils/ordernum_helper.py
+++ b/chapter14/booking_system/utils/ordernum_helper.py
@@ -3,19 +3,19 @@
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +
# ┏┓ ┏┓+ +
# ┏┛┻━━━┛┻┓ + +
-# ┃ ┃
+# ┃ ┃
# ┃ ━ ┃ ++ + + +
# ████━████ ┃+
# ┃ ┃ +
# ┃ ┻ ┃
# ┃ ┃ + +
# ┗━┓ ┏━┛
-# ┃ ┃
+# ┃ ┃
# ┃ ┃ + + + +
-# ┃ ┃ Codes are far away from bugs with the animal protecting
-# ┃ ┃ + 神兽保佑,代码无bug
+# ┃ ┃ Codes are far away from bugs with the animal protecting
+# ┃ ┃ + 神兽保佑,代码无bug
# ┃ ┃
-# ┃ ┃ +
+# ┃ ┃ +
# ┃ ┗━━━┓ + +
# ┃ ┣┓
# ┃ ┏┛
@@ -37,27 +37,42 @@
def order_num_1(package_id=12345, user_num=56789):
# 商品id后1位+下单时间的年月日12+用户2后四位+随机数3位
- local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))[2:]
- result = str(package_id)[-2:] + local_time + str(user_num)[-2:] + str(random.randint(100, 999))
+ local_time = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))[2:]
+ result = (
+ str(package_id)[-2:]
+ + local_time
+ + str(user_num)[-2:]
+ + str(random.randint(100, 999))
+ )
return result
def order_num_2(package_id=12345, user_num=56789):
# 商品id后2位+下单时间的年月日12+用户2后四位+随机数4位
- local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))[2:]
- result = str(package_id)[-2:] + local_time + str(user_num)[-2:] + str(random.randint(1000, 9999))
+ local_time = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))[2:]
+ result = (
+ str(package_id)[-2:]
+ + local_time
+ + str(user_num)[-2:]
+ + str(random.randint(1000, 9999))
+ )
return result
def order_num_3(user_num=56789):
# 商品id后2位+下单时间的年月日12+用户2后四位+随机数4位
- local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))[2:]
- result =f'{local_time}{str(user_num)[-2:] }{random.randint(10000, 99999)}'
+ local_time = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))[2:]
+ result = f"{local_time}{str(user_num)[-2:] }{random.randint(10000, 99999)}"
return result
-def order_num_srt(user_num='56789'):
+def order_num_srt(user_num="56789"):
# 商品id后2位+下单时间的年月日12+用户2后四位+随机数4位
- local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))[2:]
- result =str(user_num)[-2:] + str(random.randint(100, 999)) + local_time + str(random.randint(1000, 9999))
+ local_time = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))[2:]
+ result = (
+ str(user_num)[-2:]
+ + str(random.randint(100, 999))
+ + local_time
+ + str(random.randint(1000, 9999))
+ )
return result
diff --git a/chapter14/booking_system/utils/run_with_asyncio.py b/chapter14/booking_system/utils/run_with_asyncio.py
index 0d845ba..edf6416 100644
--- a/chapter14/booking_system/utils/run_with_asyncio.py
+++ b/chapter14/booking_system/utils/run_with_asyncio.py
@@ -2,11 +2,15 @@
import asyncio
from functools import wraps
from typing import Any, Awaitable, Callable, TypeVar
+
T = TypeVar("T")
__all__ = ["run_with_asyncio"]
+
+
def run_with_asyncio(f: Callable[..., Awaitable[T]]) -> Callable[..., T]:
@wraps(f)
def wrapper(*args: Any, **kwargs: Any) -> T:
print("pajinlail")
return asyncio.run(f(*args, **kwargs))
- return wrapper
\ No newline at end of file
+
+ return wrapper
diff --git a/chapter14/booking_system/utils/xmlhelper.py b/chapter14/booking_system/utils/xmlhelper.py
index a831fd9..883bb15 100644
--- a/chapter14/booking_system/utils/xmlhelper.py
+++ b/chapter14/booking_system/utils/xmlhelper.py
@@ -3,19 +3,19 @@
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +
# ┏┓ ┏┓+ +
# ┏┛┻━━━┛┻┓ + +
-# ┃ ┃
+# ┃ ┃
# ┃ ━ ┃ ++ + + +
# ████━████ ┃+
# ┃ ┃ +
# ┃ ┻ ┃
# ┃ ┃ + +
# ┗━┓ ┏━┛
-# ┃ ┃
+# ┃ ┃
# ┃ ┃ + + + +
-# ┃ ┃ Codes are far away from bugs with the animal protecting
-# ┃ ┃ + 神兽保佑,代码无bug
+# ┃ ┃ Codes are far away from bugs with the animal protecting
+# ┃ ┃ + 神兽保佑,代码无bug
# ┃ ┃
-# ┃ ┃ +
+# ┃ ┃ +
# ┃ ┗━━━┓ + +
# ┃ ┣┓
# ┃ ┏┛
@@ -43,10 +43,16 @@ def parse_xml_data(xml):
except (xmltodict.ParsingInterrupted, ExpatError):
raise Exception()
- if not data or 'xml' not in data:
+ if not data or "xml" not in data:
raise Exception()
- data = data['xml']
- for key in ('total_fee', 'settlement_total_fee', 'cash_fee', 'coupon_fee', 'coupon_count'):
+ data = data["xml"]
+ for key in (
+ "total_fee",
+ "settlement_total_fee",
+ "cash_fee",
+ "coupon_fee",
+ "coupon_count",
+ ):
if key in data:
data[key] = int(data[key])
return data
diff --git a/chapter15/Fastapi_cProfile/main.py b/chapter15/Fastapi_cProfile/main.py
index 3fc79e7..650464c 100644
--- a/chapter15/Fastapi_cProfile/main.py
+++ b/chapter15/Fastapi_cProfile/main.py
@@ -8,8 +8,17 @@
# app.add_middleware(CProfileMiddleware)
# app.add_middleware(CProfileMiddleware, enable=True, print_each_request = True, strip_dirs = False, sort_by='cumulative')
-app.add_middleware(CProfileMiddleware, enable=True, server_app = app, filename='.prof', strip_dirs = False, sort_by='cumulative')
+app.add_middleware(
+ CProfileMiddleware,
+ enable=True,
+ server_app=app,
+ filename=".prof",
+ strip_dirs=False,
+ sort_by="cumulative",
+)
import asyncio
+
+
@app.get("/")
async def main():
def randomlist(n):
@@ -25,11 +34,10 @@ def randomlist(n):
return {"message": "Hello World"}
-
if __name__ == "__main__":
import uvicorn
import os
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/Jaeger/test_jaeger_client/main.py b/chapter15/Jaeger/test_jaeger_client/main.py
index aa342ce..afe8d36 100644
--- a/chapter15/Jaeger/test_jaeger_client/main.py
+++ b/chapter15/Jaeger/test_jaeger_client/main.py
@@ -5,26 +5,30 @@
def construct_span(tracer):
# 定义span的名称为TestSpan
- with tracer.start_span('TestSpan') as span:
+ with tracer.start_span("TestSpan") as span:
# 设置这个span传递的日志信息
- span.log_kv({'event': '父Span', 'other': "我是第一个父的Span"})
+ span.log_kv({"event": "父Span", "other": "我是第一个父的Span"})
time.sleep(1)
# 定义AliyunTestSpan的子Span,类似第一个追踪的数据的子层级
- with tracer.start_span('TestSpan-ChildSpan-01', child_of=span) as child_span:
+ with tracer.start_span("TestSpan-ChildSpan-01", child_of=span) as child_span:
time.sleep(2)
# 设置父的span键值对日志信息
- span.log_kv({'event': '我是父Span--日志1'})
+ span.log_kv({"event": "我是父Span--日志1"})
# 设置子child_span的日志
- child_span.log_kv({'event': '父Span--第一层子Span-01'})
- with tracer.start_span('TestSpan-ChildSpan-01', child_of=span) as child_span:
+ child_span.log_kv({"event": "父Span--第一层子Span-01"})
+ with tracer.start_span("TestSpan-ChildSpan-01", child_of=span) as child_span:
time.sleep(3)
- span.log_kv({'event': '我是父Span--日志2'})
- child_span.log_kv({'event': '父Span--第一层子Span-02'})
+ span.log_kv({"event": "我是父Span--日志2"})
+ child_span.log_kv({"event": "父Span--第一层子Span-02"})
- with tracer.start_span('TestSpanC-hildSpan-01-01', child_of=child_span) as Span3_child_span:
+ with tracer.start_span(
+ "TestSpanC-hildSpan-01-01", child_of=child_span
+ ) as Span3_child_span:
time.sleep(4)
- span.log_kv({'event': '我是父Span--日志3'})
- Span3_child_span.log_kv({'event': '父Span--第一层子Span-的下一个子Span'})
+ span.log_kv({"event": "我是父Span--日志3"})
+ Span3_child_span.log_kv(
+ {"event": "父Span--第一层子Span-的下一个子Span"}
+ )
return span
@@ -32,30 +36,30 @@ def construct_span(tracer):
if __name__ == "__main__":
# 定义日志输出的登记
log_level = logging.DEBUG
- logging.getLogger('').handlers = []
+ logging.getLogger("").handlers = []
# 配置日志默认输出格式
- logging.basicConfig(format='%(asctime)s %(message)s', level=log_level)
+ logging.basicConfig(format="%(asctime)s %(message)s", level=log_level)
# Jaeger配置信息
config = Config(
# 服务信息配置
config={
# sampler 采样
- 'sampler': {
- 'type': 'const', # 采样类型
- 'param': 1, # 采样开关 1:开启全部采样 0:关闭全部
+ "sampler": {
+ "type": "const", # 采样类型
+ "param": 1, # 采样开关 1:开启全部采样 0:关闭全部
},
# 配置链接到我们的本地的agent,通过agent来上报
- 'local_agent': {
+ "local_agent": {
# 注意这里是指定了JaegerAgent的host和port。
# 根据官方建议为了保证数据可靠性,JaegerClient和JaegerAgent运行在同一台主机内,因此reporting_host填写为127.0.0.1。
- 'reporting_host': '192.168.126.130',
- 'reporting_port': 6831,
+ "reporting_host": "192.168.126.130",
+ "reporting_port": 6831,
},
- 'logging': True,
+ "logging": True,
},
# 这里填写应用名称---服务的名称
service_name="MyFirstSpan",
- validate=True
+ validate=True,
)
# this call also sets opentracing.tracer
diff --git a/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py b/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py
index be84349..c8b27c8 100644
--- a/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py
+++ b/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py
@@ -1,4 +1,3 @@
-
from typing import List, Any
from fastapi import Request
from jaeger_client import Config
@@ -9,18 +8,16 @@
from fastapi import FastAPI
-
-
class OpentracingJaegerMiddleware(BaseHTTPMiddleware):
- def __init__(self,fastapiapp: FastAPI,*args,**kwargs) -> None:
- super().__init__(*args,**kwargs)
+ def __init__(self, fastapiapp: FastAPI, *args, **kwargs) -> None:
+ super().__init__(*args, **kwargs)
self.fastapiapp = fastapiapp
- self.fastapiapp.add_event_handler('startup', self.setup_opentracing)
+ self.fastapiapp.add_event_handler("startup", self.setup_opentracing)
def setup_opentracing(self):
# 配置连接信息
- jaeger_host = '192.168.126.130'
+ jaeger_host = "192.168.126.130"
jaeger_port = 6831
service_name = "测试2"
trace_id_header = "X-TRACE-ID"
@@ -31,28 +28,28 @@ def setup_opentracing(self):
config={
"local_agent": {
"reporting_host": jaeger_host,
- "reporting_port": jaeger_port
+ "reporting_port": jaeger_port,
},
"sampler": {
"type": jaeger_sampler_type,
"param": jaeger_sampler_rate,
},
- "trace_id_header": trace_id_header
+ "trace_id_header": trace_id_header,
},
service_name=service_name,
validate=True,
- scope_manager=AsyncioScopeManager()
+ scope_manager=AsyncioScopeManager(),
)
self.fastapiapp.state.tracer = _tracer_config.initialize_tracer()
-
-
async def dispatch(self, request: Request, call_next: Any) -> Response:
# 获取tracer对象
tracer = request.app.state.tracer
# 开始解析上下文(Extract函数):
# 该函数主要用于在跨服务进程中,进行解析还原上一个传入Span 信息,通常是通过获取请求的headers进行参数信息提取;
- span_context = tracer.extract(format=Format.HTTP_HEADERS, carrier=request.headers)
+ span_context = tracer.extract(
+ format=Format.HTTP_HEADERS, carrier=request.headers
+ )
# 开始创建span对象通过span_context,来决定是否存在层级span
span = tracer.start_span(
operation_name=f"{request.method} {request.url.path}",
@@ -71,15 +68,12 @@ async def dispatch(self, request: Request, call_next: Any) -> Response:
# 设置client请求来源端口的标签
span.set_tag(tags.PEER_PORT, request.client.port or "")
# #Component(字符串)ia模块、库或正在生成跨区的包。
- span.set_tag(tags.COMPONENT, 'Fastapi')
+ span.set_tag(tags.COMPONENT, "Fastapi")
# 标记表示RPC或其他远程调用的服务器端的范围
span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_SERVER)
# (字符串)是请求的HTTP方法。
span.set_tag(tags.HTTP_METHOD, request.method)
-
-
-
# Scope 对象 主要是管理Active Span的容器
# Scope 代表着当前活跃的Span; 是对当前活跃Span的一个抽象
# ScopeManager 包含一个 Scope, Scope 又包含了 当前Span
@@ -99,5 +93,3 @@ async def dispatch(self, request: Request, call_next: Any) -> Response:
# inject之后,实际 headers = {'uber-trace-id': '6997ed0a6a74f050:bf49be2de63d86e7:e02975aab05fd358:1'}
print(headers)
return response
-
-
diff --git a/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/main.py b/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/main.py
index afd7e50..b6ffb19 100644
--- a/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/main.py
+++ b/chapter15/Jaeger/test_jaeger_client_fastapi/middeware/main.py
@@ -8,23 +8,28 @@
@app.get("/tracing")
-def tracing(request: Request, x_trace_id: Optional[str] = Header(None, convert_underscores=True)):
+def tracing(
+ request: Request, x_trace_id: Optional[str] = Header(None, convert_underscores=True)
+):
# 拿到当前生效的tracer
tracer = request.app.state.tracer
# 判断是否存在对应的上一个层级的span
span = request.state.opentracing_span
# 创建新的span
- with tracer.start_span('new—span-test', child_of=span) as child_span_1:
- span.log_kv({'event': '父类的span事件信息1'})
- span.log_kv({'event': '父类的span事件信息2',
- 'request.args': request.query_params, })
+ with tracer.start_span("new—span-test", child_of=span) as child_span_1:
+ span.log_kv({"event": "父类的span事件信息1"})
+ span.log_kv(
+ {
+ "event": "父类的span事件信息2",
+ "request.args": request.query_params,
+ }
+ )
# child_span_1.log_kv({'event': 'child_span-down below'})
# with tracer.start_span('new—span-test-childspan', child_of=child_span_1) as child_span_2:
# child_span_2.log_kv({'event': 'new—span-test-childspan-childspan'})
-
return "ok"
@@ -34,4 +39,4 @@ def tracing(request: Request, x_trace_id: Optional[str] = Header(None, convert_u
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/async_sync_change/main_asgiref_async_to_sync.py b/chapter15/async_sync_change/main_asgiref_async_to_sync.py
index a71535e..c323aac 100644
--- a/chapter15/async_sync_change/main_asgiref_async_to_sync.py
+++ b/chapter15/async_sync_change/main_asgiref_async_to_sync.py
@@ -1,6 +1,6 @@
from functools import wraps
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
from fastapi.responses import PlainTextResponse
from fastapi.params import Body
@@ -9,14 +9,16 @@
@app.post("/get/access_token")
-def access_token(request:Request,name=Body(...)):
+def access_token(request: Request, name=Body(...)):
# print(reques.body())
from asgiref.sync import async_to_sync
+
body = async_to_sync(request.body)()
print(body)
- return PlainTextResponse(body.decode(encoding='utf-8'))
+ return PlainTextResponse(body.decode(encoding="utf-8"))
-if __name__ == '__main__':
+if __name__ == "__main__":
import uvicorn
- uvicorn.run('main:app', host="127.0.0.1", port=8100, debug=True, reload=True)
\ No newline at end of file
+
+ uvicorn.run("main:app", host="127.0.0.1", port=8100, debug=True, reload=True)
diff --git a/chapter15/async_sync_change/main_asgiref_sync_to_async.py b/chapter15/async_sync_change/main_asgiref_sync_to_async.py
index 4bab1e5..13f4d1c 100644
--- a/chapter15/async_sync_change/main_asgiref_sync_to_async.py
+++ b/chapter15/async_sync_change/main_asgiref_sync_to_async.py
@@ -1,22 +1,22 @@
from functools import wraps
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
-from fastapi.responses import PlainTextResponse,HTMLResponse
+from fastapi.responses import PlainTextResponse, HTMLResponse
from asgiref.sync import sync_to_async
import requests
+
# 定义我们的APP服务对象
app = FastAPI()
-def getdata():
- return requests.get('http://www.baidu.com').text
-
+def getdata():
+ return requests.get("http://www.baidu.com").text
@app.get("/get/access_token")
async def access_token():
- asds= await sync_to_async(func=getdata)()
+ asds = await sync_to_async(func=getdata)()
return HTMLResponse(asds)
@@ -26,6 +26,4 @@ async def access_token():
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
-
-
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/async_sync_change/main_asyncer_asyncify.py b/chapter15/async_sync_change/main_asyncer_asyncify.py
index 44d1cf9..81e3d0c 100644
--- a/chapter15/async_sync_change/main_asyncer_asyncify.py
+++ b/chapter15/async_sync_change/main_asyncer_asyncify.py
@@ -1,19 +1,23 @@
-from fastapi import FastAPI,Request
-from fastapi.responses import PlainTextResponse,HTMLResponse
+from fastapi import FastAPI, Request
+from fastapi.responses import PlainTextResponse, HTMLResponse
from asyncer import asyncify
import requests
+
# 定义我们的APP服务对象
app = FastAPI()
+
def do_sync_work(name):
- return requests.get(f'http://www.baidu.com?name={name}').text
+ return requests.get(f"http://www.baidu.com?name={name}").text
+
@app.get("/get/access_token")
-async def access_token(request:Request):
+async def access_token(request: Request):
message = await asyncify(do_sync_work)(name="World")
return HTMLResponse(message)
-if __name__ == '__main__':
+if __name__ == "__main__":
import uvicorn
- uvicorn.run('main:app', host="127.0.0.1", port=8100, debug=True, reload=True)
+
+ uvicorn.run("main:app", host="127.0.0.1", port=8100, debug=True, reload=True)
diff --git a/chapter15/async_sync_change/main_asyncer_syncify.py b/chapter15/async_sync_change/main_asyncer_syncify.py
index 1cd5b55..53bb120 100644
--- a/chapter15/async_sync_change/main_asyncer_syncify.py
+++ b/chapter15/async_sync_change/main_asyncer_syncify.py
@@ -1,18 +1,20 @@
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
from fastapi.responses import PlainTextResponse
from fastapi.params import Body
-from fastapi.background import BackgroundTasks
-from asyncer import asyncify,syncify
+from fastapi.background import BackgroundTasks
+from asyncer import asyncify, syncify
app = FastAPI()
+
@app.post("/get/access_token")
-def access_token(request:Request,name=Body(...)):
+def access_token(request: Request, name=Body(...)):
body = syncify(request.body)()
print(body)
- return PlainTextResponse(body.decode(encoding='utf-8'))
+ return PlainTextResponse(body.decode(encoding="utf-8"))
+
-if __name__ == '__main__':
+if __name__ == "__main__":
import uvicorn
- uvicorn.run('main:app', host="127.0.0.1", port=8100, debug=True, reload=True)
+ uvicorn.run("main:app", host="127.0.0.1", port=8100, debug=True, reload=True)
diff --git a/chapter15/async_wrapper/main_asgiref_sync_to_async.py b/chapter15/async_wrapper/main_asgiref_sync_to_async.py
index e9dc0df..4b566ac 100644
--- a/chapter15/async_wrapper/main_asgiref_sync_to_async.py
+++ b/chapter15/async_wrapper/main_asgiref_sync_to_async.py
@@ -1,18 +1,18 @@
import cProfile
from functools import wraps
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
-from fastapi.responses import PlainTextResponse,HTMLResponse
+from fastapi.responses import PlainTextResponse, HTMLResponse
from asgiref.sync import sync_to_async
import requests
+
# 定义我们的APP服务对象
app = FastAPI()
-def getdata():
- return requests.get('http://www.baidu.com').text
-
+def getdata():
+ return requests.get("http://www.baidu.com").text
def async_decorator_with_argument(time_to_eat):
@@ -25,23 +25,20 @@ def actual_decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
-
-
-
print(time_to_eat)
print(args)
print(kwargs)
return await func(*args, **kwargs)
-
print("输出结果")
return wrapper
return actual_decorator
+
@app.get("/get/access_token")
# @async_decorator_with_argument(time_to_eat='555555')
-def access_token(request:Request,dsa:str):
+def access_token(request: Request, dsa: str):
pr = cProfile.Profile()
pr.enable() # 开始收集性能分析数据
# asds= await sync_to_async(func=getdata)()
@@ -56,6 +53,4 @@ def access_token(request:Request,dsa:str):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1',port=5667, reload=True)
-
-
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", port=5667, reload=True)
diff --git a/chapter15/body/main_01.py b/chapter15/body/main_01.py
index 382209d..11202f6 100644
--- a/chapter15/body/main_01.py
+++ b/chapter15/body/main_01.py
@@ -42,4 +42,4 @@ async def index(request: Request):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/body/main_02.py b/chapter15/body/main_02.py
index a5c33bf..7c9d3a8 100644
--- a/chapter15/body/main_02.py
+++ b/chapter15/body/main_02.py
@@ -31,10 +31,11 @@ async def dispatch(self, request: Request, call_next):
await self.set_body(request)
# 需要在日志中间件里读取body数据
_body = await request.body()
- print("Loger中间件解析读取:消费request.body()",_body)
+ print("Loger中间件解析读取:消费request.body()", _body)
response = await call_next(request)
return response
+
app.add_middleware(LogerMiddleware)
@@ -45,12 +46,10 @@ async def index(request: Request):
return PlainTextResponse("消费request.body()!")
-
-
if __name__ == "__main__":
import uvicorn
import os
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/body/main_03.py b/chapter15/body/main_03.py
index 9e3b7fb..86493a0 100644
--- a/chapter15/body/main_03.py
+++ b/chapter15/body/main_03.py
@@ -31,12 +31,11 @@ async def dispatch(self, request: Request, call_next):
await self.set_body(request)
# 需要在日志中间件里读取body数据
_body = await request.body()
- print("Loger中间件解析读取11111111:消费request.body()",_body)
+ print("Loger中间件解析读取11111111:消费request.body()", _body)
response = await call_next(request)
return response
-
class LogerMiddleware2(BaseHTTPMiddleware):
async def set_body(self, request):
@@ -51,10 +50,11 @@ async def dispatch(self, request: Request, call_next):
await self.set_body(request)
# 需要在日志中间件里读取body数据
_body = await request.body()
- print("Loger中间件解析读取22222222:消费request.body()",_body)
+ print("Loger中间件解析读取22222222:消费request.body()", _body)
response = await call_next(request)
return response
+
app.add_middleware(LogerMiddleware)
app.add_middleware(LogerMiddleware2)
@@ -66,12 +66,10 @@ async def index(request: Request):
return PlainTextResponse("消费request.body()!")
-
-
if __name__ == "__main__":
import uvicorn
import os
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/body/main_04.py b/chapter15/body/main_04.py
index 330c301..b505a3c 100644
--- a/chapter15/body/main_04.py
+++ b/chapter15/body/main_04.py
@@ -20,9 +20,8 @@
class LogerMiddleware1:
def __init__(
- self,
- app: ASGIApp,
-
+ self,
+ app: ASGIApp,
) -> None:
self.app = app
@@ -45,9 +44,8 @@ async def receive():
class LogerMiddleware2:
def __init__(
- self,
- app: ASGIApp,
-
+ self,
+ app: ASGIApp,
) -> None:
self.app = app
@@ -57,6 +55,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
return
# 接收一次
receive_ = await receive()
+
async def receive():
return receive_
@@ -71,6 +70,7 @@ async def receive():
app.add_middleware(LogerMiddleware1)
app.add_middleware(LogerMiddleware2)
+
@app.get("/")
async def index(request: Request):
_body = await request.body()
@@ -78,12 +78,10 @@ async def index(request: Request):
return PlainTextResponse("消费request.body()!")
-
-
if __name__ == "__main__":
import uvicorn
import os
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/cProfile/c_profile_text_run.py b/chapter15/cProfile/c_profile_text_run.py
index 6e8e70d..d32c72d 100644
--- a/chapter15/cProfile/c_profile_text_run.py
+++ b/chapter15/cProfile/c_profile_text_run.py
@@ -10,7 +10,5 @@ def randomlist(n):
return lists
-
-
if __name__ == "__main__":
- randomlist(20)
\ No newline at end of file
+ randomlist(20)
diff --git a/chapter15/cProfile/runtest_profile_stats_run.py b/chapter15/cProfile/runtest_profile_stats_run.py
index ead0756..3e2df66 100644
--- a/chapter15/cProfile/runtest_profile_stats_run.py
+++ b/chapter15/cProfile/runtest_profile_stats_run.py
@@ -1,4 +1,5 @@
import pstats
+
p = pstats.Stats("runtest_profile.stats")
p.sort_stats("cumulative") # 和显示明细一样
# p.print_stats()
diff --git a/chapter15/contextvar_request/bind_.py b/chapter15/contextvar_request/bind_.py
index d3d8f64..1aea75c 100644
--- a/chapter15/contextvar_request/bind_.py
+++ b/chapter15/contextvar_request/bind_.py
@@ -20,4 +20,4 @@ def __setitem__(self, index, value):
def __delitem__(self, index):
del contextvar.get()[index]
- return ContextVarBind()
\ No newline at end of file
+ return ContextVarBind()
diff --git a/chapter15/contextvar_request/main_class.py b/chapter15/contextvar_request/main_class.py
index e8f4ac9..b70ab09 100644
--- a/chapter15/contextvar_request/main_class.py
+++ b/chapter15/contextvar_request/main_class.py
@@ -19,20 +19,17 @@ async def add_process_time_header(request: Request, call_next):
request_var.reset(token)
-
-
-@app.post('/index')
+@app.post("/index")
async def index():
# 这里应该使用事务处理
print(request.headers)
- return JSONResponse({
- "code": 200,
- "msg": "成功"
- })
+ return JSONResponse({"code": 200, "msg": "成功"})
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/contextvar_request/request.py b/chapter15/contextvar_request/request.py
index 4762281..e854dc5 100644
--- a/chapter15/contextvar_request/request.py
+++ b/chapter15/contextvar_request/request.py
@@ -3,4 +3,4 @@
from chapter15.contextvar_request.bind_ import bind_contextvar
request_var: ContextVar[Request] = ContextVar("request")
-request:Request = bind_contextvar(request_var)
\ No newline at end of file
+request: Request = bind_contextvar(request_var)
diff --git a/chapter15/depends/main_class.py b/chapter15/depends/main_class.py
index a011a70..bf6a6bc 100644
--- a/chapter15/depends/main_class.py
+++ b/chapter15/depends/main_class.py
@@ -10,13 +10,16 @@ class AuthCheck:
def __init__(self, role: str):
self.role = role
+
@app.get("/auth_check")
def auth_check(role: dict = Depends(AuthCheck)):
return role
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/depends/main_class_call.py b/chapter15/depends/main_class_call.py
index 7ff35dd..1064bf8 100644
--- a/chapter15/depends/main_class_call.py
+++ b/chapter15/depends/main_class_call.py
@@ -10,19 +10,24 @@ class AuthCheck:
def __init__(self, role_name: str):
self.role_name = role_name
- def __call__(self,):
- print("当前角色是:",self.role_name)
- if self.role_name =='admin':
+ def __call__(
+ self,
+ ):
+ print("当前角色是:", self.role_name)
+ if self.role_name == "admin":
return "管理员"
return "普通用户"
+
@app.get("/auth_check")
def auth_check(role: str = Depends(AuthCheck(role_name="admin"))):
return role
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/depends/main_class_security_scopes.py b/chapter15/depends/main_class_security_scopes.py
index 19c056b..2947089 100644
--- a/chapter15/depends/main_class_security_scopes.py
+++ b/chapter15/depends/main_class_security_scopes.py
@@ -22,4 +22,4 @@ def auth_check(role: str = Security(AuthCheck, scopes=["admin"])):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/depends/main_fun.py b/chapter15/depends/main_fun.py
index 798a12a..71ad825 100644
--- a/chapter15/depends/main_fun.py
+++ b/chapter15/depends/main_fun.py
@@ -6,15 +6,19 @@
app = FastAPI()
-def auth_check(role:str):
+def auth_check(role: str):
return role
+
@app.get("/auth_check")
def auth_check(role: str = Depends(auth_check)):
return role
+
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/depends/main_fun_security_scopes.py b/chapter15/depends/main_fun_security_scopes.py
index 554c051..827d2b3 100644
--- a/chapter15/depends/main_fun_security_scopes.py
+++ b/chapter15/depends/main_fun_security_scopes.py
@@ -7,7 +7,7 @@
def auth_check(security_scopes: SecurityScopes):
print("传入的参数:", security_scopes.scopes)
- if security_scopes.scopes[0] == 'admin':
+ if security_scopes.scopes[0] == "admin":
return "管理者"
return "普通用户"
@@ -23,4 +23,4 @@ def auth_check(role: str = Security(auth_check, scopes=["admin"])):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/fastapi_cache/main.py b/chapter15/fastapi_cache/main.py
index 123ef9e..55f852f 100644
--- a/chapter15/fastapi_cache/main.py
+++ b/chapter15/fastapi_cache/main.py
@@ -8,13 +8,16 @@
from fastapi_cache.decorator import cache
from fastapi_cache.coder import JsonCoder
from typing import Optional
+
app = FastAPI()
@app.on_event("startup")
async def startup():
# 开始初始化缓存对象
- redis = aioredis.from_url("redis://localhost", encoding="utf8", decode_responses=True)
+ redis = aioredis.from_url(
+ "redis://localhost", encoding="utf8", decode_responses=True
+ )
# 缓存库的插件实例化,传入的是要的是RedisBackend后端实例
FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache")
@@ -22,26 +25,39 @@ async def startup():
@app.get("/cache1")
@cache(expire=60)
async def index():
- return dict(code=200,message="响应成功")
+ return dict(code=200, message="响应成功")
+
@app.get("/cache2")
-@cache(namespace='test',expire=60)
+@cache(namespace="test", expire=60)
async def index():
- return JSONResponse(content={"code":200,"message":"设置命名空间"})
+ return JSONResponse(content={"code": 200, "message": "设置命名空间"})
+
@app.get("/cache_jsoncode")
-@cache(expire=60,coder=JsonCoder)
+@cache(expire=60, coder=JsonCoder)
async def cache_jsoncode():
return dict(code=200, message="自定义编码器")
+
# 自定义生成缓存的KEY的方法
-def my_key_builder(func,namespace: Optional[str] = "",request: Request = None,response: Response = None,*args,**kwargs,):
+def my_key_builder(
+ func,
+ namespace: Optional[str] = "",
+ request: Request = None,
+ response: Response = None,
+ *args,
+ **kwargs,
+):
prefix = FastAPICache.get_prefix()
- cache_key = f"{prefix}:{namespace}:{func.__module__}:{func.__name__}:{args}:{kwargs}"
+ cache_key = (
+ f"{prefix}:{namespace}:{func.__module__}:{func.__name__}:{args}:{kwargs}"
+ )
return cache_key
+
@app.get("/customer_key")
-@cache(expire=60,coder=JsonCoder,key_builder=my_key_builder)
+@cache(expire=60, coder=JsonCoder, key_builder=my_key_builder)
async def index():
return dict(code=200, message="自定义生成缓存KEY示例")
@@ -49,6 +65,7 @@ async def index():
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/fastapi_cache/uu.py b/chapter15/fastapi_cache/uu.py
index cce9207..7566d9e 100644
--- a/chapter15/fastapi_cache/uu.py
+++ b/chapter15/fastapi_cache/uu.py
@@ -1,17 +1,19 @@
-x=3
+x = 3
print(x)
-y=2
-k=x+y
+y = 2
+k = x + y
print(k)
-x=5
-y=7
-print(x*y)
+x = 5
+y = 7
+print(x * y)
-def jiafa(x,y):
- return x+ y
-print(jiafa(2,4))
+def jiafa(x, y):
+ return x + y
-print(jiafa(2,4333))
+print(jiafa(2, 4))
+
+
+print(jiafa(2, 4333))
diff --git a/chapter15/model_sort/main_asyncer_syncify.py b/chapter15/model_sort/main_asyncer_syncify.py
index 395043c..4628def 100644
--- a/chapter15/model_sort/main_asyncer_syncify.py
+++ b/chapter15/model_sort/main_asyncer_syncify.py
@@ -11,7 +11,9 @@ class Item(BaseModel):
def __new__(cls, *args, **kwargs):
instance = super().__new__(cls)
# 对当前__fields__重新进行排序
- cls.__fields__ = {key: cls.__fields__[key] for key in sorted(cls.__fields__.keys())}
+ cls.__fields__ = {
+ key: cls.__fields__[key] for key in sorted(cls.__fields__.keys())
+ }
return instance
desc: Optional[str] = None
@@ -20,7 +22,7 @@ def __new__(cls, *args, **kwargs):
aname: str
-@app.post('/items/', response_model=Item)
+@app.post("/items/", response_model=Item)
async def getitem(item: Item):
return item
diff --git a/chapter15/plugins/base.py b/chapter15/plugins/base.py
index 3a3b740..915ee87 100644
--- a/chapter15/plugins/base.py
+++ b/chapter15/plugins/base.py
@@ -10,27 +10,43 @@
class PluginBase(abc.ABC):
- def __init__(self,app: fastapi.FastAPI = None,config: pydantic.BaseSettings = None):
+ def __init__(
+ self, app: fastapi.FastAPI = None, config: pydantic.BaseSettings = None
+ ):
if app is not None:
self.init_app(app)
@abc.abstractmethod
- def init_app(self,app: fastapi.FastAPI,config: pydantic.BaseSettings = None,*args,**kwargs) -> None:
- raise NotImplementedError('需要实现初始化')
-
+ def init_app(
+ self,
+ app: fastapi.FastAPI,
+ config: pydantic.BaseSettings = None,
+ *args,
+ **kwargs
+ ) -> None:
+ raise NotImplementedError("需要实现初始化")
class HookPluginClient(PluginBase):
# 设置插件默认的参数信息
- def __init__(self,
- on_before_request: typing.Sequence[typing.Callable] = None,
- on_after_request: typing.Sequence[typing.Callable] = None,
- on_teardown_appcontext: typing.Sequence[typing.Callable] = None,
- *args, **kwargs):
+ def __init__(
+ self,
+ on_before_request: typing.Sequence[typing.Callable] = None,
+ on_after_request: typing.Sequence[typing.Callable] = None,
+ on_teardown_appcontext: typing.Sequence[typing.Callable] = None,
+ *args,
+ **kwargs
+ ):
super().__init__(*args, **kwargs)
- self.on_before_request = [] if on_before_request is None else list(on_before_request)
- self.on_after_request = [] if on_after_request is None else list(on_after_request)
- self.on_teardown_appcontext = [] if on_teardown_appcontext is None else list(on_teardown_appcontext)
+ self.on_before_request = (
+ [] if on_before_request is None else list(on_before_request)
+ )
+ self.on_after_request = (
+ [] if on_after_request is None else list(on_after_request)
+ )
+ self.on_teardown_appcontext = (
+ [] if on_teardown_appcontext is None else list(on_teardown_appcontext)
+ )
def init_app(self, app: FastAPI, *args, **kwargs):
@app.middleware("http")
@@ -83,4 +99,4 @@ async def teardown_appcontext(self, request, response) -> None:
if asyncio.iscoroutinefunction(handler):
await handler(request, response)
else:
- handler(request, response)
\ No newline at end of file
+ handler(request, response)
diff --git a/chapter15/plugins/main.py b/chapter15/plugins/main.py
index b0a21c8..2e3af86 100644
--- a/chapter15/plugins/main.py
+++ b/chapter15/plugins/main.py
@@ -6,34 +6,40 @@
app = FastAPI()
# 导入插件类
from plugins.request_hook import HookPluginClient
-rehook:HookPluginClient = HookPluginClient()
+
+rehook: HookPluginClient = HookPluginClient()
rehook.init_app(app)
-@rehook.on_event(event_type='before_request')
+
+@rehook.on_event(event_type="before_request")
def before_request(reqest):
print("before_request", reqest)
-@rehook.on_event(event_type='after_request')
-def after_request(reqest,response):
- print("after_request", reqest,response)
+@rehook.on_event(event_type="after_request")
+def after_request(reqest, response):
+ print("after_request", reqest, response)
-@rehook.on_event(event_type='teardown_appcontext')
+@rehook.on_event(event_type="teardown_appcontext")
def teardown_appcontext(request, response):
- print("teardown_appcontext", request,response)
+ print("teardown_appcontext", request, response)
+
class AuthCheck:
def __init__(self, role: str):
self.role = role
+
@app.get("/index")
def index():
- return 'index'
+ return "index"
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter15/sentry/main.py b/chapter15/sentry/main.py
index 6ac7108..803eab6 100644
--- a/chapter15/sentry/main.py
+++ b/chapter15/sentry/main.py
@@ -14,6 +14,7 @@
app = FastAPI()
+
@app.get("/sentry-debug")
async def trigger_error():
division_by_zero = 1 / 0
@@ -25,4 +26,4 @@ async def trigger_error():
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", reload=True)
\ No newline at end of file
+ uvicorn.run(f"{app_modeel_name}:app", reload=True)
diff --git a/chapter15/smtplib/main_aiosmtplib.py b/chapter15/smtplib/main_aiosmtplib.py
index 07f2c93..cc46680 100644
--- a/chapter15/smtplib/main_aiosmtplib.py
+++ b/chapter15/smtplib/main_aiosmtplib.py
@@ -2,23 +2,26 @@
import asyncio
import aiosmtplib
+
# email 用于构建邮件内容
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
-#构建邮件头
+# 构建邮件头
from email.header import Header
+
# 发信服务器
-smtp_server = 'smtp.qq.com'
+smtp_server = "smtp.qq.com"
# 发信方的信息:发信邮箱账号
-from_addr = '308711822@qq.com'
+from_addr = "308711822@qq.com"
# 发信方的信息:QQ 邮箱授权码
-password = 'xxxxxxxxxx'
+password = "xxxxxxxxxx"
+
-async def send_email(send_to_addr:str,contest_msg:str):
+async def send_email(send_to_addr: str, contest_msg: str):
# 连接发信服务器
- server = aiosmtplib.SMTP(hostname=smtp_server, port=465,use_tls=True)
+ server = aiosmtplib.SMTP(hostname=smtp_server, port=465, use_tls=True)
# 建立连接--qq邮箱服务和端口号
await server.connect()
# 登入邮箱
@@ -26,31 +29,35 @@ async def send_email(send_to_addr:str,contest_msg:str):
# 配置邮件正文内容
msg = MIMEMultipart()
- msg['From'] = Header('小钟同学') # 设置来自于邮件的发送者信息
- msg['To'] = Header('其他人同学') # 设置来自于邮件的接收人信息
- msg['Subject'] = Header("用户注册通知", 'utf-8') # 设置邮件主题
+ msg["From"] = Header("小钟同学") # 设置来自于邮件的发送者信息
+ msg["To"] = Header("其他人同学") # 设置来自于邮件的接收人信息
+ msg["Subject"] = Header("用户注册通知", "utf-8") # 设置邮件主题
# 邮件正文内容
- msg.attach(MIMEText(contest_msg, 'html', 'utf-8'))
+ msg.attach(MIMEText(contest_msg, "html", "utf-8"))
# 构造附件1,传送文本附件
- file_name = 'test1.txt'
- test_file_att = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file_att["Content-Type"] = 'application/octet-stream'
+ file_name = "test1.txt"
+ test_file_att = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file_att["Content-Type"] = "application/octet-stream"
test_file_att["Content-Disposition"] = f'attachment; filename="{file_name}"'
msg.attach(test_file_att)
# 构造附件1,传送文本附件
- file_name = 'test2.txt'
- test_file = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file.add_header('Content-Type','application/octet-stream')
- test_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', file_name))
+ file_name = "test2.txt"
+ test_file = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file.add_header("Content-Type", "application/octet-stream")
+ test_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", file_name)
+ )
msg.attach(test_file)
# 构造附件2,文件附件
- image_file_name = 'test.jpg'
- image_file = MIMEImage(open(image_file_name, 'rb').read())
- image_file.add_header('Content-Type', 'application/octet-stream')
- image_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', image_file_name))
+ image_file_name = "test.jpg"
+ image_file = MIMEImage(open(image_file_name, "rb").read())
+ image_file.add_header("Content-Type", "application/octet-stream")
+ image_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", image_file_name)
+ )
msg.attach(image_file)
await server.sendmail(from_addr, send_to_addr, msg.as_string())
@@ -64,7 +71,9 @@ async def send_email(send_to_addr:str,contest_msg:str):
"""
-if __name__ == '__main__':
+if __name__ == "__main__":
loop = asyncio.get_event_loop()
- loop.run_until_complete(send_email(send_to_addr='3022600790@qq.com', contest_msg=html_msg))
+ loop.run_until_complete(
+ send_email(send_to_addr="3022600790@qq.com", contest_msg=html_msg)
+ )
# asyncio.run(send_email(send_to_addr='3022600790@qq.com', contest_msg=html_msg))
diff --git a/chapter15/smtplib/main_smtplib.py b/chapter15/smtplib/main_smtplib.py
index d2b6eeb..49b6649 100644
--- a/chapter15/smtplib/main_smtplib.py
+++ b/chapter15/smtplib/main_smtplib.py
@@ -1,18 +1,22 @@
# smtplib 用于邮件的发信动作
import smtplib
+
# email 用于构建邮件内容
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
-#构建邮件头
+
+# 构建邮件头
from email.header import Header
+
# 发信服务器
-smtp_server = 'smtp.qq.com'
+smtp_server = "smtp.qq.com"
# 发信方的信息:发信邮箱,QQ 邮箱授权码
-from_addr = '308711822@qq.com'
-password = 'xxxxxxxxxxxxxx'
+from_addr = "308711822@qq.com"
+password = "xxxxxxxxxxxxxx"
-def send_email(send_to_addr:str,contest_msg:str):
+
+def send_email(send_to_addr: str, contest_msg: str):
# 连接发信服务器
server = smtplib.SMTP_SSL(smtp_server)
# 建立连接--qq邮箱服务和端口号
@@ -22,31 +26,35 @@ def send_email(send_to_addr:str,contest_msg:str):
# 配置邮件正文内容
msg = MIMEMultipart()
- msg['From'] = Header('小钟同学') # 设置来自于邮件的发送者信息
- msg['To'] = Header('其他人同学') # 设置来自于邮件的接收人信息
- msg['Subject'] = Header("用户注册通知", 'utf-8') # 设置邮件主题
+ msg["From"] = Header("小钟同学") # 设置来自于邮件的发送者信息
+ msg["To"] = Header("其他人同学") # 设置来自于邮件的接收人信息
+ msg["Subject"] = Header("用户注册通知", "utf-8") # 设置邮件主题
# 邮件正文内容
- msg.attach(MIMEText(contest_msg, 'html', 'utf-8'))
+ msg.attach(MIMEText(contest_msg, "html", "utf-8"))
# 构造附件1,传送文本附件
- file_name = 'test1.txt'
- test_file_att = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file_att["Content-Type"] = 'application/octet-stream'
+ file_name = "test1.txt"
+ test_file_att = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file_att["Content-Type"] = "application/octet-stream"
test_file_att["Content-Disposition"] = f'attachment; filename="{file_name}"'
msg.attach(test_file_att)
# 构造附件1,传送文本附件
- file_name = 'test2.txt'
- test_file = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file.add_header('Content-Type','application/octet-stream')
- test_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', file_name))
+ file_name = "test2.txt"
+ test_file = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file.add_header("Content-Type", "application/octet-stream")
+ test_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", file_name)
+ )
msg.attach(test_file)
# 构造附件2,文件附件
- image_file_name = 'test.jpg'
- image_file = MIMEImage(open(image_file_name, 'rb').read())
- image_file.add_header('Content-Type', 'application/octet-stream')
- image_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', image_file_name))
+ image_file_name = "test.jpg"
+ image_file = MIMEImage(open(image_file_name, "rb").read())
+ image_file.add_header("Content-Type", "application/octet-stream")
+ image_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", image_file_name)
+ )
msg.attach(image_file)
server.sendmail(from_addr, send_to_addr, msg.as_string())
@@ -58,5 +66,4 @@ def send_email(send_to_addr:str,contest_msg:str):
您好,您申请的XXXX注册成功,请点击下面链接进行确认!
确认
"""
-send_email(send_to_addr='3022600790@qq.com', contest_msg=html_msg)
-
+send_email(send_to_addr="3022600790@qq.com", contest_msg=html_msg)
diff --git a/chapter16/Jaeger/test_jaeger_client/main.py b/chapter16/Jaeger/test_jaeger_client/main.py
index aa342ce..afe8d36 100644
--- a/chapter16/Jaeger/test_jaeger_client/main.py
+++ b/chapter16/Jaeger/test_jaeger_client/main.py
@@ -5,26 +5,30 @@
def construct_span(tracer):
# 定义span的名称为TestSpan
- with tracer.start_span('TestSpan') as span:
+ with tracer.start_span("TestSpan") as span:
# 设置这个span传递的日志信息
- span.log_kv({'event': '父Span', 'other': "我是第一个父的Span"})
+ span.log_kv({"event": "父Span", "other": "我是第一个父的Span"})
time.sleep(1)
# 定义AliyunTestSpan的子Span,类似第一个追踪的数据的子层级
- with tracer.start_span('TestSpan-ChildSpan-01', child_of=span) as child_span:
+ with tracer.start_span("TestSpan-ChildSpan-01", child_of=span) as child_span:
time.sleep(2)
# 设置父的span键值对日志信息
- span.log_kv({'event': '我是父Span--日志1'})
+ span.log_kv({"event": "我是父Span--日志1"})
# 设置子child_span的日志
- child_span.log_kv({'event': '父Span--第一层子Span-01'})
- with tracer.start_span('TestSpan-ChildSpan-01', child_of=span) as child_span:
+ child_span.log_kv({"event": "父Span--第一层子Span-01"})
+ with tracer.start_span("TestSpan-ChildSpan-01", child_of=span) as child_span:
time.sleep(3)
- span.log_kv({'event': '我是父Span--日志2'})
- child_span.log_kv({'event': '父Span--第一层子Span-02'})
+ span.log_kv({"event": "我是父Span--日志2"})
+ child_span.log_kv({"event": "父Span--第一层子Span-02"})
- with tracer.start_span('TestSpanC-hildSpan-01-01', child_of=child_span) as Span3_child_span:
+ with tracer.start_span(
+ "TestSpanC-hildSpan-01-01", child_of=child_span
+ ) as Span3_child_span:
time.sleep(4)
- span.log_kv({'event': '我是父Span--日志3'})
- Span3_child_span.log_kv({'event': '父Span--第一层子Span-的下一个子Span'})
+ span.log_kv({"event": "我是父Span--日志3"})
+ Span3_child_span.log_kv(
+ {"event": "父Span--第一层子Span-的下一个子Span"}
+ )
return span
@@ -32,30 +36,30 @@ def construct_span(tracer):
if __name__ == "__main__":
# 定义日志输出的登记
log_level = logging.DEBUG
- logging.getLogger('').handlers = []
+ logging.getLogger("").handlers = []
# 配置日志默认输出格式
- logging.basicConfig(format='%(asctime)s %(message)s', level=log_level)
+ logging.basicConfig(format="%(asctime)s %(message)s", level=log_level)
# Jaeger配置信息
config = Config(
# 服务信息配置
config={
# sampler 采样
- 'sampler': {
- 'type': 'const', # 采样类型
- 'param': 1, # 采样开关 1:开启全部采样 0:关闭全部
+ "sampler": {
+ "type": "const", # 采样类型
+ "param": 1, # 采样开关 1:开启全部采样 0:关闭全部
},
# 配置链接到我们的本地的agent,通过agent来上报
- 'local_agent': {
+ "local_agent": {
# 注意这里是指定了JaegerAgent的host和port。
# 根据官方建议为了保证数据可靠性,JaegerClient和JaegerAgent运行在同一台主机内,因此reporting_host填写为127.0.0.1。
- 'reporting_host': '192.168.126.130',
- 'reporting_port': 6831,
+ "reporting_host": "192.168.126.130",
+ "reporting_port": 6831,
},
- 'logging': True,
+ "logging": True,
},
# 这里填写应用名称---服务的名称
service_name="MyFirstSpan",
- validate=True
+ validate=True,
)
# this call also sets opentracing.tracer
diff --git a/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py b/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py
index be84349..c8b27c8 100644
--- a/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py
+++ b/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/__init__.py
@@ -1,4 +1,3 @@
-
from typing import List, Any
from fastapi import Request
from jaeger_client import Config
@@ -9,18 +8,16 @@
from fastapi import FastAPI
-
-
class OpentracingJaegerMiddleware(BaseHTTPMiddleware):
- def __init__(self,fastapiapp: FastAPI,*args,**kwargs) -> None:
- super().__init__(*args,**kwargs)
+ def __init__(self, fastapiapp: FastAPI, *args, **kwargs) -> None:
+ super().__init__(*args, **kwargs)
self.fastapiapp = fastapiapp
- self.fastapiapp.add_event_handler('startup', self.setup_opentracing)
+ self.fastapiapp.add_event_handler("startup", self.setup_opentracing)
def setup_opentracing(self):
# 配置连接信息
- jaeger_host = '192.168.126.130'
+ jaeger_host = "192.168.126.130"
jaeger_port = 6831
service_name = "测试2"
trace_id_header = "X-TRACE-ID"
@@ -31,28 +28,28 @@ def setup_opentracing(self):
config={
"local_agent": {
"reporting_host": jaeger_host,
- "reporting_port": jaeger_port
+ "reporting_port": jaeger_port,
},
"sampler": {
"type": jaeger_sampler_type,
"param": jaeger_sampler_rate,
},
- "trace_id_header": trace_id_header
+ "trace_id_header": trace_id_header,
},
service_name=service_name,
validate=True,
- scope_manager=AsyncioScopeManager()
+ scope_manager=AsyncioScopeManager(),
)
self.fastapiapp.state.tracer = _tracer_config.initialize_tracer()
-
-
async def dispatch(self, request: Request, call_next: Any) -> Response:
# 获取tracer对象
tracer = request.app.state.tracer
# 开始解析上下文(Extract函数):
# 该函数主要用于在跨服务进程中,进行解析还原上一个传入Span 信息,通常是通过获取请求的headers进行参数信息提取;
- span_context = tracer.extract(format=Format.HTTP_HEADERS, carrier=request.headers)
+ span_context = tracer.extract(
+ format=Format.HTTP_HEADERS, carrier=request.headers
+ )
# 开始创建span对象通过span_context,来决定是否存在层级span
span = tracer.start_span(
operation_name=f"{request.method} {request.url.path}",
@@ -71,15 +68,12 @@ async def dispatch(self, request: Request, call_next: Any) -> Response:
# 设置client请求来源端口的标签
span.set_tag(tags.PEER_PORT, request.client.port or "")
# #Component(字符串)ia模块、库或正在生成跨区的包。
- span.set_tag(tags.COMPONENT, 'Fastapi')
+ span.set_tag(tags.COMPONENT, "Fastapi")
# 标记表示RPC或其他远程调用的服务器端的范围
span.set_tag(tags.SPAN_KIND, tags.SPAN_KIND_RPC_SERVER)
# (字符串)是请求的HTTP方法。
span.set_tag(tags.HTTP_METHOD, request.method)
-
-
-
# Scope 对象 主要是管理Active Span的容器
# Scope 代表着当前活跃的Span; 是对当前活跃Span的一个抽象
# ScopeManager 包含一个 Scope, Scope 又包含了 当前Span
@@ -99,5 +93,3 @@ async def dispatch(self, request: Request, call_next: Any) -> Response:
# inject之后,实际 headers = {'uber-trace-id': '6997ed0a6a74f050:bf49be2de63d86e7:e02975aab05fd358:1'}
print(headers)
return response
-
-
diff --git a/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/main.py b/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/main.py
index afd7e50..b6ffb19 100644
--- a/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/main.py
+++ b/chapter16/Jaeger/test_jaeger_client_fastapi/middeware/main.py
@@ -8,23 +8,28 @@
@app.get("/tracing")
-def tracing(request: Request, x_trace_id: Optional[str] = Header(None, convert_underscores=True)):
+def tracing(
+ request: Request, x_trace_id: Optional[str] = Header(None, convert_underscores=True)
+):
# 拿到当前生效的tracer
tracer = request.app.state.tracer
# 判断是否存在对应的上一个层级的span
span = request.state.opentracing_span
# 创建新的span
- with tracer.start_span('new—span-test', child_of=span) as child_span_1:
- span.log_kv({'event': '父类的span事件信息1'})
- span.log_kv({'event': '父类的span事件信息2',
- 'request.args': request.query_params, })
+ with tracer.start_span("new—span-test", child_of=span) as child_span_1:
+ span.log_kv({"event": "父类的span事件信息1"})
+ span.log_kv(
+ {
+ "event": "父类的span事件信息2",
+ "request.args": request.query_params,
+ }
+ )
# child_span_1.log_kv({'event': 'child_span-down below'})
# with tracer.start_span('new—span-test-childspan', child_of=child_span_1) as child_span_2:
# child_span_2.log_kv({'event': 'new—span-test-childspan-childspan'})
-
return "ok"
@@ -34,4 +39,4 @@ def tracing(request: Request, x_trace_id: Optional[str] = Header(None, convert_u
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/async_sync_change/main_asgiref_async_to_sync.py b/chapter16/async_sync_change/main_asgiref_async_to_sync.py
index a71535e..c323aac 100644
--- a/chapter16/async_sync_change/main_asgiref_async_to_sync.py
+++ b/chapter16/async_sync_change/main_asgiref_async_to_sync.py
@@ -1,6 +1,6 @@
from functools import wraps
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
from fastapi.responses import PlainTextResponse
from fastapi.params import Body
@@ -9,14 +9,16 @@
@app.post("/get/access_token")
-def access_token(request:Request,name=Body(...)):
+def access_token(request: Request, name=Body(...)):
# print(reques.body())
from asgiref.sync import async_to_sync
+
body = async_to_sync(request.body)()
print(body)
- return PlainTextResponse(body.decode(encoding='utf-8'))
+ return PlainTextResponse(body.decode(encoding="utf-8"))
-if __name__ == '__main__':
+if __name__ == "__main__":
import uvicorn
- uvicorn.run('main:app', host="127.0.0.1", port=8100, debug=True, reload=True)
\ No newline at end of file
+
+ uvicorn.run("main:app", host="127.0.0.1", port=8100, debug=True, reload=True)
diff --git a/chapter16/async_sync_change/main_asgiref_sync_to_async.py b/chapter16/async_sync_change/main_asgiref_sync_to_async.py
index 4bab1e5..13f4d1c 100644
--- a/chapter16/async_sync_change/main_asgiref_sync_to_async.py
+++ b/chapter16/async_sync_change/main_asgiref_sync_to_async.py
@@ -1,22 +1,22 @@
from functools import wraps
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
-from fastapi.responses import PlainTextResponse,HTMLResponse
+from fastapi.responses import PlainTextResponse, HTMLResponse
from asgiref.sync import sync_to_async
import requests
+
# 定义我们的APP服务对象
app = FastAPI()
-def getdata():
- return requests.get('http://www.baidu.com').text
-
+def getdata():
+ return requests.get("http://www.baidu.com").text
@app.get("/get/access_token")
async def access_token():
- asds= await sync_to_async(func=getdata)()
+ asds = await sync_to_async(func=getdata)()
return HTMLResponse(asds)
@@ -26,6 +26,4 @@ async def access_token():
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
-
-
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/async_sync_change/main_asyncer_asyncify.py b/chapter16/async_sync_change/main_asyncer_asyncify.py
index 44d1cf9..81e3d0c 100644
--- a/chapter16/async_sync_change/main_asyncer_asyncify.py
+++ b/chapter16/async_sync_change/main_asyncer_asyncify.py
@@ -1,19 +1,23 @@
-from fastapi import FastAPI,Request
-from fastapi.responses import PlainTextResponse,HTMLResponse
+from fastapi import FastAPI, Request
+from fastapi.responses import PlainTextResponse, HTMLResponse
from asyncer import asyncify
import requests
+
# 定义我们的APP服务对象
app = FastAPI()
+
def do_sync_work(name):
- return requests.get(f'http://www.baidu.com?name={name}').text
+ return requests.get(f"http://www.baidu.com?name={name}").text
+
@app.get("/get/access_token")
-async def access_token(request:Request):
+async def access_token(request: Request):
message = await asyncify(do_sync_work)(name="World")
return HTMLResponse(message)
-if __name__ == '__main__':
+if __name__ == "__main__":
import uvicorn
- uvicorn.run('main:app', host="127.0.0.1", port=8100, debug=True, reload=True)
+
+ uvicorn.run("main:app", host="127.0.0.1", port=8100, debug=True, reload=True)
diff --git a/chapter16/async_sync_change/main_asyncer_syncify.py b/chapter16/async_sync_change/main_asyncer_syncify.py
index 1cd5b55..53bb120 100644
--- a/chapter16/async_sync_change/main_asyncer_syncify.py
+++ b/chapter16/async_sync_change/main_asyncer_syncify.py
@@ -1,18 +1,20 @@
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
from fastapi.responses import PlainTextResponse
from fastapi.params import Body
-from fastapi.background import BackgroundTasks
-from asyncer import asyncify,syncify
+from fastapi.background import BackgroundTasks
+from asyncer import asyncify, syncify
app = FastAPI()
+
@app.post("/get/access_token")
-def access_token(request:Request,name=Body(...)):
+def access_token(request: Request, name=Body(...)):
body = syncify(request.body)()
print(body)
- return PlainTextResponse(body.decode(encoding='utf-8'))
+ return PlainTextResponse(body.decode(encoding="utf-8"))
+
-if __name__ == '__main__':
+if __name__ == "__main__":
import uvicorn
- uvicorn.run('main:app', host="127.0.0.1", port=8100, debug=True, reload=True)
+ uvicorn.run("main:app", host="127.0.0.1", port=8100, debug=True, reload=True)
diff --git a/chapter16/async_wrapper/main_asgiref_sync_to_async.py b/chapter16/async_wrapper/main_asgiref_sync_to_async.py
index e9dc0df..4b566ac 100644
--- a/chapter16/async_wrapper/main_asgiref_sync_to_async.py
+++ b/chapter16/async_wrapper/main_asgiref_sync_to_async.py
@@ -1,18 +1,18 @@
import cProfile
from functools import wraps
-from fastapi import FastAPI,Request
+from fastapi import FastAPI, Request
-from fastapi.responses import PlainTextResponse,HTMLResponse
+from fastapi.responses import PlainTextResponse, HTMLResponse
from asgiref.sync import sync_to_async
import requests
+
# 定义我们的APP服务对象
app = FastAPI()
-def getdata():
- return requests.get('http://www.baidu.com').text
-
+def getdata():
+ return requests.get("http://www.baidu.com").text
def async_decorator_with_argument(time_to_eat):
@@ -25,23 +25,20 @@ def actual_decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
-
-
-
print(time_to_eat)
print(args)
print(kwargs)
return await func(*args, **kwargs)
-
print("输出结果")
return wrapper
return actual_decorator
+
@app.get("/get/access_token")
# @async_decorator_with_argument(time_to_eat='555555')
-def access_token(request:Request,dsa:str):
+def access_token(request: Request, dsa: str):
pr = cProfile.Profile()
pr.enable() # 开始收集性能分析数据
# asds= await sync_to_async(func=getdata)()
@@ -56,6 +53,4 @@ def access_token(request:Request,dsa:str):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1',port=5667, reload=True)
-
-
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", port=5667, reload=True)
diff --git a/chapter16/body/main_01.py b/chapter16/body/main_01.py
index 382209d..11202f6 100644
--- a/chapter16/body/main_01.py
+++ b/chapter16/body/main_01.py
@@ -42,4 +42,4 @@ async def index(request: Request):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/body/main_02.py b/chapter16/body/main_02.py
index a5c33bf..7c9d3a8 100644
--- a/chapter16/body/main_02.py
+++ b/chapter16/body/main_02.py
@@ -31,10 +31,11 @@ async def dispatch(self, request: Request, call_next):
await self.set_body(request)
# 需要在日志中间件里读取body数据
_body = await request.body()
- print("Loger中间件解析读取:消费request.body()",_body)
+ print("Loger中间件解析读取:消费request.body()", _body)
response = await call_next(request)
return response
+
app.add_middleware(LogerMiddleware)
@@ -45,12 +46,10 @@ async def index(request: Request):
return PlainTextResponse("消费request.body()!")
-
-
if __name__ == "__main__":
import uvicorn
import os
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/body/main_03.py b/chapter16/body/main_03.py
index 9e3b7fb..86493a0 100644
--- a/chapter16/body/main_03.py
+++ b/chapter16/body/main_03.py
@@ -31,12 +31,11 @@ async def dispatch(self, request: Request, call_next):
await self.set_body(request)
# 需要在日志中间件里读取body数据
_body = await request.body()
- print("Loger中间件解析读取11111111:消费request.body()",_body)
+ print("Loger中间件解析读取11111111:消费request.body()", _body)
response = await call_next(request)
return response
-
class LogerMiddleware2(BaseHTTPMiddleware):
async def set_body(self, request):
@@ -51,10 +50,11 @@ async def dispatch(self, request: Request, call_next):
await self.set_body(request)
# 需要在日志中间件里读取body数据
_body = await request.body()
- print("Loger中间件解析读取22222222:消费request.body()",_body)
+ print("Loger中间件解析读取22222222:消费request.body()", _body)
response = await call_next(request)
return response
+
app.add_middleware(LogerMiddleware)
app.add_middleware(LogerMiddleware2)
@@ -66,12 +66,10 @@ async def index(request: Request):
return PlainTextResponse("消费request.body()!")
-
-
if __name__ == "__main__":
import uvicorn
import os
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/body/main_04.py b/chapter16/body/main_04.py
index 330c301..b505a3c 100644
--- a/chapter16/body/main_04.py
+++ b/chapter16/body/main_04.py
@@ -20,9 +20,8 @@
class LogerMiddleware1:
def __init__(
- self,
- app: ASGIApp,
-
+ self,
+ app: ASGIApp,
) -> None:
self.app = app
@@ -45,9 +44,8 @@ async def receive():
class LogerMiddleware2:
def __init__(
- self,
- app: ASGIApp,
-
+ self,
+ app: ASGIApp,
) -> None:
self.app = app
@@ -57,6 +55,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
return
# 接收一次
receive_ = await receive()
+
async def receive():
return receive_
@@ -71,6 +70,7 @@ async def receive():
app.add_middleware(LogerMiddleware1)
app.add_middleware(LogerMiddleware2)
+
@app.get("/")
async def index(request: Request):
_body = await request.body()
@@ -78,12 +78,10 @@ async def index(request: Request):
return PlainTextResponse("消费request.body()!")
-
-
if __name__ == "__main__":
import uvicorn
import os
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/contextvar_request/bind_.py b/chapter16/contextvar_request/bind_.py
index d3d8f64..1aea75c 100644
--- a/chapter16/contextvar_request/bind_.py
+++ b/chapter16/contextvar_request/bind_.py
@@ -20,4 +20,4 @@ def __setitem__(self, index, value):
def __delitem__(self, index):
del contextvar.get()[index]
- return ContextVarBind()
\ No newline at end of file
+ return ContextVarBind()
diff --git a/chapter16/contextvar_request/main_class.py b/chapter16/contextvar_request/main_class.py
index e8f4ac9..b70ab09 100644
--- a/chapter16/contextvar_request/main_class.py
+++ b/chapter16/contextvar_request/main_class.py
@@ -19,20 +19,17 @@ async def add_process_time_header(request: Request, call_next):
request_var.reset(token)
-
-
-@app.post('/index')
+@app.post("/index")
async def index():
# 这里应该使用事务处理
print(request.headers)
- return JSONResponse({
- "code": 200,
- "msg": "成功"
- })
+ return JSONResponse({"code": 200, "msg": "成功"})
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/contextvar_request/request.py b/chapter16/contextvar_request/request.py
index 4762281..e854dc5 100644
--- a/chapter16/contextvar_request/request.py
+++ b/chapter16/contextvar_request/request.py
@@ -3,4 +3,4 @@
from chapter15.contextvar_request.bind_ import bind_contextvar
request_var: ContextVar[Request] = ContextVar("request")
-request:Request = bind_contextvar(request_var)
\ No newline at end of file
+request: Request = bind_contextvar(request_var)
diff --git a/chapter16/depends/main_class.py b/chapter16/depends/main_class.py
index a011a70..bf6a6bc 100644
--- a/chapter16/depends/main_class.py
+++ b/chapter16/depends/main_class.py
@@ -10,13 +10,16 @@ class AuthCheck:
def __init__(self, role: str):
self.role = role
+
@app.get("/auth_check")
def auth_check(role: dict = Depends(AuthCheck)):
return role
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/depends/main_class_call.py b/chapter16/depends/main_class_call.py
index 7ff35dd..1064bf8 100644
--- a/chapter16/depends/main_class_call.py
+++ b/chapter16/depends/main_class_call.py
@@ -10,19 +10,24 @@ class AuthCheck:
def __init__(self, role_name: str):
self.role_name = role_name
- def __call__(self,):
- print("当前角色是:",self.role_name)
- if self.role_name =='admin':
+ def __call__(
+ self,
+ ):
+ print("当前角色是:", self.role_name)
+ if self.role_name == "admin":
return "管理员"
return "普通用户"
+
@app.get("/auth_check")
def auth_check(role: str = Depends(AuthCheck(role_name="admin"))):
return role
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/depends/main_class_security_scopes.py b/chapter16/depends/main_class_security_scopes.py
index 19c056b..2947089 100644
--- a/chapter16/depends/main_class_security_scopes.py
+++ b/chapter16/depends/main_class_security_scopes.py
@@ -22,4 +22,4 @@ def auth_check(role: str = Security(AuthCheck, scopes=["admin"])):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/depends/main_fun.py b/chapter16/depends/main_fun.py
index 798a12a..71ad825 100644
--- a/chapter16/depends/main_fun.py
+++ b/chapter16/depends/main_fun.py
@@ -6,15 +6,19 @@
app = FastAPI()
-def auth_check(role:str):
+def auth_check(role: str):
return role
+
@app.get("/auth_check")
def auth_check(role: str = Depends(auth_check)):
return role
+
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/depends/main_fun_security_scopes.py b/chapter16/depends/main_fun_security_scopes.py
index 554c051..827d2b3 100644
--- a/chapter16/depends/main_fun_security_scopes.py
+++ b/chapter16/depends/main_fun_security_scopes.py
@@ -7,7 +7,7 @@
def auth_check(security_scopes: SecurityScopes):
print("传入的参数:", security_scopes.scopes)
- if security_scopes.scopes[0] == 'admin':
+ if security_scopes.scopes[0] == "admin":
return "管理者"
return "普通用户"
@@ -23,4 +23,4 @@ def auth_check(role: str = Security(auth_check, scopes=["admin"])):
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/model_sort/main_asyncer_syncify.py b/chapter16/model_sort/main_asyncer_syncify.py
index 395043c..4628def 100644
--- a/chapter16/model_sort/main_asyncer_syncify.py
+++ b/chapter16/model_sort/main_asyncer_syncify.py
@@ -11,7 +11,9 @@ class Item(BaseModel):
def __new__(cls, *args, **kwargs):
instance = super().__new__(cls)
# 对当前__fields__重新进行排序
- cls.__fields__ = {key: cls.__fields__[key] for key in sorted(cls.__fields__.keys())}
+ cls.__fields__ = {
+ key: cls.__fields__[key] for key in sorted(cls.__fields__.keys())
+ }
return instance
desc: Optional[str] = None
@@ -20,7 +22,7 @@ def __new__(cls, *args, **kwargs):
aname: str
-@app.post('/items/', response_model=Item)
+@app.post("/items/", response_model=Item)
async def getitem(item: Item):
return item
diff --git a/chapter16/plugins/base.py b/chapter16/plugins/base.py
index 3a3b740..915ee87 100644
--- a/chapter16/plugins/base.py
+++ b/chapter16/plugins/base.py
@@ -10,27 +10,43 @@
class PluginBase(abc.ABC):
- def __init__(self,app: fastapi.FastAPI = None,config: pydantic.BaseSettings = None):
+ def __init__(
+ self, app: fastapi.FastAPI = None, config: pydantic.BaseSettings = None
+ ):
if app is not None:
self.init_app(app)
@abc.abstractmethod
- def init_app(self,app: fastapi.FastAPI,config: pydantic.BaseSettings = None,*args,**kwargs) -> None:
- raise NotImplementedError('需要实现初始化')
-
+ def init_app(
+ self,
+ app: fastapi.FastAPI,
+ config: pydantic.BaseSettings = None,
+ *args,
+ **kwargs
+ ) -> None:
+ raise NotImplementedError("需要实现初始化")
class HookPluginClient(PluginBase):
# 设置插件默认的参数信息
- def __init__(self,
- on_before_request: typing.Sequence[typing.Callable] = None,
- on_after_request: typing.Sequence[typing.Callable] = None,
- on_teardown_appcontext: typing.Sequence[typing.Callable] = None,
- *args, **kwargs):
+ def __init__(
+ self,
+ on_before_request: typing.Sequence[typing.Callable] = None,
+ on_after_request: typing.Sequence[typing.Callable] = None,
+ on_teardown_appcontext: typing.Sequence[typing.Callable] = None,
+ *args,
+ **kwargs
+ ):
super().__init__(*args, **kwargs)
- self.on_before_request = [] if on_before_request is None else list(on_before_request)
- self.on_after_request = [] if on_after_request is None else list(on_after_request)
- self.on_teardown_appcontext = [] if on_teardown_appcontext is None else list(on_teardown_appcontext)
+ self.on_before_request = (
+ [] if on_before_request is None else list(on_before_request)
+ )
+ self.on_after_request = (
+ [] if on_after_request is None else list(on_after_request)
+ )
+ self.on_teardown_appcontext = (
+ [] if on_teardown_appcontext is None else list(on_teardown_appcontext)
+ )
def init_app(self, app: FastAPI, *args, **kwargs):
@app.middleware("http")
@@ -83,4 +99,4 @@ async def teardown_appcontext(self, request, response) -> None:
if asyncio.iscoroutinefunction(handler):
await handler(request, response)
else:
- handler(request, response)
\ No newline at end of file
+ handler(request, response)
diff --git a/chapter16/plugins/main.py b/chapter16/plugins/main.py
index b0a21c8..2e3af86 100644
--- a/chapter16/plugins/main.py
+++ b/chapter16/plugins/main.py
@@ -6,34 +6,40 @@
app = FastAPI()
# 导入插件类
from plugins.request_hook import HookPluginClient
-rehook:HookPluginClient = HookPluginClient()
+
+rehook: HookPluginClient = HookPluginClient()
rehook.init_app(app)
-@rehook.on_event(event_type='before_request')
+
+@rehook.on_event(event_type="before_request")
def before_request(reqest):
print("before_request", reqest)
-@rehook.on_event(event_type='after_request')
-def after_request(reqest,response):
- print("after_request", reqest,response)
+@rehook.on_event(event_type="after_request")
+def after_request(reqest, response):
+ print("after_request", reqest, response)
-@rehook.on_event(event_type='teardown_appcontext')
+@rehook.on_event(event_type="teardown_appcontext")
def teardown_appcontext(request, response):
- print("teardown_appcontext", request,response)
+ print("teardown_appcontext", request, response)
+
class AuthCheck:
def __init__(self, role: str):
self.role = role
+
@app.get("/index")
def index():
- return 'index'
+ return "index"
+
if __name__ == "__main__":
import uvicorn
import os
+
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", host='127.0.0.1', reload=True)
+ uvicorn.run(f"{app_modeel_name}:app", host="127.0.0.1", reload=True)
diff --git a/chapter16/sentry/main.py b/chapter16/sentry/main.py
index 6ac7108..803eab6 100644
--- a/chapter16/sentry/main.py
+++ b/chapter16/sentry/main.py
@@ -14,6 +14,7 @@
app = FastAPI()
+
@app.get("/sentry-debug")
async def trigger_error():
division_by_zero = 1 / 0
@@ -25,4 +26,4 @@ async def trigger_error():
app_modeel_name = os.path.basename(__file__).replace(".py", "")
print(app_modeel_name)
- uvicorn.run(f"{app_modeel_name}:app", reload=True)
\ No newline at end of file
+ uvicorn.run(f"{app_modeel_name}:app", reload=True)
diff --git a/chapter16/smtplib/aaaa.py b/chapter16/smtplib/aaaa.py
index 945b3c0..4520f80 100644
--- a/chapter16/smtplib/aaaa.py
+++ b/chapter16/smtplib/aaaa.py
@@ -1,19 +1,21 @@
# smtplib 用于邮件的发信动作
import smtplib
+
# email 用于构建邮件内容
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
+
# 构建邮件头
from email.header import Header
# 发信方的信息:发信邮箱,QQ 邮箱授权码
-from_addr = '@qq.com'
-password = '****'
+from_addr = "@qq.com"
+password = "****"
# 收信方邮箱
-to_addr = 'xxxxx@qq.com'
+to_addr = "xxxxx@qq.com"
# 发信服务器
-smtp_server = 'smtp.qq.com'
+smtp_server = "smtp.qq.com"
html_msg = """
Python 邮件发送HTML格式文件测试...
@@ -23,30 +25,30 @@
# 创建一个带附件的实例msg
msg = MIMEMultipart()
-msg['From'] = Header('张三') # 发送者
-msg['To'] = Header('李四') # 接收者
-subject = 'Python SMTP 邮件测试'
-msg['Subject'] = Header(subject, 'utf-8') # 邮件主题
+msg["From"] = Header("张三") # 发送者
+msg["To"] = Header("李四") # 接收者
+subject = "Python SMTP 邮件测试"
+msg["Subject"] = Header(subject, "utf-8") # 邮件主题
# 邮件正文内容
-msg.attach(MIMEText(html_msg, 'html', 'utf-8'))
+msg.attach(MIMEText(html_msg, "html", "utf-8"))
# 构造附件1,传送当前目录下的 test1.txt 文件
-att1 = MIMEText(open('test1.txt', 'rb').read(), 'base64', 'utf-8')
-att1["Content-Type"] = 'application/octet-stream'
+att1 = MIMEText(open("test1.txt", "rb").read(), "base64", "utf-8")
+att1["Content-Type"] = "application/octet-stream"
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test1.txt"'
msg.attach(att1)
# 构造附件2,传送当前目录下的 test2.txt 文件
-att2 = MIMEText(open('test2.txt', 'rb').read(), 'base64', 'utf-8')
-att2["Content-Type"] = 'application/octet-stream'
+att2 = MIMEText(open("test2.txt", "rb").read(), "base64", "utf-8")
+att2["Content-Type"] = "application/octet-stream"
att2["Content-Disposition"] = 'attachment; filename="test2.txt"'
msg.attach(att2)
smtpobj = None
try:
smtpobj = smtplib.SMTP_SSL(smtp_server)
- smtpobj.connect(smtp_server, 465) # 建立连接--qq邮箱服务和端口号
- smtpobj.login(from_addr, password) # 登录--发送者账号和口令
+ smtpobj.connect(smtp_server, 465) # 建立连接--qq邮箱服务和端口号
+ smtpobj.login(from_addr, password) # 登录--发送者账号和口令
smtpobj.sendmail(from_addr, to_addr, msg.as_string())
print("邮件发送成功")
except smtplib.SMTPException:
diff --git a/chapter16/smtplib/main_aiosmtplib.py b/chapter16/smtplib/main_aiosmtplib.py
index 7d64723..28772e5 100644
--- a/chapter16/smtplib/main_aiosmtplib.py
+++ b/chapter16/smtplib/main_aiosmtplib.py
@@ -2,23 +2,26 @@
import asyncio
import aiosmtplib
+
# email 用于构建邮件内容
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
-#构建邮件头
+# 构建邮件头
from email.header import Header
+
# 发信服务器
-smtp_server = 'smtp.qq.com'
+smtp_server = "smtp.qq.com"
# 发信方的信息:发信邮箱账号
-from_addr = '308711822@qq.com'
+from_addr = "308711822@qq.com"
# 发信方的信息:QQ 邮箱授权码
-password = 'zbpqbvcgimmrbjib'
+password = "zbpqbvcgimmrbjib"
+
-async def send_email(send_to_addr:str,contest_msg:str):
+async def send_email(send_to_addr: str, contest_msg: str):
# 连接发信服务器
- server = aiosmtplib.SMTP(hostname=smtp_server, port=465,use_tls=True)
+ server = aiosmtplib.SMTP(hostname=smtp_server, port=465, use_tls=True)
# 建立连接--qq邮箱服务和端口号
await server.connect()
# 登入邮箱
@@ -26,31 +29,35 @@ async def send_email(send_to_addr:str,contest_msg:str):
# 配置邮件正文内容
msg = MIMEMultipart()
- msg['From'] = Header('小钟同学') # 设置来自于邮件的发送者信息
- msg['To'] = Header('其他人同学') # 设置来自于邮件的接收人信息
- msg['Subject'] = Header("用户注册通知", 'utf-8') # 设置邮件主题
+ msg["From"] = Header("小钟同学") # 设置来自于邮件的发送者信息
+ msg["To"] = Header("其他人同学") # 设置来自于邮件的接收人信息
+ msg["Subject"] = Header("用户注册通知", "utf-8") # 设置邮件主题
# 邮件正文内容
- msg.attach(MIMEText(contest_msg, 'html', 'utf-8'))
+ msg.attach(MIMEText(contest_msg, "html", "utf-8"))
# 构造附件1,传送文本附件
- file_name = 'test1.txt'
- test_file_att = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file_att["Content-Type"] = 'application/octet-stream'
+ file_name = "test1.txt"
+ test_file_att = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file_att["Content-Type"] = "application/octet-stream"
test_file_att["Content-Disposition"] = f'attachment; filename="{file_name}"'
msg.attach(test_file_att)
# 构造附件1,传送文本附件
- file_name = 'test2.txt'
- test_file = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file.add_header('Content-Type','application/octet-stream')
- test_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', file_name))
+ file_name = "test2.txt"
+ test_file = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file.add_header("Content-Type", "application/octet-stream")
+ test_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", file_name)
+ )
msg.attach(test_file)
# 构造附件2,文件附件
- image_file_name = 'test.jpg'
- image_file = MIMEImage(open(image_file_name, 'rb').read())
- image_file.add_header('Content-Type', 'application/octet-stream')
- image_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', image_file_name))
+ image_file_name = "test.jpg"
+ image_file = MIMEImage(open(image_file_name, "rb").read())
+ image_file.add_header("Content-Type", "application/octet-stream")
+ image_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", image_file_name)
+ )
msg.attach(image_file)
await server.sendmail(from_addr, send_to_addr, msg.as_string())
@@ -64,7 +71,9 @@ async def send_email(send_to_addr:str,contest_msg:str):
"""
-if __name__ == '__main__':
+if __name__ == "__main__":
loop = asyncio.get_event_loop()
- loop.run_until_complete(send_email(send_to_addr='3022600790@qq.com', contest_msg=html_msg))
+ loop.run_until_complete(
+ send_email(send_to_addr="3022600790@qq.com", contest_msg=html_msg)
+ )
# asyncio.run(send_email(send_to_addr='3022600790@qq.com', contest_msg=html_msg))
diff --git a/chapter16/smtplib/main_smtplib.py b/chapter16/smtplib/main_smtplib.py
index f4a07cd..ed6fec3 100644
--- a/chapter16/smtplib/main_smtplib.py
+++ b/chapter16/smtplib/main_smtplib.py
@@ -1,18 +1,22 @@
# smtplib 用于邮件的发信动作
import smtplib
+
# email 用于构建邮件内容
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
-#构建邮件头
+
+# 构建邮件头
from email.header import Header
+
# 发信服务器
-smtp_server = 'smtp.qq.com'
+smtp_server = "smtp.qq.com"
# 发信方的信息:发信邮箱,QQ 邮箱授权码
-from_addr = '308711822@qq.com'
-password = 'zbpqbvcgimmrbjib'
+from_addr = "308711822@qq.com"
+password = "zbpqbvcgimmrbjib"
-def send_email(send_to_addr:str,contest_msg:str):
+
+def send_email(send_to_addr: str, contest_msg: str):
# 连接发信服务器
server = smtplib.SMTP_SSL(smtp_server)
# 建立连接--qq邮箱服务和端口号
@@ -22,31 +26,35 @@ def send_email(send_to_addr:str,contest_msg:str):
# 配置邮件正文内容
msg = MIMEMultipart()
- msg['From'] = Header('小钟同学') # 设置来自于邮件的发送者信息
- msg['To'] = Header('其他人同学') # 设置来自于邮件的接收人信息
- msg['Subject'] = Header("用户注册通知", 'utf-8') # 设置邮件主题
+ msg["From"] = Header("小钟同学") # 设置来自于邮件的发送者信息
+ msg["To"] = Header("其他人同学") # 设置来自于邮件的接收人信息
+ msg["Subject"] = Header("用户注册通知", "utf-8") # 设置邮件主题
# 邮件正文内容
- msg.attach(MIMEText(contest_msg, 'html', 'utf-8'))
+ msg.attach(MIMEText(contest_msg, "html", "utf-8"))
# 构造附件1,传送文本附件
- file_name = 'test1.txt'
- test_file_att = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file_att["Content-Type"] = 'application/octet-stream'
+ file_name = "test1.txt"
+ test_file_att = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file_att["Content-Type"] = "application/octet-stream"
test_file_att["Content-Disposition"] = f'attachment; filename="{file_name}"'
msg.attach(test_file_att)
# 构造附件1,传送文本附件
- file_name = 'test2.txt'
- test_file = MIMEText(open(file_name, 'rb').read(), 'base64', 'utf-8')
- test_file.add_header('Content-Type','application/octet-stream')
- test_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', file_name))
+ file_name = "test2.txt"
+ test_file = MIMEText(open(file_name, "rb").read(), "base64", "utf-8")
+ test_file.add_header("Content-Type", "application/octet-stream")
+ test_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", file_name)
+ )
msg.attach(test_file)
# 构造附件2,文件附件
- image_file_name = 'test.jpg'
- image_file = MIMEImage(open(image_file_name, 'rb').read())
- image_file.add_header('Content-Type', 'application/octet-stream')
- image_file.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', image_file_name))
+ image_file_name = "test.jpg"
+ image_file = MIMEImage(open(image_file_name, "rb").read())
+ image_file.add_header("Content-Type", "application/octet-stream")
+ image_file.add_header(
+ "Content-Disposition", "attachment", filename=("utf-8", "", image_file_name)
+ )
msg.attach(image_file)
server.sendmail(from_addr, send_to_addr, msg.as_string())
@@ -58,5 +66,4 @@ def send_email(send_to_addr:str,contest_msg:str):
您好,您申请的XXXX注册成功,请点击下面链接进行确认!
确认
"""
-send_email(send_to_addr='3022600790@qq.com', contest_msg=html_msg)
-
+send_email(send_to_addr="3022600790@qq.com", contest_msg=html_msg)