Flask VS. FastAPI
Flask和FastAPI是Python中两种流行的Web框架,它们各自具有不同的特点和适用场景。以下是它们之间的一些主要区别:
1. 框架类型
- Flask:Flask是一个轻量级的微框架,适合构建小型到中型的Web应用。它灵活且易于扩展,允许开发者根据需要添加各种插件。
- FastAPI:FastAPI是一个现代的高性能Web框架,专注于构建API。它基于Python 3.7+的类型提示,支持异步编程,提供了更丰富的功能。
2. 性能
- Flask:在处理同步请求方面表现良好,但在高并发和I/O密集型任务中性能可能不如FastAPI。
- FastAPI:由于支持异步请求处理,FastAPI在性能上表现优越,能够轻松应对高负载的请求。
3. 异步支持
- Flask:Flask本身不支持异步编程。如果需要异步功能,开发者需要使用额外的库或工具。
- FastAPI:FastAPI原生支持异步编程,可以使用
async
和await
来定义异步路由,使得处理并发请求更加高效。4. 数据验证
- Flask:Flask没有内置的数据验证功能,通常需要使用第三方库(如WTForms)来实现。
- FastAPI:FastAPI利用Pydantic进行数据验证,能够自动处理请求参数和响应体的验证,大大减少了错误请求的发生。
5. 文档生成
- Flask:Flask需要手动编写API文档或使用第三方库(如Flask-RESTPlus)来生成文档。
- FastAPI:FastAPI自动生成交互式API文档(基于OpenAPI和Swagger UI),无需额外配置即可访问。
6. 社区和生态系统
- Flask:Flask拥有一个成熟且庞大的社区,提供了丰富的第三方扩展和插件。
- FastAPI:虽然相对较新,但FastAPI的社区正在快速增长,并逐渐形成了自己的生态系统。
7. 学习曲线
- Flask:由于其简洁性,Flask通常被认为更容易上手,适合初学者。
- FastAPI:由于采用了现代Python特性(如类型提示和异步编程),FastAPI的学习曲线可能相对陡峭,但一旦掌握,其开发效率会显著提高。
总结
选择Flask还是FastAPI取决于项目需求:
- 如果你需要构建简单的Web应用或原型,并且希望快速上手,可以选择Flask。
- 如果你正在开发高性能的API,并且希望利用异步编程和自动化文档生成功能,FastAPI将是更好的选择。
这两个框架各有优势,可以根据具体情况进行选择。
gunicorn VS unicorn
gunicorn:
--workers: 指定启动的进程数;(每个进程都会加载一份模型!)
--threads: 指定每个进程启动的线程数;
python的话,由于GIL锁的作用,里面的API根本无法被并行执行的;
可被并行执行的方案:FastAPI + API都用async调用 + IO操作用await版本的 + threads设为大于1
实例代码:
from fastapi import FastAPI import asyncio app = FastAPI() # Asynchronous function that simulates a delay async def simulate_long_task(task_id: int): print(f"Task {task_id} started...") await asyncio.sleep(5) # Simulates a long-running task (non-blocking) print(f"Task {task_id} completed!") return f"Result of task {task_id}" @app.get("/tasks/{task_id}") async def run_task(task_id: int): result = await simulate_long_task(task_id) return {"task_id": task_id, "result": result} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
当第1个request执行到await asyncio.sleep(5)那里时,会放弃线程;从而第2个request开始执行run_task;
执行命令和结果:
curl http://localhost:8000/tasks/1 & curl http://localhost:8000/tasks/2 & curl http://localhost:8000/tasks/3 & Task 1 started... Task 2 started... Task 3 started... Task 1 completed! Task 2 completed! Task 3 completed!
以上案例,如果换成普通的time.sleep(5),或者--threads设成1,则只能串行执行requests