Python 100 Days Day52 Thrid Party Platform
22 Sep 2022 | beginner pythonauthor: jackfrued
接入三方平台
在Web應用的開發過程中,有一些任務並不是我們自己能夠完成的。例如,我們的Web項目中需要做個人或企業的實名認證,很顯然我們並沒有能力判斷用戶提供的認證信息的真實性,這個時候我們就要借助三方平台提供的服務來完成該項操作。再比如說,我們的項目中需要提供在線支付功能,這類業務通常也是借助支付網關來完成而不是自己去實現,我們只需要接入像微信、支付寶、銀聯這樣的三方平台即可。
在項目中接入三方平台基本上就兩種方式:API接入和SDK接入。
- API接入指的是通過訪問三方提供的URL來完成操作或獲取數據。國內有很多這樣的平台提供了大量常用的服務,例如聚合數據上提供了生活服務類、金融科技類、交通地理類、充值繳費類等各種類型的API。我們可以通過Python程序發起網絡請求,通過訪問URL獲取數據,這些API接口跟我們項目中提供的數據接口是一樣的,只不過我們項目中的API是供自己使用的,而這類三方平台提供的API是開放的。當然開放並不代表免費,大多數能夠提供有商業價值的數據的API都是需要付費才能使用的。
- SDK接入指的是通過安裝三方庫並使用三方庫封裝的類、函數來使用三方平台提供的服務的方式。例如我們剛才說到的接入支付寶,就需要先安裝支付寶的SDK,然後通過支付寶封裝的類和方法完成對支付服務的調用。
下面我們通過具體的例子來講解如何接入三方平台。
接入短信網關
一個Web項目有很多地方都可以用到短信服務,例如:手機驗證碼登錄、重要消息提醒、產品營銷短信等。要實現發送短信的功能,可以通過接入短信網關來實現,國內比較有名的短信網關包括:雲片短信、網易雲信、螺絲帽、SendCloud等,這些短信網關一般都提供了免費試用功能。下面我們以螺絲帽平台為例,講解如何在項目中接入短信網關,其他平台操作基本類似。
-
注冊賬號,新用戶可以免費試用。
-
登錄到管理後台,進入短信版塊。
-
點擊“觸發發送”可以找到自己專屬的API Key(身份標識)。

-
點擊“簽名管理”可以添加短信簽名,短信都必須攜帶簽名,免費試用的短信要在短信中添加“【鐵殼測試】”這個簽名,否則短信無法發送。

-
點擊“IP白名單”將運行Django項目的服務器地址(公網IP地址,本地運行可以打開xxx網站查看自己本機的公網IP地址)填寫到白名單中,否則短信無法發送。

-
如果沒有剩余的短信條數,可以到“充值”頁面選擇“短信服務”進行充值。

接下來,我們可以通過調用螺絲帽短信網關實現發送短信驗證碼的功能,代碼如下所示。
def send_mobile_code(tel, code):
"""發送短信驗證碼"""
resp = requests.post(
url='http://sms-api.luosimao.com/v1/send.json',
auth=('api', 'key-自己的APIKey'),
data={
'mobile': tel,
'message': f'您的短信驗證碼是{code},打死也不能告訴別人喲。【Python小課】'
},
verify=False
)
return resp.json()
運行上面的代碼需要先安裝requests三方庫,這個三方庫封裝了HTTP網絡請求的相關功能,使用起來非常的簡單,我們在之前的內容中也講到過這個三方庫。send_mobile_code函數有兩個參數,第一個參數是手機號,第二個參數是短信驗證碼的內容,第5行代碼需要提供自己的API Key,就是上面第2步中查看到的自己的API Key。請求螺絲帽的短信網關會返回JSON格式的數據,對於上面的代碼如果返回{'err': 0, 'msg': 'ok'},則表示短信發送成功,如果err字段的值不為0而是其他值,則表示短信發送失敗,可以在螺絲帽官方的開發文檔頁面上查看到不同的數值代表的含義,例如:-20表示余額不足,-32表示缺少短信簽名。
可以在視圖函數中調用上面的函數來完成發送短信驗證碼的功能,稍後我們可以把這個功能跟用戶注冊結合起來。
生成隨機驗證碼和驗證手機號的函數。
import random
import re
TEL_PATTERN = re.compile(r'1[3-9]\d{9}')
def check_tel(tel):
"""檢查手機號"""
return TEL_PATTERN.fullmatch(tel) is not None
def random_code(length=6):
"""生成隨機短信驗證碼"""
return ''.join(random.choices('0123456789', k=length))
發送短信驗證碼的視圖函數。
@api_view(('GET', ))
def get_mobilecode(request, tel):
"""獲取短信驗證碼"""
if check_tel(tel):
redis_cli = get_redis_connection()
if redis_cli.exists(f'vote:block-mobile:{tel}'):
data = {'code': 30001, 'message': '請不要在60秒內重覆發送短信驗證碼'}
else:
code = random_code()
send_mobile_code(tel, code)
# 通過Redis阻止60秒內容重覆發送短信驗證碼
redis_cli.set(f'vote:block-mobile:{tel}', 'x', ex=60)
# 將驗證碼在Redis中保留10分鐘(有效期10分鐘)
redis_cli.set(f'vote2:valid-mobile:{tel}', code, ex=600)
data = {'code': 30000, 'message': '短信驗證碼已發送,請注意查收'}
else:
data = {'code': 30002, 'message': '請輸入有效的手機號'}
return Response(data)
說明:上面的代碼利用Redis實現了兩個額外的功能,一個是阻止用戶60秒內重覆發送短信驗證碼,一個是將用戶的短信驗證碼保留10分鐘,也就是說這個短信驗證碼的有效期只有10分鐘,我們可以要求用戶在注冊時提供該驗證碼來驗證用戶手機號的真實性。
接入雲存儲服務
當我們提到雲存儲這個詞的時候,通常是指把數據存放在由第三方提供的虛擬服務器環境下,簡單的說就是將某些數據或資源通過第三平台托管。一般情況下,提供雲存儲服務的公司都運營著大型的數據中心,需要雲存儲服務的個人或組織通過向其購買或租賃存儲空間來滿足數據存儲的需求。在開發Web應用時,可以將靜態資源,尤其是用戶上傳的靜態資源直接置於雲存儲服務中,雲存儲通常會提供對應的URL使得用戶可以訪問該靜態資源。國內外比較有名的雲存儲服務(如:亞馬遜的S3、阿里的OSS2等)一般都物美價廉,相比自己架設靜態資源服務器,雲存儲的代價更小,而且一般的雲存儲平台都提供了CDN服務,用於加速對靜態資源的訪問,所以不管從哪個角度出發,使用雲存儲的方式管理Web應用的數據和靜態資源都是非常好的選擇,除非這些資源涉及到個人或商業隱私,否則就可以托管到雲存儲中。
下面我們以接入七牛雲為例,講解如何實現將用戶上傳的文件保存到七牛雲存儲。七牛雲是國內知名的雲計算及數據服務提供商,七牛雲在海量文件存儲、CDN、視頻點播、互動直播以及大規模異構數據的智能分析與處理等領域都有自己的產品,而且非付費用戶也可以免費接入,使用其提供的服務。下面是接入七牛雲的流程:
-
注冊賬號,登錄管理控制台。

-
選擇左側菜單中的對象存儲。

-
在空間管理中選擇新建空間(例如:myvote),如果提示空間名稱已被占用,更換一個再嘗試即可。注意,創建空間後會提示綁定自定義域名,如果暫時還沒有自己的域名,可以使用七牛雲提供的臨時域名,但是臨時域名會在30天後被回收,所以最好準備自己的域名(域名需要備案,不清楚如何操作的請自行查閱相關資料)。

-
在網頁的右上角點擊個人頭像中的“密鑰管理”,查看自己的密鑰,稍後在代碼中需要使用AK(AccessKey)和SK(SecretKey)兩個密鑰來認證用戶身份。

-
點擊網頁上方菜單中的“文檔”,進入到七牛開發者中心,選擇導航菜單中的“SDK&工具”並點擊“官方SDK”子菜單,找到Python(服務端)並點擊“文檔”查看官方文檔。

接下來,只要安裝官方文檔提供的示例,就可以接入七牛雲,使用七牛雲提供的雲存儲以及其他服務。首先可以通過下面的命令安裝七牛雲的三方庫。
pip install qiniu
接下來可以通過qiniu模塊中的put_file和put_stream兩個函數實現文件上傳,前者可以上傳指定路徑的文件,後者可以將內存中的二進制數據上傳至七牛雲,具體的代碼如下所示。
import qiniu
AUTH = qiniu.Auth('密鑰管理中的AccessKey', '密鑰管理中的SecretKey')
BUCKET_NAME = 'myvote'
def upload_file_to_qiniu(key, file_path):
"""上傳指定路徑的文件到七牛雲"""
token = AUTH.upload_token(BUCKET_NAME, key)
return qiniu.put_file(token, key, file_path)
def upload_stream_to_qiniu(key, stream, size):
"""上傳二進制數據流到七牛雲"""
token = AUTH.upload_token(BUCKET_NAME, key)
return qiniu.put_stream(token, key, stream, None, size)
下面是一個文件上傳的簡單前端頁。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上傳文件</title>
</head>
<body>
<form action="/upload/" method="post" enctype="multipart/form-data">
<div>
<input type="file" name="photo">
<input type="submit" value="上傳">
</div>
</form>
</body>
</html>
說明:前端如果使用表單實現文件上傳,表單的method屬性必須設置為post,enctype屬性需要設置為multipart/form-data,表單中type屬性為file的input標簽,就是上傳文件的文件選擇器。
實現上傳功能的視圖函數如下所示。
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload(request):
# 如果上傳的文件小於2.5M,則photo對象的類型為InMemoryUploadedFile,文件在內存中
# 如果上傳的文件超過2.5M,則photo對象的類型為TemporaryUploadedFile,文件在臨時路徑下
photo = request.FILES.get('photo')
_, ext = os.path.splitext(photo.name)
# 通過UUID和原來文件的擴展名生成獨一無二的新的文件名
filename = f'{uuid.uuid1().hex}{ext}'
# 對於內存中的文件,可以使用上面封裝好的函數upload_stream_to_qiniu上傳文件到七牛雲
# 如果文件保存在臨時路徑下,可以使用upload_file_to_qiniu實現文件上傳
upload_stream_to_qiniu(filename, photo.file, photo.size)
return redirect('/static/html/upload.html')
注意:上面的視圖函數使用了
csrf_exempt裝飾器,該裝飾器能夠讓表單免除必須提供CSRF令牌的要求。此外,代碼第11行使用了uuid模塊的uuid1函數來生成全局唯一標識符。
運行項目嘗試文件上傳的功能,文件上傳成功後,可以在七牛雲“空間管理”中點擊自己空間並進入“文件管理”界面,在這里可以看到我們剛才上傳成功的文件,而且可以通過七牛雲提供的域名獲取該文件。

Comments