Python 3.x 如何在FastAPI中提供静态文件

Python 3.x 如何在FastAPI中提供静态文件,python-3.x,routes,static-files,fastapi,pkg-resources,Python 3.x,Routes,Static Files,Fastapi,Pkg Resources,我正在尝试为包目录中的静态文件提供服务。当我在浏览器中打开时: ,页面正在运行 但我想打开页面: 没有源文件。并且输出为404未找到 app.mount("/packages/docs", StaticFiles(directory=pkg_resources.resource_filename(__name__, 'package_docs') ), name="package_docs") @app.get("/packages/docs/.*", includ

我正在尝试为包目录中的静态文件提供服务。当我在浏览器中打开时:

,页面正在运行

但我想打开页面:

没有源文件。并且输出为
404未找到

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"])
如何更改代码?任何建议都会有帮助。提前谢谢。

来自

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

这意味着您将在装载目录,但是您需要在URL中指定一个文件,或者像以前那样添加一个处理程序。但问题是,由于您首先装载了路径,因此它不会考虑包含部分路径的以下路径

一种可能性是首先指定的路径,以便由fastapi处理,然后装载文件夹,为静态文件提供服务


另外,我会将请求的用户重定向到

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

请求
作为Jinja2上下文中键值对的一部分。因此,还必须将其声明为查询参数。你必须指定一个html文件,你想用Jinja
(“your.html”,{“request”:request})

另外,要直接返回HTMLResponse,您可以使用
fastapi.responses中的
HTMLResponse

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.responses导入HTMLResponse
@app.get(“/items/”,response\u class=HTMLResponse)
异步def read_items():
返回“”
"""

您可以从

了解有关自定义响应的更多信息Starlette中有一个html选项,可以在FastAPI中使用

这将使您拥有以下内容:

app.mount("/site", StaticFiles(directory="site", html = True), name="site")
它将解析/site-to/site/index.html、/site/foo/to/site/foo/index.html等


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

如果
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')

此解决方案与javascript框架(例如svelte)配合使用效果很好,因为您可以使用jinja呈现index.html,如
bundle.js?{{bundle\u version}}
页面将是最新的,上一个示例中缺少关闭引号
“”“
在最后一行。捕捉得很好,谢谢@do meThis。如果您使用前端模板,例如AngularJs,请参考。
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')