Как обслуживать статические файлы в FastAPI


person Christy Nakou    schedule 18.06.2020    source источник


Ответы (4)


В Starlette есть опция html, которую можно использовать в FastAPI. Документация по Starlette

Это позволит вам получить что-то вроде:

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

Что будет анализировать / site до /site/index.html, / site / foo / до /site/foo/index.html и т. Д.

Другие ответы могут помочь вам перенаправить, если вы хотите изменить имена папок способом, который не обрабатывается с помощью directory = / foo, но это самый простой вариант, если вы просто хотите загрузить связанные файлы .html.

person Justin Malloy    schedule 09.09.2020

Вам нужно использовать 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. Итак, вы также должны объявить его как параметр запроса. и вам нужно указать html-файл, который вы хотите отобразить с помощью Jinja ("your.html", {"request": request})

Также, чтобы напрямую вернуть 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.

person Yagiz Degirmenci    schedule 16.07.2020
comment
Это решение будет хорошо работать с фреймворком javascript (например, svelte), поскольку вы можете отображать index.html с помощью jinja, например bundle.js?{{bundle_version}}, страница будет обновлена - person Peko Chan; 10.01.2021
comment
В последнем примере """ в последней строке отсутствуют закрывающие кавычки. - person do-me; 27.01.2021
comment
Хороший улов, спасибо @ do-me - person Yagiz Degirmenci; 27.01.2021
comment
Это сломается, если вы используете шаблоны внешнего интерфейса, например. AngularJs к сведению. - person zfj3ub94rf576hc4eegm; 24.03.2021

Из документов

Первый «/ 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

person lsabi    schedule 18.06.2020

Если 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')
person Nitsan BenHanoch    schedule 17.12.2020