除了把 Python 整合出來的數據結果以表格、互動圖表等的方法展示出來以外,您亦可以在運算完畢時把結果以電郵方式寄送到自己的郵箱!
假如您有一些每天都需要製做的報告,那麼除了人手在 Outlook 裡複製貼上以外,您還可以每天運行同一個 Python 的編程(script),自動把電郵發送到有關人士手上!
以下我們來學學如何使用 Mailjet 的免費限額從 Python 發電郵吧。
簡單的製成品
完成這篇教學後,我們會製成以上的電郵,而這封電郵是直接從 Python 發出到我們的郵箱!
當然,這只是一個初階的例子,我們在下一篇會介紹如何製成更加精美的電郵。在此之前,我們先來學習基本功吧!
申請資格
基本上如果您有一個電郵地址,便可以開始使用 Mailjet Email API!
哪怕您的電郵地址是 @gmail.com,也可以透過簡單的電郵認證直接開始使用這個服務。
當然,如果您有一個自訂的網域(Domain),那麼最好當然是使用自己的網域(例如 @mydomain.com),便可以享受完整的電郵服務。如果您的電郵地址是大眾服務(例如 Gmail、Hotmail 等),由 Python 發出電郵很大機會會墮進垃圾郵件(Spam)喔!
第一步:註冊 Mailjet 帳戶
首先我們到 Mailjet 網站註冊新的帳戶:https://www.mailjet.com/
在主頁按一下 “Get Started”。
填寫您希望使用的電郵地址、帳戶密碼,並完成 reCAPTCHA。
填寫有關您的資料,例如公司/機構名稱等。
因為我們只需要使用免費試用版,便不用填寫信用卡資料,可以直接按 “Complete Order”。
Mailjet 應該會向您的電郵地址發送一封認證電郵。按一下電郵的認證連結。
在瀏覽器新一頁會顯示 Welcome,在這頁選擇 “Developer”。
選擇以 API 的形式發送電郵,並按一下 “Continue”。
在 Coding Language 一欄選擇 “Python”。
在下方會見到 “Install the package” 和 “Send your first email” 的指示。
我們在下一步會介紹如何到 VS Code/您的編程器使用這段編程。
第二步:到 VS Code 以 API 發送第一封電郵
架設 Virtualenv 及安裝 mailjet_rest
首先我們開啟一個新的文件夾,並架設一個新的 virtual environment。
在這個 virtual environment(下圖為 .venv
),我們在 Terminal 運行以下指令:
pip install mailjet_rest
開啟新的 .py 文件並加入 Python 編程
接下來我們把第一步獲得的程式碼貼上一個新的文件,並取名為 mailjet.py。
這裡略略介紹一下這段編程的元素。api_key
和 api_secret
就是您 mailjet 帳戶的用戶名稱和密碼,這段編程透過一個網路的 POST request(就好像到瀏覽器開啟一個網頁一樣),以
和 api_key
「登入」mailjet 並指令 mailjet 系統發出郵件。因此記得把 api_secret
和 api_key
保管妥當喔!api_secret
除此之外,這個 POST request 的數據是 data
這個函數,而它是一個字典(Dictionary),可以讓您指定發件人(From)、收件人(To)、主題(Subject)、郵件內容(TextPart 和 HTMLPart)等。
如果您使用 Python 3.X,記得將原本的編程最後兩句的 print 改為以下 Python 3.X 的語法:
print(result.status_code) print(result.json())
注意!不要把 .py 檔案命名為 email.py
這是一個我找了很久才發現解決方法的一個小問題。如果您想使用 Mailjet 的 Python Library (即是 mailjet_rest),千萬不要把您的 .py 檔案命名為 email.py,否則您的 Python 程序會跳出以下的錯誤:
ImportError: cannot import name 'Client' from 'mailjet_rest'
這裡附上找到這個答案的大大:https://github.com/mailjet/mailjet-apiv3-python/issues/33
運行 mailjet.py 去發送 API 認證電郵
儲存了 mailjet.py 以後,我們到 Terminal 輸入以下代碼運行:
python mailjet.py
我們可以見到在指令運行後有 2 個輸出。
- 「200」是
result.status_code
的輸出,代表成功發出這個 POST 的網路請求(request)。如果見到這個輸出不是 200,就代表指令未能完成 - {‘Messages’: []} 代表 mailjet 回送的結果,可以見到 Status 是 ‘success’ 和這個電郵的發送人/收件人。如果
result.status_code
不是 200 的話,{‘Messages’: []} 會顯示這段代碼失敗的原因
確認收到郵件並完成 Mailjet API 登記
回到您的電子郵箱,我們會發現剛才的API 認證電郵在我們的郵箱中。
如果您使用 Gmail 或其他的免費郵箱註冊 Mailjet,那麼這封電郵很大機會將在您的垃圾郵件中。這是因為 Google 或其他的郵箱服務有時會把不是從 Gmail 發出的 @gmail.com 電郵認作虛假/詐騙電郵。
因此,如果您希望發送電郵作商業用途/其他非個人用途,最好就註冊自己的域名(Domain name)並使用 @yourdomain.com 的電郵地址註冊 Mailjet 服務。
完成後,我們回到 Mailjet 並按一下 “Verify Now” 的按鈕,可以見到 Mailjet 確認我們成功透過他們的 API 發送郵件!
第三步:自訂含有 pandas dataframe 的簡單郵件
現在我們把原來的程式碼稍為改變以下,製成我們開首展示的電郵吧!
使用 pandas_datareader 讀取股票數據
# 透過 pandas_datareader 讀取當天數據 import datetime import pandas as pd from pandas_datareader import get_data_yahoo pd.options.display.float_format = '{:,.2f}'.format symbol = '0005.HK' endDate = datetime.datetime.now() startDate = endDate - datetime.timedelta(days=10) df = get_data_yahoo(symbol, startDate, endDate) lastprice = df.tail(1)['Adj Close'][0]
這個具體的方法我們在 新手 2/3:Google Colab 如何製做互動表格和圖表?快來學 Import library/Jupyter 提及過,有興趣從零開始了解可以到上面的連結看看喔。
由於我們新的 virtual environment 沒有安裝 pandas_datareader,記得先在 Terminal 運行以下指令:
pip install pandas_datareader
留意我們特別加入了 pd.options.display.float_format
的一句。這是為了在電郵上表格的數字格式。
(重點)生成 HTML 代碼
html = ''' <center><h1>''' + symbol + ''' 的股價走勢報告</h1></center> <br> <p>''' + f'截止 {df.index[-1]:%Y/%m/%d},{symbol} 的股價為' + '''</p> <h2>'''+ f'{lastprice:.2f}' + '''</h2> <p>以下是 5 天走勢:</p>''' + df.tail(5).to_html()+ ''' <br> <p>此致,</p> <p>Python Viz</p> '''
這裡是本次教學的重點。我們需要透過生成一段 HTML 代碼,組成我們的電郵主體(body)。
我們不在這裡詳談 HTML 的格式(畢竟我們不是 htmlviz),但這裡想重點介紹以下有關 Python 的要點:
f{'some string {num: format}'}
是一個強大的數字格式功能。我們透過例如{df.index[-1]:%Y/%m/%d}
把日期轉換成為 “2021/04/16” 格式的 string。還未背熟這個編程方法的朋友記得記下來!- 我們使用
dataframe.to_html()
功能將 pandas dataframe 轉換稱 HTML 代碼,可以直接使用於這個電郵主體上。
熟悉 HTML/網頁設計的朋友會知道我們可以透過加入 CSS 代碼,使電郵變得更加華倫華美。但是這個要留待我們下一篇教學了!
生成電郵的 API request
data = { 'Messages': [ { "From": { "Email": "[email protected]", "Name": "Python" }, "To": [ { "Email": "[email protected]", "Name": "Python" } ], "Subject": symbol + '的股價走勢報告', "TextPart": symbol + '的股價走勢報告', "HTMLPart": html, "CustomID": "AppGettingStartedTest" } ] }
這裡我們修改了 Subject, TextPart 和 HTMLPart 的代碼,改為使用我們剛才生成的、含有股票價格數據的 HTML 代碼。
第四步:完整代碼及結果
以下是我們以上例子的完整代碼,您只要把 api_key、api_secret、data 裡面的 From/To 改成您的 Mailjet 設定便可以試試了:
# Mailjet 的設定 from mailjet_rest import Client import os api_key = '您的 Mailjet api_key' api_secret = '您的 Mailjet api_secret' mailjet = Client(auth=(api_key, api_secret), version='v3.1') # 透過 pandas_datareader 讀取當天數據 import datetime import pandas as pd from pandas_datareader import get_data_yahoo pd.options.display.float_format = '{:,.2f}'.format symbol = '0005.HK' endDate = datetime.datetime.now() startDate = endDate - datetime.timedelta(days=10) df = get_data_yahoo(symbol, startDate, endDate) lastprice = df.tail(1)['Adj Close'][0] # 製做 HTML 內容作為郵件主體 html = ''' <center><h1>''' + symbol + ''' 的股價走勢報告</h1></center> <br> <p>''' + f'截止 {df.index[-1]:%Y/%m/%d},{symbol} 的股價為' + '''</p> <h2>'''+ f'{lastprice:.2f}' + '''</h2> <p>以下是 5 天走勢:</p>''' + df.tail(5).to_html()+ ''' <br> <p>此致,</p> <p>Python Viz</p> ''' data = { 'Messages': [ { "From": { "Email": "您的電郵地址", "Name": "您的名稱" }, "To": [ { "Email": "您的電郵地址", "Name": "您的名稱" } ], "Subject": symbol + '的股價走勢報告', "TextPart": symbol + '的股價走勢報告', "HTMLPart": html, "CustomID": "AppGettingStartedTest" } ] } result = mailjet.send.create(data=data) print(result.status_code) print(result.json())
發出電郵以後,如果您使用 @gmail.com 的電郵地址發出,您會在 Gmail 見到以下的警告:
這也再次說明如果我們有自己的域名(Domain name),使用自己域名的電郵地址(如 @yourdomain.com)可以減低電郵被郵件服務視作垃圾郵件的機會!
下一步
我們下一次會介紹如何把這個 Python 發出的電郵透過免費的網上服務變得更加精美,以及如何在電郵嵌入(Embed)透過 plotly 製做的數據圖表。記得留意詳情了!