mail_helper.py是邮件操作包,用来发送邮件的。

 #!/usr/bin/evn python
# coding=utf-8 import smtplib
from email.mime.text import MIMEText
from traceback import format_exc
from config import const # 初始化邮件参数
smtp = const.SMTP
port = const.PORT
user = const.EMAIL_USER
passwd = const.EMAIL_PWD
email_list = const.EMAIL_LIST
err_title = const.EMAIL_ERR_TITLE def send_mail(subject, context, to_list):
'''
发送邮件
接收参数:
subject 邮件主题
context 邮件内容
to_list 接收者邮件列表,每个邮件地址用","分隔
'''
if not subject or not context or not to_list:
return '邮件发送失败,邮件主题、内容与收件人邮件都是必填项' # 初始始化邮件相关参数
email = MIMEText(context, 'html', 'utf-8')
email['To'] = to_list
email['Subject'] = subject
email['From'] = user # QQ邮箱改为ssl方式发送了
# s = smtplib.SMTP(smtp)
s = smtplib.SMTP_SSL(smtp)
try:
s.login(user, passwd)
s.sendmail(user, email_list, email.as_string())
s.close()
return None
except Exception as e:
s.close()
stacktrace = format_exc()
return '邮件发送失败,出现异常:' + str(e.args) + stacktrace + '\n' def send_error_mail(context):
'''
发送邮件
接收参数:
context 邮件内容
'''
if not context:
return '邮件内容是必填项' send_mail(err_title, context, email_list)

  send_mail()函数只需要提交邮件标题、内容和收件人列表,就可以将邮件发送出去,使用的发件人是前面配置const.py里设置的帐号,如果没有在配置里设置好对应的账号密码,邮件将会发送不成功。

  send_error_mail()函数是用来发送异常日志信息的,它默认是给log_helper.py里的异常日志记录函数error()调用,这样当代码执行时出现异常,我们第一时间就会收到这封异常邮件,然后可以针对性的去进行处理。当然如果服务器出现故障时,有可能会一下子收到非常多的邮件,被邮件服务器封掉IP的。所以一般我都会用自己的邮箱给自己发,这样万一给封了IP还是可以收到发送不成功的邮件的。另外,前面说过,api文件夹里的__init__.py和其他文件夹的这个文件有点不一样,大家可以对比一下,它会帮我们解决很多很基本的问题,特别是更新线上代码时,有时会忘记提交新建的python文件,而这个文件又被其它文件所调用,这时python初始化就会发生异常,第一时间我们就会收到提醒邮件,避免线上服务挂了也不知道的情况发生。

  send_error_mail()函数的邮件标题可以在const.py配置中进行设置(见下面参数),一般我会分开发、测试、预生产、生产等标题,这样在收到邮件时方便我们区分是那一个环境出现了故障

### 邮件服务参数 ###
# 邮件服务器
SMTP = 'smtp.qq.com'
# 邮件服务器端口
PORT = 465
# email发送账号
EMAIL_USER = 'xxxxxx@qq.com'
# email发送密码
EMAIL_PWD = 'xxxxxxxxxxxxxxxxx'
# 系统异常邮件通知地址,多个地址用逗号分隔
EMAIL_LIST = 'xxxxxx@qq.com'
# 异常邮件通知标题
# ——由于我们有开发环境、测试环境、预生产环境、生产环境等多个不同的环境,
# ——所以在发送异常通知时如果区分的话,可能就弄不清是那个环境出了问题,
# ——我们可以通过设置邮件标题为:开发、测试、预生产、生产等标签来方便区分是那个环境发送的异常通知
EMAIL_ERR_TITLE = '系统异常通知-simple-开发'

  测试用例:

#!/usr/bin/evn python
# coding=utf-8 import unittest
from common import mail_helper, except_helper class MailHelperTest(unittest.TestCase):
"""邮件操作包测试类""" def setUp(self):
"""初始化测试环境"""
print('------ini------') def tearDown(self):
"""清理测试环境"""
print('------clear------') def test(self):
mail_helper.send_mail('test', 'test', '1654937@qq.com')
except_info = except_helper.detailtrace()
mail_helper.send_error_mail('出现异常,堆栈信息:' + except_info) if __name__ == '__main__':
unittest.main()

  执行结果:

  log_helper.py是日志操作包

 #!/usr/bin/evn python
# coding=utf-8 import logging
import logging.handlers
import traceback from common import mail_helper, except_helper def info(content):
"""记录日志信息"""
if content:
logging.info(content) def error(content = '', is_send_mail = True):
"""记录错误日志信息"""
if traceback:
content = content + '\n' + traceback.format_exc() + '\n'
# 获取程序当前运行的堆栈信息
detailtrace = except_helper.detailtrace()
content = content + '程序调用堆栈的日志:' + detailtrace + '\n' logging.info(content) # 发送邮件通知相关人员
if is_send_mail:
info = mail_helper.send_error_mail(context=content)
if info: logging.info(info)

  info()函数用于记录程序执行过程中的一些信息,比如与第三方接口(最常见的是支付接口)通讯时,将提交的网址、参数和返回的结果记录下来,方便我们在需要时查看,排查出错问题;比如我们需要排查生产环境异常,定位错误信息位置时,在相关代码中间添加,然后将相关数据变量值记录下来,帮助我们定位问题所在......

  error()函数除了拥有info()函数的功能外,它在记录信息的同时,还会自动发送一封邮件到我们的邮箱。通过它放在try...except...中。

#!/usr/bin/evn python
# coding=utf-8 import logging
import os
import unittest
from common import log_helper class LogHelperTest(unittest.TestCase):
"""日志操作包测试类""" def setUp(self):
"""初始化测试环境"""
print('------ini------')
# 获取本脚本所在的上级路径(因为log_helper_text.py是在test目录下面,并不在根目录,而我们想将日志都记录在根据目录下的log目录里,所以需要获取test的上级目录)
program_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
# 初始化日志目录
log_path = os.path.join(program_path, 'log')
# 当日志目录不存在时创建日志目录
if not os.path.exists(log_path):
os.mkdir(log_path)
# 定义日志输出格式
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
filename="%s/info.log" % log_path,
filemode='a') def tearDown(self):
"""清理测试环境"""
print('------clear------') def test(self):
log_helper.info('记录代码执行的相关记录或信息') try:
result = '' / 10
except Exception as e:
log_helper.error('出现异常:' + str(e.args)) if __name__ == '__main__':
unittest.main()

  执行结果:

  random_helper.py是随机数操作包,通过里面的函数,我们可以方便快捷的获取指定大小范围的数值型随机数;指定长度的数字、大小写字母、数字与字母混合型随机数;获取uuid随机码。

 #!/usr/bin/evn python
# coding=utf-8 import random
import uuid
from common import encrypt_helper ### 定义常量 ###
# 小写字母
lowercase_letters = "abcdefghijklmnopqrstuvwxyz"
# 大写字母
majuscule = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# 数字
numbers = ""
################ def ___get_randoms(length, text):
"""
内部函数,获取指定长度的随机字符
:param length: 将要生成的字符长度
:param text: 生成随机字符的字符池
:return: 生成好的随机字符串
"""
return random.sample(text, length) def get_number(length):
"""
获取指定长度的数字,类型是字符串
:param length: 将要生成的字符长度
:return: 生成好的随机字符串
"""
return ''.join(___get_randoms(length, numbers)) def get_number_for_range(small, max):
"""
获取指定大小的整形数值
:param small: 最小数值
:param max: 最大数值
:return: 生成好的随机数值
"""
return random.randint(small, max) def get_string(length):
"""
获取指定长度的字符串(大小写英文字母+数字)
:param length: 将要生成的字符长度
:return: 生成好的随机字符串
"""
return ''.join(___get_randoms(length, lowercase_letters + majuscule + numbers)) def get_letters(length):
"""
生成随机英文字母字符串(大小写英文字母)
:param length: 将要生成的字符长度
:return: 生成好的随机字符串
"""
return ''.join(___get_randoms(length, lowercase_letters + majuscule)) def get_uuid():
"""
随机生成uuid
:return: 生成好的uuid
"""
return str(uuid.uuid4()).replace('-', '')

  因为比较简单,所以不一一说明,直接看测试用例

#!/usr/bin/evn python
# coding=utf-8 import unittest
from common import random_helper class RandomHelperTest(unittest.TestCase):
"""随机数操作包测试类""" def setUp(self):
"""初始化测试环境"""
print('------ini------') def tearDown(self):
"""清理测试环境"""
print('------clear------') def test(self):
print('获取0到100之间的随机数')
print(random_helper.get_number_for_range(0, 100))
print(random_helper.get_number_for_range(0, 100)) print('获取长度为5的数字随机码')
print(random_helper.get_number(5))
print(random_helper.get_number(5)) print('获取长度为6的英文随机码')
print(random_helper.get_letters(6))
print(random_helper.get_letters(6)) print('获取长度为6的数字与英文随机码')
print(random_helper.get_string(6))
print(random_helper.get_string(6)) print('获取uuid')
print(random_helper.get_uuid())
print(random_helper.get_uuid())
if __name__ == '__main__':
unittest.main()

  执行结果:

------ini------
获取0到100之间的随机数
54
21
获取长度为5的数字随机码
20156
58132
获取长度为6的英文随机码
BqQCZP
ybFIaB
获取长度为6的数字与英文随机码
FZfEgd
GAslRy
获取uuid
2aba0e946414434ea6b7f2e425d8b41b
52fe4545b09443a088ce460453d909fa
------clear------

  本文对应的源码下载

版权声明:本文原创发表于 博客园,作者为 AllEmpty 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

python开发QQ群:669058475(本群已满)、733466321(可以加2群)    作者博客:http://www.cnblogs.com/EmptyFS/

我的第一个python web开发框架(12)——工具函数包说明(三)的更多相关文章

  1. 我的第一个python web开发框架(41)——总结

    我的第一个python web开发框架系列博文从17年6.7月份开始写(存了近十章稿留到9月份才开始发布),到今天结束,一年多时间,想想真不容易啊. 整个过程断断续续,中间有段时间由于工作繁忙停了好长 ...

  2. 我的第一个python web开发框架(14)——后台管理系统登录功能

    接下来正式进入网站的功能开发.要完成后台管理系统登录功能,通过查看登录页面,我们可以了解到,我们需要编写验证码图片获取接口和登录处理接口,然后在登录页面的HTML上编写AJAX. 在进行接口开发之前, ...

  3. 我的第一个python web开发框架(10)——工具函数包说明(一)

    PS:原先是想直接进入功能开发,要用到什么函数时再创建,这样也容易熟悉每个函数的由来和使用方法,但考虑到这样操作,到时会经常在不同文件间切换,不好描述,容易造成混乱,所以还是使用函数库这种方式来说明. ...

  4. 我的第一个python web开发框架(5)——开发前准备工作(了解编码前需要知道的一些常识)

    中午吃饭时间到了,小白赶紧向老菜坐的位置走过去. 小白:老大,中午请你吃饭. 老菜:哈哈...又遇到问题了吧,这次得狠狠宰你一顿才行. 小白:行行行,只要您赏脸,米饭任吃,嘻嘻,我们边走边聊. ... ...

  5. 我的第一个python web开发框架(1)——前言

    由于之前经验不是很丰富,写的C#系统太过复杂,所以一直想重写,但学的越多越觉得自己懂的越少,越觉的底气不足.所以一直不敢动手,在内心深处对自己讲,要静下心来认真学习,继续沉淀沉淀.这两年多以来找各种机 ...

  6. 我的第一个python web开发框架(3)——怎么开始?

    小白与小美公司经过几次接触商谈,好不容易将外包签订了下来,准备开始大干一场.不过小白由于没有太多的项目经验,学过python懂得python的基本语法,在公司跟着大家做过简单功能,另外还会一些HTML ...

  7. 我的第一个python web开发框架(22)——一个安全小事故

    在周末的一个早上,小白还在做着美梦,就收到了小美的连环追魂call,电话一直响个不停. 小白打着哈欠拿起电话:早上好美女. 小美:出事了出事了,我们公司网站一早访问是一片空白,什么内容都没有了,你赶急 ...

  8. 我的第一个python web开发框架(8)——项目结构与RESTful接口风格说明

    PS:再次说明一下,原本不想写的太啰嗦的,可之前那个系列发布后发现,好多朋友都想马上拿到代码立即能上手开发自己的项目,对代码结构.基础常识.分类目录与文件功能结构.常用函数......等等什么都不懂, ...

  9. 我的第一个python web开发框架(9)——目录与配置说明

    和老大聊完后,小白回家接收到相关工具函数包后,就按要求开始干活,首先要做的是熟悉配置参数和了解工具函数有哪些实用的工具. 由于这个项目比较简单,所以不用创建那么多分类,只需要api.common.co ...

  10. 我的第一个python web开发框架(17)——产品管理

    这是后台管理系统最后一个功能,产品管理,它的接口与页面功能与上一章差不多. 获取产品列表接口 @get('/api/product/') def callback(): ""&qu ...

随机推荐

  1. 201521123052《Java程序设计》第1周学习总结

    1. 本周学习总结 1.认识Java,了解JVM.JRE与JDK,并下载与安装JDK: 2.设置好eclipse并使用eclipse完成简单的Java编程: 3.使用博客.码云与PTA,这些对Java ...

  2. 控制结构(8) 线性化(linearization)

    // 上一篇:管道(pipeline) // 下一篇:程序计数器(PC) "编程语言不过是一个工具,什么语言都一样","编程语言能改变人的思维,不同的语言会带给你不同的思 ...

  3. 201521123001《Java程序设计》第11周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  4. 201521123118《java程序与设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 1. finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中fi ...

  5. Python的自学之路:Python基础(一)

    声明:我写博客不是为了什么,只是为了记录自己的学习状态,学过的知识点!方便以后进行好的复习!python小白,勿喷 python环境的搭建,在这里就不细说了,这里有我的链接,可以参考一下:https: ...

  6. Struts2第三篇【Action开发方式、通配符、Struts常量、跳转全局视图、action节点默认配置】

    前言 上篇Struts博文已经讲解了Struts的开发步骤以及执行流程了-..对Struts的配置文件有了了解-..本博文继续讲解Struts在配置的时候一些值得要学习的细节- Action开发的三种 ...

  7. [android游戏开发初学]简单的游戏框架

    这两天,没事想学习游戏开发,看了一些资料之后准备开始.为了将来编码方便,先写了一个简单的游戏框架方便自己以后做练习用. 如果以后没有什么特殊的需求--比如opengl什么的,会尽量用这个简单框架来实现 ...

  8. Apache CXF入门

    CXF简介 Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了.CXF 继承了 Celtix 和 XFire 两大 ...

  9. [js高手之路] html5 canvas系列教程 - 掌握画直线图形的常用API

    我们接着上文[js高手之路] html5 canvase系列教程 - 认识canvas以及基本使用方法继续. 一.直线的绘制 cxt.moveTo( x1, y1 ): 将画笔移动到x1, y1这个点 ...

  10. MySQL数据库设计基础

    为什么需要规范的数据库设计? 什么是数据库设计? 数据库设计就是将数据库中的数据实体及这些数据实体之间的关系,进行规划和结构化的过程. 数据库设计非常重要! 数据库中创建的数据结构的种类,以及在数据实 ...