【Flask 3.1.2】4 访问 API 并通过队列处理任务
一、测试Redis
我这里没有配置密码等
import redis
REDIS_CONN_PARAMS = {
"host": '127.0.0.1',
"password": '',
"port": 6379,
"encoding": 'utf-8'
}
conn = redis.Redis(**REDIS_CONN_PARAMS)
conn.lpush("task_1", "123")
conn.lpush("task_1", "456")
conn.lpush("task_1", "789")
data = conn.rpop("task_1")
print(data)
成功获取输出

二、请求发送到任务队列
服务端代码
import uuid
from flask import Flask, request, jsonify
import redis
import json
app = Flask(__name__)
@app.route("/task", methods=["POST"])
def task():
"""
请求的数据格式要求:{"ordered_string": "..."}
"""
ordered_string = request.json.get("ordered_string")
if not ordered_string:
return jsonify({'status': False, 'error': "参数错误"})
# 生成任务ID
tid = str(uuid.uuid4())
# 1. 放入到redis队列中
task_dict = {
'tid': tid,
'data': ordered_string
}
REDIS_CONN_PARAMS = {
"host": '127.0.0.1',
"password": '',
"port": 6379,
"encoding": 'utf-8'
}
conn = redis.Redis(**REDIS_CONN_PARAMS)
conn.lpush("task_1", json.dumps(task_dict))
# 2. 给用户返回
return jsonify({
'status': True,
'data': tid,
'message': "正在处理中,预计10分钟完成"
})
if __name__ == '__main__':
app.run(host="127.0.0.1", port=5000)
请求端代码
import requests
# 目标URL
url = "http://127.0.0.1:5000/task"
# 要发送的请求体数据(字典形式)
data = {
"ordered_string": "dnsaonv039h09g095h1nnoc0wjv91ncmosad01-e95ghwe9nfc0mq"
}
# 发送POST请求
response = requests.post(url, json=data)
# 处理响应
print("状态码:", response.status_code) # 200表示成功
print("响应内容:", response.text) # 响应的文本内容
# 如果响应是JSON格式,可以直接解析
if response.status_code == 200:
try:
json_data = response.json()
print("JSON响应:", json_data)
except ValueError:
print("响应不是JSON格式")

三、Worker.py 读取任务队列,写入结果队列
import hashlib
import redis
import json
def get_task():
REDIS_CONN_PARAMS = {
"host": '127.0.0.1',
"password": '',
"port": 6379,
"encoding": 'utf-8'
}
conn = redis.Redis(**REDIS_CONN_PARAMS)
data = conn.brpop("task_1", timeout=10) # 阻塞式取任务,最长等待10s
if not data:
return
# data是一个元组(键, 值)
value = data[1].decode('utf-8') # 解码
return json.loads(value)
def set_result(tid, value):
REDIS_CONN_PARAMS = {
"host": '127.0.0.1',
"password": '',
"port": 6379,
"encoding": 'utf-8'
}
conn = redis.Redis(**REDIS_CONN_PARAMS)
conn.hset("task_1_result", tid, value)
def run():
while True:
# 1. 获取Redis中的任务
task_dict = get_task()
print(task_dict)
if not task_dict:
continue
# 2. 执行耗时操作 这里假设任务是返回签名
ordered_string = task_dict['data']
encrypt_string = ordered_string + "dsj08u3hvhn9219bvnzc0102u8vhkzc"
obj = hashlib.md5(encrypt_string.encode('utf-8'))
sign = obj.hexdigest()
# 3.写入结果队列 (redis的hash)
tid = task_dict['tid']
set_result(tid, sign)
if __name__ == '__main__':
run()
四、请求端读取结果队列
import uuid
from flask import Flask, request, jsonify
import redis
import json
app = Flask(__name__)
@app.route("/task", methods=["POST"])
def task():
"""
请求的数据格式要求:{"ordered_string": "..."}
"""
ordered_string = request.json.get("ordered_string")
if not ordered_string:
return jsonify({'status': False, 'error': "参数错误"})
# 生成任务ID
tid = str(uuid.uuid4())
# 1. 放入到redis队列中
task_dict = {
'tid': tid,
'data': ordered_string
}
REDIS_CONN_PARAMS = {
"host": '127.0.0.1',
"password": '',
"port": 6379,
"encoding": 'utf-8'
}
conn = redis.Redis(**REDIS_CONN_PARAMS)
conn.lpush("task_1", json.dumps(task_dict))
# 2. 给用户返回
return jsonify({
'status': True,
'data': tid,
'message': "正在处理中,预计10分钟完成"
})
@app.route("/result", methods=["GET"])
def result():
tid = request.args.get("tid")
if not tid:
return jsonify({"status": False, 'error': "参数错误"})
REDIS_CONN_PARAMS = {
"host": '127.0.0.1',
"password": '',
"port": 6379,
"encoding": 'utf-8'
}
conn = redis.Redis(**REDIS_CONN_PARAMS)
sign = conn.hget("task_1_result", tid)
if not sign:
return jsonify({
"status": True,
"data": "",
"message": "未完成 请继续等待"
})
print(sign)
sign_string = sign.decode('utf-8')
conn.hdel("task_1_result", tid) # 拿完就删除
return jsonify({
"status": True,
"data": sign_string
})
if __name__ == '__main__':
app.run(host="127.0.0.1", port=5000)
五、模拟访问
运行请求端代码,获取结果:

通过返回的id, 访问:http://127.0.0.1:5000/result?tid=772592f9-13f8-46ca-9cca-c8a7a62bee15
得到结果:

六、优化为连接池
服务端
import uuid
from flask import Flask, request, jsonify
import redis
import json
app = Flask(__name__)
REDIS_POOL = redis.ConnectionPool(
host='127.0.0.1',
password='',
port=6379,
encoding='utf-8',
max_connections=100
)
TASK_QUEUE = "task_1"
RESULT_QUEUE = "task_1_result"
@app.route("/task", methods=["POST"])
def task():
"""
请求的数据格式要求:{"ordered_string": "..."}
"""
ordered_string = request.json.get("ordered_string")
if not ordered_string:
return jsonify({'status': False, 'error': "参数错误"})
# 生成任务ID
tid = str(uuid.uuid4())
# 1. 放入到redis队列中
task_dict = {
'tid': tid,
'data': ordered_string
}
conn = redis.Redis(connection_pool=REDIS_POOL)
conn.lpush(TASK_QUEUE, json.dumps(task_dict))
# 2. 给用户返回
return jsonify({
'status': True,
'data': tid,
'message': "正在处理中,预计10分钟完成"
})
@app.route("/result", methods=["GET"])
def result():
tid = request.args.get("tid")
if not tid:
return jsonify({"status": False, 'error': "参数错误"})
conn = redis.Redis(connection_pool=REDIS_POOL)
sign = conn.hget(RESULT_QUEUE, tid)
if not sign:
return jsonify({
"status": True,
"data": "",
"message": "未完成 请继续等待"
})
print(sign)
sign_string = sign.decode('utf-8')
conn.hdel(RESULT_QUEUE, tid) # 拿完就删除
return jsonify({
"status": True,
"data": sign_string
})
if __name__ == '__main__':
app.run(host="127.0.0.1", port=5000)
Worker.py
import hashlib
import redis
import json
REDIS_POOL = redis.ConnectionPool(
host='127.0.0.1',
password='',
port=6379,
encoding='utf-8',
max_connections=100
)
TASK_QUEUE = "task_1"
RESULT_QUEUE = "task_1_result"
def get_task():
conn = redis.Redis(connection_pool=REDIS_POOL)
data = conn.brpop(TASK_QUEUE, timeout=10) # 阻塞式取任务,最长等待10s
if not data:
return
# data是一个元组(键, 值)
value = data[1].decode('utf-8') # 解码
return json.loads(value)
def set_result(tid, value):
conn = redis.Redis(connection_pool=REDIS_POOL)
conn.hset(RESULT_QUEUE, tid, value)
def run():
while True:
# 1. 获取Redis中的任务
task_dict = get_task()
print(task_dict)
if not task_dict:
continue
# 2. 执行耗时操作 这里假设任务是返回签名
ordered_string = task_dict['data']
encrypt_string = ordered_string + "dsj08u3hvhn9219bvnzc0102u8vhkzc"
obj = hashlib.md5(encrypt_string.encode('utf-8'))
sign = obj.hexdigest()
# 3.写入结果队列 (redis的hash)
tid = task_dict['tid']
set_result(tid, sign)
if __name__ == '__main__':
run()
浙公网安备 33010602011771号