FastAPI is not loading static files

Question:

So, I’m swapping my project from node.js to python FastAPI. Everything has been working fine with node, but here it says that my static files are not present, so here’s the code:

from fastapi import FastAPI, Request, WebSocket
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

app = FastAPI()

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

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

The project’s structure looks like this:
Project structure

Files are clearly where they should be, but when I connect to the website, the following error occurs:

←[32mINFO←[0m:     connection closed
←[32mINFO←[0m:     127.0.0.1:54295 - "←[1mGET /img/separator.png HTTP/1.1←[0m" ←[31m404 Not Found←[0m
←[32mINFO←[0m:     127.0.0.1:54296 - "←[1mGET /css/rajdhani.css HTTP/1.1←[0m" ←[31m404 Not Found←[0m
←[32mINFO←[0m:     127.0.0.1:54295 - "←[1mGET /js/pixi.min.js HTTP/1.1←[0m" ←[31m404 Not Found←[0m
←[32mINFO←[0m:     127.0.0.1:54296 - "←[1mGET /js/ease.js HTTP/1.1←[0m" ←[31m404 Not Found←[0m
←[32mINFO←[0m:     127.0.0.1:54298 - "←[1mGET / HTTP/1.1←[0m" ←[32m200 OK←[0m
←[32mINFO←[0m:     127.0.0.1:54298 - "←[1mGET /img/separator.png HTTP/1.1←[0m" ←[31m404 Not Found←[0m
←[32mINFO←[0m:     127.0.0.1:54299 - "←[1mGET /css/rajdhani.css HTTP/1.1←[0m" ←[31m404 Not Found←[0m
←[32mINFO←[0m:     127.0.0.1:54298 - "←[1mGET /js/pixi.min.js HTTP/1.1←[0m" ←[31m404 Not Found←[0m
←[32mINFO←[0m:     127.0.0.1:54299 - "←[1mGET /js/ease.js HTTP/1.1←[0m" ←[31m404 Not Found←[0m

So, basically, any static file that I’m using is missing, and I have no idea what I am doing wrong. How to fix it?

Asked By: Moder New

||

Answers:

Here:

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

You mount your static directory under /static path. That means, if you want access static files in your html you need to use static prefix, e.g. <img src="static/img/separator.png"/>

Answered By: kosciej16

To mount a StaticFiles instance to a specific path, you could use the following:

from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

app = FastAPI()

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

To link to static files from within your Jinja2 (HTML) template, you could use the following, as described in Starlette documentation:

<link href="{{ url_for('static', path='/css/rajdhani.css') }}" rel="stylesheet">

Alternatively, you could directly use the pathname given when you mounted a StaticFiles instance (in this case, that is, /static). Any path that starts with /static will be handled by it. Example below:

<link href="static/css/rajdhani.css'" rel="stylesheet">
Answered By: Chris
folder = os.path.dirname(__file__)
app.mount("/static", StaticFiles(directory=folder+"/../static",html=True), name="static")

works. Somehow using directory="../static" does not work, the full path is required when pointing outside of your FastAPI project. Then html=True is also needed for serving html files correctly. See https://www.starlette.io/staticfiles/.

Answered By: tww59