Flask API 使用 Visual Studio Code 開發環境

使用 Flask 建立常見的 API 傳輸模式

預計展示傳輸 json、圖片等

最後完成簡易的圖片瀏覽器

本文sourceCode v1

虛擬環境

安裝 virtualenv (若沒有安裝)

pip3 install virtualenv

建立

virtualenv flaskEnv

指定版本建立

virtualenv venv --python=python3.6

專案底下會出現 flaskEnv 資料夾,開啟 vs Code 會偵測到該環境

安裝套件

pip3 install flask

GET 接收資料

from flask import Flask, escape, request

app = Flask(__name__)
app.config["DEBUG"] = True
app.config['SECRET_KEY'] = 'secret!'


@app.route('/')
def hello():
    name = request.args.get("name", "World")
    return f'Hello, {escape(name)}!'

選擇 Flask 編譯

改為 run.py

編譯成功

打開瀏覽器輸入網址: http://127.0.0.1:5000/?name=david

POST 傳送 JSON 資料

from flask import Flask, escape, request,jsonify
import json
import os
import time
app = Flask(__name__)
app.config["DEBUG"] = True
app.config['SECRET_KEY'] = 'secret!'

@app.route("/userPhoto", methods=['POST', "GET"])
def userPhoto():
    jsondata = json.loads(request.values['my_data'])
    jsondata['time'] = str(time.time())
    return jsonify(jsondata)

使用 postman 傳送資料測試

POST 傳送 JSON 資料與圖片

接收使用者傳送過來之圖片,並且存至指定資料夾內(my_data 中的 name)

from flask import Flask, escape, request,jsonify
import json
import os
import time
app = Flask(__name__)
app.config["DEBUG"] = True
app.config['SECRET_KEY'] = 'secret!'

@app.route("/userPhoto", methods=['POST', "GET"])
def userPhoto():
    jsondata = json.loads(request.values['my_data'])
    jsondata['time'] = str(time.time())
    img = request.files.get('file')
    # 使用時間戳記當作檔案名稱
    fileName = str(time.time())
    # 檢查資料夾是否存在
    if not os.path.isdir("photo/"):
        os.mkdir("photo/")
    if not os.path.isdir("photo/"+jsondata['name']):
        os.mkdir("photo/"+jsondata['name'])
    filename = "photo/"+jsondata['name']+"/"+fileName+".png"
    img.save(filename)
    return jsonify(jsondata)

傳送測試

專案底下出現photo資料夾,與指定的 david 資料夾,並得到一張圖片

顯示圖片

顯示存在本地資料夾底下的圖片

from flask import Flask, escape, request, jsonify, make_response
import json
import os
import time
app = Flask(__name__)
app.config["DEBUG"] = True
app.config['SECRET_KEY'] = 'secret!'


@app.route('/getUserPhoto/<string:mydir>/<string:filename>', methods=['GET'])
# 取得圖片
def getUserPhoto(mydir, filename):
    image_data = open(os.path.join(
        'photo/'+mydir+'/', '%s' % filename), "rb").read()
    response = make_response(image_data)
    response.headers['Content-Type'] = 'image/png'
    return response

瀏覽器打開輸入網址 http://127.0.0.1:5000/getUserPhoto/david/1607676633.8338518.png

其中 1607676633.8338518.png 是上次上傳圖片的時間戳,記得要修改

刪除圖片

使用 get 方式刪除圖片,並在使用瀏覽器時顯示”執行成功”並關閉網頁

專案底下新增 templates 資料夾並建立 close.html 檔案

from flask import Flask, escape, request, jsonify, make_response, render_template
import json
import os
import time
app = Flask(__name__)
app.config["DEBUG"] = True
app.config['SECRET_KEY'] = 'secret!'


@app.route('/delfile/<string:mydir>/<string:filename>', methods=['GET'])
# 刪除圖片資料
def delfile(mydir, filename):
    if request.method == "GET":
        # if os.path.isdir(os.path.join(mydir+'/'+myid, '%s' % filename)):
        try:
            os.remove(os.path.join('photo/'+mydir+'/', '%s' % filename))
        except OSError as e:
            print(e)
            return "查無檔案"

        return render_template('close.html')

close.html

<script type="text/javascript">
    setTimeout(function(){ 
    window.opener=null;
    window.open("","_self");
    window.close();
    }, 1000);
    </script>

    執行成功

開啟瀏覽器測試 http://127.0.0.1:5000/delfile/david/1607676633.8338518.png

瀏覽所有圖片,並可點擊刪除

使用者不會知道上傳圖片的檔案名稱,做個簡易的圖片瀏覽功能,並且可點擊圖片進行刪除

建立 showUser.html 檔案

from flask import Flask, escape, request, jsonify, make_response, render_template
import json
import os
import time
app = Flask(__name__)
app.config["DEBUG"] = True
app.config['SECRET_KEY'] = 'secret!'

# 判斷是否為圖片
def isPhoto(imgpath):
    if(imgpath.lower().endswith(('.bmp', '.dib', '.png', '.jpg', '.jpeg', '.pbm', '.pgm', '.ppm', '.tif', '.tiff'))):
        return True
    else:
        return False

@app.route('/showUser', methods=['GET'])
def showUser():
    userPhotoDic = dict()
    dirlist = os.listdir('photo')
    for dirname in dirlist:
        if os.path.isdir('photo/'+dirname):
            filelist = os.listdir('photo/'+dirname)
            for name in filelist:
                if isPhoto('photo/'+dirname+'/'+name):
                    if dirname not in userPhotoDic:
                        userPhotoDic[dirname] = list()
                    userPhotoDic[dirname].append(dirname+'/'+name)
    return render_template('showUser.html', data=userPhotoDic)

showUser.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>FLASK / HTML</title>
</head>

<body>

  <table class="table">
    <thead>
      <tr>
        <td>name</td>
        <td>圖片</td>
      </tr>
    </thead>
    <tbody>
      {%for key in data%}
      <tr>
        <td>
          {{key}}
        </td>
        {% for path in data[key] %}
        <td>
          <a href="./delfile/{{path}}" target="_blank">
            <image width=100 height=100 src=http://127.0.0.1:5000/getUserPhoto/{{path}}></image>
          </a>
          </a>
        </td>
        {% endfor %}
        </td>
      </tr>
      {%endfor%}
    </tbody>
  </table>
</body>
</html>

已上是常用的 Flask 傳輸方法

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *