Flask框架之异常处理、请求钩子、上下文的使用
- 异常处理
- 捕获指定异常状态码
- 捕获指定异常类型
- 抛出HTTP Exception
- 请求钩子
- 概述
- 基本使用
- 请求上下文
- 概述
- 应用上下文
- current_app对象
- g对象
- 请求上下文
- request对象
- session对象
异常处理
捕获指定异常状态码
可以使用
@app.errorhandler装饰器
,定义一个异常处理函数,当程序抛出指定错误状态码的时候,就会调用该装饰器所装饰的方法
@app.route('/')
def index():
abort(500)
return 'Hello World'
@app.errorhandler(500)
def internal_server_error(e):
print(e)
return '服务器错误''
捕获指定异常类型
可以使用
@app.errorhandler装饰器
,定义一个异常处理函数,当程序抛出特定类型的异常的时候,就会调用该装饰器所装饰的方法
@app.route('/')
def index():
1 / 0
return 'Hello World'
@app.errorhandler(ZeroDivisionError)
def zero_division_error(e):
print(e)
return '除数不能为0'
抛出HTTP Exception
可以使用Flask自带的
abort函数
抛出一个给定状态代码的HTTP Exception或者指定响应错误消息
注意:抛出的状态码,只能抛出HTTP协议的错误状态码
@app.route('/')
def index():
abort(404)
return 'Hello World'
@app.route('/')
def index():
abort(500,"Internal Server Error")
return 'Hello World'
请求钩子
概述
在 Flask 中,可以使用请求钩子来在请求处理过程中注册函数,以执行一些操作。
通常客户端与服务器交互过程中,会存在一些准备工作或收尾工作需要处理,例如:
1.在请求开始时,与数据库建立连接
2.在请求过程中,进行日志记录
3.在请求结束时,与数据库断开连接
在实际应用开发中,请求钩子常被用于以下场景:
认证和授权:使用 before_request 钩子来检查用户是否已登录或具有所需的权限,并根据需要重定向或返回一个错误信息。
日志记录:使用 before_request 钩子来记录每个请求的时间、来源 IP 和调用服务等信息,以便后续分析和排错。
跨域资源共享 (CORS) 支持:使用 after_request 钩子来添加 CORS 响应头,从而允许跨域请求访问应用程序接口。
缓存管理:使用 after_request 钩子来缓存响应结果,以加快后续相同请求的响应时间并减少对后端系统的负载。
响应格式转换:使用 after_request 钩子来将响应结果转换为特定的数据格式,如 JSON 或 XML。
基本使用
总之,请求钩子提供了一种优雅而简单的方式来执行与请求相关的辅助操作,可以使代码更易于维护和扩展。
Flask支持四种请求钩子:
before_first_request
before_request
after_request
teardown_request
from flask import Flask
app = Flask(__name__)
# 第一次请求之前调用,可以在方法内部做一些初始化操作
@app.before_first_request
def before_first_request():
print("before_first_request")
# 在每一次请求之前调用,此时已经有请求,可能在方法里做请求校验
# 如果请求校验不成功,可以直接在方法中进行响应,直接return之后就不会执行视图函数
@app.before_request
def before_request():
print("before_request")
# return "fail"
# 在每次请求后执行,前提是没有抛出错误
# 接受一个参数:视图函数作出的响应
# 可以对响应值在返回之前做统一修改处理
@app.after_request
def after_request(response):
print("after_request")
response.headers["Content-Type"] = "application/json"
response.headers["Token"] = "Python"
return response
# 请每一次请求之后都会调用,接受一个参数:服务器出现的错误信息
@app.teardown_request
def teardown_request(err):
print("teardown_request")
@app.route('/')
def index():
return 'index'
if __name__ == '__main__':
app.run(debug=True)
第1次请求时的打印:
before_first_request
before_request
after_request
teardown_request
第2次请求时的打印:
before_request
after_request
teardown_request
请求上下文
概述
在 Flask 中,上下文分为两种类型:
1.应用程序上下文 (app_context):
:表示整个 Flask 应用程序的状态,在应用程序启动之后一直存在于进程内。它提供了一种方便的方法来访问应用程序配置、数据库连接、日志记录、模板引擎等全局状态,能够在不同请求之间共享数据。
2.请求上下文 (request_context):
表示每个请求处理过程中的状态,包括 HTTP 请求对象、HTTP 响应对象等。
这两种上下文都可以使用上下文管理器(with 语句)手动创建和释放,也可以通过 Flask 中提供的装饰器(例如 @app.route 和 @app.before_request)实现自动创建和释放。
在 Flask 应用程序中,可以通过以下方式访问上下文:
在Flask程序未运行的情况下,调试代码时需要使用
current_app、g、request、session
等对象时,需要通过with语句进行使用
from flask import Flask, g, request, current_app
app = Flask(__name__)
# 使用 app_context 上下文管理器
with app.app_context():
# 可以访问 app.config 配置参数
print(current_app.config)
# 使用 request_context 上下文管理器
with app.test_request_context('/'):
# 可以访问 request 和 g 对象
request.args['key'] = 'value'
g.my_value = 22
from flask import Flask
app = Flask('')
app.my_variable = 'my_variable'
from flask import current_app
with app.app_context():
print(current_app.my_variable)
应用上下文
在 Flask 中,应用程序上下文(app_context)是一个全局对象,表示整个应用程序的状态,在应用程序启动后一直存在于进程内。它提供了一种方便的方法来访问应用程序配置、数据库连接、日志记录、模板引擎等全局状态,能够在不同请求之间共享数据。
current_app对象
和 g 对象
都是 Flask 提供的全局对象,用于在不同请求之间共享数据。它们的作用比较相似,但用途有所不同:
current_app对象
它是应用程序上下文中的一个全局对象,是当前请求应用程序实例的引用。它提供了访问Flask应用程序的全局状态和配置参数的方法。需要注意的是,只有在 Flask 应用处于处理请求的情况下才能使用current_app对象。否则,需要使用应用程序上下文来手动创建应用程序上下文。
g对象
它是请求上下文中的一个全局对象,它可以用于存储在多个请求之间共享的全局状态。g 通常是用来存储当前请求中的临时数据以便其他函数或中间件能够访问和修改。g 对象是线程安全的,在不同的请求间互不影响。
current_app对象
应用程序上下文,用于存储应用程序中的变量,可以通过
current_app.name
打印当前app的名称,也可以在current_app中存储一些变量
应用程序上下文可以使用 Flask.app_context() 上下文管理器手动创建,或者在 Flask 应用中自动创建。
from flask import Flask, current_app
app = Flask(__name__)
# 使用app_context() 上下文管理器创建了一个新的应用程序上下文,并在其中通过current_app.config获取了当前应用程序的调试配置值
with app.app_context():
print(current_app.config["DEBUG"])
注意:current_app就是当前运行的flask app,在代码不方便直接操作flask的app对象时,操作current_app就等价于操作flask app对象
from flask import Flask, current_app
app1 = Flask(__name__)
app2 = Flask(__name__)
# 为每个应用创建一个变量,并在后续视图中使用
app1.my_variable = 'app1 my_variable'
app2.my_variable = 'app2 my_variable'
@app1.route('/')
def test1():
return current_app.my_variable
@app2.route('/')
def test2():
return current_app.my_variable
配置环境变量
1.pycharm
2.命令方式
export FLASK_APP=main:app1
flask run
g对象
g作为flask程序全局的一个临时变量,充当中间媒介的作用,可以通过它在一次请求调用的多个函数间传递一些数据。每次请求都会重设这个变量。
from flask import Flask, g
app = Flask(__name__)
def user():
name = g.name
age = g.age
print('name={} age={}'.format(name, age))
return {"name": name, "age": age}
@app.route('/')
def get_user():
g.name = "Python"
g.age = 20
return user()
请求上下文
Flask 的请求上下文是一个存在于每个请求期间的变量容器。它提供了一种方便的方法来访问请求相关的信息和对象,例如请求头、URL 参数、表单数据、Session 对象等。
在flask中,请求上下文对象有:request
、session
1.request对象
它存储了关于客户端(如浏览器)发出的HTTP请求的信息,比如请求的URL、POST数据、HTTP头等。代码可以通过访问request对象来访问这些信息。
2.Session对象
它存储了与特定用户相关的信息,并将这些信息跨越多个页面请求进行持久化。一旦会话(session)在服务器端创建,会生成一个唯一标识符,也被称为“session ID”。每次向服务器发送请求时,客户端都会包含该ID,从而使得服务器能够识别当前请求属于哪个会话。 然后就可以通过访问session对象来读取或修改与特定用户相关的信息。
request对象
request 对象代表当前 HTTP 请求,包含了请求方法、URL、请求头、表单数据、查询参数等请求相关的信息,通过 Flask.request 全局变量可以访问到该对象。通常可以使用
request.args
来获取请求 URL 中的参数,使用request.form
获取 POST 请求中提交的数据。
# 获取get请求的参数
user = request.args.get('user')
session对象
session对象它可以在不同请求之间存储和共享数据,并被浏览器端的cookie技术所支持。主要用来记录请求会话中的信息,针对用户信息
# 记录用户信息
session['name'] = user.name
# 获取用户信息
session.get('name')