DevOps-Automation with Python 15

Website Monitoring 2: Automated Email Notification(with語法)

ZONGRU Li
7 min readNov 14, 2023

Email Notification

這邊就要加入寄信的相關Python程式,會使用到smtplib這個library

並且會需要有A email寄信給B eamil的程式內容

首先要填寫的是寄送的SMTP主機,例如google的會是"smtp.gmail.com"

基礎寫法如下:

上面587 PORT是gmail的SMTP Server對應的

接下來要透過Python的關鍵語法來改造 — with

with語法:

用來加以控制那些不在我們掌控下的外部Resource元件或應用程式或檔案等

可以用來取代try finally的寫法,並讓Code看起來更加整潔!

原本使用try finally在針對檔案操作寫法可能如下

但是改用with寫法可以寫成如下:

以下是講師課程內容解釋

with statement:

  • alternative to try/finally statements
  • is used in exception handling and clean up code to make code cleaner
  • used with unmanaged resources (e.g. file handling)

我們這邊例子寫法就會是

如上smtp即是前面smtplib.SMTP(blablabla....的簡化物件

接下來就是簡單處理一下帳號密碼的部分

首先帳號就是email位置

再來就是考量到若沒有啟用two-way verification(雙因素認證)

就會必須填寫真的密碼在Python程式碼內

並且這時候要啟用"less secure app"的Google account設置

首先到以下連結:

https://myaccount.google.com/lesssecureapps

大概某年後就已經不給啟用了

講師畫面長這樣,可以切換:

如本圖中啟用狀態下,就可以透過email帳號與密碼來使Python寄信

講師另一個帳號則是顯示:

這時候可以另外建立應用程式使用的密碼也就是Token

來到以下的連結:

https://myaccount.google.com/u/1/apppasswords

在啟用google帳號的雙因素認證後,就會看到以下畫面

例如:

建立後會看到密碼:

然後我們會希望把這類帳號密碼資訊放到環境變數去

就會需要os這個Library,最後寫法變成

這時候可以注意到我們變數都用大寫

Constants:

  • Best Practice: to write them uppercase
  • in Python: there is NO difference, just semantics Python interpreter treats them the same
  • in general: a constant is a variable, whose value cannot be changed by the program

其他程式語言處理常數可能長這樣:

或是這樣:

而在Python撰寫上就簡單用全大寫的方式來區分

接著就是要在terminal內設置環境變數

#Terminal建立環境變數:
export EMAIL_ADD="email帳號"
export EMAIL_PWD="剛剛弄的應用程式Token"

#確認:
echo $EMAIL_ADD

但是以上設置只是給到Terminal,還沒給到Python程式使用

而且換到另一個Terminal也沒效果

要持久化地設置環境變數,例如Mac機台就要

#Mac機台持久化環境變數設置(但是設置完,PyCharm要重啟才會吃到):
vi ~/.bash_profile

但是在PyCharm尚有其他的選擇:

然後就可以開始新增只針對PyCharm內可以使用的環境變數:

如上就把EMAIL_ADD跟EMAIL_PWD的環境變數填入

最後就要寫寄信邏輯:

這邊讓收件者等同自己

所以寫成:

程式直接執行目前會回應正常:

後來發現這邊要用數字,不是字串,改成這樣:

這邊故意讓其失敗:

然後執行後反而撞到一些錯誤:

後來發現是PyCharm的環境變數的KEY設錯,然後改對它還一直跳回錯的...

改正後順利執行完成

到自己信箱看到:

改回if判斷式後程式當前長這樣:

Handle Connection Error

我們現在Python程式會去檢視HTTP的Response Code

但如果連Response都沒有的話該怎麼辦!?

也就是在requests.get(URL)這行就出現Exception

比如到機台內關掉Nginx container

再次執行程式會看到連線錯誤:

這邊就要加入try except

執行後看到:

另外為了加強這段錯誤處理,在攔截到連線網站發生連線異常時候

也一併寄信通知,所以可以複製整段寄信的程式到Exception處理:

而可以看到上面有很多重複的程式,很適合寫成Function

另外下方連線異常的寄信也是:

這時候Nginx container還是關閉的當下,再次執行

連線失敗

當前完整程式碼:

這邊我就先把linode機台移除,然後先移除google的應用程式密碼(LINK):

變成

參考課程reference

--

--

ZONGRU Li

2022/11/17 開源部分個人筆記給LINE "Java程式語言討論區"社群,希望能對社群的技術學習做一點點貢獻.(掩面....記得退訂閱!