site-calc-investment 1.2.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 (40) hide show
  1. site_calc_investment-1.2.0/.github/workflows/ci.yml +80 -0
  2. site_calc_investment-1.2.0/.github/workflows/publish.yml +107 -0
  3. site_calc_investment-1.2.0/.gitignore +48 -0
  4. site_calc_investment-1.2.0/CHANGELOG.md +65 -0
  5. site_calc_investment-1.2.0/CONTRIBUTING.md +213 -0
  6. site_calc_investment-1.2.0/LICENSE +21 -0
  7. site_calc_investment-1.2.0/MIGRATION_GUIDE.md +238 -0
  8. site_calc_investment-1.2.0/PKG-INFO +256 -0
  9. site_calc_investment-1.2.0/QUICK_START.md +196 -0
  10. site_calc_investment-1.2.0/README.md +219 -0
  11. site_calc_investment-1.2.0/READY_TO_PUBLISH.md +244 -0
  12. site_calc_investment-1.2.0/docs/INVESTMENT_CLIENT_SPEC.md +692 -0
  13. site_calc_investment-1.2.0/examples/01_basic_capacity_planning.py +172 -0
  14. site_calc_investment-1.2.0/examples/02_scenario_comparison.py +197 -0
  15. site_calc_investment-1.2.0/examples/03_financial_analysis.py +159 -0
  16. site_calc_investment-1.2.0/publish_to_github.bat +80 -0
  17. site_calc_investment-1.2.0/publish_to_github.sh +94 -0
  18. site_calc_investment-1.2.0/pyproject.toml +81 -0
  19. site_calc_investment-1.2.0/site_calc_investment/__init__.py +100 -0
  20. site_calc_investment-1.2.0/site_calc_investment/analysis/__init__.py +17 -0
  21. site_calc_investment-1.2.0/site_calc_investment/analysis/comparison.py +121 -0
  22. site_calc_investment-1.2.0/site_calc_investment/analysis/financial.py +202 -0
  23. site_calc_investment-1.2.0/site_calc_investment/api/__init__.py +5 -0
  24. site_calc_investment-1.2.0/site_calc_investment/api/client.py +442 -0
  25. site_calc_investment-1.2.0/site_calc_investment/exceptions.py +91 -0
  26. site_calc_investment-1.2.0/site_calc_investment/models/__init__.py +84 -0
  27. site_calc_investment-1.2.0/site_calc_investment/models/common.py +174 -0
  28. site_calc_investment-1.2.0/site_calc_investment/models/devices.py +263 -0
  29. site_calc_investment-1.2.0/site_calc_investment/models/requests.py +133 -0
  30. site_calc_investment-1.2.0/site_calc_investment/models/responses.py +105 -0
  31. site_calc_investment-1.2.0/tests/conftest.py +273 -0
  32. site_calc_investment-1.2.0/tests/test_api_client.py +441 -0
  33. site_calc_investment-1.2.0/tests/test_common_models.py +191 -0
  34. site_calc_investment-1.2.0/tests/test_device_models.py +338 -0
  35. site_calc_investment-1.2.0/tests/test_financial_analysis.py +301 -0
  36. site_calc_investment-1.2.0/tests/test_production.py +341 -0
  37. site_calc_investment-1.2.0/tests/test_request_models.py +234 -0
  38. site_calc_investment-1.2.0/tests/test_scenario_comparison.py +413 -0
  39. site_calc_investment-1.2.0/uv.lock +1052 -0
  40. site_calc_investment-1.2.0/verify_ready.py +97 -0
@@ -0,0 +1,80 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main, develop ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ matrix:
14
+ os: [ubuntu-latest, windows-latest, macos-latest]
15
+ python-version: ['3.10', '3.11', '3.12']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v2
27
+
28
+ - name: Install dependencies
29
+ run: |
30
+ uv venv
31
+ uv pip install -e ".[dev]"
32
+
33
+ - name: Lint with ruff
34
+ run: |
35
+ uv run ruff check .
36
+
37
+ - name: Check formatting with ruff
38
+ run: |
39
+ uv run ruff format --check .
40
+
41
+ - name: Type check with mypy
42
+ run: |
43
+ uv run mypy site_calc_investment/
44
+
45
+ - name: Run tests with pytest
46
+ run: |
47
+ uv run pytest tests/ --cov=site_calc_investment --cov-report=xml --cov-report=term
48
+
49
+ - name: Upload coverage to Codecov
50
+ uses: codecov/codecov-action@v4
51
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
52
+ with:
53
+ file: ./coverage.xml
54
+ flags: unittests
55
+ name: codecov-umbrella
56
+
57
+ build:
58
+ runs-on: ubuntu-latest
59
+ needs: test
60
+
61
+ steps:
62
+ - uses: actions/checkout@v4
63
+
64
+ - name: Set up Python
65
+ uses: actions/setup-python@v5
66
+ with:
67
+ python-version: '3.11'
68
+
69
+ - name: Install build dependencies
70
+ run: |
71
+ pip install build
72
+
73
+ - name: Build package
74
+ run: |
75
+ python -m build
76
+
77
+ - name: Check distribution
78
+ run: |
79
+ pip install twine
80
+ twine check dist/*
@@ -0,0 +1,107 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+ inputs:
8
+ target:
9
+ description: 'Publish target'
10
+ required: true
11
+ default: 'testpypi'
12
+ type: choice
13
+ options:
14
+ - testpypi
15
+ - pypi
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: '3.11'
27
+
28
+ - name: Install build dependencies
29
+ run: pip install build twine
30
+
31
+ - name: Build package
32
+ run: python -m build
33
+
34
+ - name: Check distribution
35
+ run: twine check dist/*
36
+
37
+ - name: Upload build artifacts
38
+ uses: actions/upload-artifact@v4
39
+ with:
40
+ name: dist
41
+ path: dist/
42
+
43
+ test:
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+
48
+ - name: Set up Python
49
+ uses: actions/setup-python@v5
50
+ with:
51
+ python-version: '3.11'
52
+
53
+ - name: Install uv
54
+ uses: astral-sh/setup-uv@v2
55
+
56
+ - name: Install dependencies
57
+ run: |
58
+ uv venv
59
+ uv pip install -e ".[dev]"
60
+
61
+ - name: Run tests
62
+ run: uv run pytest tests/ -v -m "not production"
63
+
64
+ publish-testpypi:
65
+ needs: [build, test]
66
+ runs-on: ubuntu-latest
67
+ if: github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'testpypi'
68
+ environment:
69
+ name: testpypi
70
+ url: https://test.pypi.org/project/site-calc-investment/
71
+ permissions:
72
+ id-token: write
73
+
74
+ steps:
75
+ - name: Download build artifacts
76
+ uses: actions/download-artifact@v4
77
+ with:
78
+ name: dist
79
+ path: dist/
80
+
81
+ - name: Publish to TestPyPI
82
+ uses: pypa/gh-action-pypi-publish@release/v1
83
+ with:
84
+ repository-url: https://test.pypi.org/legacy/
85
+ verbose: true
86
+
87
+ publish-pypi:
88
+ needs: [build, test]
89
+ runs-on: ubuntu-latest
90
+ if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi')
91
+ environment:
92
+ name: pypi
93
+ url: https://pypi.org/project/site-calc-investment/
94
+ permissions:
95
+ id-token: write
96
+
97
+ steps:
98
+ - name: Download build artifacts
99
+ uses: actions/download-artifact@v4
100
+ with:
101
+ name: dist
102
+ path: dist/
103
+
104
+ - name: Publish to PyPI
105
+ uses: pypa/gh-action-pypi-publish@release/v1
106
+ with:
107
+ verbose: true
@@ -0,0 +1,48 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ venv/
25
+ env/
26
+ ENV/
27
+ .venv
28
+
29
+ # IDE
30
+ .vscode/
31
+ .idea/
32
+ *.swp
33
+ *.swo
34
+ *~
35
+
36
+ # Testing
37
+ .pytest_cache/
38
+ .coverage
39
+ htmlcov/
40
+ .tox/
41
+
42
+ # MyPy
43
+ .mypy_cache/
44
+ .dmypy.json
45
+ dmypy.json
46
+
47
+ # Distribution
48
+ *.whl
@@ -0,0 +1,65 @@
1
+ # Changelog
2
+
3
+ All notable changes to the Site-Calc Investment Client will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.2.0] - 2026-02-03
9
+
10
+ ### Changed
11
+ - **Repository URLs**: Updated package metadata to point to official GitHub repository
12
+ - **CI/CD**: Added automatic PyPI publishing workflow on release tags
13
+
14
+ ### Fixed
15
+ - Minor documentation improvements and URL corrections
16
+
17
+ ---
18
+
19
+ ## [1.1.0] - 2026-02-01
20
+
21
+ ### Added
22
+ - **SOC Anchoring**: New optional fields `soc_anchor_interval_hours` and `soc_anchor_target`
23
+ in `BatteryProperties` for improved long-term battery optimization
24
+ - **Version Validation**: Client automatically checks server version compatibility and warns
25
+ if MAJOR.MINOR versions don't match
26
+ - **Timeout Control**: Jobs can now specify custom timeout limits
27
+
28
+ ### Changed
29
+ - **Default Solver**: Changed from CBC to HiGHS for 30-40% faster optimization times
30
+ - Results are identical; no code changes required
31
+
32
+ ### Notes
33
+ - All v1.0.x client code continues to work without modification
34
+ - SOC anchoring is opt-in via new optional fields
35
+ - Version warnings are informational only and don't affect functionality
36
+
37
+ ---
38
+
39
+ ## [1.0.0] - 2024-12-15
40
+
41
+ ### Added
42
+ - Initial release of Site-Calc Investment Client
43
+ - Complete Pydantic V2 models for investment planning requests and responses
44
+ - 10 device types: Battery, CHP, HeatAccumulator, Photovoltaic, ElectricityDemand, HeatDemand, ElectricityImport, ElectricityExport, GasImport, HeatExport
45
+ - API client with automatic retry logic and exponential backoff
46
+ - Financial analysis functions: NPV, IRR (Newton-Raphson), payback period
47
+ - Scenario comparison utilities for evaluating multiple investment options
48
+ - Support for 10-year hourly optimization (up to 100,000 intervals)
49
+ - Comprehensive test suite with 120 tests and 93% coverage
50
+ - Three complete examples demonstrating capacity planning, scenario comparison, and financial analysis
51
+
52
+ ### Features
53
+ - **Investment-Specific**: Designed exclusively for long-term capacity planning and ROI analysis
54
+ - **No Ancillary Services**: Investment client does not support ANS optimization (reserved for operational client)
55
+ - **1-Hour Resolution Only**: Optimized for multi-year planning horizons
56
+ - **Automatic Binary Relaxation**: CHP binary constraints automatically relaxed for tractability
57
+ - **Financial Metrics**: Built-in NPV, IRR, and payback period calculations
58
+ - **Type-Safe**: Full type hints with Pydantic V2 validation
59
+ - **Well-Tested**: 120 tests covering all major functionality with mocked HTTP responses
60
+
61
+ ### Notes
62
+ - Requires API key with `inv_` prefix
63
+ - Maximum 100,000 intervals (~11 years at 1-hour resolution)
64
+ - Default timeout: 3600 seconds (1 hour)
65
+ - Python 3.10+ required
@@ -0,0 +1,213 @@
1
+ # Contributing to Site-Calc Investment Client
2
+
3
+ Thank you for considering contributing to the Site-Calc Investment Client! This document provides guidelines for contributing to the project.
4
+
5
+ ## Development Setup
6
+
7
+ ### Prerequisites
8
+ - Python 3.10 or higher
9
+ - `uv` package manager (recommended) or `pip`
10
+
11
+ ### Setup Steps
12
+
13
+ 1. **Clone the repository**
14
+ ```bash
15
+ git clone https://github.com/site-calc/investment-client.git
16
+ cd investment-client
17
+ ```
18
+
19
+ 2. **Create virtual environment**
20
+ ```bash
21
+ uv venv
22
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
23
+ ```
24
+
25
+ 3. **Install dependencies**
26
+ ```bash
27
+ uv pip install -e ".[dev]"
28
+ ```
29
+
30
+ ## Development Workflow
31
+
32
+ ### Running Tests
33
+
34
+ Run all tests:
35
+ ```bash
36
+ pytest tests/
37
+ ```
38
+
39
+ Run with coverage:
40
+ ```bash
41
+ pytest tests/ --cov=site_calc_investment --cov-report=html
42
+ ```
43
+
44
+ Run specific test file:
45
+ ```bash
46
+ pytest tests/test_financial_analysis.py -v
47
+ ```
48
+
49
+ ### Code Style
50
+
51
+ We use `ruff` for linting and formatting:
52
+
53
+ ```bash
54
+ # Check for issues
55
+ ruff check .
56
+
57
+ # Auto-fix issues
58
+ ruff check --fix .
59
+
60
+ # Format code
61
+ ruff format .
62
+ ```
63
+
64
+ ### Type Checking
65
+
66
+ We use `mypy` for static type checking:
67
+
68
+ ```bash
69
+ mypy site_calc_investment/
70
+ ```
71
+
72
+ ## Code Standards
73
+
74
+ ### Style Guidelines
75
+ - **Line length**: 120 characters maximum
76
+ - **Type hints**: Required for all functions and methods
77
+ - **Docstrings**: Use reStructuredText format (PEP 257)
78
+ - **Imports**: Organized with `ruff` (stdlib, third-party, local)
79
+
80
+ ### Testing Requirements
81
+ - All new features must include tests
82
+ - Maintain or improve code coverage (currently 93%)
83
+ - Use pytest fixtures for common test data
84
+ - Mock HTTP requests (no real API calls in tests)
85
+
86
+ ### Commit Messages
87
+ Follow conventional commits format:
88
+ - `feat:` New feature
89
+ - `fix:` Bug fix
90
+ - `docs:` Documentation changes
91
+ - `test:` Test additions or changes
92
+ - `refactor:` Code refactoring
93
+ - `chore:` Maintenance tasks
94
+
95
+ Example:
96
+ ```
97
+ feat: Add support for wind turbine devices
98
+
99
+ - Add WindTurbine device model
100
+ - Add generation profile validation
101
+ - Add tests for wind turbine
102
+ ```
103
+
104
+ ## Test-Driven Development (TDD)
105
+
106
+ We follow TDD methodology:
107
+
108
+ 1. **Write tests first** - Define the interface and expected behavior
109
+ 2. **Implement code** - Make tests pass
110
+ 3. **Refactor** - Improve code quality while keeping tests green
111
+
112
+ Example workflow:
113
+ ```python
114
+ # 1. Write test (tests/test_new_feature.py)
115
+ def test_wind_turbine_creation():
116
+ turbine = WindTurbine(
117
+ name="WT1",
118
+ properties=WindTurbineProperties(capacity=5.0)
119
+ )
120
+ assert turbine.name == "WT1"
121
+
122
+ # 2. Run test (should fail)
123
+ pytest tests/test_new_feature.py::test_wind_turbine_creation
124
+
125
+ # 3. Implement feature (site_calc_investment/models/devices.py)
126
+ class WindTurbine(BaseModel):
127
+ name: str
128
+ properties: WindTurbineProperties
129
+
130
+ # 4. Run test again (should pass)
131
+ pytest tests/test_new_feature.py::test_wind_turbine_creation
132
+ ```
133
+
134
+ ## Pull Request Process
135
+
136
+ 1. **Create a branch**
137
+ ```bash
138
+ git checkout -b feat/your-feature-name
139
+ ```
140
+
141
+ 2. **Make your changes**
142
+ - Follow TDD workflow
143
+ - Add/update tests
144
+ - Update documentation if needed
145
+
146
+ 3. **Run quality checks**
147
+ ```bash
148
+ ruff check --fix .
149
+ ruff format .
150
+ mypy site_calc_investment/
151
+ pytest tests/
152
+ ```
153
+
154
+ 4. **Commit your changes**
155
+ ```bash
156
+ git add .
157
+ git commit -m "feat: Add your feature description"
158
+ ```
159
+
160
+ 5. **Push and create PR**
161
+ ```bash
162
+ git push origin feat/your-feature-name
163
+ ```
164
+
165
+ 6. **PR Checklist**
166
+ - [ ] Tests pass locally
167
+ - [ ] Code coverage maintained or improved
168
+ - [ ] Type hints added for all new code
169
+ - [ ] Docstrings added for public functions/classes
170
+ - [ ] CHANGELOG.md updated
171
+ - [ ] No breaking changes (or clearly documented)
172
+
173
+ ## Project Structure
174
+
175
+ ```
176
+ client-investment/
177
+ ├── site_calc_investment/ # Main package
178
+ │ ├── models/ # Pydantic models
179
+ │ │ ├── common.py # TimeSpan, Resolution, Location
180
+ │ │ ├── devices.py # Device models
181
+ │ │ ├── requests.py # Request models
182
+ │ │ └── responses.py # Response models
183
+ │ ├── api/ # API client
184
+ │ │ └── client.py # InvestmentClient
185
+ │ ├── analysis/ # Financial analysis
186
+ │ │ ├── financial.py # NPV, IRR, payback
187
+ │ │ └── comparison.py # Scenario comparison
188
+ │ └── exceptions.py # Custom exceptions
189
+ ├── tests/ # Test suite
190
+ │ ├── conftest.py # Pytest fixtures
191
+ │ ├── test_*.py # Test modules
192
+ ├── examples/ # Usage examples
193
+ └── docs/ # Documentation (if added)
194
+ ```
195
+
196
+ ## Adding New Device Types
197
+
198
+ If adding a new device type:
199
+
200
+ 1. **Define model** in `site_calc_investment/models/devices.py`
201
+ 2. **Add tests** in `tests/test_device_models.py`
202
+ 3. **Update examples** if relevant
203
+ 4. **Update CHANGELOG.md**
204
+
205
+ ## Questions or Issues?
206
+
207
+ - **Bug reports**: Open an issue with reproduction steps
208
+ - **Feature requests**: Open an issue describing the use case
209
+ - **Questions**: Check README.md first, then open a discussion
210
+
211
+ ## License
212
+
213
+ By contributing, you agree that your contributions will be licensed under the MIT License.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Site-Calc Team
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.