Ronin
Ronin

Reputation: 103

FastAPI as a Windows service

I am trying to run FastAPI as a windows service.Couldn't find any documentation or any article to run Uvicorn as a Window's service. I tried using NSSM as well but my windows service stops.

Upvotes: 10

Views: 23169

Answers (3)

Vitor Rezende
Vitor Rezende

Reputation: 11

I prefer a different way to create a service for FastAPI using NSSM. First, I build the entire app with pyinstaller and then I use the executable as a service. This is simpler than creating a .bat file and gave me less headache when trying to create it.

  1. Install pyinstaller following the docs
  2. You need to add this line to your main.py
if __name__ == '__main__':
    multiprocessing.freeze_support()  # For Windows support
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=False, workers=1)

Using uvicorn for running the application may be simple for the most people, but the multiprocessing should be new for the most too.

The multiprocessing.freeze_support() helps the application work properly on Windows systems when running multiple processes. Think of this as special setup needed just for Windows computers.

  1. Run this command here to build your entire app into an executable

pyinstaller path/to/main.py --collect-submodules application --onefile --name <filename>

This command will create a ./build and a ./dist inside the directory you executed

We gonna use the executable inside the ./dist folder. Try to execute it, if it gave no errors, you can follow to the next step.

  1. Now create the service using NSSM.

nssm install <ServiceName>

  1. Open services on Windows and start your new service.

Upvotes: 0

perev
perev

Reputation: 262

I managed to run FastAPI with uvicorn as a Windows Service using NSSM.

I had to deploy uvicorn programatically, basically run uvicorn directly from your Python script, then create and install a custom service with NSSM.

Here's a small example based on FastAPI's example, but instead of running it with uvicorn main:app --reload from the command line, you add uvicorn.run(app, **config) with your own config.

from fastapi import FastAPI
import uvicorn

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

if __name__ == "__main__":
    uvicorn.run("main:app", host="127.0.0.1", port=5000, log_level="info")

Then you can install it with NSSM using the standard nssm install command

nssm.exe install "FastAPIWindowsService" "C:\Scripts\FastAPIWindowsService\venv\Scripts\python.exe" "C:\Scripts\FastAPIWindowsService\src\main.py"

Change your service name, the path of your python.exe, and the path of your script accordingly. Your service should appear in the Windows Services Manager when installed.

Hope this helps, and works for you!

Edit: My experience with installing the service with NSSM, as in the example above, is that it would not correctly utilise my virtual environment.

My preferred method now is to use a bat-file that first activates the virtual environment, then runs the desired script. The bat-file can be named whatever you prefer, for example run_app.bat, placed in the same folder as your script, with the following contents:

call venv\Scripts\activate.bat
call python src\main.py

I then use the standard nssm install command, but only provide the service name, as I use NSSM’s user interface to fill in the rest of my required information – file path for example, as shown here:

NSSM service installer user interface

Again, hope this helps and works for you!

Upvotes: 23

Kevin
Kevin

Reputation: 51

Expanding a bit on the other answer, there are a few different ways to run FastAPI as a Windows Service (which generalizes to being able to run any Python app as a Windows Service). The most common ways I have found are:

  1. Use NSSM
  2. Use one of the officially documented techniques here.

After trying a few of them out, I found NSSM to be by far the easiest and most effective method. Basic steps below:

  1. Add a __main__ entry point to your FastAPI app that will be called by the Windows Service. The FastAPI deployment guide has helpful info on the various parameters. You probably want to tweak your "workers" variable based on expected load. Example (assumes your main FastAPI file is named main.py):
if __name__ == "__main__":
    uvicorn.run("main:app", host="127.0.0.1", port=8000, workers=4)
  1. Install Python on the Windows machine if it isn't already there. Also download nssm.exe

  2. Test out your app on the Windows box by running py main.py. If it starts up and runs then you are good to deploy as a windows service.

  3. Create the service using nssm:

nssm install <windows service name> <python.exe path> main.py  
nssm set <windows service name> AppDirectory <root directory of app>  
nssm set <windows service name> Description <app description>
nssm start <windows service name> 

If all is well then it should be up and running. A few other commenters above have issues with the app starting, which is likely because the AppDirectory was not set so the files could not be found.

Upvotes: 5

Related Questions