Serve Simple Page App (angular) on root alongside a backend on starlette
See original GitHub issueHello, I’m developing an angular (7)+ starlette api backend and I would like to make starlette serve the angular app alongside with the api. I know that I could use ngnix to serve it but I would like to try to deploy just one server. Also I have found the https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker and it would be amazing to be able to just use it with the whole app. As a normal angular app, it expects (by default) to be located to the “/” endpoint. As my angular prod files are in a folder ./angular relative to the starlette app.py file I have tried the following:
_CURDIR = dirname(abspath(__file__))
app = Starlette()
app.mount('/', StaticFiles(directory=join(_CURDIR, 'angular' )))
@app.exception_handler(404)
async def not_found(request, exc):
return FileResponse('./angular/index.html')
if __name__ == '__main__':
uvicorn.run(app, host='0.0.0.0', port=8090)
The index.html is the usual on the angular apps:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ArcherytimerMatrix</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.54bd9f72bfb2c07e2a6b.css"></head>
<body>
<app-root></app-root>
<script type="text/javascript" src="runtime.253d2798c34ad4bc8428.js"></script><script type="text/javascript" src="es2015-polyfills.4a4cfea0ce682043f4e9.js" nomodule>
</script><script type="text/javascript" src="polyfills.407a467dedb63cfdd103.js"></script><script type="text/javascript" src="main.cfa2a2d950b21a173917.js"></script></body>
</html>
when I try to reach localhost:8090 the index.html is “shown” but it can’t find the styles / runtime / polyfills and main
INFO: Uvicorn running on http://0.0.0.0:8090 (Press CTRL+C to quit)
INFO: ('127.0.0.1', 34138) - "GET / HTTP/1.1" 200
INFO: ('127.0.0.1', 34138) - "GET /styles.54bd9f72bfb2c07e2a6b.css HTTP/1.1" 200
INFO: ('127.0.0.1', 34140) - "GET /runtime.253d2798c34ad4bc8428.js HTTP/1.1" 200
INFO: ('127.0.0.1', 34138) - "GET /polyfills.407a467dedb63cfdd103.js HTTP/1.1" 200
INFO: ('127.0.0.1', 34140) - "GET /main.cfa2a2d950b21a173917.js HTTP/1.1" 200
(the status is 200 as I’m catching the exception and redirecting…)
If I try to access the static file directy:
localhost:8090/styles.54bd9f72bfb2c07e2a6b.css
Is not found either
If I serve the statics files from an endpoint:
app.mount('/angular', StaticFiles(directory=join(_CURDIR, 'angular' )))
and I try to access to the “angular”
localhost:8090/angular/styles.54bd9f72bfb2c07e2a6b.css
the file is served.
So It seems that the “/” root can’t be used for endopoint to static files (or there is a bug if this is not the intended behavior)
Maybe I’m doing it wrong, is there another way to achieve this?
Thank you in advance Regards
Issue Analytics
- State:
- Created 5 years ago
- Comments:22 (9 by maintainers)
Top GitHub Comments
@andrewmwhite If you create your frontend and api as separate starlette apps, and then mount each of those in a single “parent” app, you should be able to adapt the approach above without any awkward explicit excludes, since the FileResponse-generating middleware will now only apply to the frontend app:
I just ran the above in a file exactly as is, in the root folder of starlette, and I get the auth docs page for any 404 that doesn’t start /api, and I get the standard mostly-blank 404 response from any route starting /api.
Would that work for you?
This has been answered, but if you don’t want to override 404 – for example if you’re serving your SPA in a subdirectory like
/app/'
, this works well enough: