climate-change 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. climate_change-1.0.0/LICENSE +21 -0
  2. climate_change-1.0.0/PKG-INFO +564 -0
  3. climate_change-1.0.0/README.md +476 -0
  4. climate_change-1.0.0/__init__.py +142 -0
  5. climate_change-1.0.0/ai_interpreter/__init__.py +6 -0
  6. climate_change-1.0.0/ai_interpreter/interpreter.py +437 -0
  7. climate_change-1.0.0/climate_change.egg-info/PKG-INFO +564 -0
  8. climate_change-1.0.0/climate_change.egg-info/SOURCES.txt +101 -0
  9. climate_change-1.0.0/climate_change.egg-info/dependency_links.txt +1 -0
  10. climate_change-1.0.0/climate_change.egg-info/requires.txt +73 -0
  11. climate_change-1.0.0/climate_change.egg-info/top_level.txt +1 -0
  12. climate_change-1.0.0/core/__init__.py +31 -0
  13. climate_change-1.0.0/core/base_use_case.py +176 -0
  14. climate_change-1.0.0/core/cache.py +40 -0
  15. climate_change-1.0.0/core/dask_engine.py +113 -0
  16. climate_change-1.0.0/core/gee_auth.py +282 -0
  17. climate_change-1.0.0/core/runner.py +118 -0
  18. climate_change-1.0.0/disease/__init__.py +15 -0
  19. climate_change-1.0.0/disease/cog_export.py +120 -0
  20. climate_change-1.0.0/disease/features.py +593 -0
  21. climate_change-1.0.0/disease/model.py +373 -0
  22. climate_change-1.0.0/disease/use_case.py +261 -0
  23. climate_change-1.0.0/drought/__init__.py +17 -0
  24. climate_change-1.0.0/drought/cdi_runner.py +465 -0
  25. climate_change-1.0.0/drought/features.py +93 -0
  26. climate_change-1.0.0/drought/model.py +410 -0
  27. climate_change-1.0.0/drought/use_case.py +312 -0
  28. climate_change-1.0.0/flood/__init__.py +3 -0
  29. climate_change-1.0.0/flood/cog_export.py +165 -0
  30. climate_change-1.0.0/flood/features.py +614 -0
  31. climate_change-1.0.0/flood/model.py +350 -0
  32. climate_change-1.0.0/flood/use_case.py +337 -0
  33. climate_change-1.0.0/food_security/__init__.py +17 -0
  34. climate_change-1.0.0/food_security/cog_export.py +159 -0
  35. climate_change-1.0.0/food_security/features.py +623 -0
  36. climate_change-1.0.0/food_security/model.py +340 -0
  37. climate_change-1.0.0/food_security/use_case.py +384 -0
  38. climate_change-1.0.0/land_degradation/__init__.py +3 -0
  39. climate_change-1.0.0/land_degradation/cog_export.py +95 -0
  40. climate_change-1.0.0/land_degradation/features.py +469 -0
  41. climate_change-1.0.0/land_degradation/model.py +383 -0
  42. climate_change-1.0.0/land_degradation/use_case.py +258 -0
  43. climate_change-1.0.0/pyproject.toml +164 -0
  44. climate_change-1.0.0/registry.py +263 -0
  45. climate_change-1.0.0/reporting/__init__.py +3 -0
  46. climate_change-1.0.0/reporting/report_builder.py +3067 -0
  47. climate_change-1.0.0/setup.cfg +4 -0
  48. climate_change-1.0.0/tests/test_ai_interpreter.py +199 -0
  49. climate_change-1.0.0/tests/test_core_base_use_case.py +300 -0
  50. climate_change-1.0.0/tests/test_core_cache.py +53 -0
  51. climate_change-1.0.0/tests/test_core_dask_engine.py +93 -0
  52. climate_change-1.0.0/tests/test_core_gee_auth.py +83 -0
  53. climate_change-1.0.0/tests/test_core_runner.py +100 -0
  54. climate_change-1.0.0/tests/test_disease_features.py +88 -0
  55. climate_change-1.0.0/tests/test_disease_model.py +111 -0
  56. climate_change-1.0.0/tests/test_drought_cdi_runner.py +178 -0
  57. climate_change-1.0.0/tests/test_drought_features.py +109 -0
  58. climate_change-1.0.0/tests/test_drought_model.py +212 -0
  59. climate_change-1.0.0/tests/test_drought_xee_compat.py +37 -0
  60. climate_change-1.0.0/tests/test_flood_features.py +78 -0
  61. climate_change-1.0.0/tests/test_flood_model.py +188 -0
  62. climate_change-1.0.0/tests/test_food_security_features.py +65 -0
  63. climate_change-1.0.0/tests/test_food_security_model.py +114 -0
  64. climate_change-1.0.0/tests/test_land_degradation_model.py +158 -0
  65. climate_change-1.0.0/tests/test_registry.py +78 -0
  66. climate_change-1.0.0/tests/test_reporting.py +91 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 George Odero
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,564 @@
1
+ Metadata-Version: 2.4
2
+ Name: climate-change
3
+ Version: 1.0.0
4
+ Summary: Climate Resilience and Adaptation Decision Support System — multi-hazard EO analysis (drought, flood, food security, disease, land degradation)
5
+ Author: George Odero
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Odero54/climate-change
8
+ Project-URL: Source Code, https://github.com/Odero54/climate-change
9
+ Project-URL: Documentation, https://github.com/Odero54/climate-change#readme
10
+ Project-URL: Bug Tracker, https://github.com/Odero54/climate-change/issues
11
+ Keywords: climate-change,drought,flood,food-security,disease-surveillance,land-degradation,google-earth-engine,remote-sensing,machine-learning
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Scientific/Engineering :: GIS
16
+ Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Requires-Python: <3.14,>=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: bottleneck>=1.6.0
22
+ Requires-Dist: dask[distributed]>=2024.8.0
23
+ Requires-Dist: drought-monitoring>=0.1.8
24
+ Requires-Dist: earthengine-api>=0.1.370
25
+ Requires-Dist: joblib>=1.3
26
+ Requires-Dist: lightgbm>=4.0
27
+ Requires-Dist: matplotlib>=3.5
28
+ Requires-Dist: numpy>=1.24
29
+ Requires-Dist: openai>=1.0
30
+ Requires-Dist: pandas>=2.0
31
+ Requires-Dist: Pillow>=10.0
32
+ Requires-Dist: python-dotenv>=1.0
33
+ Requires-Dist: rasterio>=1.3
34
+ Requires-Dist: reportlab>=4.0
35
+ Requires-Dist: requests>=2.31
36
+ Requires-Dist: rioxarray>=0.15
37
+ Requires-Dist: ruptures>=1.1
38
+ Requires-Dist: scikit-learn>=1.3
39
+ Requires-Dist: scipy>=1.11
40
+ Requires-Dist: shap>=0.49.1
41
+ Requires-Dist: torch>=2.1
42
+ Requires-Dist: xarray>=2023.1
43
+ Requires-Dist: xee>=0.0.22
44
+ Requires-Dist: xgboost>=2.0
45
+ Provides-Extra: gee
46
+ Requires-Dist: earthengine-api>=0.1.370; extra == "gee"
47
+ Requires-Dist: xee>=0.0.22; extra == "gee"
48
+ Provides-Extra: cog
49
+ Requires-Dist: rasterio>=1.3; extra == "cog"
50
+ Requires-Dist: rioxarray>=0.15; extra == "cog"
51
+ Provides-Extra: ml
52
+ Requires-Dist: scikit-learn>=1.3; extra == "ml"
53
+ Requires-Dist: xgboost>=2.0; extra == "ml"
54
+ Requires-Dist: lightgbm>=4.0; extra == "ml"
55
+ Requires-Dist: shap>=0.44; extra == "ml"
56
+ Requires-Dist: torch>=2.1; extra == "ml"
57
+ Requires-Dist: numba>=0.58; extra == "ml"
58
+ Requires-Dist: llvmlite>=0.41; extra == "ml"
59
+ Provides-Extra: ai
60
+ Requires-Dist: openai>=1.0; extra == "ai"
61
+ Provides-Extra: report
62
+ Requires-Dist: reportlab>=4.0; extra == "report"
63
+ Requires-Dist: Pillow>=10.0; extra == "report"
64
+ Provides-Extra: dev
65
+ Requires-Dist: pytest>=7; extra == "dev"
66
+ Requires-Dist: pytest-cov; extra == "dev"
67
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
68
+ Requires-Dist: ruff>=0.4; extra == "dev"
69
+ Requires-Dist: mypy>=1.10; extra == "dev"
70
+ Requires-Dist: jupyterlab; extra == "dev"
71
+ Requires-Dist: matplotlib>=3.5; extra == "dev"
72
+ Requires-Dist: rasterio>=1.3; extra == "dev"
73
+ Requires-Dist: rioxarray>=0.15; extra == "dev"
74
+ Provides-Extra: all
75
+ Requires-Dist: earthengine-api>=0.1.370; extra == "all"
76
+ Requires-Dist: xee>=0.0.22; extra == "all"
77
+ Requires-Dist: rasterio>=1.3; extra == "all"
78
+ Requires-Dist: rioxarray>=0.15; extra == "all"
79
+ Requires-Dist: scikit-learn>=1.3; extra == "all"
80
+ Requires-Dist: xgboost>=2.0; extra == "all"
81
+ Requires-Dist: lightgbm>=4.0; extra == "all"
82
+ Requires-Dist: shap>=0.44; extra == "all"
83
+ Requires-Dist: torch>=2.1; extra == "all"
84
+ Requires-Dist: openai>=1.0; extra == "all"
85
+ Requires-Dist: reportlab>=4.0; extra == "all"
86
+ Requires-Dist: Pillow>=10.0; extra == "all"
87
+ Dynamic: license-file
88
+
89
+ # Climate Change
90
+
91
+ [![PyPI version](https://img.shields.io/pypi/v/climate-change?label=pypi)](https://pypi.org/project/climate-change/)
92
+ [![Python versions](https://img.shields.io/pypi/pyversions/climate-change?label=python)](https://pypi.org/project/climate-change/)
93
+ [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](#license)
94
+
95
+ `climate-change` is the core Python package for the ARIN Climate Resilience
96
+ Decision Support System. It combines Earth observation data, geospatial
97
+ processing, machine-learning models, distributed execution, explainability,
98
+ AI-assisted interpretation, and PDF reporting in one analysis library.
99
+
100
+ The package supports five climate-risk use cases:
101
+
102
+ - drought monitoring and early warning;
103
+ - flood-risk monitoring and mitigation;
104
+ - food-security assessment;
105
+ - climate-driven disease surveillance; and
106
+ - rangeland dynamics and land-degradation assessment.
107
+
108
+ Each analysis accepts an area of interest (AOI), date range, country or region
109
+ name, and optional model settings. It returns a common `AnalysisOutput` object
110
+ containing GeoJSON, raster paths, statistics, SHAP explanations, chart data,
111
+ and metadata.
112
+
113
+ > [!IMPORTANT]
114
+ > This repository contains the computation package, not a web application or
115
+ > command-line interface. It is designed to be called from Python, notebooks,
116
+ > task workers, or an API backend.
117
+
118
+ ## Features
119
+
120
+ - Google Earth Engine integration for satellite and climate datasets
121
+ - Five analysis modules behind one asynchronous Python API
122
+ - Random Forest, XGBoost, LightGBM, Gradient Boosting, and LSTM models
123
+ - Dask-based local or distributed processing
124
+ - Cloud-Optimized GeoTIFF (COG) exports
125
+ - GeoJSON risk and severity layers
126
+ - SHAP feature-importance payloads where supported
127
+ - Optional OpenAI interpretation for policymaker-friendly summaries
128
+ - Optional PDF reports with maps, charts, findings, and recommendations
129
+ - In-process caching for repeated analyses
130
+
131
+ ## Use cases
132
+
133
+ | Module ID | Analysis | Default runtime model | Typical outputs | Suggested period |
134
+ | --- | --- | --- | --- | --- |
135
+ | `drought` | Composite Drought Index monitoring and forecasting | LSTM | CDI severity map, sub-index time series, six-month forecast | At least 5 years; 10–30 years is preferable |
136
+ | `flood` | Flood susceptibility and event-risk mapping | RF + XGBoost ensemble | Four-class risk map, COG, risk distribution, SHAP drivers | A rainy season or known flood event |
137
+ | `food_security` | Vegetation and climate stress assessment | Random Forest | Food-insecurity risk map, COG, vegetation/rainfall charts | At least one complete growing season |
138
+ | `disease` | Climate suitability for disease outbreaks | Gradient Boosting | Risk map, COG, hotspot and forecast charts | Recent 3–6 months; longer for trends |
139
+ | `land_degradation` | Vegetation decline and degradation detection | LightGBM | Degradation map, COG, NDVI trend and breakpoint statistics | At least 5 years; 10+ years is preferable |
140
+
141
+ Alternative models can be selected through `extra_params["model_type"]`:
142
+
143
+ | Module | Supported values |
144
+ | --- | --- |
145
+ | Drought | `lstm`, `drought_monitoring` |
146
+ | Flood | `rf`, `xgboost`, `ensemble` |
147
+ | Food security | `rf`, `xgboost`, `ensemble` |
148
+ | Disease | `gbm`, `xgboost`, `ensemble` |
149
+ | Land degradation | `rf`, `lgbm`, `ensemble` |
150
+
151
+ The registry exposes longer descriptions, input variables, date guidance, and
152
+ model notes:
153
+
154
+ ```python
155
+ from climate_change import USE_CASE_REGISTRY
156
+
157
+ for module_id, info in USE_CASE_REGISTRY.items():
158
+ print(module_id, info.name, info.default_model)
159
+ ```
160
+
161
+ ## Requirements
162
+
163
+ - Python 3.10–3.13
164
+ - A Google Cloud project with the Earth Engine API enabled
165
+ - Google Earth Engine credentials available on the machine
166
+ - Sufficient memory and disk space for geospatial and ML workloads
167
+
168
+ Some analyses download and process substantial satellite datasets. Runtime
169
+ depends on AOI size, date range, Earth Engine quotas, spatial resolution, and
170
+ the selected model.
171
+
172
+ ## Installation
173
+
174
+ Install the published package from PyPI:
175
+
176
+ ```bash
177
+ python -m pip install climate-change
178
+ ```
179
+
180
+ With `uv`:
181
+
182
+ ```bash
183
+ uv add climate-change
184
+ ```
185
+
186
+ The distribution name uses a hyphen, while the Python import uses an
187
+ underscore:
188
+
189
+ ```python
190
+ from climate_change import run_analysis
191
+ ```
192
+
193
+ ### Install from source with `uv`
194
+
195
+ ```bash
196
+ git clone https://github.com/Odero54/climate-change.git
197
+ cd climate-change
198
+ uv sync --all-extras
199
+ ```
200
+
201
+ Run Python inside the managed environment:
202
+
203
+ ```bash
204
+ uv run python
205
+ ```
206
+
207
+ ### Install from source with `pip`
208
+
209
+ ```bash
210
+ git clone https://github.com/Odero54/climate-change.git
211
+ cd climate-change
212
+ python -m venv .venv
213
+ source .venv/bin/activate
214
+ python -m pip install --upgrade pip
215
+ python -m pip install -e .
216
+ ```
217
+
218
+ For development tools and all optional integrations:
219
+
220
+ ```bash
221
+ python -m pip install -e ".[all,dev]"
222
+ ```
223
+
224
+ The repository root is mapped to the import package `climate_change` by
225
+ Setuptools. An editable installation is therefore recommended when working
226
+ from a clone.
227
+
228
+ ## Google Earth Engine setup
229
+
230
+ Authenticate once on the machine that will run the analyses:
231
+
232
+ ```bash
233
+ earthengine authenticate
234
+ ```
235
+
236
+ Set the Google Cloud project ID in your shell:
237
+
238
+ ```bash
239
+ export GEE_PROJECT="your-google-cloud-project-id"
240
+ ```
241
+
242
+ Alternatively, add it to a local `.env` file:
243
+
244
+ ```dotenv
245
+ GEE_PROJECT=your-google-cloud-project-id
246
+ ```
247
+
248
+ The project must exist, have the Earth Engine API enabled, and be accessible
249
+ to the authenticated Google account or service account.
250
+
251
+ You may validate a project before accepting analysis requests:
252
+
253
+ ```python
254
+ from climate_change import validate_gee_project
255
+
256
+ validate_gee_project("your-google-cloud-project-id")
257
+ ```
258
+
259
+ For backend deployments, authenticate non-interactively before starting the
260
+ application. Pass each user's validated project explicitly as `gee_project`;
261
+ do not rely on an interactive prompt in workers or API processes.
262
+
263
+ ## Quick start
264
+
265
+ `run_analysis()` is asynchronous:
266
+
267
+ ```python
268
+ import asyncio
269
+ from dataclasses import asdict
270
+
271
+ from climate_change import run_analysis
272
+
273
+ NAIROBI_AOI = {
274
+ "type": "Polygon",
275
+ "coordinates": [
276
+ [
277
+ [36.65, -1.45],
278
+ [37.10, -1.45],
279
+ [37.10, -1.10],
280
+ [36.65, -1.10],
281
+ [36.65, -1.45],
282
+ ]
283
+ ],
284
+ }
285
+
286
+
287
+ async def main() -> None:
288
+ output = await run_analysis(
289
+ module="flood",
290
+ aoi_geojson=NAIROBI_AOI,
291
+ start_date="2024-03-01",
292
+ end_date="2024-05-31",
293
+ country="Kenya",
294
+ gee_project="your-google-cloud-project-id",
295
+ extra_params={
296
+ "model_type": "rf",
297
+ "scale": 90,
298
+ "n_pixels": 5000,
299
+ "output_dir": "outputs",
300
+ },
301
+ )
302
+
303
+ print(output.stats)
304
+ print(output.raster_path)
305
+ print(asdict(output))
306
+
307
+
308
+ asyncio.run(main())
309
+ ```
310
+
311
+ Inside Jupyter, FastAPI, or another running event loop, call it directly:
312
+
313
+ ```python
314
+ output = await run_analysis(...)
315
+ ```
316
+
317
+ ## Example notebooks
318
+
319
+ The
320
+ [`example-usage`](https://github.com/Odero54/climate-change/tree/main/example-usage)
321
+ directory contains a runnable notebook
322
+ for each analysis module:
323
+
324
+ - [Drought monitoring and early warning](https://github.com/Odero54/climate-change/blob/main/example-usage/01_drought_analysis.ipynb)
325
+ - [Flood-risk monitoring and mitigation](https://github.com/Odero54/climate-change/blob/main/example-usage/02_flood_risk_analysis.ipynb)
326
+ - [Food-security assessment](https://github.com/Odero54/climate-change/blob/main/example-usage/03_food_security_analysis.ipynb)
327
+ - [Climate-driven disease surveillance](https://github.com/Odero54/climate-change/blob/main/example-usage/04_disease_risk_analysis.ipynb)
328
+ - [Land-degradation and rangeland dynamics](https://github.com/Odero54/climate-change/blob/main/example-usage/05_land_degradation_analysis.ipynb)
329
+
330
+ Launch Jupyter from the repository:
331
+
332
+ ```bash
333
+ uv run jupyter lab
334
+ ```
335
+
336
+ Each notebook reads `GEE_PROJECT` from the environment, uses a representative
337
+ African AOI, leaves cells unexecuted, and includes optional chart and PDF
338
+ report examples.
339
+
340
+ ## Public API
341
+
342
+ ```python
343
+ async def run_analysis(
344
+ module: str,
345
+ aoi_geojson: dict,
346
+ start_date: str,
347
+ end_date: str,
348
+ country: str,
349
+ gee_project: str = "",
350
+ extra_params: dict | None = None,
351
+ openai_api_key: str | None = None,
352
+ report_output_dir: str | None = None,
353
+ map_png_bytes: bytes | None = None,
354
+ ) -> AnalysisOutput:
355
+ ...
356
+ ```
357
+
358
+ ### Required arguments
359
+
360
+ - `module`: one of `drought`, `flood`, `food_security`, `disease`, or
361
+ `land_degradation`;
362
+ - `aoi_geojson`: a GeoJSON `Polygon`, `MultiPolygon`, `Feature`, or
363
+ `FeatureCollection`;
364
+ - `start_date` and `end_date`: ISO dates in `YYYY-MM-DD` format;
365
+ - `country`: display label included in statistics, metadata, and reports.
366
+
367
+ ### Optional arguments
368
+
369
+ - `gee_project`: Google Cloud project used for Earth Engine. If omitted,
370
+ `GEE_PROJECT` is used.
371
+ - `extra_params`: model and module-specific overrides.
372
+ - `openai_api_key`: generates an optional plain-language interpretation.
373
+ - `report_output_dir`: writes a timestamped PDF report to this directory.
374
+ - `map_png_bytes`: embeds a supplied PNG map image in the PDF report.
375
+
376
+ Common `extra_params` include:
377
+
378
+ | Parameter | Meaning |
379
+ | --- | --- |
380
+ | `model_type` | Selects one of the module's supported models |
381
+ | `scale` | Earth Engine sampling/export resolution in metres |
382
+ | `n_pixels` | Approximate number of training pixels to sample |
383
+ | `output_dir` | Directory for generated raster artifacts |
384
+ | `prefix` | Prefix used for output filenames |
385
+
386
+ Flood analyses also accept event-specific pre-flood, post-flood, rainfall, and
387
+ surface-water date windows. See
388
+ [`FloodRiskUseCase`](https://github.com/Odero54/climate-change/blob/main/flood/use_case.py)
389
+ for the complete configuration schema.
390
+
391
+ ## Result structure
392
+
393
+ Every module returns `AnalysisOutput`:
394
+
395
+ ```python
396
+ @dataclass
397
+ class AnalysisOutput:
398
+ module: str
399
+ geojson: dict
400
+ raster_path: str | dict[str, str] | None
401
+ stats: dict
402
+ shap: dict | None
403
+ charts: dict
404
+ metadata: dict
405
+ ```
406
+
407
+ - `geojson` contains spatial risk or severity features.
408
+ - `raster_path` points to one or more generated COG files when export
409
+ succeeds.
410
+ - `stats` contains module-specific summary metrics.
411
+ - `shap` contains feature importance for supported ML modules.
412
+ - `charts` contains frontend-ready chart payloads.
413
+ - `metadata` records the model, features, country, date range, and optional
414
+ report or AI interpretation information.
415
+
416
+ Because fields differ by module, consumers should treat `stats` and `charts`
417
+ as module-specific payloads.
418
+
419
+ ## AI interpretation and PDF reports
420
+
421
+ Pass an OpenAI API key to request a concise climate-risk interpretation:
422
+
423
+ ```python
424
+ output = await run_analysis(
425
+ module="land_degradation",
426
+ aoi_geojson=aoi,
427
+ start_date="2015-01-01",
428
+ end_date="2024-12-31",
429
+ country="Kenya",
430
+ gee_project="your-google-cloud-project-id",
431
+ openai_api_key="your-openai-api-key",
432
+ )
433
+
434
+ print(output.metadata.get("ai_interpretation"))
435
+ ```
436
+
437
+ The key is supplied to the OpenAI client for that analysis and is not managed
438
+ or persisted by this package.
439
+
440
+ To generate a PDF:
441
+
442
+ ```python
443
+ from pathlib import Path
444
+
445
+ map_bytes = Path("map.png").read_bytes()
446
+
447
+ output = await run_analysis(
448
+ module="drought",
449
+ aoi_geojson=aoi,
450
+ start_date="2010-01-01",
451
+ end_date="2024-12-31",
452
+ country="Kenya",
453
+ gee_project="your-google-cloud-project-id",
454
+ report_output_dir="reports",
455
+ map_png_bytes=map_bytes,
456
+ )
457
+
458
+ print(output.metadata["report_path"])
459
+ ```
460
+
461
+ `map_png_bytes` is optional. The report can still include generated charts
462
+ when no map screenshot is supplied.
463
+
464
+ ## Backend integration
465
+
466
+ The package can be called from a FastAPI route or background task:
467
+
468
+ ```python
469
+ from fastapi import APIRouter
470
+
471
+ from climate_change import run_analysis
472
+
473
+ router = APIRouter()
474
+
475
+
476
+ @router.post("/analyses")
477
+ async def create_analysis(body: dict):
478
+ output = await run_analysis(
479
+ module=body["module"],
480
+ aoi_geojson=body["aoi_geojson"],
481
+ start_date=body["start_date"],
482
+ end_date=body["end_date"],
483
+ country=body["country"],
484
+ gee_project=body["gee_project"],
485
+ extra_params=body.get("extra_params"),
486
+ )
487
+ return output
488
+ ```
489
+
490
+ In a production service:
491
+
492
+ - validate the GEE project during user registration;
493
+ - keep OAuth or service-account credentials on the server, not in the user
494
+ database;
495
+ - scope project IDs to their owners;
496
+ - run long analyses in a task queue;
497
+ - configure Dask workers before accepting jobs; and
498
+ - persist generated artifacts outside ephemeral worker storage.
499
+
500
+ ## Development
501
+
502
+ Install all development dependencies:
503
+
504
+ ```bash
505
+ uv sync --all-extras
506
+ ```
507
+
508
+ Run the test suite:
509
+
510
+ ```bash
511
+ uv run pytest
512
+ ```
513
+
514
+ Run linting and type checks:
515
+
516
+ ```bash
517
+ uv run ruff check .
518
+ uv run mypy .
519
+ ```
520
+
521
+ Format Python files:
522
+
523
+ ```bash
524
+ uv run ruff format .
525
+ ```
526
+
527
+ ## Package layout
528
+
529
+ ```text
530
+ .
531
+ ├── ai_interpreter/ # OpenAI result interpretation
532
+ ├── core/ # orchestration, caching, GEE auth, and Dask
533
+ ├── disease/ # disease-risk features, models, and exports
534
+ ├── drought/ # CDI processing and drought forecasting
535
+ ├── flood/ # flood features, models, and exports
536
+ ├── food_security/ # food-security features, models, and exports
537
+ ├── land_degradation/ # degradation features, models, and exports
538
+ ├── reporting/ # PDF report generation
539
+ ├── tests/ # unit tests
540
+ ├── registry.py # use-case metadata and model options
541
+ └── pyproject.toml # package and tool configuration
542
+ ```
543
+
544
+ ## Limitations
545
+
546
+ - Outputs are decision-support indicators, not operational warnings or
547
+ substitutes for field observations.
548
+ - Model performance depends on AOI, period, source-data availability, labels,
549
+ and Earth Engine processing limits.
550
+ - Synthetic or proxy labels used by individual workflows may not represent
551
+ locally observed outcomes.
552
+ - Large AOIs, long periods, or fine spatial resolutions may exceed Earth
553
+ Engine memory or quota limits.
554
+ - AI-generated interpretations should be reviewed by a domain expert before
555
+ informing policy or emergency action.
556
+
557
+ ## License
558
+
559
+ The package metadata declares the project under the MIT License.
560
+
561
+ ## Links
562
+
563
+ - Repository: <https://github.com/Odero54/climate-change>
564
+ - Issues: <https://github.com/Odero54/climate-change/issues>