climagrid 0.1.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 (92) hide show
  1. climagrid-0.1.0/.dockerignore +17 -0
  2. climagrid-0.1.0/.github/workflows/ci.yml +38 -0
  3. climagrid-0.1.0/.github/workflows/docs.yml +26 -0
  4. climagrid-0.1.0/.github/workflows/media.yml +122 -0
  5. climagrid-0.1.0/.github/workflows/publish.yml +95 -0
  6. climagrid-0.1.0/.gitignore +51 -0
  7. climagrid-0.1.0/.readthedocs.yaml +17 -0
  8. climagrid-0.1.0/CITATION.cff +39 -0
  9. climagrid-0.1.0/CODE_OF_CONDUCT.md +43 -0
  10. climagrid-0.1.0/CONTRIBUTING.md +51 -0
  11. climagrid-0.1.0/Dockerfile +21 -0
  12. climagrid-0.1.0/GOVERNANCE.md +39 -0
  13. climagrid-0.1.0/LICENSE +202 -0
  14. climagrid-0.1.0/PKG-INFO +254 -0
  15. climagrid-0.1.0/README.md +187 -0
  16. climagrid-0.1.0/docs/api/assets.md +17 -0
  17. climagrid-0.1.0/docs/api/features.md +45 -0
  18. climagrid-0.1.0/docs/api/index.md +12 -0
  19. climagrid-0.1.0/docs/api/outputs.md +13 -0
  20. climagrid-0.1.0/docs/api/pipeline.md +28 -0
  21. climagrid-0.1.0/docs/api/schema.md +36 -0
  22. climagrid-0.1.0/docs/api/sources.md +50 -0
  23. climagrid-0.1.0/docs/assets/banner.png +0 -0
  24. climagrid-0.1.0/docs/assets/demo.cast +204 -0
  25. climagrid-0.1.0/docs/assets/demo.gif +0 -0
  26. climagrid-0.1.0/docs/assets/quickstart_map.png +0 -0
  27. climagrid-0.1.0/docs/conf.py +120 -0
  28. climagrid-0.1.0/docs/data_sources.md +158 -0
  29. climagrid-0.1.0/docs/demo.py +99 -0
  30. climagrid-0.1.0/docs/getting_started.md +147 -0
  31. climagrid-0.1.0/docs/index.md +65 -0
  32. climagrid-0.1.0/docs/make_banner.py +187 -0
  33. climagrid-0.1.0/docs/make_cast.py +108 -0
  34. climagrid-0.1.0/docs/national_impact.md +74 -0
  35. climagrid-0.1.0/docs/related_work.md +81 -0
  36. climagrid-0.1.0/docs/schema.md +117 -0
  37. climagrid-0.1.0/examples/data/sample_assets.csv +46 -0
  38. climagrid-0.1.0/examples/data/tx_assets.csv +16 -0
  39. climagrid-0.1.0/examples/eagle_i_validation.ipynb +362 -0
  40. climagrid-0.1.0/examples/quickstart.ipynb +334 -0
  41. climagrid-0.1.0/examples/xgboost_lift_demo.ipynb +329 -0
  42. climagrid-0.1.0/pyproject.toml +117 -0
  43. climagrid-0.1.0/src/climagrid/__init__.py +17 -0
  44. climagrid-0.1.0/src/climagrid/assets/__init__.py +4 -0
  45. climagrid-0.1.0/src/climagrid/assets/joiner.py +177 -0
  46. climagrid-0.1.0/src/climagrid/assets/registry.py +153 -0
  47. climagrid-0.1.0/src/climagrid/cli.py +166 -0
  48. climagrid-0.1.0/src/climagrid/features/__init__.py +15 -0
  49. climagrid-0.1.0/src/climagrid/features/conductor_sag.py +136 -0
  50. climagrid-0.1.0/src/climagrid/features/freeze_thaw.py +83 -0
  51. climagrid-0.1.0/src/climagrid/features/ice_loading.py +110 -0
  52. climagrid-0.1.0/src/climagrid/features/soil.py +94 -0
  53. climagrid-0.1.0/src/climagrid/features/thermal.py +129 -0
  54. climagrid-0.1.0/src/climagrid/features/wildfire.py +157 -0
  55. climagrid-0.1.0/src/climagrid/outputs/__init__.py +9 -0
  56. climagrid-0.1.0/src/climagrid/outputs/exporters.py +165 -0
  57. climagrid-0.1.0/src/climagrid/pipeline/__init__.py +3 -0
  58. climagrid-0.1.0/src/climagrid/pipeline/orchestrator.py +190 -0
  59. climagrid-0.1.0/src/climagrid/schema.py +175 -0
  60. climagrid-0.1.0/src/climagrid/sources/__init__.py +21 -0
  61. climagrid-0.1.0/src/climagrid/sources/base.py +126 -0
  62. climagrid-0.1.0/src/climagrid/sources/nasa_power.py +118 -0
  63. climagrid-0.1.0/src/climagrid/sources/noaa_hrrr.py +206 -0
  64. climagrid-0.1.0/src/climagrid/sources/noaa_ncei.py +158 -0
  65. climagrid-0.1.0/src/climagrid/sources/usda_nrcs.py +204 -0
  66. climagrid-0.1.0/src/climagrid/sources/usfs_wfigs.py +201 -0
  67. climagrid-0.1.0/tests/__init__.py +0 -0
  68. climagrid-0.1.0/tests/conftest.py +156 -0
  69. climagrid-0.1.0/tests/test_assets/__init__.py +0 -0
  70. climagrid-0.1.0/tests/test_assets/test_joiner.py +66 -0
  71. climagrid-0.1.0/tests/test_assets/test_registry.py +99 -0
  72. climagrid-0.1.0/tests/test_cli.py +165 -0
  73. climagrid-0.1.0/tests/test_features/__init__.py +0 -0
  74. climagrid-0.1.0/tests/test_features/test_freeze_thaw.py +44 -0
  75. climagrid-0.1.0/tests/test_features/test_other_features.py +111 -0
  76. climagrid-0.1.0/tests/test_features/test_thermal.py +85 -0
  77. climagrid-0.1.0/tests/test_features/test_wildfire.py +49 -0
  78. climagrid-0.1.0/tests/test_outputs/__init__.py +0 -0
  79. climagrid-0.1.0/tests/test_outputs/test_exporters.py +139 -0
  80. climagrid-0.1.0/tests/test_pipeline/__init__.py +0 -0
  81. climagrid-0.1.0/tests/test_pipeline/test_integration.py +243 -0
  82. climagrid-0.1.0/tests/test_pipeline/test_orchestrator.py +123 -0
  83. climagrid-0.1.0/tests/test_properties.py +140 -0
  84. climagrid-0.1.0/tests/test_schema.py +70 -0
  85. climagrid-0.1.0/tests/test_sources/__init__.py +0 -0
  86. climagrid-0.1.0/tests/test_sources/test_base.py +47 -0
  87. climagrid-0.1.0/tests/test_sources/test_nasa_power.py +159 -0
  88. climagrid-0.1.0/tests/test_sources/test_noaa_hrrr.py +230 -0
  89. climagrid-0.1.0/tests/test_sources/test_noaa_ncei.py +157 -0
  90. climagrid-0.1.0/tests/test_sources/test_usda_nrcs.py +121 -0
  91. climagrid-0.1.0/tests/test_sources/test_usfs_wfigs.py +133 -0
  92. climagrid-0.1.0/uv.lock +4162 -0
@@ -0,0 +1,17 @@
1
+ .git/
2
+ .github/
3
+ tests/
4
+ docs/
5
+ examples/
6
+ dist/
7
+ build/
8
+ *.egg-info/
9
+ __pycache__/
10
+ *.pyc
11
+ *.pyo
12
+ .pytest_cache/
13
+ .mypy_cache/
14
+ .ruff_cache/
15
+ .env
16
+ *.parquet
17
+ *.csv
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, develop]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - uses: actions/setup-python@v5
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+ cache: pip
23
+
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev]"
26
+
27
+ - name: Lint (ruff)
28
+ run: ruff check src/ tests/
29
+
30
+ - name: Run tests (no live APIs)
31
+ run: pytest tests/ -m "not integration" -q --tb=short
32
+
33
+ - name: Upload coverage report
34
+ if: matrix.python-version == '3.12'
35
+ uses: codecov/codecov-action@v4
36
+ with:
37
+ token: ${{ secrets.CODECOV_TOKEN }}
38
+ fail_ci_if_error: false
@@ -0,0 +1,26 @@
1
+ name: Docs
2
+
3
+ # Validate that the Sphinx build is clean on every PR to main
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ jobs:
11
+ build-docs:
12
+ name: Build Sphinx docs
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+ cache: pip
21
+
22
+ - name: Install docs dependencies
23
+ run: pip install -e ".[docs]"
24
+
25
+ - name: Build docs (warnings = errors)
26
+ run: sphinx-build -W -b html docs/ docs/_build/html
@@ -0,0 +1,122 @@
1
+ name: Regenerate README media
2
+
3
+ # Runs on every published release (tag) OR manually from the Actions tab.
4
+ # Generates:
5
+ # docs/assets/demo.gif — animated terminal demo
6
+ # docs/assets/quickstart_map.png — notebook map screenshot
7
+ # and commits both back to the default branch.
8
+
9
+ on:
10
+ release:
11
+ types: [published]
12
+ workflow_dispatch:
13
+
14
+ permissions:
15
+ contents: write
16
+
17
+ jobs:
18
+ # ─────────────────────────────────────────────────────────────────────────
19
+ # Job 1: animated demo gif
20
+ # ─────────────────────────────────────────────────────────────────────────
21
+ demo-gif:
22
+ name: Generate demo gif
23
+ runs-on: ubuntu-latest
24
+
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+ with:
28
+ ref: main # always update main, not the tag
29
+
30
+ - uses: actions/setup-python@v5
31
+ with:
32
+ python-version: "3.12"
33
+ cache: pip
34
+
35
+ - name: Install climagrid and demo dependencies
36
+ run: pip install -e ".[dev]"
37
+
38
+ - name: Generate asciinema cast file
39
+ run: python docs/make_cast.py
40
+
41
+ - name: Install agg (asciinema gif renderer)
42
+ run: |
43
+ curl -sL https://github.com/asciinema/agg/releases/latest/download/agg-x86_64-unknown-linux-musl \
44
+ -o /usr/local/bin/agg
45
+ chmod +x /usr/local/bin/agg
46
+ agg --version
47
+
48
+ - name: Render cast to gif
49
+ run: |
50
+ agg docs/assets/demo.cast docs/assets/demo.gif \
51
+ --font-size 14 \
52
+ --speed 1.5 \
53
+ --theme monokai
54
+
55
+ - name: Upload gif as workflow artifact
56
+ uses: actions/upload-artifact@v4
57
+ with:
58
+ name: demo-gif
59
+ path: docs/assets/demo.gif
60
+ retention-days: 7
61
+
62
+ - name: Commit gif to main
63
+ run: |
64
+ git config user.name "github-actions[bot]"
65
+ git config user.email "github-actions[bot]@users.noreply.github.com"
66
+ git add docs/assets/demo.cast docs/assets/demo.gif
67
+ git diff --cached --quiet && echo "No changes." || \
68
+ git commit -m "chore: regenerate demo gif [skip ci]" && git push
69
+
70
+
71
+ # ─────────────────────────────────────────────────────────────────────────
72
+ # Job 2: notebook screenshot
73
+ # ─────────────────────────────────────────────────────────────────────────
74
+ notebook-screenshot:
75
+ name: Generate quickstart map screenshot
76
+ runs-on: ubuntu-latest
77
+
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ with:
81
+ ref: main
82
+
83
+ - uses: actions/setup-python@v5
84
+ with:
85
+ python-version: "3.12"
86
+ cache: pip
87
+
88
+ - name: Install climagrid and notebook dependencies
89
+ run: pip install -e ".[dev]" matplotlib
90
+
91
+ - name: Execute notebook headlessly
92
+ run: |
93
+ jupyter nbconvert \
94
+ --to notebook \
95
+ --execute \
96
+ --ExecutePreprocessor.timeout=300 \
97
+ --output /tmp/quickstart_executed.ipynb \
98
+ examples/quickstart.ipynb
99
+ env:
100
+ # Notebook saves map PNG to docs/assets/ via relative path
101
+ # No credentials needed — uses NASA POWER (public)
102
+ PYTHONPATH: src
103
+
104
+ - name: Verify PNG was generated
105
+ run: |
106
+ ls -lh docs/assets/quickstart_map.png
107
+ file docs/assets/quickstart_map.png
108
+
109
+ - name: Upload screenshot as workflow artifact
110
+ uses: actions/upload-artifact@v4
111
+ with:
112
+ name: quickstart-map
113
+ path: docs/assets/quickstart_map.png
114
+ retention-days: 7
115
+
116
+ - name: Commit screenshot to main
117
+ run: |
118
+ git config user.name "github-actions[bot]"
119
+ git config user.email "github-actions[bot]@users.noreply.github.com"
120
+ git add docs/assets/quickstart_map.png
121
+ git diff --cached --quiet && echo "No changes." || \
122
+ git commit -m "chore: regenerate quickstart map screenshot [skip ci]" && git push
@@ -0,0 +1,95 @@
1
+ name: Publish to PyPI
2
+
3
+ # Triggered only when a version tag is pushed (e.g. v0.1.0)
4
+ on:
5
+ push:
6
+ tags:
7
+ - "v[0-9]+.[0-9]+.[0-9]+"
8
+
9
+ permissions:
10
+ contents: read
11
+ # Required for OIDC Trusted Publisher authentication with PyPI
12
+ id-token: write
13
+
14
+ jobs:
15
+ # ── 1. Run the full test suite before publishing ──────────────────────────
16
+ test:
17
+ name: Test before publish
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+ cache: pip
26
+
27
+ - name: Install dependencies
28
+ run: pip install -e ".[dev]"
29
+
30
+ - name: Run tests (no live APIs)
31
+ run: pytest tests/ -m "not integration" -q --tb=short
32
+
33
+ # ── 2. Build the distribution ─────────────────────────────────────────────
34
+ build:
35
+ name: Build distribution
36
+ needs: test
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+
41
+ - name: Install uv
42
+ uses: astral-sh/setup-uv@v3
43
+ with:
44
+ version: "latest"
45
+
46
+ - name: Build sdist and wheel
47
+ run: uv build
48
+
49
+ - name: Upload distribution artifacts
50
+ uses: actions/upload-artifact@v4
51
+ with:
52
+ name: dist
53
+ path: dist/
54
+
55
+ # ── 3. Publish to TestPyPI (dry-run) ──────────────────────────────────────
56
+ publish-testpypi:
57
+ name: Publish to TestPyPI
58
+ needs: build
59
+ runs-on: ubuntu-latest
60
+ environment:
61
+ name: testpypi
62
+ url: https://test.pypi.org/p/climagrid
63
+ permissions:
64
+ id-token: write
65
+ steps:
66
+ - name: Download distribution artifacts
67
+ uses: actions/download-artifact@v4
68
+ with:
69
+ name: dist
70
+ path: dist/
71
+
72
+ - name: Publish to TestPyPI
73
+ uses: pypa/gh-action-pypi-publish@release/v1
74
+ with:
75
+ repository-url: https://test.pypi.org/legacy/
76
+
77
+ # ── 4. Publish to PyPI (production) ───────────────────────────────────────
78
+ publish-pypi:
79
+ name: Publish to PyPI
80
+ needs: publish-testpypi
81
+ runs-on: ubuntu-latest
82
+ environment:
83
+ name: pypi
84
+ url: https://pypi.org/p/climagrid
85
+ permissions:
86
+ id-token: write
87
+ steps:
88
+ - name: Download distribution artifacts
89
+ uses: actions/download-artifact@v4
90
+ with:
91
+ name: dist
92
+ path: dist/
93
+
94
+ - name: Publish to PyPI
95
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,51 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+
8
+ # Distribution / packaging
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+ *.egg
13
+ MANIFEST
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+ env/
19
+ ENV/
20
+
21
+ # Testing
22
+ .pytest_cache/
23
+ .coverage
24
+ coverage.xml
25
+ htmlcov/
26
+ .hypothesis/
27
+
28
+ # Type checking / linting
29
+ .mypy_cache/
30
+ .ruff_cache/
31
+
32
+ # Sphinx build output
33
+ docs/_build/
34
+
35
+ # Jupyter
36
+ .ipynb_checkpoints/
37
+
38
+ # OS
39
+ .DS_Store
40
+ Thumbs.db
41
+
42
+ # Editor
43
+ .idea/
44
+ .vscode/
45
+ *.swp
46
+ *.swo
47
+
48
+ # Data / output files (user-generated, not committed)
49
+ *.parquet
50
+ *.nc
51
+
@@ -0,0 +1,17 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-22.04
5
+ tools:
6
+ python: "3.12"
7
+
8
+ python:
9
+ install:
10
+ - method: pip
11
+ path: .
12
+ extra_requirements:
13
+ - docs
14
+
15
+ sphinx:
16
+ configuration: docs/conf.py
17
+ fail_on_warning: false
@@ -0,0 +1,39 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use climagrid in your research or engineering work, please cite it as below."
3
+ type: software
4
+ title: climagrid
5
+ abstract: >
6
+ Open-source Python toolkit that converts public NOAA, NASA, USDA, and U.S. Forest Service environmental data into standardized predictive-maintenance input features for electric utility grid resilience systems. Designed for rural electric cooperatives and municipal utilities serving approximately 42 million Americans.
7
+ authors:
8
+ - family-names: Adesiji
9
+ given-names: Temidire
10
+ email: temidireadesiji@gmail.com
11
+ repository-code: "https://github.com/TemidireAdesiji/climagrid"
12
+ url: "https://climagrid.readthedocs.io"
13
+ license: Apache-2.0
14
+ version: "0.1.0"
15
+ date-released: "2026-05-16"
16
+ keywords:
17
+ - NOAA
18
+ - NASA
19
+ - USDA
20
+ - electric utility
21
+ - predictive maintenance
22
+ - grid resilience
23
+ - rural cooperative
24
+ - climate
25
+ - weather
26
+ - environmental data
27
+ references:
28
+ - type: standard
29
+ title: "IEEE Standard for Calculating the Current-Temperature Relationship of Bare Overhead Conductors"
30
+ authors:
31
+ - name: "IEEE"
32
+ number: "738-2012"
33
+ year: 2012
34
+ - type: standard
35
+ title: "IEEE Guide for Loading Mineral-Oil-Immersed Transformers"
36
+ authors:
37
+ - name: "IEEE"
38
+ number: "C57.91-2011"
39
+ year: 2011
@@ -0,0 +1,43 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in the climagrid community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes
17
+ * Focusing on what is best for the overall community
18
+
19
+ Examples of unacceptable behavior:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or advances of any kind
22
+ * Trolling, insulting or derogatory comments, and personal or political attacks
23
+ * Public or private harassment
24
+ * Publishing others' private information without their explicit permission
25
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
26
+
27
+ ## Enforcement Responsibilities
28
+
29
+ Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the project in public spaces.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project maintainer at temidireadesiji@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
38
+
39
+ ## Attribution
40
+
41
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
42
+
43
+ [homepage]: https://www.contributor-covenant.org
@@ -0,0 +1,51 @@
1
+ # Contributing to climagrid
2
+
3
+ Thank you for helping improve grid resilience tooling for rural electric cooperatives.
4
+
5
+ ## Quick start
6
+
7
+ ```bash
8
+ git clone https://github.com/TemidireAdesiji/climagrid.git
9
+ cd climagrid
10
+ uv pip install -e ".[dev]"
11
+ uv run pytest tests/ -m "not integration" -q
12
+ ```
13
+
14
+ ## Adding a new data source
15
+
16
+ 1. Create `src/climagrid/sources/your_source.py` subclassing `BaseEnvironmentalSource`.
17
+ 2. Name columns using the `source_variable_unit` convention (e.g. `yourapi_temperature_2m`).
18
+ 3. Add column definitions to `src/climagrid/schema.py`.
19
+ 4. Add `"your_source"` to `_SOURCE_MAP` in `src/climagrid/pipeline/orchestrator.py`.
20
+ 5. Write unit tests with `responses` mocking. No live API calls in `tests/`.
21
+
22
+ ## Adding a new stress feature
23
+
24
+ 1. Create `src/climagrid/features/your_feature.py` with a class that has a `.compute(df) -> pd.DataFrame` method.
25
+ 2. The method must accept arbitrary extra columns and return a copy with the new `feat_` column added.
26
+ 3. Add the column spec to `FEATURE_COLUMNS` in `schema.py`.
27
+ 4. Add it to `_FEATURE_MAP` in `orchestrator.py`.
28
+
29
+ ## Code style
30
+
31
+ - `ruff check src/ tests/` must pass (enforced in CI).
32
+ - No live API calls in unit tests. Use the `responses` library for HTTP mocking.
33
+ - All new columns must be defined in `schema.py` before being emitted.
34
+
35
+ ## Pull request process
36
+
37
+ 1. Fork and branch from `main`.
38
+ 2. Run `uv run pytest tests/ -m "not integration"` locally.
39
+ 3. Open a PR against `main` with a clear description of the change.
40
+ 4. A maintainer will review within 5 business days.
41
+
42
+ ## Reporting bugs
43
+
44
+ Open an issue at https://github.com/TemidireAdesiji/climagrid/issues with:
45
+ - Python version and OS
46
+ - Minimal reproducible example
47
+ - Full traceback
48
+
49
+ ## License
50
+
51
+ By contributing, you agree your contributions will be licensed under the Apache 2.0 License.
@@ -0,0 +1,21 @@
1
+ FROM python:3.12-slim
2
+
3
+ LABEL maintainer="Temidire Adesiji <temidireadesiji@gmail.com>" \
4
+ description="climagrid — climate data, grid-ready" \
5
+ license="Apache-2.0"
6
+
7
+ WORKDIR /app
8
+
9
+ # Copy package manifest first so the install layer is cached when only src/ changes
10
+ COPY pyproject.toml README.md LICENSE ./
11
+ COPY src/ ./src/
12
+
13
+ RUN pip install --no-cache-dir --upgrade pip \
14
+ && pip install --no-cache-dir --root-user-action=ignore .
15
+
16
+ # Run as non-root
17
+ RUN useradd --create-home appuser
18
+ USER appuser
19
+
20
+ ENTRYPOINT ["climagrid"]
21
+ CMD ["--help"]
@@ -0,0 +1,39 @@
1
+ # climagrid Governance
2
+
3
+ ## Project status
4
+
5
+ climagrid is an open-source project released under the Apache 2.0 License with the explicit goal of being freely usable by any electric utility, rural cooperative, researcher, or regulator in the United States and worldwide.
6
+
7
+ The Apache 2.0 license will never change. Patent grants and freedom from royalties are permanent.
8
+
9
+ ## Current model: Benevolent Dictator For Now (BDFN)
10
+
11
+ The project is currently maintained by its author. Major decisions (API changes, new data source additions, schema column additions or renames) are made by the maintainer with input from the community via GitHub issues and discussions.
12
+
13
+ ## Commit rights
14
+
15
+ Commit rights are granted to contributors who have:
16
+
17
+ 1. Submitted at least two accepted pull requests
18
+ 2. Demonstrated familiarity with the column schema conventions in `schema.py`
19
+ 3. Written tests that pass in CI without live API calls
20
+
21
+ Request commit rights by opening a GitHub issue titled "Commit access request".
22
+
23
+ ## Decision process
24
+
25
+ For non-breaking changes (new source adapters, new feature modules, documentation): a pull request with a passing CI and one maintainer approval is sufficient.
26
+
27
+ For breaking changes (schema column renames, removed public API): a 14-day comment period on the relevant GitHub issue is required before merging.
28
+
29
+ ## Roadmap
30
+
31
+ The roadmap is maintained at [docs/roadmap.md](docs/roadmap.md) and discussed in GitHub Discussions. Community members are encouraged to propose new data sources and feature modules through the issue tracker.
32
+
33
+ ## Evolution
34
+
35
+ As the contributor base grows, governance will evolve toward a Steering Committee model with representatives from rural cooperatives and utility research organizations. Governance changes themselves require a 30-day comment period and consensus among existing committers.
36
+
37
+ ## Security
38
+
39
+ Report security issues privately to temidireadesiji@gmail.com. Do not open public issues for security vulnerabilities. We aim to respond within 72 hours and publish an advisory within 14 days of a confirmed vulnerability.