flask 实现简易的图片服务器

659 阅读1分钟

项目结构

├─flaskr
│  ├─blueprint
|  |  ├─__init__.py
│  │  └─image.py
│  └─__init__.py
├─static
│  └─images
├─app.py
├─config.py
├─readme.md
├─requirements.txt
└─venv

在 config.py 内配置 (根据自己需求)

# 图片上传目录
IMAGE_UPLOAD_FOLDER = "static/images/"

# 限制图片仅 2M
MAX_CONTENT_LENGTH = 2 * 1024 * 1024

# 根目录
ROOT_PATH = os.path.dirname(__file__)

在 image.py 里写上

import os
from uuid import uuid4
from flask import (
    Blueprint,
    abort,
    jsonify,
    request,
    current_app,
    send_from_directory,
)
from werkzeug.utils import secure_filename

img = Blueprint("image", __name__, url_prefix="/image")

ALLOWED_EXTENSIONS = set(["png", "jpg"])


# 是否允许某个格式图片上传
def allowed_image(file_name):
    return (
        "." in file_name
        and file_name.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS  # noqa 501
    )


@img.route("/upload", methods=["post"])
def upload_image():
    f = request.files["image"]

    if f is not None and allowed_image(f.filename):  # 判断是否是允许上传的文件类型

        # 获取某个文件名的安全文件名, 因为 “永远不要信任用户输入”
        fname = secure_filename(f.filename)

        ext = fname.rsplit(".", 1)[1]  # 获取文件后缀

        u = uuid4().hex
        new_file_name = f"{u}.{ext}"  # 重写文件名

        root = current_app.config["ROOT_PATH"] # config.py 中的配置
        dir = current_app.config["IMAGE_UPLOAD_FOLDER"]

        # 保存图片到目录
        f.save(os.path.join(os.path.join(root, dir), new_file_name))

        return jsonify(
            {
                "code": 810,
                "msg": "图片上传成功",
                "name": new_file_name,
                "id": u,
            }
        )
    else:
        return jsonify(
            {
                "code": 811,
                "msg": "图片上传失败",
            }
        )


# 根据 id 获取相应图片
@img.route("/<file_name>", methods=["GET"])
def get_image(file_name):
    root = current_app.config["ROOT_PATH"]
    dir = current_app.config["IMAGE_UPLOAD_FOLDER"]

    try:
        return send_from_directory(os.path.join(root, dir), file_name)
    except FileNotFoundError:
        abort(404)

在 flaskr/blueprint/__init__.py 里封装注册方法

from flask import Flask
from .image import img


def blueprint_init(app: Flask):
    # 注册蓝图
    app.register_blueprint(img)

在 flaskr/__init__.py 里

import os
from flask import Flask
from .blueprint import blueprint_init


def create_app():
    # 创建 flask 实例
    app = Flask(__name__, instance_relative_config=True)  
    app.config.from_object("config")

    # 创建静态文件目录
    image_upload_folder = app.config["IMAGE_UPLOAD_FOLDER"]

    if not os.path.exists(image_upload_folder):
        os.makedirs(image_upload_folder)

    blueprint_init(app)  # 初始化蓝图

    return app

在 app.py 里

from flaskr import create_app

app = create_app()


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=9000)