在Python中使用FastAPI和Celery结合HDFS(Hadoop Distributed File System)进行异步上传图文教程,可以分为以下几个步骤来实现:
步骤 1: 环境准备
-
安装必要的库
pip install fastapi uvicorn celery hdfs -
安装Redis
Celery 使用 Redis 作为消息代理,确保 Redis 已经安装并运行。
# 安装Redis sudo apt-get install redis-server
步骤 2: 创建FastAPI应用
创建一个main.py文件,设置FastAPI应用:
from fastapi import FastAPI, HTTPException, File, UploadFile
from celery import Celery
import os app = FastAPI()
# 设置Celery
celery = Celery('tasks',
broker='redis://localhost:6379/0',
backend='redis://localhost:6379/0')
@app.post("/upload/")
async def upload_file(file: UploadFile = File(...)):
try:
task = upload_to_hdfs.delay(file.filename, file.content)
return {"status": "success", "task_id": task.id}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)
步骤 3: 创建Celery任务
在同一个目录下创建一个tasks.py文件,定义上传到HDFS的任务:
from celery import shared_task
from hdfs import InsecureClient
import io
# 配置HDFS客户端
client = InsecureClient('http://localhost:50070',
user='your_username')
@shared_task(bind=True)
def upload_to_hdfs(self, filename, file_content):
with io.BytesIO(file_content) as buffer:
buffer.seek(0) # 重置指针位置到文件开始处
client.upload(f'/user/your_username/{filename}', buffer)
return f"File {filename} uploaded successfully."
步骤 4: 运行你的应用和Celery worker
-
启动Redis服务器 (如果尚未启动):
redis-server -
启动Celery worker:
celery -A tasks worker --loglevel=info -
运行FastAPI应用:
uvicorn main:app --reload
步骤 5: 测试上传功能
使用Postman或者curl来测试上传功能:
curl -X POST http://127.0.0.1:8000/upload/ -F "file=@path_to_your_file" -H "Content-Type: multipart/form-data"
确保替换path_to_your_file为你的文件路径。你应该会看到一个包含任务ID的响应。你可以使用这个ID来跟踪任务状态。
步骤 6: (可选) 监控任务状态
你可以在FastAPI中添加一个端点来获取任务状态:
@app.get("/status/{task_id}")
async def get_task_status(task_id: str):
task = upload_to_hdfs.AsyncResult(task_id) # 使用AsyncResult以支持异步查询状态
if task.state == 'PENDING':
response = {"state": task.state, "status": "Pending..."}
elif task.state != 'FAILURE':
response = {"state": task.state, "status": task.info} # 获取任务结果或错误信息等。
else: # 任务失败时,获取失败的原因。
response = {"state": task.state, "status": str(task.info)} # 这里可以更详细地获取异常信息等。
return response
这样,你可以通过访问/status/{task_id}来检查任务的执行状态