This is just an example of how to capture the stdout and stderr output of a
process and use it in a Python application.
It uses the Threading and Queue modules to capture the output of a Uvicorn server and then use it in the main application.
It also shows how to cleanly catch the ctrl-c keystroke and pass that on to the
uvicorn server to allow it and the application to shut down cleanly.
As a uvicorn server, it includes a simple API server based on FastAPI, though the same technique could be used with most other types of processes.
Install the dependencies using Poetry:
$ poetry installThen, activate the virtual environment:
$ poetry shellNow you can run the application:
$ python main.pyThe important code is in the main.py file, in the __call__ method of the
App class. This method does the following:
- Set up the
uvicornserver and start it. - Sets up a
Queueto capture the output. - Start a separate thread to fill that queue from the
uvicornserver's output.
The main thread then reads the output. from the queue and simply prints it for now.
The server.py file just creates a very simple API server using FastAPI with
one route that returns a simple JSON response on the root
('http://localhost:8000/')
I will write a documentation page to explain this in more detail soon.
Below is an example of the output from running the application, showing the
ctrl-c being pressed and the application shutting down cleanly.
$ python main.py
INFO: Will watch for changes in these directories: ['/home/seapagan/code/capture-uvicorn-output']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [167389] using WatchFiles
INFO: Started server process [167396]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: 127.0.0.1:56914 - "GET / HTTP/1.1" 200 OK
INFO: 127.0.0.1:46182 - "GET / HTTP/1.1" 200 OK
INFO: Ctrl-C pressed, Shutting Down...
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [167396]
INFO: Stopping reloader process [167389]
This project is released under the terms of the MIT license.
The original Python boilerplate for this package was created using Pymaker by Grant Ramsay (me 😄)