It's a Web-App to display dynamic status information, there is a continuous stream of incoming updates. To have the images and text dynamically appear, WebSockets are being used. WebSockets allow for a higher amount of efficiency compared to REST because they do not require the HTTP request/response overhead for each message sent and received.
-
Using a 73 Million parameter object detection model to detect objects from images and cut out one bounding box per image.
-
Implemented asynchronous api calls to the Pl@ntNet identify API to determine plant species.
-
It uses FastAPI framework for API development. FastAPI is a modern, highly performant, web framework for building APIs with Python.
-
The APIs are served with Gunicorn server with multiple Uvicorn workers. Uvicorn is a lightning-fast "ASGI" server. Univorn runs asynchronous Python web code in a single process.
-
Reverse-proxying with Nginx. Nginx is very good at serving static content.
-
Dockerized using the uvicorn-gunicorn-fastapi-docker Docker image.
The System consists of two docker containers: Gunicorn and Nginx. How can they communicate? Well, they use a shared volume, it's that simple. Most requests are not served by nginx directly, but passed back to the Gunicorn / FastAPI app which sits behind nginx. These are dynamic calls, rather than static content. This can be implemented by setting a proxy_pass in the nginx.conf.
The number of Worker threads is variable. Generally speaking, they scale with the number of CPU cores. This configuration can be overridden in the varia/gunicorn.conf file.
- Websocket endpoint for low-latency bidirectional communication
- Dynamically display status information
- Display pictures, updated by
- Timer, fetch Timestamp from device
- Switch between tabs
- nginx running in docker
- Specify species and similarity of plants.
- species -> API
- Show Progress bar
- image processing: image comparison algorithm
The app expects a constants.py in the app
directory. This class contains the api-key which is needed for plant identification.
Get a key for plantnet.
Create a file constants.py which contains a class Constants
and replace the <your-api-key>
with the api key you got from plant net.
class Constants:
def __init__(self):
self.api_key = "<your-api-key>"
After that, startup quickly with Docker:
Open the build_and_run_locally.sh
file.
Adjust the absolute path, it should point to the directory where you cloned the repository.
./build_and_run_locally.sh
If you develop in a IDE, it's much easier with auto completion. Create a virtual environment. This will create a python interpreter for your local development environment.
conda create --name rover python=3.9.0
conda activate rover
pip install -r requirements-conda-for-local.txt
This application expects a valid certificate at ~/cert/rover
. You can edit this path in the docker-compose
file. To get a certificate, I followed this https://help.zerossl.com/hc/en-us/articles/360058295894-Installing-SSL-Certificate-on-NGINX.
The certificate itself is is mounted as a volume in the nginx container.
If you don't want SSL, you'd need to make some adjustments in the nginx/nginx.conf file.