iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0
AI & Data

AI 營養師 + Web3 數位健康護照系列 第 14

Day14. 用 Flask 規劃 AI 營養顧問的專案架構 Ep .2:使用 Google Fit 獲取個人健康資料

  • 分享至 

  • xImage
  •  

隨著健康意識抬頭,市面上已充斥各式健康數據平台,例如 Apple Health、Fitbit、Huawei Health 等,無論是監測睡眠、步數還是飲食紀錄,都希望為使用者提供更有智慧的健康管理。

本日重點

  • 了解 Google Fit 平台資料架構與常見健康數據類型
  • 透過 API 取得個人健康資料的權限、授權與技術流程
  • 如何將 Google Fit 資訊串接進 Flask AI 營養顧問專案
  • 範例程式教學:串接、取得並處理健康資料的方法
  • 健康數據整合到個人化 AI 營養管理應用的架構設計

一、認識 Google Fit

Google Fit 是 Google 官方的健康與健身資料平台,它能匯集來自各種穿戴裝置、應用程式的運動、睡眠、心率等健康數據。

1. 特色

  • 跨裝置整合:可匯集Android、iOS、各種穿戴設備數據
  • 標準化資料結構:如步數、卡路里、運動項目皆有一致定義
  • API 授權彈性:可選定要存取哪些資訊,保護用戶隱私

2. 溫馨小提醒

Google Fit 的功能將於 2026年併入 Health Connect, 屆時 Fit API 將會整合,實際情況請參閱 Health Connect 官網說明:

  • 專案全部完成之後,會在 Web3 之後,再補充說明「如何將 Google Fit 移轉到 Health Connect」
  • 改用其他家的,請參考以下功能對照表:
服務 平台支援 API開放性 數據類型 適合開發場景 生態系統整合力
Google Fit Android, Web 高(REST API) 全面(運動, 睡眠, 飲食) Android App、數據收集後端 佳,Health Connect整合進行中
Apple Health iOS, watchOS 中(HealthKit) 全面(運動, 睡眠, 心率) iOS/Apple Watch App 極佳,蘋果裝置專屬生態
Fitbit 多平台 高(REST API) 運動, 睡眠, 心率 跨品牌App、穿戴裝置串接 穩定,和Google深度合作
Samsung Health Android, WearOS 中(SDK) 運動, 睡眠, 心率 三星裝置App、IoT健康服務 穩定,重三星自系統

這張表格可以清楚比較各家健康資料平台對開發者的友善度、主流支援平台和生態整合力,選擇最適合自己的應用情境!


二、Google Fit API 授權與串接流程

示意流程圖

https://ithelp.ithome.com.tw/upload/images/20251014/20129220lGeM34gIME.png
(圖片由 Copilot 協助生成)

1. 建立 Google Cloud 專案並啟用 Fitness API

在 Google Cloud Platform (以下簡稱 GCP) 上建立新專案,建立後請到「API 與服務」,啟用「Fitness API」。

https://ithelp.ithome.com.tw/upload/images/20250926/20129220cmXewVhTvd.jpg

2. 建立憑證

  • 一樣是在「API與服務」,找到「憑證」,建立OAuth 2.0 憑證(Web應用程式)

https://ithelp.ithome.com.tw/upload/images/20250926/20129220cORs4Jxqus.jpg

選擇 「Web 應用程式」,並自訂名稱。在 「已授權的重新導向 URI」 欄位中,輸入這個應用程式回調網址。在本地端開發時,通常是 http://127.0.0.1:5000/oauth2callback 

3. OAuth 同意畫面 & 測試帳號設置

  • 找到「API 與服務」 > 「OAuth 同意畫面」 >

(1) 新增測試使用者:

在 「測試使用者」 (Test users) 頁面,點擊 「新增使用者」 (Add users)。輸入用來測試的 Google 帳號,然後點擊 「儲存」 (Save)。

這一步很重要!!如果沒有新增測試使用者,待會 「測試」的時候,會被拒絕。(「發布應用程式」(Publish App) 後,所有擁有 Google 帳號的使用者都可以使用這個應用程式,就不會有這個問題。)

(2) 權限「Scope」選擇

「資料存取權」,在 「範圍」 頁面,點擊 「新增或移除範圍」,搜尋與 Google Fit 相關的功能。這些權限決定應用程式能讀取哪些類型的 Google Fit 資料。

https://ithelp.ithome.com.tw/upload/images/20250926/20129220PSUPNi35N7.jpg


4. 點擊「建立」,就會取得一組用戶端 ID (Client ID)&用戶端密鑰 (Client Secret),可以下載。

溫馨小提醒:
下載後,改檔名為「credentials.json」,和 main.py 一起放在同一層,稍後就會用到。


三、Flask + Google Fit 的設計理念

1. 建立虛擬環境並安裝所需套件:

# 建立並啟用虛擬環境
python -m venv venv
source venv/bin/activate  
# 在 Windows 上使用
source venv/Scripts/activate  

# 安裝 Google 認證套件
pip install google-auth google-auth-oauthlib google-api-python-client

2. 專案架構

AI_Nutri_Project/
    ├── main.py
    ├── templates/
    ├── static/
    └── credentials.json

3. main.py 核心功能設計

  • index:主頁導覽,顯示授權連結
  • /authorize:導向Google OAuth流程
  • /oauth2callback:處理Google授權回傳
  • /fetch_fit_data:呼叫API取得健康數據並呈現

4. 將 Google Fit 登入連結畫面新增至 index.html

# 匯入 os 模組,用於與作業系統互動(例如:存取環境變數)
import os 

# 從 flask 模組中匯入核心組件
from flask import Flask, redirect, url_for, request, render_template 

# 建立一個 Flask 應用程式實例 (instance)。
# '__name__' 是 Python 的標準變數,是當前模組的名稱。
app = Flask(__name__) 

# 定義根目錄('/')的路由 (Route)。
# 當使用者訪問網站的根 URL 時,會觸發這個函式。
@app.route('/')

# 這個裝飾器(Decorator)告訴 Flask,當使用者在瀏覽器中輸入網站的根網址(例如 http://127.0.0.1:5000/)時,就應該執行下面的 index() 函式。

def index():
    # 函式會回傳一個 HTML 字串,作為網頁的內容。
    # 這裡包含一個標題和一個超連結,超連結導向到 '/authorize' 路由(用於後續的 OAuth 授權流程)。
    return '<h1>歡迎來到我的 Google Fit!</h1><a href="/authorize">點此登入並授權</a>'

# 啟動內建的開發伺服器,讓應用程式可以在本機執行,並透過瀏覽器訪問。
if __name__ == '__main__':
    # 執行 Flask 應用程式。
    # debug=True 會啟用除錯模式,當程式碼有變動時伺服器會自動重載,並在發生錯誤時提供除錯資訊。
    app.run(debug=True)
  • 執行


https://ithelp.ithome.com.tw/upload/images/20250928/20129220Qo6CuGVWvU.jpg


成功!!
(明天會重新調整 index.html 的 UI 排版)


5. 啟用 Google Fit 登入連結

# 匯入 Flow 類別,這是處理 OAuth 流程的核心工具
from google_auth_oauthlib.flow import Flow    

# 匯入 Credentials,用於處理和儲存認證資訊 (Access Token)
from google.oauth2.credentials import Credentials   

# 匯入 Request,通常用於重新整理 (Refresh) 過期的存取權杖
from google.auth.transport.requests import Request 

# 匯入 Google API Client Library,用於後續呼叫 Google Fit 服務
import googleapiclient.discovery

# ----------------------------------------------------
# 第一步:導向 Google 授權頁面 (Authorization URL)
# ----------------------------------------------------

@app.route('/authorize')
def authorize():

    # 1. 初始化 Flow:從客戶端密鑰檔案 ('credentials.json') 建立 OAuth 流程實例
    flow = Flow.from_client_secrets_file(
        'credentials.json',
        
        # 2. 定義權限範圍 (Scopes):指定應用程式需要的資料權限。
        # 這裡請求讀取 Google Fit 的活動資料 (fitness.activity.read)。
        scopes=['https://www.googleapis.com/auth/fitness.activity.read'],
        
        # 3. 定義回呼 URL:Google 授權成功後,會將使用者重定向 (redirect) 回此 URL。
        redirect_uri='http://127.0.0.1:5000/oauth2callback')

    # 4. 產生授權 URL:建立導向 Google 登入/授權頁面的 URL。
    # prompt='consent' 確保使用者每次都看到授權畫面。
    auth_url, state = flow.authorization_url(prompt='consent')

    # 5. 儲存狀態參數:將生成的 'state' 參數儲存到 session,這是為了防止 CSRF(跨站請求偽造)攻擊。
    session['state'] = state

    # 6. 重定向:將使用者導向 Google 的授權 URL,開始登入和授權過程。
    return redirect(auth_url)

# ----------------------------------------------------
# 第二步:接收 Google 回呼並處理授權碼 (Callback)
# ----------------------------------------------------

@app.route('/oauth2callback')
def oauth2callback():
    # 使用者授權
    # 接收Google回傳code,取得存取token,儲存於session 
    
    # 注意事項
    # 1. 應檢查 session['state'] 是否與 request.args.get('state') 匹配,以進行 CSRF 驗證。
    # 2. 使用 flow.fetch_token() 配合 Google 回傳的授權碼 (code),交換取得 Access Token。
    # 3. 將取得的 Credentials 物件 (包含 Access Token 和 Refresh Token) 儲存起來。
    pass


四、Google Fit API 資料取得與分析

# 匯入 build 函式,用於建立 Google API 服務
from googleapiclient.discovery import build 

# 確保匯入 request 和 session
from flask import request, session, redirect, url_for 

# 路由裝飾器:定義當使用者訪問此 URL 時執行的函式
@app.route('/fetch_fit_data') 
def fetch_steps_data():

    # 檢查 session 中是否有儲存的 Google 認證資訊 (Credentials)
    if 'credentials' not in session:
    
        # 如果沒有,將使用者導向授權頁面,要求他們登入和授權
        return redirect(url_for('authorize'))
    
    # 1. 取得參數:從 URL 查詢參數中獲取時間範圍(通常是毫秒格式字串)
    # 使用 request.args.get() 取得,並提供一個預設值(例如 None)
    start_time_str = request.args.get('start_time')
    end_time_str = request.args.get('end_time')

    # 檢查必要參數是否存在
    if not start_time_str or not end_time_str:
        return "<h1>錯誤:請提供 start_time 和 end_time 查詢參數!</h1>"

    try:
        # 將字串格式的時間參數轉換為整數 (毫秒)
        start_time = int(start_time_str)
        end_time = int(end_time_str)
    except ValueError:
        return "<h1>錯誤:時間參數必須是有效的整數 (毫秒)!</h1>"

    # 2. 取得認證資訊 (Credentials Token)
    # 從 session 中載入儲存的 Google Credentials 物件
    # (假設 /oauth2callback 成功將其序列化並儲存為 'credentials')
    token = session['credentials'] 
    
    # 3. 初始化 Google Fit API 服務
    # 使用 build() 建立 'fitness' 服務 (v1 版本),並以取得的 'token' 進行認證。
    service = build('fitness', 'v1', credentials=token)
    
    # 4. 發送 API 請求:使用 aggregate 查詢方法,用於彙總 (Aggregate) 資料集 (Dataset)
    response = service.users().dataset().aggregate(
    
        # userId='me' 表示查詢的是目前已授權使用者 (即當前使用者) 的資料
        userId='me',
        
        # body 包含了所有查詢參數,以 JSON 格式定義
        body={
        
            # aggregateBy 欄位:定義彙總哪些資料類型和資料來源
            "aggregateBy": [{
                "dataTypeName": "com.google.step_count.delta",
                "dataSourceId": "derived:com.google.step_count.delta:com.google.android.gms:estimated_steps"
            }],
            
            # bucketByTime 欄位:以時間分桶,這裡設定 86,400,000 毫秒 = 24 小時(即按「日」分組)
            "bucketByTime": {"durationMillis": 86400000}, 
            
            # startTimeMillis / endTimeMillis:使用從 URL 參數中解析出的時間範圍
            "startTimeMillis": start_time,
            "endTimeMillis": end_time,
        }
    ).execute() # 實際發送 API 請求

    # 5. 回傳結果
    # API 響應 (response) 中的 'bucket' 欄位包含按日彙總的步數數據列表
    return response['bucket']

執行

python main.py

https://ithelp.ithome.com.tw/upload/images/20250926/20129220CvRs8KzXUt.jpg


  • 點此登入並授權


https://ithelp.ithome.com.tw/upload/images/20250926/20129220KgXstzcUTm.jpg


  • 溫馨小提醒:

這是查詢的期間,如果選到「未來日期」的話,API 回傳的數據將會是空的 (bucket 列表可能為空)。強烈建議將查詢時間設為有實際活動數據的日期來進行測試。

  • 回傳 2025-09-25 當天的數據


https://ithelp.ithome.com.tw/upload/images/20250926/20129220z3NngqfYYT.jpg


  • 注意事項:

可能會觸及資安與隱私的議題,例如:

  • OAuth流程應妥善保存token至session或加密資料庫
  • 切勿將敏感資訊公開repo
  • 尊重用戶資料存取權,只申請必要scope
  • 合規(GDPR、CCPA)設計

五、應用延伸

學會 Google Fit API/Health Connect 後,能延伸串接 AI 推薦、前端 Dashboard、健康挑戰活動等,資料標準化後易於產品擴展。

延伸閱讀


上一篇
Day13. 用 Flask 規劃 AI 營養顧問的專案架構 Ep .1:建立第一個 Flask 應用程式
下一篇
Day15. 用 Flask 規劃 AI 營養顧問的專案架構 Ep .3:給 AI 顧問穿新衣~打造人性化的首頁 UI(index.html)
系列文
AI 營養師 + Web3 數位健康護照35
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言