Spy*_*lis 2 python charts matplotlib next.js fastapi
我正在为网站使用 Nextjs 前端和 FastAPI 后端。我在前端有一个“以太坊地址”的输入表单,并使用输入的地址,我在后端生成一个 matplotlib 图表,显示“一段时间内的以太坊余额”。现在,我尝试使用 FastAPI 返回此图表,以便可以在前端显示它。我不想在本地保存图表。
这是到目前为止我的相关代码:
前端/ nexjs 文件名为“Chart.tsx”。正文中的“ethAddress”正在捕获输入表单中输入的数据。
fetch("http://localhost:8000/image", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(ethAddress),
}).then(fetchEthAddresses);
Run Code Online (Sandbox Code Playgroud)
生成名为 ethBalanceTracker.py 的 matplotlib 图表的后端 python 文件
#Imports
#Logic for chart here
plt.plot(times, balances)
buf = BytesIO()
plt.savefig(buf, format="png")
buf.seek(0)
return StreamingResponse(buf, media_type="image/png")
Run Code Online (Sandbox Code Playgroud)
使用名为 api.py 的 FastAPI 的后端 python 文件
@app.get("/image")
async def get_images() -> dict:
return {"data": images}
@app.post("/image")
async def add_image(ethAddress: dict) -> dict:
test = EthBalanceTracker.get_transactions(ethAddress["ethAddress"])
images.append(test)
Run Code Online (Sandbox Code Playgroud)
我已经尝试了上面的代码和其他一些变体。我使用是StreamingResponse因为我不想在本地保存图表。我的问题是我无法显示图表localhost:8000/images并得到一个'Internal Server Error'.
您应该buf.getvalue()作为 的content传递Response,以便获取包含缓冲区全部内容的字节。StreamingResponse此外,如果整个图像数据已经加载到内存中(在本例中,在内存中的字节缓冲区中),则不应使用,而是Response直接返回 a 并设置Content-Disposition标头,以便可以将图像在浏览器中查看,如本答案以及本答案中所述。如果您使用Fetch API或 Axios 来获取图像,请查看此答案,了解如何在客户端显示图像。您还可以使用 FastAPI/Starlette在返回响应后关闭缓冲区,以释放内存,如此处所述。例子:BackgroundTasks
import io\nimport matplotlib\nmatplotlib.use(\'AGG\')\nimport matplotlib.pyplot as plt\nfrom fastapi import FastAPI, Response, BackgroundTasks\n\napp = FastAPI()\n\ndef create_img():\n plt.rcParams[\'figure.figsize\'] = [7.50, 3.50]\n plt.rcParams[\'figure.autolayout\'] = True\n fig = plt.figure() # make sure to call this, in order to create a new figure\n plt.plot([1, 2])\n img_buf = io.BytesIO()\n plt.savefig(img_buf, format=\'png\')\n plt.close(fig)\n return img_buf\n \n@app.get(\'/\')\ndef get_img(background_tasks: BackgroundTasks):\n img_buf = create_img()\n background_tasks.add_task(img_buf.close)\n headers = {\'Content-Disposition\': \'inline; filename="out.png"\'}\n return Response(img_buf.getvalue(), headers=headers, media_type=\'image/png\')\nRun Code Online (Sandbox Code Playgroud)\n如果您想get_img()成为async def端点,则可以在外部 ThreadPool 或 PorcessPool 中执行同步函数,这样事件循环就不会被阻塞。 create_img()请查看此答案,其中提供了有关如何执行此操作的详细信息和示例。
另外,如果您在使用时收到以下警告matplotlib:
UserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail.\nWARNING: QApplication was not created in the main() thread.\nRun Code Online (Sandbox Code Playgroud)\n这是因为它matplotlib不是线程安全的,并且大多数 GUI 后端需要从主线程运行(这实际上是来自 Qt 库本身的警告)。为了避免收到该警告,您可以简单地切换到非 GUI 后端\xe2\x80\x94,因为您甚至不需要后端,因为您在客户端的用户浏览器中显示图像\xe2\ x80\x94using ,如后端文档和上面的示例matplotlib.use()中所示(注意:必须在导入之前使用)。上面的示例中使用的是一个将图形渲染为 PNG 的后端。matplotlib.use()pyplotAGG
| 归档时间: |
|
| 查看次数: |
2431 次 |
| 最近记录: |