在FastAPI自动文档中插入本地图片

问题描述 投票:0回答:2

简介

FastAPI当您使用FastAPI创建API时,可以自动生成您的文档。

我正在尝试在我的一个端点的描述(降价)中插入图像,但当图像位于本地硬盘中时我无法执行此操作。

我尝试过直接插入(查看本文末尾),但是不行。

我尝试创建一个端点来提供图像,在这种情况下,只有当地址的 IP 是我的公共 IP 时它才有效。如果我输入

localhost
127.0.0.1
,则不起作用。我想我在这里遗漏了一些东西。

最小示例

安装:

$ pip install fastapi
$ pip install "uvicorn[standard]"

文件:

main.py

from fastapi import FastAPI
from fastapi.responses import FileResponse

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/my-endpoint")
def example_function():
    """
    Documentation for my enpoint. Insert some images

    1) This online image works:

    ![This image works](https://upload.wikimedia.org/wikipedia/commons/0/08/STockholmspanorama_1928b.jpg)
    
    2) This local image doesn't work:
    
    ![This image doesn't work](/home/test01/example-photo.jpg)

    3) This local image served by the api works if the link is to the public IP:

    ![This image works](http://10.0.0.15:8000/img/example-photo.jpg)

    4) This local image served by the api doesn't work because when specified as localhost:

    ![This image doesn't work](http://127.0.0.1:8000/img/example-photo.jpg)

    ![This image doesn't work](http://localhost:8000/img/example-photo.jpg)

    """
    return {"This is my endpoint"}


# An endpoint to serve images for documentation
@app.get("/img/example-photo.jpg")
async def read_image():
    return FileResponse("example-photo.jpg")

使用以下命令执行 API:

$ uvicorn main:app --reload --host 0.0.0.0 --port 8000

您可以访问自动文档:

http://<you-ip>:8000/docs

示例结果

Result of the automatic documentation

额外

在我的实际案例中,文件夹结构如下:

/myProject/
|
|---/docs/
|     |---/img/
|           |---example-photo.jpg
|
|---/src/
       |---/myApp/
              |----main.py

如果我尝试直接插入图像,它不会显示任何内容。

![This image does not work](../../docs/img/example-photo.jpg)
python swagger markdown fastapi openapi
2个回答
3
投票

选项1

本地镜像应该可以正常工作;您所要做的就是将

example-photo.jpg
移动到
main.py
文件所在的目录,因为
return FileResponse("example-photo.jpg")
正在启动应用程序的目录下查找该图像。

但是,使用您的方法,您需要每个图像都有一个端点。或者,您可以声明一个 path 参数,以便您可以传递引用项目中图像的任何文件名。您还应该创建一个文件夹,例如

images
(在下面的示例中,它应该与
main.py
文件位于同一目录中),其中保存所有相关图像;否则,用户可能会通过传递指向您的 Python 文件和/或主目录中的其他敏感数据的文件名来获得对敏感信息的未经授权的访问,这些文件必须远离所有外部人员。示例:

from fastapi import FastAPI
from fastapi.responses import FileResponse
import os

app = FastAPI()

@app.get("/")
def main():
    """
    1) This online image works:

    ![This image works](https://upload.wikimedia.org/wikipedia/commons/0/08/STockholmspanorama_1928b.jpg)

    2) This local image works:

    ![This image works](http://127.0.0.1:8000/img/example-photo.jpg)
    
    3) This local image works:

    ![This image works](http://localhost:8000/img/example-photo.jpg)
    """
    return "success"


# An endpoint to serve images for documentation
@app.get("/img/{filename}")
def get_img(filename: str):
    filepath = os.path.join('images/', os.path.basename(filename))
    return FileResponse(filepath)

选项 2(推荐解决方案)

一个更优雅的解决方案是将

StaticFiles
实例挂载到特定目录,例如
static
(它不一定需要与您的
main.py
文件位于同一目录中)——如 this 中所述答案——这将允许您从该目录自动提供静态文件。任何以
/static
开头的路径(如果您愿意,您可以选择不同的路径名称)都将由它处理。下面的
directory="static"
指的是包含静态文件/图像的目录名称。示例:

from fastapi import FastAPI
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles

app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")

@app.get("/")
def main():
    """
    1) This online image works:

    ![This image works](https://upload.wikimedia.org/wikipedia/commons/0/08/STockholmspanorama_1928b.jpg)

    2) This local image works:

    ![This image works](http://127.0.0.1:8000/static/example-photo.jpg)
    
    3) This local image works:

    ![This image works](http://localhost:8000/static/example-photo.jpg)
    """
    return "success"

0
投票

您可以在文档中使用相对URL,例如:

![This image uses a relative URL](/img/example-photo.jpg)

然后浏览器使用与获取文档页面相同的域来访问图像。

© www.soinside.com 2019 - 2024. All rights reserved.