Skip to content

Instantly share code, notes, and snippets.

@ultrafunkamsterdam
Last active June 20, 2024 18:35
Show Gist options
  • Save ultrafunkamsterdam/b1655b3f04893447c3802453e05ecb5e to your computer and use it in GitHub Desktop.
Save ultrafunkamsterdam/b1655b3f04893447c3802453e05ecb5e to your computer and use it in GitHub Desktop.
FastAPI support for React ( with working react-router )
"""
███████╗ █████╗ ███████╗████████╗ █████╗ ██████╗ ██╗
██╔════╝██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║
█████╗ ███████║███████╗ ██║ ███████║██████╔╝██║
██╔══╝ ██╔══██║╚════██║ ██║ ██╔══██║██╔═══╝ ██║
██║ ██║ ██║███████║ ██║ ██║ ██║██║ ██║
╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝
██████╗ ███████╗ █████╗ ██████╗████████╗
██╔══██╗ ██╔════╝ ██╔══██╗ ██╔════╝╚══██╔══╝
██████╔╝ █████╗ ███████║ ██║ ██║
██╔══██╗ ██╔══╝ ██╔══██║ ██║ ██║
██║ ██║ ███████╗ ██║ ██║ ╚██████╗ ██║
╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
serve react app via fastapi, complete with working react-router
How to use ?
-------
it's actually very simple.
create your fastapi app like you'd normally do
but you have to use this as your VERY LAST mount to your main app
example
----
```
# regular fastapi setup
root = fastapi.FastAPI()
@root.get('/some/path')
...
...code...
...
@root.get('/some/other/path')
...
...code...
...
... some static files maybe ?
root.mount('/some/staticfiles')
...
...code...
...
# moment of truth
from fastapi_react import frontend
root.mount('/', frontend(build_dir='build')) # we are MOUNTING it!
...
...
uvicorn.run(root, port=8080) # maybe ?
```
"""
def frontend(build_dir="./build"):
"""
FASTAPI ROUTER FOR REACT FRONTEND
:param build_dir: the path to your build folder for react
we are assuming the "static" folder lives within your build folder
if not, change it some lines below
:return: fastapi.FastAPI
"""
import pathlib
import fastapi.exceptions
from fastapi import FastAPI, Request, Response
from fastapi.staticfiles import StaticFiles
build_dir = pathlib.Path(build_dir)
react = FastAPI(openapi_url="")
react.mount('/static', StaticFiles(directory=build_dir / "static"))
@react.get('/{path:path}')
async def handle_catch_all(request: Request, path):
if path and path != "/":
disk_path = build_dir / path
if disk_path.exists():
return Response(disk_path.read_bytes(), 200)
else:
if disk_path.is_file():
raise fastapi.exceptions.HTTPException(404)
return Response((build_dir / "index.html").read_bytes(), 200)
return react
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment