Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 44 additions & 10 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,19 +1,53 @@
# ClimateVision Environment Variables
# Copy this file to .env and fill in your actual credentials
# NEVER commit .env to git!
# Copy this file to .env and fill in your actual credentials.
# NEVER commit .env or secrets/ to git!

# Google Earth Engine
# ---------------------------------------------------------------------------
# Google Earth Engine (required for real satellite imagery)
# ---------------------------------------------------------------------------
# Service account email registered with Earth Engine.
GEE_SERVICE_ACCOUNT=your-service-account@your-project.iam.gserviceaccount.com
GEE_PRIVATE_KEY_FILE=path/to/your-private-key.json
# OR if using OAuth:

# Path to the service-account JSON key, relative to the project root.
# Keep the file in secrets/ (gitignored).
GEE_SERVICE_ACCOUNT_KEY=secrets/gee-key.json

# Google Cloud / Earth Engine project ID.
GEE_PROJECT_ID=your-gee-project-id

# Sentinel Hub (optional - for later)
# ---------------------------------------------------------------------------
# Sentinel Hub (optional future source)
# ---------------------------------------------------------------------------
SENTINEL_HUB_CLIENT_ID=your_client_id_here
SENTINEL_HUB_CLIENT_SECRET=your_client_secret_here

# API Keys (optional - for later)
API_SECRET_KEY=your_secret_key_here
# ---------------------------------------------------------------------------
# API Security
# ---------------------------------------------------------------------------
# Secret used for API-key hashing and any signed tokens.
# Generate with: openssl rand -hex 32
API_SECRET_KEY=change_me_in_production

# Set to 1 ONLY in local development to enable the cv_dev bypass key.
# NEVER enable this in production.
CLIMATEVISION_ALLOW_DEV_KEY=0

# ---------------------------------------------------------------------------
# CORS / Frontend
# ---------------------------------------------------------------------------
# Comma-separated list of origins allowed to call the API.
# Include your production domain and any local dev URLs.
CLIMATEVISION_CORS_ORIGINS=https://climatevision.green,https://www.climatevision.green,http://localhost:5173,http://127.0.0.1:5173

# ---------------------------------------------------------------------------
# LLM Reporting (optional)
# ---------------------------------------------------------------------------
ANTHROPIC_API_KEY=your_anthropic_api_key
CLIMATEVISION_LLM_MODEL=claude-haiku-4-5-20251001

# Database (optional - for later)
DATABASE_URL=postgresql://user:password@localhost:5432/climatevision
# ---------------------------------------------------------------------------
# Database
# ---------------------------------------------------------------------------
# SQLite is used by default. Use an absolute path or a project-relative path.
# For production with high traffic, switch to PostgreSQL and update db.py.
DATABASE_URL=sqlite:///outputs/climatevision.sqlite3
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Dependabot configuration for pip, npm, and GitHub Actions updates
- CHANGELOG.md (this file)
- CITATION.cff for GitHub "Cite this repository" button
- `team_docs/ROLE_REASSIGNMENT.md` documenting departure of @Hopelynconsult and redistribution of Responsible AI responsibilities to @Goldokpa and @obielin

### Removed
- `team_docs/Hopelyn_Role_INTERNAL.md` (internal credentials file for departed team member); associated PAT must be revoked

### Changed
- CODE_OF_CONDUCT.md — replaced placeholder email with GitHub private reporting link
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Thanks to everyone who has contributed to ClimateVision! 🎉

<a href="https://github.com/Climate-Vision/ClimateVision/graphs/contributors">
<img src="https://contrib.rocks/image?repo=Climate-Vision/ClimateVision" />
</a>a>
</a>

| Contributor | Merged PRs |
|-------------|-----------|
Expand All @@ -165,7 +165,6 @@ Thanks to everyone who has contributed to ClimateVision! 🎉
| [@femi23](https://github.com/femi23) | #34, #40, #41, #42 |
| [@obielin](https://github.com/obielin) | #35, #36, #37, #38, #39 |
| [@franchaise](https://github.com/franchaise) | #46, #47, #48, #49 |
| [@Hopelynconsult](https://github.com/Hopelynconsult) | #51 |
| [@emekambachu](https://github.com/emekambachu) | Co-author contributions |
| [@Godswill-code](https://github.com/Godswill-code) | Co-author contributions |
| [@cutewizzy11](https://github.com/cutewizzy11) | Co-author contributions |
Expand Down
169 changes: 169 additions & 0 deletions docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# ClimateVision Deployment Guide

This guide covers deploying ClimateVision to **Fly.io** at `https://climatevision.green` with real Google Earth Engine (GEE) satellite data.

---

## Prerequisites

- A Fly.io account: https://fly.io
- The Fly CLI (`flyctl`) installed and authenticated
- A Google Cloud project with Earth Engine enabled
- This repository cloned and dependencies installed

---

## 1. Google Earth Engine credentials

Real satellite imagery requires a GEE service account.

1. Go to https://console.cloud.google.com/ and select your project.
2. Enable the **Earth Engine API**.
3. Navigate to **IAM & Admin → Service Accounts**.
4. Create a service account with the role **Earth Engine Resource Writer**.
5. Create a JSON key and download it.
6. Place the key at `secrets/gee-key.json` (the `secrets/` directory is gitignored).
7. Register the service account in the Earth Engine console: https://code.earthengine.google.com/
8. Copy `.env.example` to `.env` and fill in:
```bash
GEE_SERVICE_ACCOUNT=your-service-account@your-project.iam.gserviceaccount.com
GEE_SERVICE_ACCOUNT_KEY=secrets/gee-key.json
GEE_PROJECT_ID=your-gee-project-id
```

> **Never commit `secrets/` or `.env` to Git.**

---

## 2. Local production-like run (Docker)

Build and run the full stack locally:

```bash
# Make sure .env is populated and secrets/gee-key.json exists
docker compose up --build
```

The API will be available at http://localhost:8000 and the dashboard at http://localhost:8000/.

---

## 3. Fly.io setup

### 3.1 Create the app and provision secrets

```bash
# Create the Fly app
fly apps create climatevision-green

# Set all secrets from .env
./scripts/setup_fly_secrets.sh

# Create a persistent volume for SQLite and outputs (1 GB is plenty for demos)
fly volumes create climatevision_data --region lhr --size 1
```

### 3.2 Custom domain

```bash
# Request a certificate for your domain
fly certs create climatevision.green
```

Add the DNS records shown by `fly certs show` to your DNS provider. Once propagated, Fly will serve the app at `https://climatevision.green`.

### 3.3 Deploy

```bash
# Manual deploy
fly deploy --remote-only

# Or push to main — GitHub Actions will deploy automatically
# once FLY_API_TOKEN is configured (see section 4).
```

---

## 4. GitHub Actions CI/CD

The repository includes two workflows:

- `.github/workflows/ci.yml` — runs on every PR/push to `main` or `develop`.
- `.github/workflows/deploy.yml` — deploys to Fly.io on every push to `main`.

### Required repository secrets

Add these in **GitHub → Settings → Secrets and variables → Actions**:

| Secret | Value |
|--------|-------|
| `FLY_API_TOKEN` | A Fly.io access token from https://fly.io/user/personal_access_tokens |

GEE credentials are **not** stored in GitHub; they are set directly on Fly via `scripts/setup_fly_secrets.sh`.

---

## 5. Verify the deployment

Check the health endpoint:

```bash
curl https://climatevision.green/api/health
```

Check which models have trained weights:

```bash
curl https://climatevision.green/api/health/models
```

Open the dashboard:

```bash
open https://climatevision.green
```

---

## 6. Model status for investor demos

As of this deployment, only the **flooding** analysis ships with trained weights (`models/flooding_20260513_124208/model.onnx`).

Deforestation and arctic-ice analyses run using synthetic fallback tiles and untrained weights. The API reports this transparently via `/api/health/models` and the `is_synthetic` flag in prediction responses.

To add production models:

1. Train or obtain `models/unet_deforestation.pth` and `models/unet_ice.pth`.
2. Upload them to the `models/` directory.
3. Redeploy.

---

## 7. Alert delivery

The alert generator emits notifications to pluggable channels. By default only the `log` channel is active.

To enable email or webhook alerts, register a delivery function in `src/climatevision/inference/alert_generator.py` or implement the alert worker (see open issue #10).

For email, configure an SMTP provider or a transactional email service such as Mailgun or SendGrid, then set the relevant secrets via `fly secrets set`.

---

## 8. Security checklist

- [ ] `CLIMATEVISION_ALLOW_DEV_KEY` is `0` in production.
- [ ] `API_SECRET_KEY` is a strong, unique secret.
- [ ] The GEE service-account key is stored only in `secrets/` or Fly secrets, never in Git.
- [ ] Hopelyn’s old PAT has been revoked in GitHub.
- [ ] The Fly app uses HTTPS via `fly certs`.

---

## 9. Troubleshooting

| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| `GEE tile download failed` | Missing or invalid GEE credentials | Check `.env` / Fly secrets and service-account registration |
| Frontend shows blank page | `frontend/dist` not built or mounted | Re-run `npm run build` in `frontend/` or redeploy |
| CORS errors | Origin not allowed | Add domain to `CLIMATEVISION_CORS_ORIGINS` |
| SQLite data lost on deploy | No Fly volume mounted | Create and mount `climatevision_data` volume on `/app/outputs` |
10 changes: 7 additions & 3 deletions frontend/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# API base URL for frontend requests
# Leave empty when using Vite dev server (proxy handles /api -> backend)
# Set to http://127.0.0.1:8000 when serving built app separately
# ClimateVision frontend environment variables
# Copy to .env and fill in before building for production.

# Base URL for the ClimateVision API.
# Leave empty for same-origin deployment (e.g. when the API serves the frontend).
# For separate frontend hosting, set the full API origin:
# VITE_API_BASE_URL=https://climatevision.green/api
VITE_API_BASE_URL=
2 changes: 1 addition & 1 deletion frontend/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

// API Configuration
export const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
export const API_TIMEOUT = 30000;

// Map Configuration
Expand Down
18 changes: 10 additions & 8 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
export default defineConfig(({ mode }) => ({
plugins: [react()],
server: {
port: 5173,
strictPort: true,
proxy: {
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
},
proxy: mode === 'development'
? {
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
}
: undefined,
},
})
}))
14 changes: 7 additions & 7 deletions run_api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ cd "$(dirname "$0")"

PORT="${1:-8000}"

if [ ! -d "venv" ]; then
echo "Virtual environment not found. Run: python -m venv venv && source venv/bin/activate && pip install -r requirements.txt && pip install -e ."
if [ ! -d ".venv" ]; then
echo "Virtual environment not found. Run: python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt && pip install -e ."
exit 1
fi

source venv/bin/activate
source .venv/bin/activate

# Avoid OpenMP sandbox issues; fix NumPy/PyTorch compatibility in spawned workers
export OMP_NUM_THREADS=1

echo "Starting ClimateVision API on http://127.0.0.1:$PORT"
echo " Health: http://127.0.0.1:$PORT/api/health"
echo " API docs: http://127.0.0.1:$PORT/docs"
echo "Starting ClimateVision API on http://0.0.0.0:$PORT"
echo " Health: http://0.0.0.0:$PORT/api/health"
echo " API docs: http://0.0.0.0:$PORT/docs"
echo ""
exec uvicorn climatevision.api.main:app --reload --port "$PORT"
exec uvicorn climatevision.api.main:app --host 0.0.0.0 --port "$PORT" --workers 1
9 changes: 5 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@

setup(
name="climatevision",
version="0.1.0",
version="0.2.0",
author="ClimateVision Contributors",
description="Open-source ML platform for automated deforestation detection using deep learning and satellite imagery",
description="Open-source ML platform for automated environmental monitoring using deep learning and satellite imagery",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourusername/ClimateVision",
url="https://github.com/Climate-Vision/ClimateVision",
packages=find_packages(where="src"),
package_dir={"": "src"},
classifiers=[
Expand All @@ -36,7 +36,7 @@
],
python_requires=">=3.8",
install_requires=[
"numpy>=1.21.0",
"numpy>=1.21.0,<2.0.0",
"pandas>=1.3.0",
"torch>=2.0.0",
"torchvision>=0.15.0",
Expand All @@ -50,6 +50,7 @@
"tqdm>=4.62.0",
"pyyaml>=6.0",
"requests>=2.26.0",
"python-dotenv>=0.19.0",
],
extras_require={
"dev": [
Expand Down
Loading
Loading