Reputation: 17056
I want to write a minimal FastAPI static file server launched from a script that allows you to specify the directory to share on the command line. Following the example in the FastAPI documentation, I wrote this.
import uvicorn
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
server = FastAPI()
if __name__ == "__main__":
import sys
directory = sys.argv[1]
server.mount("/static", StaticFiles(directory=directory), name="static")
uvicorn.run(app="my_package:server")
If I run this with the argument /my/directory
where this directory contains file.txt
I expect that I'd be able to download file.txt
at the URL http://localhost:8000/static/file.txt
, but this returns an HTTP 404.
How do I write this minimal static file server script?
Upvotes: 0
Views: 445
Reputation: 2986
When you call uvicorn.run(app="my_package:server")
, it actually starts a separate process where my_package
is imported. Therefore, everything inside if __name__ == "__main__":
will not be run in the uvicorn process, so your directory will never be mounted.
One possible solution would be getting the directory from an environment variable, which is set from a small bash script:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
server = FastAPI()
directory = os.getenv("DIRECTORY")
server.mount("/static", StaticFiles(directory=directory), name="static")
start.sh
:
#!/usr/bin/env bash
DIRECTORY=$1 uvicorn mypackage:server
Upvotes: 0
Reputation: 52862
The assumption I made about sys.argv
not being available when uvicorn loads your module is wrong, so it should work as you expect by moving your static setup outside of the __main__
guard:
import uvicorn
import sys
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
server = FastAPI()
directory = sys.argv[1]
server.mount("/static", StaticFiles(directory=directory), name="static")
if __name__ == "__main__":
uvicorn.run(app="my_package:server")
Upvotes: 1