During the development of a Web application, there are some tasks we cannot finish by ourselves. For example, if our Web project needs personal or company real-name verification, clearly we do not have the ability to judge whether the verification information given by the user is true. At this time, we need to use services provided by a third-party platform to complete this operation. Another example is that if our project needs to provide online payment, this kind of business is usually also finished through a payment gateway instead of being implemented by ourselves. We only need to connect to third-party platforms such as WeChat Pay, Alipay, or UnionPay.
There are basically two ways to connect a third-party platform in a project: API integration and SDK integration.
- API integration means completing an operation or getting data by visiting a URL provided by the third party. In China, many platforms like this provide many commonly used services. For example, Juhe Data provides many kinds of APIs, such as life services, fintech, traffic and geography, recharge and payment, and so on. We can start network requests through a Python program and get data by visiting URLs. These API interfaces are the same as the data interfaces provided in our own project. The difference is that the APIs in our project are for our own use, while the APIs provided by third-party platforms are open. Of course, open does not mean free. Most APIs that can provide commercially valuable data need payment before use.
- SDK integration means installing a third-party library and using the classes and functions wrapped by that library to use the services provided by the third-party platform. For example, if we want to connect Alipay, we need to first install the Alipay SDK, and then complete the payment service call through the classes and methods wrapped by Alipay.
Next, we explain how to integrate third-party platforms through concrete examples.
An SMS service can be used in many places in a Web project, for example mobile verification code login, important message reminders, product marketing SMS, and so on. To send SMS messages, we can connect an SMS gateway. In China, well-known SMS gateways include Yunpian SMS, NetEase Yunxin, Luosimao, SendCloud, and so on. These SMS gateways usually provide free trial functions. Below, we use Luosimao as an example to explain how to connect an SMS gateway in a project. The operation of other platforms is basically similar.
-
Register an account. New users can try it for free.
-
Log in to the management backend and enter the SMS section.
-
Click "Trigger Send" to find your own API Key, which is your identity mark.
-
Click "Signature Management" to add an SMS signature. SMS messages must carry a signature. For free trial SMS, you need to add the signature
【Tieke Test】in the SMS message, otherwise the SMS cannot be sent. -
Click "IP Whitelist" and fill in the server address, meaning the public IP address of the server running the Django project, into the whitelist. If you are running locally, you can open an IP-checking website to see the public IP address of your machine. Otherwise, the SMS cannot be sent.
-
If there are no SMS credits left, go to the "Recharge" page and choose "SMS Service" to recharge.
Next, we can call the Luosimao SMS gateway to implement the function of sending SMS verification codes. The code is shown below.
def send_mobile_code(tel, code):
"""Send an SMS verification code"""
resp = requests.post(
url='http://sms-api.luosimao.com/v1/send.json',
auth=('api', 'key-your-own-api-key'),
data={
'mobile': tel,
'message': f'Your SMS verification code is {code}. Do not tell it to anyone no matter what. [Python Mini Course]'
},
verify=False
)
return resp.json()To run the code above, you need to first install the third-party library requests. This library wraps HTTP network request functions and is very easy to use. We also talked about this library before. The send_mobile_code function has two parameters. The first parameter is the mobile number, and the second parameter is the content of the SMS verification code. Line 5 of the code needs your own API Key, which is the API Key you saw in step 2 above. Requesting Luosimao's SMS gateway returns data in JSON format. If the code above returns {'err': 0, 'msg': 'ok'}, it means the SMS was sent successfully. If the value of the err field is not 0 but another value, it means the SMS failed to send. You can see what different values mean on Luosimao's official developer documentation. For example, -20 means the balance is not enough, and -32 means the SMS signature is missing.
We can call the function above in a view function to complete sending an SMS verification code. Later, we can combine this function with user registration.
Functions for generating a random verification code and validating a mobile number.
import random
import re
TEL_PATTERN = re.compile(r'1[3-9]\d{9}')
def check_tel(tel):
"""Check a mobile number"""
return TEL_PATTERN.fullmatch(tel) is not None
def random_code(length=6):
"""Generate a random SMS verification code"""
return ''.join(random.choices('0123456789', k=length))View function for sending an SMS verification code.
@api_view(('GET', ))
def get_mobilecode(request, tel):
"""Get an SMS verification code"""
if check_tel(tel):
redis_cli = get_redis_connection()
if redis_cli.exists(f'vote:block-mobile:{tel}'):
data = {'code': 30001, 'message': 'Please do not send another SMS verification code within 60 seconds'}
else:
code = random_code()
send_mobile_code(tel, code)
# Use Redis to stop repeated sending of SMS verification codes within 60 seconds
redis_cli.set(f'vote:block-mobile:{tel}', 'x', ex=60)
# Keep the verification code in Redis for 10 minutes, with a valid period of 10 minutes
redis_cli.set(f'vote2:valid-mobile:{tel}', code, ex=600)
data = {'code': 30000, 'message': 'The SMS verification code has been sent, please check it'}
else:
data = {'code': 30002, 'message': 'Please enter a valid mobile number'}
return Response(data)Note: The code above uses Redis to implement two extra functions. One is to stop the user from sending another SMS verification code within 60 seconds. The other is to keep the user's SMS verification code for 10 minutes, which means the valid period of this verification code is only 10 minutes. We can ask the user to provide this code during registration to verify whether the user's mobile number is real.
When we mention the term cloud storage, we usually mean storing data in a virtual server environment provided by a third party. Simply speaking, some data or resources are hosted through a third-party platform. Usually, companies that provide cloud storage services run large data centers. Individuals or organizations that need cloud storage buy or rent storage space from them to meet data storage needs. When developing a Web application, static resources, especially user-uploaded static resources, can be placed directly in cloud storage services. Cloud storage usually provides corresponding URLs so users can access these static resources. Well-known cloud storage services both in China and outside China, such as Amazon S3 and Alibaba OSS, are usually good and low-cost. Compared with building a static resource server by ourselves, cloud storage costs less. Also, general cloud storage platforms provide CDN service to speed up access to static resources. So from almost every angle, using cloud storage to manage the data and static resources of a Web application is a very good choice, unless these resources involve personal or business privacy. Otherwise, they can be hosted in cloud storage.
Below, we use Qiniu Cloud as an example to explain how to save user-uploaded files to Qiniu Cloud storage. Qiniu Cloud is a well-known cloud computing and data service provider in China. Qiniu Cloud has its own products in mass file storage, CDN, video on demand, live interaction, and intelligent analysis and processing of large-scale heterogeneous data. Even users who do not pay can connect to it for free and use the services it provides. Below is the process of connecting Qiniu Cloud:
-
Register an account and log in to the management console.
-
Choose Object Storage in the menu on the left side.
-
In space management, choose to create a new space, for example
myvote. If you are told the space name is already taken, change the name and try again. Notice that after creating the space, you will be prompted to bind a custom domain name. If you do not have your own domain name yet, you can use the temporary domain name provided by Qiniu Cloud, but the temporary domain name will be taken back after 30 days. So it is better to prepare your own domain name. -
Click "Key Management" in the personal avatar menu in the upper-right corner of the page to see your keys. Later, we need to use the two keys AK, meaning AccessKey, and SK, meaning SecretKey, in the code to authenticate the user.
-
Click "Documentation" in the top menu of the page to enter the Qiniu Developer Center. Choose "SDK & Tools" in the navigation menu and click the "Official SDK" submenu. Find Python, server side, and click "Documentation" to read the official documentation.
Next, as long as we follow the example in the official documentation, we can connect Qiniu Cloud and use the cloud storage and other services it provides. First, we can install the Qiniu third-party library through the command below.
pip install qiniuNext, we can use the put_file and put_stream functions in the qiniu module to implement file upload. The former uploads a file at a specified path, and the latter uploads binary data in memory to Qiniu Cloud. The code is shown below.
import qiniu
AUTH = qiniu.Auth('AccessKey from key management', 'SecretKey from key management')
BUCKET_NAME = 'myvote'
def upload_file_to_qiniu(key, file_path):
"""Upload the file at a specified path to Qiniu Cloud"""
token = AUTH.upload_token(BUCKET_NAME, key)
return qiniu.put_file(token, key, file_path)
def upload_stream_to_qiniu(key, stream, size):
"""Upload a binary data stream to Qiniu Cloud"""
token = AUTH.upload_token(BUCKET_NAME, key)
return qiniu.put_stream(token, key, stream, None, size)Below is a simple frontend page for file upload.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload File</title>
</head>
<body>
<form action="/upload/" method="post" enctype="multipart/form-data">
<div>
<input type="file" name="photo">
<input type="submit" value="Upload">
</div>
</form>
</body>
</html>Note: If the frontend uses a form to upload a file, the
methodattribute of the form must be set topost, theenctypeattribute needs to be set tomultipart/form-data, and theinputtag whosetypeattribute isfileis the file selector for uploading a file.
The view function that implements the upload function is shown below.
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload(request):
# If the uploaded file is smaller than 2.5M, the type of the photo object is InMemoryUploadedFile, and the file is in memory
# If the uploaded file is larger than 2.5M, the type of the photo object is TemporaryUploadedFile, and the file is under a temporary path
photo = request.FILES.get('photo')
_, ext = os.path.splitext(photo.name)
# Use UUID and the original file extension to generate a unique new file name
filename = f'{uuid.uuid1().hex}{ext}'
# For files in memory, we can use the wrapped function upload_stream_to_qiniu above to upload the file to Qiniu Cloud
# If the file is saved under a temporary path, we can use upload_file_to_qiniu to upload the file
upload_stream_to_qiniu(filename, photo.file, photo.size)
return redirect('/static/html/upload.html')Notice: The view function above uses the
csrf_exemptdecorator. This decorator allows the form to be exempt from the requirement of providing a CSRF token. Also, line 11 of the code uses theuuid1function in theuuidmodule to generate a globally unique identifier.
Run the project and try the file upload function. After the file is uploaded successfully, you can click your own space in Qiniu Cloud "Space Management" and enter the "File Management" page. Here you can see the file that we just uploaded successfully, and you can get this file through the domain name provided by Qiniu Cloud.









