flask学习1-基础
-
- 1.环境安装
- 2.使用
-
- [2.1 创建一个应用](#2.1 创建一个应用)
- [2.2 路由](#2.2 路由)
- [2.3 HTTP 方法](#2.3 HTTP 方法)
- [2.4 请求对象](#2.4 请求对象)
- [2.5 文件上传](#2.5 文件上传)
- [2.6 Cookie](#2.6 Cookie)
- [2.7 重定向和错误](#2.7 重定向和错误)
- [2.8 返回json](#2.8 返回json)
- [2.9 会话](#2.9 会话)
- [2.10 日志](#2.10 日志)
- 2.11 WSGI 中间件中的挂钩[¶](https://flask.palletsprojects.com/zh-cn/stable/quickstart/#hooking-in-wsgi-middleware))
- [2.12 使用 Flask 扩展](#2.12 使用 Flask 扩展)
- [2.13 部署到 Web 服务器](#2.13 部署到 Web 服务器)
- [2.14 flask、wsgi服务器、wsgi中间件、nginx的关系](#2.14 flask、wsgi服务器、wsgi中间件、nginx的关系)
在线的省的自己装环境,选择python创建项目: Python: main.py - MarsCode
有2网站学flask:Flask 应用_w3cschool
1.环境安装
# 创建虚拟环境
$ mkdir testflask
$ cd testflask
$ python3 -m venv .venv
# 激活虚拟环境
$ . .venv/bin/activate
# 安装 Flask
pip install Flask
2.使用
2.1 创建一个应用
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
启动项目 --debug 调试模式,不要在生产用
flask --app hello run --host=0.0.0.0
访问:https://5dmoq7jq-pou9c8l4-cnsn6oy3hfgo.vcc3.mcprev.cn
或者本地访问:curl http://localhost:5000

当然创建项目有可以选择flask的,我选择的是python,用做练习flask的安装使用。

2.2 路由
# 路由也可以用add_url_rule绑定,访问/ak绑定到了hello_worldd函数,其他的都是可选值
def hello_worldd():
return "<p>sssfsHello, World!</p>"
app.add_url_rule('/ak', 'hello', hello_worldd)
支持转换:
@app.route('/post/<int:post_id>')
@app.route('/path/<path:subpath>')
转换器类型:
string |
(默认)接受任何不带斜杠的文本 |
---|---|
int |
接受正整数 |
float |
接受正浮点值 |
path |
like 但也接受斜杠string |
uuid |
接受 UUID 字符串 |
2.3 HTTP 方法
@app.route('/login', methods=['GET', 'POST'])
# url_for使用
def hello_user(name):
if name =='admin':
return redirect(url_for('hello_admin'))
else:
return redirect(url_for('hello_guest', guest = name))
# 静态文件
url_for('static', filename='style.css')
# Jinja2 模板引擎
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', person=name)
/templates
/hello.html
<!doctype html>
<title>Hello from Flask</title>
{% if person %}
<h1>Hello {{ person }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
# ---
# 当 Flask 接收到一个请求时,它会创建一个请求上下文(Request Context),并将其绑定到当前线程。
# 在请求处理期间,request 和 session 等对象会被绑定到这个上下文。
# 由于每个线程都有自己的上下文,因此即使在多线程环境中,request 和 session 也能正确地返回当前请求的数据。
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe'))
# 上下文结束后,request 对象不再可用
try:
request.path
except RuntimeError:
print("Request context is no longer available.")
2.4 请求对象
要访问表单数据
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'],
request.form['password']):
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template('login.html', error=error)
要访问在 URL () 中提交的参数,您可以使用以下属性:?key=value
searchword = request.args.get('key', '')
2.5 文件上传
from flask import request
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/uploaded_file.txt')
...
2.6 Cookie
# 取
from flask import request
request.cookies.get('username')
# 存
from flask import make_response
resp = make_response(render_template(...))
resp.set_cookie('username', 'the username')
2.7 重定向和错误
from flask import abort, redirect, url_for
@app.route('/')
def index():
return redirect(url_for('login'))
@app.route('/login')
def login():
abort(401)
this_is_never_executed()
from flask import render_template
# 全局拦截定义错误页面 404
@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
2.8 返回json
如果您从视图返回dict or list ,它将转换为 JSON 响应。 dict 或 list 中的所有数据都必须是 JSON 可序列化。
@app.route("/me")
def get_current_user():
user = {
"username": "example_user",
"theme": "dark",
"image": "default.jpg"
}
return user
@app.route("/users")
def get_all_users():
# 假设这里有一些逻辑来获取所有用户
users = [
{"id": 1, "username": "user1"},
{"id": 2, "username": "user2"},
{"id": 3, "username": "user3"},
]
# users = get_all_users()
# return [user.to_json() for user in users]
return users
2.9 会话
python
from flask import session
# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
@app.route('/')
def index():
if 'username' in session:
return f'Logged in as {session["username"]}'
return 'You are not logged in'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))
访问:http://localhost:5000/login
生成密钥
python -c 'import secrets; print(secrets.token_hex())'
关于基于 cookie 的会话的说明:Flask 将采用您放入 session 对象并将它们序列化为 cookie。如果您发现一些 值不会在请求之间保留,Cookie 确实已启用,并且您 没有收到明确的错误消息,请检查页面中 cookie 的大小 响应与 Web 浏览器支持的大小进行比较。
2.10 日志
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
2.11 WSGI 中间件中的挂钩¶
要将 WSGI 中间件添加到您的 Flask 应用程序,请包装应用程序的 attribute。例如,要应用 Werkzeug 的中间件来运行 Nginx 后面:wsgi_app
nginx
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:5000; # 将请求转发到 Flask 应用
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
python
from flask import Flask
from werkzeug.middleware.proxy_fix import ProxyFix
app = Flask(__name__)
@app.route('/')
def index():
return "Hello, World!"
# 包装 wsgi_app,修复请求头
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1, x_prefix=1)
if __name__ == '__main__':
app.run()
x_for=1
:修复X-Forwarded-For
头,获取客户端的真实 IP 地址。x_proto=1
:修复X-Forwarded-Proto
头,确保 Flask 应用知道请求是通过 HTTPS 发起的
2.12 使用 Flask 扩展
查找扩展
Flask 扩展通常命名为 "Flask-Foo" 或 "Foo-Flask"。您可以 在 PyPI 中搜索标记为 Framework :: Flask 的包。
使用扩展
请查阅每个扩展的文档,了解安装、配置、 和使用说明。通常,扩展会拉取自己的 配置 from ``和 are 在初始化期间传递应用程序实例。例如 一个名为 "Flask-Foo" 的扩展可以像这样使用:
from flask_foo import Foo
foo = Foo()
app = Flask(__name__)
app.config.update(
FOO_BAR='baz',
FOO_SPAM='eggs',
)
foo.init_app(app)
构建扩展
虽然 PyPI 包含许多 Flask 扩展,但您可能找不到 适合您需求的扩展。如果是这种情况,您可以创建 您自己的,并将其发布供其他人使用。阅读 Flask 扩展开发 以开发您自己的 Flask 扩展。
2.13 部署到 Web 服务器
WSGI服务器有内置的HTTP服务器。但是,专用的HTTP服务器可能更安全、更高效或功能更强大。将HTTP服务器放在WSGI服务器的前面称为"反向代理"。
2.14 flask、wsgi服务器、wsgi中间件、nginx的关系
Flask
- Flask 是一个轻量级的 WSGI Web 框架,用于开发 Web 应用。
- Flask 应用本质上是一个 WSGI 应用,可以通过任何符合 WSGI 标准的服务器运行。
WSGI 服务器(如 Gunicorn 或 uWSGI)
- WSGI 服务器是运行 Flask 应用的后端服务,负责处理 Python 应用的请求和响应。
- 常用的 WSGI 服务器包括 Gunicorn 和 uWSGI:
- Gunicorn:轻量级、易于配置,适合快速部署。
- uWSGI:功能丰富,支持多进程、多线程和异步模式,适合高性能需求。
Nginx
- Nginx 是一个高性能的 Web 服务器和反向代理服务器。
- 在部署 Flask 应用时,Nginx 通常作为反向代理服务器,将客户端的 HTTP 请求转发到后端的 WSGI 服务器(如 Gunicorn 或 uWSGI),并处理静态文件、SSL/TLS 终止等
WSGI 中间件
- WSGI 中间件是位于 WSGI 服务器和 Flask 应用之间的可调用对象,用于在不修改应用代码的情况下添加功能
部署流程
步骤 1:运行 Flask 应用
-
使用 WSGI 服务器(如 Gunicorn 或 uWSGI)启动 Flask 应用。
-
示例:使用 Gunicorn 启动 Flask 应用:
bash复制
bashgunicorn -w 4 -b 0.0.0.0:8000 app:app
其中
-w 4
表示启动 4 个工作进程,-b 0.0.0.0:8000
表示绑定到 8000 端口。
步骤 2:配置 Nginx 作为反向代理
-
Nginx 配置文件示例:
nginx复制
nginxserver { listen 80; server_name yourdomain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static { alias /path/to/your/static/files; } }
proxy_pass
将请求转发到后端的 WSGI 服务器。location /static
用于处理静态文件。
步骤 3:启动和管理服务
-
启动 Nginx 并确保其配置生效:
bash复制
bashsudo systemctl restart nginx
-
确保 WSGI 服务器(如 Gunicorn 或 uWSGI)在后台持续运行。
WSGI 中间件的作用
-
WSGI 中间件是位于 WSGI 服务器和 Flask 应用之间的可调用对象,用于在不修改应用代码的情况下添加功能。
-
例如,可以使用
ProxyFix
中间件修复在 Nginx 反向代理环境下可能出现的请求头问题:pythonfrom werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app)
这样可以确保 Flask 应用能够正确处理通过 Nginx 转发的请求。
总结
- Flask 是 WSGI 应用,负责处理业务逻辑。
- WSGI 服务器(如 Gunicorn 或 uWSGI)运行 Flask 应用,处理 Python 请求。
- Nginx 作为反向代理,处理静态文件、SSL/TLS 终止,并将动态请求转发到 WSGI 服务器。
- WSGI 中间件 用于在 WSGI 服务器和 Flask 应用之间添加额外功能,如请求头修复。
通过这种架构,可以实现高性能、高可用的 Flask 应用部署。