Python Flask快速搭建Web服务

Flask是Python最流行的轻量级Web框架,核心简洁、扩展灵活。不管是快速写个API服务还是搭建小型Web应用,Flask都是很好的选择。这篇文章从安装到RESTful API,快速过一遍Flask的核心功能。

安装

pip install flask

最小应用

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello, Flask!"

if __name__ == "__main__":
    app.run(debug=True)
$ python app.py
 * Running on http://127.0.0.1:5000

debug=True开启调试模式,代码修改后自动重载,报错时显示详细信息(生产环境一定要关掉)。

路由

# 基本路由
@app.route("/about")
def about():
    return "About page"

# 动态路由
@app.route("/user/<username>")
def user_profile(username):
    return f"User: {username}"

# 指定类型
@app.route("/post/<int:post_id>")
def show_post(post_id):
    return f"Post #{post_id}"

# 支持的转换器:string(默认), int, float, path, uuid

# 指定HTTP方法
@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST":
        return do_login()
    return show_login_form()

请求处理

from flask import request

@app.route("/search")
def search():
    # 查询参数: /search?q=python&page=1
    keyword = request.args.get("q", "")
    page = request.args.get("page", 1, type=int)
    return f"Search: {keyword}, page: {page}"

@app.route("/submit", methods=["POST"])
def submit():
    # 表单数据
    name = request.form.get("name")
    email = request.form.get("email")
    return f"Received: {name}, {email}"

@app.route("/upload", methods=["POST"])
def upload():
    # 文件上传
    file = request.files.get("file")
    if file:
        file.save(f"./uploads/{file.filename}")
        return "Upload OK"
    return "No file", 400

JSON响应

写API时最常用的就是JSON响应:

from flask import jsonify, request

@app.route("/api/users", methods=["GET"])
def list_users():
    users = [
        {"id": 1, "name": "Alice", "email": "alice@example.com"},
        {"id": 2, "name": "Bob", "email": "bob@example.com"},
    ]
    return jsonify({"code": 0, "data": users})

@app.route("/api/users", methods=["POST"])
def create_user():
    data = request.get_json()
    if not data or "name" not in data:
        return jsonify({"code": 400, "msg": "name is required"}), 400

    # 这里实际项目中会写入数据库
    new_user = {
        "id": 3,
        "name": data["name"],
        "email": data.get("email", "")
    }
    return jsonify({"code": 0, "data": new_user}), 201

模板渲染

Flask内置Jinja2模板引擎。在templates/目录下放HTML文件:

templates/index.html

<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body>
    <h1>{{ title }}</h1>
    <ul>
    {% for item in items %}
        <li>{{ item.name }} - {{ item.price }}元</li>
    {% endfor %}
    </ul>
</body>
</html>
from flask import render_template

@app.route("/products")
def products():
    items = [
        {"name": "键盘", "price": 299},
        {"name": "鼠标", "price": 99},
    ]
    return render_template("index.html", title="商品列表", items=items)

错误处理

from flask import abort

@app.route("/api/users/<int:uid>")
def get_user(uid):
    user = find_user_by_id(uid)
    if user is None:
        abort(404)
    return jsonify(user)

# 自定义错误处理
@app.errorhandler(404)
def not_found(error):
    return jsonify({"code": 404, "msg": "Not Found"}), 404

@app.errorhandler(500)
def server_error(error):
    return jsonify({"code": 500, "msg": "Internal Server Error"}), 500

Blueprint模块化

项目大了之后用Blueprint拆分模块:

# api/user.py
from flask import Blueprint, jsonify

user_bp = Blueprint("user", __name__, url_prefix="/api/user")

@user_bp.route("/list")
def user_list():
    return jsonify({"users": []})

@user_bp.route("/<int:uid>")
def user_detail(uid):
    return jsonify({"id": uid, "name": "Alice"})
# app.py
from flask import Flask
from api.user import user_bp

app = Flask(__name__)
app.register_blueprint(user_bp)

完整的API示例

把上面的知识点串起来,做一个简单的待办事项API:

from flask import Flask, jsonify, request, abort

app = Flask(__name__)

todos = []
next_id = 1

@app.route("/api/todos", methods=["GET"])
def list_todos():
    return jsonify({"code": 0, "data": todos})

@app.route("/api/todos", methods=["POST"])
def add_todo():
    global next_id
    data = request.get_json()
    if not data or "title" not in data:
        return jsonify({"code": 400, "msg": "title required"}), 400

    todo = {
        "id": next_id,
        "title": data["title"],
        "done": False
    }
    next_id += 1
    todos.append(todo)
    return jsonify({"code": 0, "data": todo}), 201

@app.route("/api/todos/<int:tid>", methods=["PUT"])
def update_todo(tid):
    data = request.get_json()
    for todo in todos:
        if todo["id"] == tid:
            todo["done"] = data.get("done", todo["done"])
            todo["title"] = data.get("title", todo["title"])
            return jsonify({"code": 0, "data": todo})
    abort(404)

@app.route("/api/todos/<int:tid>", methods=["DELETE"])
def delete_todo(tid):
    global todos
    todos = [t for t in todos if t["id"] != tid]
    return jsonify({"code": 0, "msg": "deleted"})

if __name__ == "__main__":
    app.run(debug=True, port=5000)

小结

Flask的设计哲学是微框架——核心只提供路由和请求处理,其他功能通过扩展实现。入门容易、灵活度高,适合API服务和中小型Web应用。如果项目复杂度上来了,可以考虑加上Flask-SQLAlchemy、Flask-Migrate、Flask-JWT等扩展,或者直接换Django。