在使用 API 服務 (例如 Line Notify, OpenAI) 時都要申請金鑰 (Key) 或權杖 (Token), 於程式中呼叫 API 時必須同時送出金鑰或權杖才能獲得回應. 但把它們以明碼方式放在程式中並不安全, 常常在分享程式時不慎洩漏出去, 最好是將它們隱藏在系統變數裡, 與程式分離開來較安全, 有兩個好用的 Python 第三方模組可以輕鬆辦到 : python-decouple 與 python-dotenv:
1. 使用 python-decouple 套件儲存環境變數 :
python-decouple 為第三方套件, 須先用 pip install 指令安裝 :
pip install python-decouple
D:\python\test>pip install python-decouple
Collecting python-decouple
Downloading python_decouple-3.8-py3-none-any.whl (9.9 kB)
Installing collected packages: python-decouple
Successfully installed python-decouple-3.8
教學文件參考 :
首先在專案工作目錄下用記事本新增一個檔名為 .env 的純文字檔, 以如下格式將金鑰或權杖值設為環境變數 :
環境變數名稱=金鑰/權杖
可以同時定義多個環境變數 (一列一個, 環境變數名稱習慣上使用全大寫), 但要注意右邊的值不可以加引號. 然後將此 .env 檔以 utf-8 編碼方式存檔. 這種以點號開頭的都是隱藏檔, 必須在檔案總管的 "檢視/顯示" 中勾選 "隱藏的檔案" 才看得到.
例如 :
LINE_NOTIFY_TOKEN=ud7PaDL45fz849A0e1f5oaMCbRIkxMXapQCt7PfNkzz
使用時先從 decouple (注意不是 python-decouple) 匯入 config() 函式 :
from decouple import config
然後呼叫 config() 並傳入環境變數名稱即可取得所儲存之金鑰或權杖 :
line_token=config('LINE_NOTIFY_TOKEN') # 取得 Line Notify Token
例如 :
>>> from decouple import config
>>> config('LINE_NOTIFY_TOKEN')
'ud7PaDL45fz849A0e1f5oaMCbRIkxMXapQCt7PfNkzz'
也可以用內建模組 os 的 environ 字典來檢視或取得環境變數 :
>>> import os
>>> os.environ['LINE_NOTIFY_TOKEN']
'ud7PaDL45fz849A0e1f5oaMCbRIkxMXapQCt7PfNkzz'
但這種方法在環境變數不存在時會拋出 KeyError 例外, 須用 try except 捕捉, 例如 :
>>> os.environ['OPENAI_API_KEY']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\tony1\AppData\Local\Programs\Thonny\lib\os.py", line 680, in __getitem__
raise KeyError(key) from None
KeyError: 'OPENAI_API_KEY'
最好是呼叫 os.environ.get() 或 os.getenv() 函式來取得, 若變數不存在時會傳回 None :
>>> os.environ.get('LINE_NOTIFY_TOKEN')
'ud7PaDL45fz849A0e1f5oaMCbRIkxMXapQCt7PfNkzz'
>>> os.getenv('LINE_NOTIFY_TOKEN')
'ud7PaDL45fz849A0e1f5oaMCbRIkxMXapQCt7PfNkzz'
>>> print(os.environ.get('OPENAI_API_KEY'))
None
2. 使用 python-dotenv 套件儲存環境變數 :
python-dotenv 也是第三方套件, 須先用 pip install 指令安裝 :
pip install python-dotenv
D:\python\test>pip install python-dotenv
Collecting python-dotenv
Downloading python_dotenv-1.0.0-py3-none-any.whl (19 kB)
Installing collected packages: python-dotenv
Successfully installed python-dotenv-1.0.0
教學文件參考 :
使用方式很簡單, 同樣也是要先在工作目錄下準備一個檔名為 .env 的純文字隱藏檔設定環境變數的 key-value 對 (參考上面做法), 然後從 dotenv 套件載入 load_dotenv() 函式 :
from dotenv import load_dotenv
接著呼叫 load_dotenv() 函式, 它會從 .env 檔讀取 key-value 對並將其設為環境變數, 設定成功會傳回 True, 例如 :
>>> from dotenv import load_dotenv
>>> load_dotenv()
True
然後匯入內建模組 os, 呼叫 os.environ.get() 函式並傳入環境變數名稱即可取得其值, 例如 :
>>> import os
>>> os.environ.get('LINE_NOTIFY_TOKEN')
'ud7PaDL45fz849A0e1f5oaMCbRIkxMXapQCt7PfNkzz'
不過要注意的是, 如果工作目錄使用 Git 備份到例如 GitHub 等遠端寄存庫 (repository), 則這個 .env 檔也會被上傳, 若寄存庫是公開的, 那 .env 檔內的金鑰或權杖也會被無意中公開, 這可以透過 將 .env 寫入 .gitignore 檔中來防止, 當使用 git commit 指令進行提交時就會跳過 ,env 檔. 參考 :
3. 用環境變數儲存 Line Notify 權杖 :
以下使用 python-dotenv 套件來載入透過 ,env 檔設定的 Line Notify 權杖環境變數 :
# dotenv_test.py
import os
import socket
import requests
from dotenv import load_dotenv
def line_notify(msg, token):
url="https://notify-api.line.me/api/notify"
headers={"Authorization": "Bearer " + token,
"Content-Type": "application/x-www-form-urlencoded"
}
payload={"message": msg}
r=requests.post(url, headers=headers, params=payload)
return r.status_code
if __name__ == '__main__':
load_dotenv() # 載入環境變數
msg='dotenv 測試'
token=os.environ.get('LINE_NOTIFY_TOKEN') # 取得 Line Notify 權杖
code=line_notify(msg, token)
if code==200:
print('Line 訊息發送成功!')
else:
print('Line 訊息發送失敗!')
此例使用 python-dotenv 套件的 load_dotenv 來載入環境變數, 然後透過 os.environ.get() 取得 Line Notify 的權杖, 最後傳給 line_notify() 函式發送訊息, 結果如下 :
沒有留言:
張貼留言