請啟用 JavaScript 來查看內容

「TDX 運輸資料流通服務平台」含 Python 範例程式,PTX 平台的升級版~

·

    前言

    在之前文章介紹 PTX 公共運輸整合資訊流通服務平台,它整合多項公共運輸的資料服務 API,供我們串接取得相關數據。

    1. 「PTX 公共運輸資訊平台」API 介紹 (含 Odata 說明)
    2. 「PTX 公共運輸資訊平台」Python 範例
    3. 「PTX 公共運輸資訊平台」Google Apps Script 範例

    但經網友提醒,才發現 PTX 竟然只服務到今年(2022年)底,之後會改以「TDX 運輸資訊整合流通服務平台」代替,因此本篇文章將帶大家快速了解一下 TDX 平台,以及實際使用 Python 來串接,取得相關數據資料。

    PTX 平台關閉
    PTX 平台關閉

    後來我有寫一篇 Google Apps Script 範例程式 可以參考哦~


    TDX 運輸資訊整合流通服務平台
    TDX 運輸資訊整合流通服務平台

    TDX 平台說明

    按照官網的說法,TDX 整合交通部運輸數據五大平台(PTX、Traffic、GIS-T、TICP、LINK),並使用全新的認證授權方式管控資源存取權限,提供單一服務查詢與介接入口。短時間內五大平台與 TDX 平台將持續並行運作,但未來會以 TDX 為主要的數據流通平台。
    (參考:TDX 平台常見問題)

    TDX 整合五大平台 (圖片來源:TDX官網)
    TDX 整合五大平台 (圖片來源:TDX官網)

    實際使用其實「TDX 運輸資訊整合流通服務平台」服務及概念是跟「PTX 公共運輸整合資訊流通服務平台」差不多的,只是相較於 PTX 平台,TDX 平台又多了許多種類的資料,像是 "即時路況"、"停車資訊"、"GIS圖資"、"道路編碼" 等等也把它整合進來。

    TDX 平台服務範疇
    TDX 平台服務範疇

    TDX 平台也有個詳細各項服務查詢頁面,可依照 "服務類型"、"資料主題"、"領域類型"、"資料類型" 來做篩選。

    TDX 各項服務查詢
    TDX 各項服務查詢

    註冊會員 & 取得API金鑰

    同樣為了系統資源使用之公平性與資通訊安全考量,要先註冊會員來取得 API 金鑰(TDX 註冊頁面),但不知道是不是因為平台還在試營運階段的關係,審核完成並沒有寄 Email 通知,是我主動登入平台才發覺已審核通過……

    註冊 TDX 平台會員
    註冊 TDX 平台會員

    登入 TDX 平台後,前往 會員中心 > (左邊) > 資料服務 > API金鑰 頁面,對 預設的API Key (或建立新的金鑰) 點擊 "編輯",即可查看 "Client Id" 和 "Client Secret",這兩組字串先記錄下來,之後 call API 時需要帶上。

    API金鑰 頁面
    API金鑰 頁面

    API 呼叫次數限制:

    • 使用 API 金鑰呼叫,每個呼叫來源端 IP 呼叫次數限制為 50 次/秒 (無每日上限)。
    • 不使用 API 金鑰呼叫,則僅能透過瀏覽器呼叫 API,且每個呼叫來源端 IP 的上限為每日 50 次。

    有關 API 金鑰服務使用流程說明,請參考官方說明


    Swagger 工具

    從上方導航欄 開發指引 > API說明,前往 TDX 平台的 Swagger 工具,能查看有提供哪些 API,與各自的請求參數與回傳欄位說明。
    詳細使用說明可以查看之前我寫的 PTX 介紹 (含 Odata 說明) 文章。

    TDX 平台 Swagger 工具
    TDX 平台 Swagger 工具

    右方有 Authorize 按鈕,填入 "Client Id" 與 "Client Secret" 驗證,即可使用你的 API 金鑰來呼叫。不使用 API 金鑰呼叫,有每日 50 次的上限。


    API 認證授權機制

    API 認證授權機制與 PTX 平台有蠻大的差異,簡單來說每次請求前要先身份認證取得 Access Token,才能使用 Access Token 來取得 TDX API 服務的數據資料。
    (或使用尚未過期的 Access Token,有效期限預設為 1 天)


    詳細步驟說明如下:

    1. 取得 Access Token

    依照以下格式發出請求:

    Request URL: https://tdx.transportdata.tw/auth/realms/TDXConnect/protocol/openid-connect/token
    Request Method: POST
    Request Headers:
        content-type: application/x-www-form-urlencoded
    data:
        grant_type: client_credentials
        client_id: <your_client_id>
        client_secret: <your_client_secret>
    

    data 參數說明如下:

    KeyValue
    grant_type固定使用 client_credentials
    client_id您的 Client Id,從 TDX 會員中心取得
    client_secret您的 Client Secret,從 TDX 會員中心取得

    回傳資料是 JSON 格式,其中包含 access_token 參數,就是我們要的 Access Token。


    1. 呼叫 TDX API 服務,取得數據資料
    Request URL: TDX_API_URI
    Request Method: GET
    Request Headers:
        authorization: Bearer <Access_Token>
    

    * 若 Access Token 時間超過有效期限(第一步驟收到回應中的 expires_in 參數),則再重新透過第一步驟取得即可。


    * 官方的說明文件: https://github.com/tdxmotc/SampleCode


    完整 Python 程式範例

    因為 TDX 平台的 API 一樣使用 OData (Open Data Protocol) 標準介面,所以這邊我就不再寫一次了,還不太懂的可前往 「PTX 平台」API 介紹 (含 Odata 說明) 了解。

    同樣以下方條件當範例查詢:

    台鐵"台北"車站即時的列車到離站看板資訊,並且只要"逆行"的列車


    查詢的 URL 會長得像這樣:
    https://tdx.transportdata.tw/api/basic/v2/Rail/TRA/LiveBoard/Station/1000?$filter=Direction eq 1&$format=JSON

    會發現與 PTX 平台根本一樣,只差在網址前方的部分。


     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    import requests
    
    
    client_id = '<your_client_id>'
    client_secret = '<your_client_secret>'
    
    
    class TDX():
        def __init__(self, client_id, client_secret):
            self.client_id = client_id
            self.client_secret = client_secret
    
        def get_token(self):
            token_url = 'https://tdx.transportdata.tw/auth/realms/TDXConnect/protocol/openid-connect/token'
            headers = {'content-type': 'application/x-www-form-urlencoded'}
            data = {
                'grant_type': 'client_credentials',
                'client_id': self.client_id,
                'client_secret': self.client_secret
            }
            response = requests.post(token_url, headers=headers, data=data)
            # print(response.status_code)
            # print(response.json())
            return response.json()['access_token']
    
        def get_response(self, url):
            headers = {'authorization': f'Bearer {self.get_token()}'}
            response = requests.get(url, headers=headers)
            return response.json()
    
    
    if __name__ == '__main__':
        tdx = TDX(client_id, client_secret)
    
        # url = 'https://tdx.transportdata.tw/api/basic/v2/Rail/TRA/LiveBoard/Station/1000?$filter=Direction eq 1&$format=JSON'
        base_url = "https://tdx.transportdata.tw/api"
        # 取得指定[車站]列車即時到離站電子看板(動態前後30分鐘的車次)
        endpoint = "/basic/v2/Rail/TRA/LiveBoard/Station/1000"
        filter = "Direction eq 1"  # 順逆行: [0:'順行', 1:'逆行']
        url = f"{base_url}{endpoint}?$filter={filter}&$format=JSON"
    
        response = tdx.get_response(url)
        print(response)
    

    如此應該就能順利取得資料 🎉🎉🎉


    其他程式範例

    除了參考我上面的 Python 範例,TDX 官方有提供 JavaScript 與 C# 程式語言的範例程式碼,需要的可前往參考 (GitHub)。


    我有寫一篇 Google Apps Script 範例程式 可以參考。

    也感謝熱心網友 meebox,提供 "適用在嵌入式系統的 MicroPython 環境、token 有效期判斷" 的版本:
    https://github.com/codemee/tdx


    結語

    這次快速(?)帶大家了解「TDX 運輸資料流通服務平台」,看起來就是 PTX 平台的升級版,加入更多不同服務的資料。
    如果你之前已經用 PTX 做些作品出來,不妨試著將其改串接至 TDX,畢竟可能明年 PTX 平台就無法使用了。


    歡迎追蹤『IT空間』FB 粉專,取得最新發文通知🔔




    參考:
    TDX 運輸資料流通服務平台 | 官網
    TDX API 說明 | Swagger 文件工具
    TDX 官方介接說明與範例程式碼 | GitHub
    TDX 平台常見問題 | 官網


    你不可能有先見之明,只能有後見之明,
    因此,你必須相信,這些小事一定會和你的未來產生關聯。

    —— 史蒂夫·賈伯斯


    🔻 如果覺得喜歡,歡迎在下方獎勵我 5 個讚~
    分享

    Jia
    作者
    Jia
    軟體工程師 - Software Engineer