首页 > 编程语言 >Python中HTTPException(基于werkzeug.exceptions包)

Python中HTTPException(基于werkzeug.exceptions包)

时间:2024-01-30 17:25:23浏览次数:32  
标签:返回 body None code get Python self werkzeug exceptions

  当我们在开发HTTP服务时(接口服务),由于很多从内部引发的 Python 异常,会触发标准 HTTP 非 200 响应的视图。为了让前端有着更好的视图体验(如果因为内部异常,会返回给前端/调用方更好的一个页面/返回)。对于我们来说,给予调用方一个固定的返回格式时非常重要的(因此通过HTTPException来固定当发生异常、成功返回时等场景下发送给请求方的格式)。

  本文使用的werkzeug版本为3.0.x,官方文档:HTTP 异常 — 工具文档 (3.0.x)

1、HTTPException详解

  根据源码中类描述:所有 HTTP 异常的基类。这个异常可以被称为 WSGI应用程序呈现默认错误页面,或者您可以捕获子类它独立并呈现更好的错误消息。我们可以认知到这个类其实是一种模板模式(定义一个操作中的算法的骨架,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤),HTTPException类中定义好了大部分返回形式以及结构,作为其子类只用重写其中的某些关键方法,就可以完成定制化输出。

 1.1、类属性

  HTTPExceptuon的类属性有两个:

  • code:状态码
  • description:状态描述

  这两个类属性用于告知 前端/调用方 当前服务的状态以及描述,其中code将会被设置为HTTP返回状态码(因此最好遵循HTTP状态码规则)。而description则是会放置在返回的html页面的描述中。

 1.2、类方法

  前面有说到HTTPException其实类似于模板模式,其中它已经写好了大部分方法用于更好的返回给前端页面,我们将解释其中的一些方法:

get_description():

  用于将类属性description转换为<p></p>标签包裹结构(也就是HTML结构)用于被其他方法调用

get_body():

  返回给调用方的实际展示。在源码中这是一段HTML页面视图,如下图

   我们从图中可以看到该方法默认返回的是一个HTML页面,从代码中可以看到返回的内容包括了状态码以及状态码的描述(这里的self.name是根据code获取得到的http包中的描述),以及一些其他的信息。这个方法就是子类实现中需要重点重写的方法,因为get_body()方法的返回值就是调用方接收到的主要信息。

get_headers():

  用于设置返回请求的返回头,下图是源码实现:

   从源码中可以看到其实这个方法就是在设置返回头中的header内容使用[(key,value),]的方式,给返回头中注入内容。由于源码中get_body()方法返回的是一个html页面,因此这里返回头中设置的也是"text/html",如果我们的get_body()返回的是一个json格式,那么我们就需要同时重写这个方法,将返回值设定为[('Content-Type', 'application/json; charset=utf-8')]。

 ...

2、自定义异常类型

   从上一节中我们了解到,其实我们只需要重写一个HTTPException的子类,并重写重要的方法(主要是get_body(),get_headers()),即可得到一个我们自己的自定义异常类基类(其实这不仅仅只作为异常类,如果我们的code设置为200,也可以看成是一种格式化出参的包装类)。

  下面我们以返回一个json对象作为异常值的返回,来构建一个自定义异常类:

import json
from werkzeug.exceptions import HTTPException
from typing_extensions import override


class APIException(HTTPException):
    """这个类由Flask监听并返回响应的错误代码
    1. 为了返回特定的body信息, 需要重写get_body;
    2. 为了指定返回类型, 需要重写get_headers.
    3. 为了接收自定义的参数, 重写了__init__;
        data: 放在返回值中的结构
    4. 同时定义了类变量作为几个默认参数.
        code: HTTP状态码, 需要遵守http常规约定,
        error_code: 表示自定义异常code, 用于自己排除错
    """
    data = None   # 默认为None, 子类可以不用设置

    # 自定义需要返回的信息,在初始化完成并交给父类
    def __init__(self, message=None, code=None, error_code=None, data=None):
        if code:
            self.code = code
        if error_code:
            self.error_code = error_code
        if data:
            self.data = data
        if message:
            self.message = message
        super(APIException, self).__init__(message, None)

    @override
    def get_body(self, environ=None, scope=None):
        """ 返回的内容将会返回给前端.
        """
        body = dict(
            message=self.message,
            error_code=self.error_code,
            data=self.data
        )
        text = json.dumps(body)
        return text

    @override
    def get_headers(self, environ=None, scope=None):
        """Get a list of headers. 返回给前端表示数据接收方式为json
        """
        return [('Content-Type', 'application/json; charset=utf-8')]

  我们自己创建了一个APIException类,其中data是放在返回的json中,当抛出这个异常时,我们会以json格式返回(内容看get_body()方法)。

  接下来我们就可以基于这个APIException类设置更多的不同异常类,比如我下面创建了三个类:

class ValidateFailed(APIException):
    """验证出现错误
    """
    code = 500


class ServiceFailed(APIException):
    """调用其他服务器时, 服务器返回错误错误
    error_code=9901: 表示xxx服务器出现异常
    error_code=9902: 表示xxx服务器出现异常
    """
    code = 500


class Success(APIException):
    code = 200
    message = 'success'
    error_code = 0

  我们这里创建了三个基于APIException(我们自己创建的异常基类),我们在类上就已经定义好了code(HTTP状态码),因此在抛出此异常时我们只用传递data,message等参数即可(Success什么都不用传)。下面是使用样例:

....

@app.route('/success', methods=["POST"]) def receive_quality_info(): return Success(data=["a", "s"]) @app.route('/validateFailed', methods=["POST"]) def receive_failure_info(): raise ValidateFailed(error_code=9901, message='测试')

  

3、自带错误类

  werkzeug.exceptions包中的HTTPException文件中,其实已经为我们封装好了一些常见常用的异常类。包括有:

  • BadRequest(400错误类):服务无法处理  
  • Unauthorized(401错误类):资源无权访问
  • Forbidden(403错误类): 没有所请求资源的权限但已通过身份验证
  • MethodNotAllowed(405错误类):请求方法错误

  上述的一些常见错误类都可以直接使用import导入使用。实际上从源码中看这些类的编写模式与上述说的也几乎一样,基本是重新定义类属性code,description,并重写get_headers方法等,这样在运行时就可以返回指定的错误类型以及描述。

 

标签:返回,body,None,code,get,Python,self,werkzeug,exceptions
From: https://www.cnblogs.com/CircleWang/p/17997268

相关文章

  • python之常用标准库-log
    log级别:debug(),info(),warning(),error()andcritical()5个级别,最低为debug,最高位criticallog标准输出格式:%(name)sLogger的名字%(levelno)s数字形式的日志级别%(levelname)s文本形式的日志级别%(pathname)s调用日志输出函数的模块的完整......
  • Python 在Windows上监控Linux日志
    importparamikoimporttimedefmonitor_linux_log(linux_ip,username,password,log_file):client=paramiko.SSHClient()client.set_missing_host_key_policy(paramiko.AutoAddPolicy())client.connect(linux_ip,username=username,password=passwo......
  • [-001-]-Python语言的GUI编程工具包之PyQt5初步认识
    一、PyQt5的QtWidgets介绍PyQt5的QtWidgets模块包含了很多类,用于创建GUI应用程序的各种控件和窗口部件。其中一些主要的类包括:QApplication:应用程序类,负责管理应用程序的控制流程和事件循环QMainWindow:主窗口类,提供了一个应用程序的主界面QWidget:窗口部件类,是所有用户界面......
  • windows上使用python2.7获取svn info,中文路径乱码问题
    #-*-coding:utf-8-*-from__future__importunicode_literalsimportsubprocessimportcmdimportosos.environ['LANG']='en_US.UTF-8'classSVNCommand(cmd.Cmd):defdo_svninfo(self,folder_path):#构建svninfo命令......
  • 100个python模块
    1.NumPy-数值计算扩展库。提供高效的多维数组对象和用于处理这些数组的工具。http://www.numpy.org/2.SciPy-科学计算库。构建在NumPy之上,用于科学与技术计算。https://www.scipy.org/3.Pandas-数据分析与操作库。提供高性能易用的数据结构和数据分析工具。http://panda......
  • Python正则表达式之: (?P<name>…)
    importres="2023-12-2314:34:56|liming|20230789"parren="(?P<time>^\d+-\d+-\d+\s\d+:\d+:\d+)\|(?P<name>[\w]+)\|(?P<number>\d+)$"g=re.search(parren,s)>>>g.groupdict(){'time':'2......
  • python获取表格数据总结
    获取表格内容:图片中首先import了两个模块,一个os一个openyxl,然后指定表格路径,打开表格。os:这里os在Python中,os.chdir()方法用于改变当前的工作目录。工作目录是指当前正在执行的脚本所在的目录。通过使用os.chdir()方法,我们可以在脚本执行过程中切换到不同的目录。openy......
  • python之常用标准库-hashlib
    这个模块比较简单,直接上1#!/usr/bin/python2importhashlib3hash=hashlib.sha384()#支持md5/sha1/sha224/sha256等,用法一致4hash.update(b'test')5print(hash.digest())#二进制hash6print(hash.hexdigest())#十六进制hashViewCode ......
  • python之常用标准库-json/pickle/shelve
    json,用于各个平台语言的字符串和python数据类型间进行转换json的方法:dumps,loads,dump,loadpickle-用于python特有的类型(字符串,列表,字典,集合等)和python的数据类型间进行转换pickle的方法:dumps,loads,dump,load,但是都是以二进制存储shelve,是一个简单的k,v将内存数据通过......
  • Python计算两图相似性-像素匹配(pixelmatch)
    1、简介GitHub:https://github.com/whtsky/pixelmatch-py 2、代码fromPILimportImagefrompixelmatch.contrib.PILimportpixelmatchimg_a=Image.open("WD1.png").resize((1920,1080))img_b=Image.open("WD2.png").resize((1920,1080))img......