Python: 建立 REST API

使用 Python 的 Flask 建立 REST API 的逐步指南

👋 歡迎來到 Stackhero 文件中心!

Stackhero 提供即時可用的 Python 雲端 解決方案,專為簡化您的部署流程而設計:

  • 只需一個簡單的 git push,即可在數秒內將您的應用程式部署到正式環境。
  • 支援自訂網域名稱,並為您自動設定 HTTPS 憑證,確保連線安全。
  • 享有自動備份一鍵更新可預測的計價,讓您專注於程式開發,而無需煩惱基礎架構管理。
  • 專屬私有基礎架構上,獲得強大的效能安全性。您的執行環境完全隔離並受到保護。

節省時間簡化您的工作流程:透過 Stackhero 的 Python 雲端主機,您的程式碼只需 5 分鐘即可上線運作。

本指南將帶您一步步使用 Python 和 Flask 建立一個簡單的 REST API。Flask 是一個輕量級的微型框架,讓您能夠快速開發 Web 應用程式與 API。

在開始之前,請確保您已安裝以下工具:

  1. Python
  2. pip
  3. git
  4. asdf

如果您需要協助設定開發環境,請參考 Development platform 指南。或者,您也可以直接在 Code-Hero 線上平台立即開始撰寫程式。Code-Hero 提供線上 IDE 與終端機,所有必要工具皆已預先安裝,讓您能專注於程式開發,而無需花時間在安裝與設定上。

Python REST API 在 Code-Hero 執行,可直接透過瀏覽器存取Python REST API 在 Code-Hero 執行,可直接透過瀏覽器存取

首先建立一個新的專案目錄。本範例中,專案名稱為 myRestApi

mkdir myRestApi
cd myRestApi

使用 asdf 設定 Python 為最新版本,並初始化 Git 儲存庫:

asdf install python latest \
  && asdf local python latest

echo "__pycache__/" >> .gitignore

git init
git add -A .
git commit -m "First commit"

本範例僅需一個主要相依套件:Flask。

Flask 設計簡單且高效,讓您能夠無負擔地建立與部署 Web API。它內建路由、模板與 HTTP 請求處理等功能,協助您從想法到可運作的 API 只需幾分鐘。

您可以透過 pip 安裝 Flask 與 python-dotenv

pip install Flask python-dotenv

我們加入 python-dotenv,以便安全且方便地管理環境變數。後續步驟會示範如何使用。

安裝完成後,將相依套件凍結到 requirements.txt 檔案:

pip freeze > requirements.txt

凍結相依套件可確保每位開發者使用相同的套件版本,這個小動作能為您省下日後大量除錯時間。

現在您可以開始撰寫 API 程式碼。

建立一個名為 app.py 的檔案,並加入以下程式碼:

import os
from dotenv import load_dotenv
from flask import Flask, jsonify, request

# 非 production 環境時,從 .env 載入環境變數
if os.environ.get('ENV') != 'production':
    load_dotenv()

app = Flask(__name__)

# 範例任務資料
tasks = [
    {
        'id': 1,
        'title': 'Buy groceries',
        'description': 'Milk, Cheese, Pizza, Fruits',
        'done': False
    },
    {
        'id': 2,
        'title': 'Learn Python',
        'description': 'Learn Python programming basics',
        'done': False
    }
]

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})

@app.route('/api/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if not task:
        return jsonify({'error': 'Task not found'}), 404
    return jsonify({'task': task[0]})

@app.route('/api/tasks', methods=['POST'])
def create_task():
    if not request.json or 'title' not in request.json:
        return jsonify({'error': 'Title is required'}), 400
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

if __name__ == '__main__':
    if os.environ.get('ENV') == 'production':
        app.run()
    else:
        app.run(host='0.0.0.0', port=8080, debug=True)

您可以使用以下指令啟動伺服器:

python app.py

使用 host='0.0.0.0' 時,您的 API 可在 Code-Hero 透過瀏覽器存取。請造訪 http://<XXXXXX>.stackhero-network.com:8080/api/tasks,將 <XXXXXX> 替換為您的 Code-Hero 網域。

伺服器啟動後,您可以使用 cURL 與 API 互動。以下是一些範例指令:

  • 取得所有任務:

    curl -s http://localhost:8080/api/tasks
    # Output:
    # {
    #   "tasks": [
    #     ...
    #   ]
    # }
    
  • 取得特定任務(ID 2):

    curl -s http://localhost:8080/api/tasks/2
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    
  • 建立新任務:

    curl -s -X POST -H "Content-Type: application/json" \
    -d '{"title": "New task", "description": "Created with cURL"}' \
    http://localhost:8080/api/tasks
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    

小技巧:為了讓輸出更易讀,您可以將結果導入 jq。例如,curl -s http://localhost:8080/api/tasks/2 | jq 可讓 JSON 格式更清晰。

Python REST API 使用 Flask 範例,在 Stackhero Code-Hero 執行,左為伺服器 (1),右為使用 cURL 的客戶端 (2)Python REST API 使用 Flask 範例,在 Stackhero Code-Hero 執行,左為伺服器 (1),右為使用 cURL 的客戶端 (2)

環境變數可協助您保護像是資料庫密碼或 API 金鑰等機密資訊。使用環境變數能讓敏感資料不會出現在程式碼庫或 Git 歷史紀錄中,也方便針對不同環境設定不同參數。

您可以使用 python-dotenv 模組來管理環境變數。如果您先前未安裝,現在可以補裝:

pip install python-dotenv
pip freeze > requirements.txt

在專案根目錄建立 .env 檔案,並加入開發用的環境變數:

ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"

.env 加入 .gitignore,避免被提交到 Git:

echo ".env" >> .gitignore

您可以在 Python 中透過 os.environ.get() 取得這些變數:

import os

print(os.environ.get('ENV'))

.env 檔案僅供開發使用。若為正式或測試環境,請直接在 Stackhero 控制台的 Python 服務設定中設置環境變數。

Flask 內建伺服器適合開發階段使用。若要部署到正式環境,建議使用如 Gunicorn 這類穩定的 WSGI 伺服器。以下是準備方式:

  1. 安裝 Gunicorn:

    pip install gunicorn
    pip freeze > requirements.txt
    
  2. 使用 Gunicorn 啟動您的應用程式:

    ENV=production gunicorn app:app \
      --error-logfile - \
      -b 0.0.0.0:8080
    

    這裡的 app:app 指的是您的檔案(app.py)與 Flask 應用實例(app)。

  3. 您可以新增 Makefile,方便在開發與正式模式間切換:

    .DEFAULT_GOAL := dev
    
    # Stackhero for Python 預設執行 "run" 規則。我們覆寫為執行 'prod'。
    run: prod
    
    prod:
    	ENV=production gunicorn app:app \
    	  --error-logfile - \
    	  -b 0.0.0.0:8080
    
    dev:
    	python app.py
    

您可以用 make dev(或直接 make)啟動開發模式,或用 make prod 啟動正式模式。

Stackhero 讓雲端部署變得簡單又安全。您可以透過 Python cloud hosting service 部署您的 Python 專案。主要功能包括:

  • 只需一行 git push 即可部署
  • 自動 TLS(HTTPS)與可自訂網域
  • 專屬基礎架構,提升安全性
  • 支援 HTTP/2、TLS 1.3、WebSockets、GZIP & Brotli、ETag,以及 TCP/UDP 埠存取

請依下列步驟部署:

  1. 取得您的 SSH 公鑰:

    cat ~/.ssh/id_*.pub
    
  2. 在 Stackhero 控制台開啟您的「Stackhero for Python」服務並選擇「Configure」。

  3. 將公鑰貼到「SSH public keys」或「Key」欄位。

  4. 點擊「Validate」以確認設定。

「Stackhero for Python」公鑰設定畫面「Stackhero for Python」公鑰設定畫面

如果您尚未產生 SSH 金鑰,可以使用以下指令產生:

ssh-keygen -t ed25519

依 Stackhero 服務提供的指令(將 <XXXXXX> 換成您的服務網域)將 Git remote 加入專案:

git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git

Git remote 指令畫面Git remote 指令畫面

準備好部署時,請使用以下指令推送程式碼:

git push stackhero main

請記得在部署前先 commit 您的變更。在 Stackhero Code-Hero 中,您可以使用 Command Palette(Ctrl+Shift+PCmd+Shift+P),輸入 Git: Commit 以快速提交。

部署完成後,您的 API 將可透過 https://<XXXXXX>.stackhero-network.com/api/tasks 存取。請將 <XXXXXX> 換成您的服務網域,即可存取 Flask API。

您現在已經擁有一個以 Flask 建立的 REST API。以這個基礎,您可以輕鬆擴充應用程式、連接資料庫,或整合其他服務。Flask 提供彈性,讓您從簡單原型一路成長為完整的正式 API。