(一個可執行 .py 腳本、可分區管理、可控權限、可日誌化的輕量級 API Framework)
在企業內部資訊環境中,我們常常需要快速提供一些 API 介面給內部系統、後台工具、腳本或排程器使用。例如:
- 產生報表
- 查詢狀態
- 執行批次腳本
- 提供內部資料查詢 API
- 後台管理介面呼叫
市面上雖有許多 API Gateway、後端框架,但如果只是內部使用,其實不需要架構過於複雜。
本篇文章分享我如何利用:
- Python + Flask
- Docker
- Apache Reverse Proxy
- 動態載入 .py 腳本(真正可執行 python script!)
- 分區(root / api / admin)
- API Key & Admin Key 權限控管
- IP 白名單
- 統一日誌 + Trace ID + Error Logging
- 健康檢查 / 路由列表 / Metrics
打造出一套 輕量但強大、可長期維運的 Internal API Platform。
這套系統現在已可讓我直接用:
http://domain.com/api/hello.py?name=Rico
http://domain.com/admin/stats.py
http://domain.com/report_json.py
來呼叫不同 Python 腳本,非常彈性。
✨ 一、平台目標:快速、安全、可維運
這個 Internal API Platform 要做到:
✔ 1. 可以像執行 script 一樣執行 Python
例如:
/api/report_json.py
/admin/stats.py
/inventory.py
每支 .py 都是獨立的 handler,只要定義:
def main(request):
...
即可對外提供 API。
✔ 2. 分區管理
根據 URL 不同目錄:
| URL Prefix | 對應目錄 | 用途 |
|---|---|---|
/xxx.py | /app/xxx.py | 一般 Script |
/api/xxx.py | /app/api/xxx.py | 內部 API |
/admin/xxx.py | /app/admin/xxx.py | 後台 API(通常更高權限) |
✔ 3. 權限保護
支援:
- IP 白名單
/api:API Key/admin:Admin Key
例如(docker run 時設定):
-e API_TRUSTED_IPS="172.18.0.1,127.0.0.1"
-e API_KEY="secret123"
-e ADMIN_API_KEY="admin456"
✔ 4. 統一日誌(已企業化)
平台會自動記錄:
- 呼叫 API 的路徑
- 區域(root/api/admin)
- caller IP
- Query 參數
- 耗時
- status code
- trace_id(回應 header 也會帶出)
- script error stack trace(防止 silent fail)
所有日誌寫在:
/opt/docker/python/app/logs/framework.log
✔ 5. 平台 API(讓你維運更方便)
/_platform/health
→ 系統健康狀態、運行時間、錯誤數、請求數/_platform/routes
→ 列出目前有哪些 script/_platform/metrics
→ 簡易 metrics,可給監控系統抓取
🧱 二、平台架構概述
整套架構如下(Docker 化):
Client → Apache Reverse Proxy → Python Flask Platform → 動態執行各 .py script
每次呼叫 .py,平台會:
- 解析 URL 找到 script
- 執行
handle(request)或main(request) - 回傳結果(文字 / JSON / Response / 檔案下載皆可)
- 自動記錄日誌、計算 metrics
- 發出 trace_id
📂 三、目錄結構設計(根據 URL Prefix 自動分區)
/opt/docker/python/app
├── app.py # 平台主程式(Dispatcher)
├── logs/ # 統一日誌
│ └── framework.log
├── api/ # /api/*.py
│ ├── hello.py
│ └── report_json.py
└── admin/ # /admin/*.py
└── stats.py
🧠 四、關鍵技術:核心 Dispatcher
平台最核心的部分,是 自動載入 script 並執行。
在 app.py 中:
spec = importlib.util.spec_from_file_location(module_name, script_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
handler = getattr(module, "handle", None) or getattr(module, "main", None)
result = handler(request)
✔ 這段讓平台可以真正「執行任意 .py 檔」,而不是 REST 固定路由。
✔ 讓 IT 部門可以快速增加 API,只要放一支 .py 即可!
🔐 五、安全設計:IP 白名單 + API Key + Admin Key
app.py 中做了精細的安全控管:
1. IP 白名單
if ALLOWED_IP_SET and client_ip not in ALLOWED_IP_SET:
return make_response("Forbidden (IP not allowed)", 403)
2. API Key(給 /api)
if area == "api" and API_KEY:
if request.headers.get("X-API-Key") != API_KEY:
return make_response("Forbidden (invalid API key)", 403)
3. Admin Key(給 /admin)
if area == "admin" and ADMIN_API_KEY:
if request.headers.get("X-Admin-Key") != ADMIN_API_KEY:
return make_response("Forbidden (invalid Admin key)", 403)
✔ 這讓平台可以安全對內部系統與後台管理工具暴露 API。
✔ 不會不小心讓整個平台暴露出去。
📈 六、平台級功能:Health / Routes / Metrics
我加入了三個維運必備 API。
✔ 1. Health Check
/_platform/health:
{
"status": "ok",
"uptime_sec": 1623,
"requests_total": 83,
"errors_total": 1
}
✔ 2. 列出所有 script
/_platform/routes:
{
"root": ["report.py"],
"api": ["hello.py", "report_json.py"],
"admin": ["stats.py"]
}
✔ 3. Metrics(可送入 Prometheus/Grafana)
/_platform/metrics:
{
"uptime_sec": 1644,
"requests_total": 95,
"requests_by_area": {
"root": 30,
"api": 50,
"admin": 15
},
"errors_total": 1
}
👨💻 七、Script 寫法(非常簡單!)
✔ /api/hello.py
def main(request):
name = request.args.get("name", "Guest")
return {"message": f"Hello, {name}!"}
✔ /admin/stats.py
def main(request):
return {"status": "admin ok"}
✔ /api/download.py
from flask import send_file
def main(request):
return send_file("/app/data/sample.txt", as_attachment=True)
Script 寫法 越簡單越好,平台層會幫你處理所有格式化 / error / 日誌。
🐳 八、Docker 啟動方式
Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY app/ /app/
RUN pip install flask gunicorn
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
啟動命令(包含安全性設定):
docker run -d \
--name pyapp \
--network intranet-net \
-v /opt/docker/python/app:/app \
-e API_TRUSTED_IPS="192.168.1.10,127.0.0.1" \
-e API_KEY="secret123" \
-e ADMIN_API_KEY="admin456" \
mypython:1.0
🔄 九、Apache Reverse Proxy
只要把所有流量導向:
ProxyPass / http://pyapp:5000/
ProxyPassReverse / http://pyapp:5000/
即可讓 platform 對外提供 API。
🎯 結語:一套真正企業級、實用、又輕量的 Internal API Framework
這套 Internal API Platform 的價值:
| 能力 | 說明 |
|---|---|
| 🧠 動態執行 Python Script | 不需 REST 路由定義,新增檔案即可上線 |
| 📂 分區管理 | root / api / admin 狀態明確 |
| 🔐 安全性 | IP 白名單 + API Key + Admin Key |
| 📜 企業級日誌 | trace_id、耗時、stacktrace 全記錄 |
| 🩺 健康檢查 | /_platform/health |
| 📊 Metrics | /_platform/metrics |
| 🔍 API 列表 | /_platform/routes |
| 🧰 易開發易維運 | script 只有一個 main() 就能變 API |
這對企業內部 IT 來說非常實用:
- IT 自己可以用它做報表、做背景處理
- 內部系統可以呼叫它當 API Gateway
- 甚至可以做成一個 Internal Developer Tooling 平台
- 不需要龐大的微服務架構