Impact Dashboard
Functionalities Overview and API Points
This project has 2 main functionalities: serving the main backend for on-request data and managing scheduled tasks in order to aggregate data on regular time basis.
The Impact Dashboard Backend is a Django-based API microservice that is connected to the main Coldtivate backend. It provides functionalities for data aggregation, processing, and querying for cold storage monitoring. The API serves precomputed metrics stored in PostgreSQL tables and exposes them through structured endpoints.
This project also contains a python file (indicator_reporter.py
) which is executed through cron jobs in order to fill in some statistical data on certain time periods. The cron jobs are triggered inside of a separate docker container. This handles the routine tasks that aggregate the data and update the appropriate tables.
API Endpoints
Endpoint | Method | Description |
---|---|---|
/ |
GET |
Simple UI that makes it easier to interact with the API points below |
/api/company-slice |
GET |
Returns storage, revenue, and metadata for a given company |
/api/coolingunit-slice |
GET |
Returns utilization statistics for a date range and list of cooling units |
/api/impact-slice |
GET |
Returns impact metrics for a date range and list of cooling units or a company |
Cloning Git Repository
To begin development, clone the repository (this is the setup if you have connected Github with SSH keys, otherwise you will have to use an alternative git clone argument):
git clone [email protected]:YourVirtualColdChainAssistant/Impact-Dashboard-Backend.git
cd impact-dashboard-backend
Ensure you have the correct branch checked out:
Recommended IDE Configuration
- PyCharm Professional (supports Django)
- VSCode (requires Django and Python extensions)
Database Setup
Please check the setup of the main backend API where it is described how to set up the database, however read through the documentation below to ensure all the required tables and views exist.
This project is dependable on tables and views to exist in the Database.
Intermediate tables
The “intermediate” tables were created specifically for the impact dashboard backend. They store precomputed metrics (computed by indicator_reporter.py
) which are then served to the front-end of the Coldtivate app via the API endpoints. There are 3 intermediate tables and each one of them stores metrics for different screens of the Impact Dashboard.
The tables (or called intermediate tables) used are:
-
company_metrics - This table stores a single row of data for each company in the database. This table is updated daily by the
indicator_reporter.py --view company
python script, which is triggered in thedaily-at-midnight.sh
cron job script. -
cooling_unit_metrics - This intermediate table stores the daily utilization indicators for cooling units in the Coldtivate DB as a time series. The metrics can be sliced along the cooling units and time dimensions to serve the aggregated results to the front-end. This table serves the Aggregated and Comparison screens of the dashboard enabling the functionality of the cooling unit and calendar selectors on the front-end. The table also serves the ‘impact’ section of the Company screen specifically for the CO2 metrics. The table is updated daily by the
indicator_reporter.py --view aggregated-comparison
python script triggered in thedaily-at-midnight.sh
cron job script. -
impact_metrics - The impact_metrics stores all impact related metrics such as the farmer revenue evolution and food loss evolution. The data on the table is extracted from the user baseline and post-checkout surveys. Each row in the table corresponds to impact metrics for a single crop belonging to a farmer in a single cooling unit (i.e the index is farmer-coolingunit-crop). A user needs to have successfully completed a baseline survey and at least one post-checkout survey for a crop to have an entry in this table. The table is updated at monthly intervals by the
indicator_reporter.py --view impact_metrics
python script triggered in theimpact-metrics.sh
cron job script.
Required Views (in DB)
The views required are located in the views
folder. These sql scripts need to be executed (only if the views don't exist already - please check database before that). The scripts and respectable views names are:
- analytics_crate_movements.sql
- create_relevant_checkins_view.sql
Local Deployment in Docker
To run the API within Docker:
- Set up the
.env
file:
DB_NAME=impact_db
DB_USERNAME=user
DB_PASSWORD=pass
DB_HOST=db # or for docker sometimes it is better to use host.docker.internal
DB_PORT=5432
Alternative Local Setup
1. Setup the URL resolving to be using the localhost
echo "127.0.0.1 api.coldtivate.localhost air.coldtivate.localhost farmer.coldtivate.localhost impact.coldtivate.localhost" | sudo tee /etc/hosts
cat /etc/hosts # confirm it was added.
2. Update the code to include the DB credentials
The code is not written in the most optimal way for now, therefore you would have to search through it to see where do you have to set up the environment variables in order to connect to the database. The easiest way to do this is do a global search in your IDE for some of the key values, e.g. DB_HOST
.
If you do this you will find that the values need to be updated in the
- DataSlicer.py
- utils.py
3. Install Python Dependencies
Create a virtual environment and install dependencies:
4. Run the project
Project Structure - Directories and Files
Directory/File | Description |
---|---|
cron/ |
Contains scheduled task scripts (cron jobs). Includes script for scheduled task that updates the intermediate tables company_metrics, cooling_unit_metrics and impact_metrics |
├ crontab |
Main crontab configuration file for scheduling scripts. |
├ daily-at-midnight.sh |
Script for daily scheduled tasks. |
├ impact-metrics.sh |
Script for impact metrics calculations executed monthly |
├ test.sh |
Test script for cron jobs. |
├ testEnvVars.sh |
Script to print the environment variables propagated. |
fastAPI/ |
HTML file for FastAPI frontend - UI for API points |
impact_queries/ |
SQL queries related to impact metrics. The SQL scripts generate the impact related metrics such as revenue evolution and food loss evolution. |
LCA/ |
Pipeline for CO2 metrics computation |
├ model/ |
Contains model definitions. |
├ sect_query/ |
Queries related to sector-specific data. |
├ sql_queries/ |
SQL scripts related to LCA processing. |
│ ├ __init__.py |
Init file for the SQL queries module. |
│ ├ co2_reporter.py |
Script for CO₂ reporting. |
│ ├ LCA.py |
Main script for lifecycle analysis. |
├ requirements.txt |
Dependencies for LCA module. |
logos/ |
Directory containing logos or images. |
sql_queries/ |
SQL scripts that are run to generate various utilization and demographic metrics. |
tests/ |
Contains unit and integration test scripts. |
├ test_app.py |
Tests for the main application. |
├ test_compute_co2.py |
Tests for CO₂ computations. |
├ test_data_slicer_interfaces.py |
Tests for data slicing interfaces. |
views/ |
Directory containing SQL views. |
├ analytics_create_movements.sql |
SQL script for movement analytics. |
├ create_relevant_checkins_view.sql |
SQL script for check-in views. |
compute_co2.py |
Script for computing CO₂ emissions. |
create_view.py |
Script for creating database views. |
dataProcessor.py |
Data processing script. |
DataSlicer.py |
Classess for aggregating data |
docker-compose.yaml |
Defines multi-container setup for Docker. |
Dockerfile |
Docker configuration file for API container |
Dockerfile.scheduler |
Docker configuration file for scheduler container |
heat_capacity.ini |
Configuration file for heat capacity data. |
indicator_reporter.py |
Reports indicators based on data. |
INTEGRATION-GUIDE.md |
Integration guide with instruction for deployment |
main.py |
Main entry point for the application. This is the fastAPI server |
queries_data.json |
JSON file matching queries to front-end pages |
README.md |
Documentation for the project. |
requirements.txt |
List of dependencies required for the project. |
utils.py |
Utility functions used in the project. |
Graphical Representation of Deployed Architecture
graph TD
%% Define server with Docker containers
subgraph Server [Server Node]
A1["API Backend Container"]
A2["Scheduler Container containing Cron Jobs"]
end
subgraph Database [Database]
B1["Views"]
B2["Intermediate Tables"]
end
%% Other components
C["Main API"]
%% Connections
A1 <--> C
A1 <--> Database
C <--> Database
A2 --> Database
Schedulers, Cron Jobs and ENV Variables
The cron jobs are deployed inside of docker containers. In order to check the list of containers you will have to run
After you have identified the name of the container you can start a session in it by ssh-ing in the container by running an interactive terminal:The cron jobs definitions can be found at the location inside of the docker container at the location:
The cron jobs are highly dependent to the environment variables being passed through in the deployment process. Scheduled tasks update intermediate tables daily and monthly.Deployment debugging scenario
Let's say you have already set up the whole project and it is in the cloud. If you have any errors for the metrics not being generated you need to find the error caused and check if the cron jobs are being triggered correctly. In the debugging scenario below you can learn how to do that.
1. SSH into the server.
2. Then list the docker container:
3. Enter the desired Docker Container:Once you've identified the container, open an interactive bash session:
4. Check Cron Jobs:
Navigate to the cron jobs definition folder and print the content of the crontab file:
The content should look something like this:SHELL=/bin/bash
0 0 * * * root /etc/cron.d/scripts/daily-at-midnight.sh > /proc/1/fd/1 2>/proc/1/fd/2 # Daily at midnight
0 1 1 * * root /etc/cron.d/scripts/impact-metrics.sh > /proc/1/fd/1 2>/proc/1/fd/2 # First day every month
> /proc/1/fd/1 2>/proc/1/fd/2
part is used to redirect the standard output (stdout) and standard error (stderr) of a command inside a Docker container to the container's logs.
5. Check Scripts Content:
Navigate to the location of the scripts and first check the content for the script executed on daily basis:
The content for debugging should be:#!/bin/bash
cd /scheduler
# Export environment variables
export $(cat /proc/1/environ | tr '\0' '\n' | sed 's/^\([^=]*\)=\(.*\)$/\1="\2"/')
# Run Python scripts
python3 /scheduler/indicator_reporter.py --view aggregated-comparison
python3 /scheduler/indicator_reporter.py --view company
export $(cat /proc/1/environ | tr '\0' '\n' | sed 's/^\([^=]*\)=\(.*\)$/\1="\2"/')
Now we check the monthly executed script content:
#!/bin/bash
cd /scheduler
# Export environment variables
export $(cat /proc/1/environ | tr '\0' '\n' | sed 's/^\([^=]*\)=\(.*\)$/\1="\2"/')
# Run Python script
python3 /scheduler/indicator_reporter.py --view impact_metrics
6. Create your own test script
The test script will be triggered by the cron job itself so you have complete context (same permissions same user) as when the scripts are executed.
We need to set up a test cron script inside the script directory. Create the script file naming it testEnvVars.sh
. The script should have the following permission and ownership only when listed with ls -la
command (ignore the timestamp below):
The script that we are creating will print out the environment variables. It will look like this:
#!/bin/bash
cd /scheduler
# Debug message to check execution
echo "Loading environment variables from /proc/1/environ"
# Read, parse, and export variables using sed and eval
eval $(cat /proc/1/environ | tr '\0' '\n' | sed 's/^\([^=]*\)=\(.*\)$/export \1="\2"/')
# Print environment variables to verify they are loaded
echo "Environment variables after loading:"
printenv
7. Call the script from the cron job
Backup Crontab File:
Add Test Script to Cron:
echo "* * * * * root /etc/cron.d/scripts/testEnvVars.sh > /proc/1/fd/1 2>/proc/1/fd/2" >> /etc/cron.d/crontab
Confirm addition:
8. Debugging Cron Output:
In another terminal, SSH again and start logging container outputs, this will print you what is happening:
Please notecoldtivate-staging-impact_dashboard_scheduler-1
is the name of the container, you will have to replace it with different one
9. Debugging finished
When you want to revert back to the original crontab and stop running the other script you will just delete the crontab
file and rename the backup file back: