在 Day 28 完成 OpenCV 影像品質防衛 與 Chain-of-Thought 多模態提示詞工程 後,PrescriptionVLM 系統已具備後端穩定度、AI 識別精準度與邊緣異常防衛的能力。
隨著系統準備邁入營運,未來可能需要與第三方長照關懷平台、社工管理系統或醫院藥局系統進行 API 對接。如果僅依靠口頭說明或手動維護的文件,容易因為欄位型別不一致、漏傳 Header 或錯誤碼定義不明確而增加溝通成本。
今天我們將為 PrescriptionVLM 系統導入 Flask-RESTX(Swagger / OpenAPI 3.0),自動化生成互動式 API 測試文件。完成項目包含:
@app.route 升級為 RESTX Resource 與 Namespace 架構。X-Request-ID Header 帶入測試。在現代 Web API 開發與跨系統對接中,導入 OpenAPI 規範有以下好處:
/doc 互動介面測試,檢視 HTTP 回應狀態碼與 JSON 欄位格式。requirements.txt)請開啟專案根目錄的 requirements.txt,加入 Flask-RESTX 套件:
flask-restx==1.3.0
schemas_restx.py)在專案根目錄建立 schemas_restx.py,定義 API 請求與回應的資料模型結構:
from flask_restx import Api, fields
def init_swagger_models(api: Api):
"""定義 Swagger / OpenAPI 回應結構 Schema"""
medicine_model = api.model('MedicineItem', {
'name': fields.String(required=True, description='藥品名稱', example='阿斯匹靈 (Aspirin)'),
'dosage': fields.String(required=True, description='單位劑量', example='100mg / 1 錠'),
'timing': fields.String(required=True, description='服用時間與頻率', example='每日一次,早餐後')
})
metrics_model = api.model('PerformanceMetrics', {
'vlm_latency_ms': fields.Float(description='Gemini VLM 耗時 (ms)', example=1250.5),
'line_latency_ms': fields.Float(description='LINE 推播耗時 (ms)', example=180.2)
})
prescription_response_model = api.model('PrescriptionAnalysisResponse', {
'status': fields.String(required=True, description='執行狀態', example='success'),
'cached': fields.Boolean(required=True, description='是否命中 Redis 快取', example=False),
'request_id': fields.String(required=True, description='全域請求 Trace ID', example='req-uuid-12345'),
'metrics': fields.Nested(metrics_model, description='分段效能耗時'),
'data': fields.Nested(api.model('PrescriptionData', {
'is_prescription': fields.Boolean(description='是否為有效藥袋照片', example=True),
'confidence_score': fields.Float(description='模型辨識信心度', example=0.98),
'medicines': fields.List(fields.Nested(medicine_model), description='解析藥品清單'),
'safety_warnings': fields.List(fields.String, description='注意事項與警語', example=['服藥後請勿駕駛車輛']),
'spoken_summary': fields.String(description='語音摘要簡述', example='這是您的止痛藥,請記得早餐後配水服用一錠。')
}))
})
return prescription_response_model
app.py)開啟 app.py,掛載 Flask-RESTX 介面並配置 /doc 路徑:
from flask import Flask, request, jsonify, g
from flask_restx import Api, Resource, reqparse
from werkzeug.datastructures import FileStorage
from schemas_restx import init_swagger_models
from logger import logger
app = Flask(__name__)
# 初始化 Flask-RESTX API 物件
api = Api(
app,
version='1.0.0',
title='PrescriptionVLM API 服務文件',
description='整合 Gemini 多模態 VLM、LINE Messaging API 與高齡化無障礙體驗之藥單解析後端系統',
doc='/doc', # 指定 Swagger UI 存取路徑為 /doc
prefix='/api/v1'
)
ns = api.namespace('prescription', description='藥單解析與語音關懷相關 API')
prescription_model = init_swagger_models(api)
# 設定檔案上傳 Request Parser
upload_parser = reqparse.RequestParser()
upload_parser.add_argument('image', location='files', type=FileStorage, required=True, help='藥袋照片檔案 (JPG/PNG)')
upload_parser.add_argument('X-Request-ID', location='headers', type=str, required=False, help='全域 Trace ID')
@ns.route('/analyze-prescription')
class PrescriptionAnalysisResource(Resource):
@ns.expect(upload_parser)
@ns.response(200, '解析成功', prescription_model)
@ns.response(400, '圖片品質不佳或參數錯誤')
@ns.response(429, '已達流量限制')
@ns.response(500, '系統內部錯誤')
def post(self):
"""上傳藥袋照片進行 AI 多模態辨識與關懷推播"""
req_id = getattr(g, "request_id", "N/A")
logger.info(f"收到 Swagger/Client 藥單解析請求 [ReqID: {req_id}]")
# 呼叫原本 Day 28 優化後的完整解析邏輯 ...
return {
"status": "success",
"cached": False,
"request_id": req_id,
"metrics": {"vlm_latency_ms": 1200.0, "line_latency_ms": 150.0},
"data": {
"is_prescription": True,
"confidence_score": 0.98,
"medicines": [{"name": "阿斯匹靈", "dosage": "1 錠", "timing": "早餐後"}],
"safety_warnings": ["請遵照醫囑服用"],
"spoken_summary": "這是您的阿斯匹靈,早餐後服用一錠。"
}
}, 200
1. 啟動服務並訪問 Swagger UI
在 Terminal 啟動服務:
docker-compose up --build -d
開啟瀏覽器連線至:http://localhost:5000/doc
PrescriptionVLM API 服務文件 v1.0.0。/api/v1/prescription/analyze-prescription 端點,看到完整清晰的 Response Schema。2. 在 Swagger UI 執行線上 API 測試
image 欄位選擇一張本地藥袋照片。X-Request-ID: swagger-test-1234。測試通過後,將 Day 29 的修改提交至 GitHub:
git add requirements.txt schemas_restx.py app.py
git commit -m "保留雙引號 改填寫自己要記錄的標記 ex.鐵人賽第二十九天"
git push
今天我們透過 Flask-RESTX 為 PrescriptionVLM 建立了符合 OpenAPI 規範的互動式文件,完成了系統邁向開放生態與跨系統對接的基礎建設。
明天(Day 30),我們將迎來 30 天的最終完結篇!進行 PrescriptionVLM 系統整體架構回顧、30 天成果總結與未來展望!