如何在FastAPI中提供静态文件

时间:2020-06-18 17:15:42

标签: python-3.x routes static-files fastapi pkg-resources

我正在尝试提供我在package_docs目录中拥有的静态文件。当我在浏览器中打开时:

http://127.0.0.1:8001/packages/docs/index.html,页面正在运行。

但是我要打开页面:http://127.0.0.1:8001/packages/docs/

没有源文件。输出为404 Not Found

app.mount("/packages/docs", 
    StaticFiles(directory=pkg_resources.resource_filename(__name__, 'package_docs')
    ), 
    name="package_docs")

@app.get("/packages/docs/.*", include_in_schema=False)
def root():
    return HTMLResponse(pkg_resources.resource_string(__name__, "package_docs/index.html"))


app.include_router(static.router)
app.include_router(jamcam.router, prefix="/api/v1/cams", tags=["jamcam"])

如何更改我的代码?任何建议都会有所帮助。预先谢谢你。

4 个答案:

答案 0 :(得分:4)

您需要使用FastAPI的TemplateResponse(实际上是Starlette的):

from fastapi import Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

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

templates = Jinja2Templates(directory="package_docs")

@app.get("/items/{id}")
async def example(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

Request作为Jinja2上下文中的键值对的一部分。因此,您还必须将其声明为查询参数。并且您必须指定要使用Jinja ("your.html", {"request": request})

呈现的html文件

也可以直接返回HTMLResponse,也可以使用HTMLResponse中的fastapi.responses

from fastapi.responses import HTMLResponse

@app.get("/items/", response_class=HTMLResponse)
async def read_items():
    return """
    <html>
        <head>
            <title></title>
        </head>
        <body>
        </body>
    </html>

您可以从FastAPI Custom Responses

了解更多有关自定义响应的信息

答案 1 :(得分:2)

Starlette中有一个html选项,可在FastAPI中使用。 Starlette Documentation

这将使您拥有诸如:

app.mount("/site", StaticFiles(directory="site", html = True), name="site")

将/ site解析为/site/index.html,/site/foo/解析为/site/foo/index.html,等等。

如果您要更改文件夹名称的方式不是使用“ directory = / foo”处理的方式,其他答案可以帮助您重定向,但是如果您只想加载关联的.html文件,这是最简单的选择。

答案 2 :(得分:0)

docs

第一个“ / static”是指将“挂载”该“子应用程序”的子路径。因此,任何以“ / static”开头的路径都将由它处理。

这意味着您将目录安装在http://127.0.0.1:8001/packages/docs/上,但随后需要在URL中指定文件,或像以前一样添加处理程序。但是,问题在于,由于您是先安装路径,因此不会考虑以下路径(包括路径的一部分)。

一种可能性是首先为http://127.0.0.1:8001/packages/docs/指定路径,以便fastapi处理该路径,然后挂载该文件夹,以提供静态文件。

此外,我会将要求http://127.0.0.1:8001/packages/docs/的用户重定向到http://127.0.0.1:8001/packages/docs/index.html

答案 3 :(得分:0)

如果没有app.mount选项, 您可以随时手动读取文件并使用其内容进行回复...

例如,如果您的静态文件位于/site内,则:

from os.path import isfile
from fastapi import Response
from mimetypes import guess_type


@app.get("/site/{filename}")
async def get_site(filename):
    filename = './site/' + filename

    if not isfile(filename):
        return Response(status_code=404)

    with open(filename) as f:
        content = f.read()

    content_type, _ = guess_type(filename)
    return Response(content, media_type=content_type)


@app.get("/site/")
async def get_site_default_filename():
    return await get_site('index.html')