From edc131b2e5a141c50e0811d34afdb2cf5a6e0d28 Mon Sep 17 00:00:00 2001 From: Aarav Anand Date: Thu, 5 Mar 2026 14:09:32 +0530 Subject: [PATCH 1/2] docs: document environment variable configuration strategy --- .env.template | 35 ++++++++++++++++++++++++++++++++++ README.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 .env.template diff --git a/.env.template b/.env.template new file mode 100644 index 000000000..4688caa74 --- /dev/null +++ b/.env.template @@ -0,0 +1,35 @@ +# .env.template — Copy to `.env` for local development +# Environment variables set in the shell always override values in this file. +# DO NOT commit your actual .env file (it is listed in .gitignore). + +# --------------------------------------------------------------- +# Server +# --------------------------------------------------------------- + +# Port the Flask/Waitress server listens on. +# Default: 5002 +PORT=5002 + +# --------------------------------------------------------------- +# AWS / S3 (only required when AWS_SYNC=1) +# --------------------------------------------------------------- + +# Name of the S3 bucket used for case-file synchronisation. +S3_BUCKET= + +# AWS access-key credentials (IAM user with S3 read/write on the bucket above). +S3_KEY= +S3_SECRET= + +# --------------------------------------------------------------- +# Deployment flags +# --------------------------------------------------------------- + +# Set to 1 to enable automatic S3 ↔ local synchronisation on startup. +# Default: 0 (sync disabled) +AWS_SYNC=0 + +# Set to 1 when deploying to Heroku. Changes the CORS origin and the server +# binding from localhost to 0.0.0.0. +# Default: 0 (local / non-Heroku) +HEROKU_DEPLOY=0 diff --git a/README.md b/README.md index 001bb8b91..0b45eada4 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,58 @@ This repository contains the user interface for the Open Source Energy Modelling 4. The App will open automatically once the installation is complete. If not, search on the Windows Taskbar for ‘’MUIO’’ and open the App. 5. You will see the MUIO in a new window. +## Configuration + +MUIO is configured entirely through environment variables. This makes it easy to adapt the +application to different environments (local development, staging, production) without touching +source code. + +### Using a `.env` file for local development + +A `.env.template` file is included in the repository as a reference. To get started locally: + +```bash +# 1. Copy the template +cp .env.template .env + +# 2. Edit .env with your values (see table below) +# 3. Run the server — it will pick up .env automatically +python API/app.py +``` + +> **Important:** Never commit your `.env` file. +> It is already listed in `.gitignore` to prevent accidental exposure of credentials. + +### Environment variable reference + +| Variable | Default | Description | +|---|---|---| +| `PORT` | `5002` | TCP port the server listens on. | +| `S3_BUCKET` | *(empty)* | Name of the AWS S3 bucket used for case-file sync. | +| `S3_KEY` | *(empty)* | AWS IAM access key ID (required when `AWS_SYNC=1`). | +| `S3_SECRET` | *(empty)* | AWS IAM secret access key (required when `AWS_SYNC=1`). | +| `AWS_SYNC` | `0` | Set to `1` to enable S3 ↔ local synchronisation on startup. | +| `HEROKU_DEPLOY` | `0` | Set to `1` when deploying to Heroku (changes CORS origin and server binding). | + +### Precedence + +``` +Shell environment variables > .env file > built-in defaults +``` + +Real environment variables (e.g. those set in Heroku Config Vars or a CI/CD pipeline) +always override any value defined in a local `.env` file. + +### Example minimal `.env` for local development + +``` +PORT=5002 +AWS_SYNC=0 +HEROKU_DEPLOY=0 +``` + +--- + ## Questions and Issues For troubleshooting model-related issues and discussions, please visit the [Energy Modelling Community Discussion Forum](https://forum.u4ria.org/). From d65c28eaa77b9b4842cbf0d5f28b7bf2761c308c Mon Sep 17 00:00:00 2001 From: Aarav Anand Date: Thu, 5 Mar 2026 14:09:32 +0530 Subject: [PATCH 2/2] feat: enable dotenv loading for local development --- API/Classes/Base/Config.py | 25 ++++++++++++------------- API/app.py | 6 ++++++ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/API/Classes/Base/Config.py b/API/Classes/Base/Config.py index bbbe41ab3..b188caafa 100644 --- a/API/Classes/Base/Config.py +++ b/API/Classes/Base/Config.py @@ -1,21 +1,19 @@ from pathlib import Path import os -#from dotenv import load_dotenv +from dotenv import load_dotenv import platform -#load environment variables -#load_dotenv() +# Load .env file for local development. +# Real environment variables always override values from .env. +load_dotenv() SYSTEM = platform.system() -# S3_BUCKET = os.environ.get("S3_BUCKET") -# S3_KEY = os.environ.get("S3_KEY") -# S3_SECRET = os.environ.get("S3_SECRET") - -#S3 bucket is not used in Osemosys -S3_BUCKET = "" -S3_KEY = "" -S3_SECRET = "" +# S3 credentials – read from environment; fall back to empty strings so the app +# starts without AWS configured (AWS functionality is optional in OSeMOSYS). +S3_BUCKET = os.environ.get("S3_BUCKET", "") +S3_KEY = os.environ.get("S3_KEY", "") +S3_SECRET = os.environ.get("S3_SECRET", "") ALLOWED_EXTENSIONS = set(['zip', 'application/zip']) ALLOWED_EXTENSIONS_XLS = set(['xls', 'xlsx']) @@ -39,8 +37,9 @@ os.chmod(DATA_STORAGE, 0o777) -HEROKU_DEPLOY = 0 -AWS_SYNC = 0 +# Deployment flags – read from environment; default to 0 (local / non-Heroku). +HEROKU_DEPLOY = int(os.environ.get("HEROKU_DEPLOY", "0").strip() or "0") +AWS_SYNC = int(os.environ.get("AWS_SYNC", "0").strip() or "0") PINNED_COLUMNS = ('Sc', 'Tech', 'Comm', 'Emis','Stg', 'Ts', 'MoO', 'UnitId', 'Se','Dt', 'Dtb', 'paramName','TechName', 'CommName', 'EmisName', 'ConName', 'MoId') diff --git a/API/app.py b/API/app.py index f2fc8c476..386747eee 100644 --- a/API/app.py +++ b/API/app.py @@ -2,6 +2,12 @@ import os import sys +from dotenv import load_dotenv + +# Load .env file for local development. +# Environment variables already set in the shell take precedence over .env values. +load_dotenv() + from flask import Flask, jsonify, request, session, render_template from flask_cors import CORS from datetime import timedelta