Tags
I wanted to host some static files through fastapi. Typical use cases for this might be some static web content like html/css/js. It could also be images or some data that doesn't need dynamically rendered.
From the Docs
The docs cover how to host static files, and give this solution that is built into fastapi.
https://fastapi.tiangolo.com/tutorial/static-files/
from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static")
Authenticated Static Files
Thanks to #858.
OscartGiles posted this solution to add authentication to static files. I tried this out on my thoughts and it worked flawlessly.
import typing from pathlib import Path import secrets from fastapi import FastAPI, Request, HTTPException, status from fastapi.staticfiles import StaticFiles from fastapi.security import HTTPBasic, HTTPBasicCredentials PathLike = typing.Union[str, "os.PathLike[str]"] app = FastAPI() security = HTTPBasic() async def verify_username(request: Request) -> HTTPBasicCredentials: credentials = await security(request) correct_username = secrets.compare_digest(credentials.username, "user") correct_password = secrets.compare_digest(credentials.password, "password") if not (correct_username and correct_password): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect email or password", headers={"WWW-Authenticate": "Basic"}, ) return credentials.username class AuthStaticFiles(StaticFiles): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) async def __call__(self, scope, receive, send) -> None: assert scope["type"] == "http" request = Request(scope, receive) await verify_username(request) await super().__call__(scope, receive, send) app.mount( "/static", AuthStaticFiles(directory=Path(__file__).parent / "static"), name="static", )
If you want both then, all you have to do is mount AuthStaticFiles
to a
different route. Now you can have private, or paid content behind
/restricted
.
app.mount("/static", StaticFiles(directory="static"), name="static") app.mount( "/restricted", AuthStaticFiles(directory=Path(__file__).parent / "restricted"), name="restricted" )