Skip to main content

Contributing Guide

Prerequisites

Before you begin, ensure you have the following installed:

  • Python 3.11
  • pip (Python package manager)
  • Git
  • Azure Account (for cloud services)
  • Virtual Environment (recommended)
System Requirements
  • OS: macOS, Linux, or Windows with WSL2
  • RAM: Minimum 4GB (8GB recommended)
  • Disk Space: At least 2GB free space

Development Setup

1. Clone the Repository

git clone https://github.com/Fluxgentech/aquagenapi.git
cd aquagenapi

2. Create a Virtual Environment

python -m venv .venv

# Activate on macOS/Linux:
source .venv/bin/activate

# Activate on Windows:
.venv\Scripts\activate

3. Install Dependencies

pip install -r requirements.txt
macOS Users

If you encounter errors with PDF generation libraries, install these specific versions:

pip install xhtml2pdf==0.2.13
pip install reportlab==4.0.7

4. Run the Server

export FLASK_DEBUG=1 && export FLASK_ENV=dev && flask run --host localhost --port 5001

The application will start on http://localhost:5001.

Swagger UI

Troubleshooting

Port already in use:

lsof -ti:5001 | xargs kill -9

Package installation errors:

pip install --upgrade pip
pip install -r requirements.txt

Feature Branch Workflow

  1. Create a feature branch from production:

    git checkout production
    git pull origin production
    git checkout -b feature/my-feature-name
  2. Make changes, commit frequently with clear messages.

  3. Push and create a pull request against production.

  4. Request review from at least one team member.

  5. Merge after approval and passing CI.


Architecture Principles

Core design rules

Separation of concerns — Routes handle HTTP, services handle logic, formatters handle output, the database layer is the bridge between the codebase and Cosmos DB. Never query the database from a route or formatter directly.

DatabaseSupporter as the single data access layer — All Cosmos DB interactions go through DatabaseSupporter static methods. No code outside database/ should import CosmosClient directly.

current_user as the request context — Industry data, user data, and permissions are loaded once per request into current_user. Services access this via flask_jwt_extended.current_user rather than making additional DB calls for the same data.

No secrets in code — All credentials and configuration values come from Key Vault via smi.get(). Never hardcode secrets, even in development.


PR Checklist

  • New routes have @jwt_required() (or explicitly excluded in PUBLIC_ROUTES)
  • New routes declare Authorization in the request parser
  • Error cases return appropriate status codes (1403, 1401, etc.)
  • New POST/PUT endpoints validate request body with JSON Schema
  • Swagger responses declared with @namespace.response()
  • New database methods added to DatabaseSupporter (not inline in service)
  • No hardcoded industry IDs, user IDs, or secrets
  • No print() statements left in production code (use logging)
  • Code follows existing naming conventions

Commit Conventions

feat: add water neutrality endpoint
fix: correct monthly report date range calculation
docs: update authentication guide
refactor: extract common alert logic to base class
chore: update requirements.txt

Branch Conventions

feature/water-neutrality-endpoint
fix/monthly-report-date-bug
docs/update-auth-guide
refactor/alert-base-class

Security Rules

warning
  • No hardcoded secrets — all secrets via smi.get(SecretName.XYZ) from Key Vault
  • No sensitive data in logs — no passwords, tokens, or PII in log messages
  • Input validation — validate all user-supplied input before processing
  • Soft deletes — use deleted: true flag rather than hard-deleting industry or user data