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.
- site_calc_investment-1.2.0/.github/workflows/ci.yml +80 -0
- site_calc_investment-1.2.0/.github/workflows/publish.yml +107 -0
- site_calc_investment-1.2.0/.gitignore +48 -0
- site_calc_investment-1.2.0/CHANGELOG.md +65 -0
- site_calc_investment-1.2.0/CONTRIBUTING.md +213 -0
- site_calc_investment-1.2.0/LICENSE +21 -0
- site_calc_investment-1.2.0/MIGRATION_GUIDE.md +238 -0
- site_calc_investment-1.2.0/PKG-INFO +256 -0
- site_calc_investment-1.2.0/QUICK_START.md +196 -0
- site_calc_investment-1.2.0/README.md +219 -0
- site_calc_investment-1.2.0/READY_TO_PUBLISH.md +244 -0
- site_calc_investment-1.2.0/docs/INVESTMENT_CLIENT_SPEC.md +692 -0
- site_calc_investment-1.2.0/examples/01_basic_capacity_planning.py +172 -0
- site_calc_investment-1.2.0/examples/02_scenario_comparison.py +197 -0
- site_calc_investment-1.2.0/examples/03_financial_analysis.py +159 -0
- site_calc_investment-1.2.0/publish_to_github.bat +80 -0
- site_calc_investment-1.2.0/publish_to_github.sh +94 -0
- site_calc_investment-1.2.0/pyproject.toml +81 -0
- site_calc_investment-1.2.0/site_calc_investment/__init__.py +100 -0
- site_calc_investment-1.2.0/site_calc_investment/analysis/__init__.py +17 -0
- site_calc_investment-1.2.0/site_calc_investment/analysis/comparison.py +121 -0
- site_calc_investment-1.2.0/site_calc_investment/analysis/financial.py +202 -0
- site_calc_investment-1.2.0/site_calc_investment/api/__init__.py +5 -0
- site_calc_investment-1.2.0/site_calc_investment/api/client.py +442 -0
- site_calc_investment-1.2.0/site_calc_investment/exceptions.py +91 -0
- site_calc_investment-1.2.0/site_calc_investment/models/__init__.py +84 -0
- site_calc_investment-1.2.0/site_calc_investment/models/common.py +174 -0
- site_calc_investment-1.2.0/site_calc_investment/models/devices.py +263 -0
- site_calc_investment-1.2.0/site_calc_investment/models/requests.py +133 -0
- site_calc_investment-1.2.0/site_calc_investment/models/responses.py +105 -0
- site_calc_investment-1.2.0/tests/conftest.py +273 -0
- site_calc_investment-1.2.0/tests/test_api_client.py +441 -0
- site_calc_investment-1.2.0/tests/test_common_models.py +191 -0
- site_calc_investment-1.2.0/tests/test_device_models.py +338 -0
- site_calc_investment-1.2.0/tests/test_financial_analysis.py +301 -0
- site_calc_investment-1.2.0/tests/test_production.py +341 -0
- site_calc_investment-1.2.0/tests/test_request_models.py +234 -0
- site_calc_investment-1.2.0/tests/test_scenario_comparison.py +413 -0
- site_calc_investment-1.2.0/uv.lock +1052 -0
- 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.
|