guohanghui commited on
Commit
d23db5b
·
verified ·
1 Parent(s): edebe8d

Upload 781 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +24 -0
  2. PyPSA/mcp_output/README_MCP.md +77 -0
  3. PyPSA/mcp_output/analysis.json +982 -0
  4. PyPSA/mcp_output/env_info.json +15 -0
  5. PyPSA/mcp_output/mcp_logs/llm_statistics.json +11 -0
  6. PyPSA/mcp_output/mcp_logs/run_log.json +66 -0
  7. PyPSA/mcp_output/mcp_plugin/__init__.py +0 -0
  8. PyPSA/mcp_output/mcp_plugin/__pycache__/adapter.cpython-310.pyc +0 -0
  9. PyPSA/mcp_output/mcp_plugin/__pycache__/mcp_service.cpython-310.pyc +0 -0
  10. PyPSA/mcp_output/mcp_plugin/adapter.py +129 -0
  11. PyPSA/mcp_output/mcp_plugin/main.py +13 -0
  12. PyPSA/mcp_output/mcp_plugin/mcp_service.py +524 -0
  13. PyPSA/mcp_output/requirements.txt +9 -0
  14. PyPSA/mcp_output/simple_revise_error_analysis.json +6 -0
  15. PyPSA/mcp_output/start_mcp.py +33 -0
  16. PyPSA/mcp_output/tests_mcp/test_mcp_basic.py +49 -0
  17. PyPSA/mcp_output/tests_smoke/test_smoke.py +29 -0
  18. PyPSA/source/.codespell.ignore +9 -0
  19. PyPSA/source/.git-blame-ignore-revs +6 -0
  20. PyPSA/source/.github/ISSUE_TEMPLATE/bug_report.yaml +73 -0
  21. PyPSA/source/.github/ISSUE_TEMPLATE/config.yml +9 -0
  22. PyPSA/source/.github/ISSUE_TEMPLATE/documentation_improvement.yaml +26 -0
  23. PyPSA/source/.github/ISSUE_TEMPLATE/feature_request.md +16 -0
  24. PyPSA/source/.github/dependabot.yml +18 -0
  25. PyPSA/source/.github/pull_request_template.md +11 -0
  26. PyPSA/source/.github/workflows/codeql.yml +96 -0
  27. PyPSA/source/.github/workflows/release.yml +174 -0
  28. PyPSA/source/.github/workflows/test-models.yml +206 -0
  29. PyPSA/source/.github/workflows/test.yml +223 -0
  30. PyPSA/source/.gitignore +54 -0
  31. PyPSA/source/.pre-commit-config.yaml +58 -0
  32. PyPSA/source/.readthedocs.yml +28 -0
  33. PyPSA/source/CITATION.cff +22 -0
  34. PyPSA/source/CONTRIBUTING.md +11 -0
  35. PyPSA/source/LICENSE +18 -0
  36. PyPSA/source/LICENSES/CC-BY-4.0.txt +156 -0
  37. PyPSA/source/LICENSES/MIT.txt +18 -0
  38. PyPSA/source/MANIFEST.in +10 -0
  39. PyPSA/source/README.md +210 -0
  40. PyPSA/source/REUSE.toml +51 -0
  41. PyPSA/source/__init__.py +4 -0
  42. PyPSA/source/codecov.yml +15 -0
  43. PyPSA/source/docs/CODE_OF_CONDUCT.md +143 -0
  44. PyPSA/source/docs/api/components/common.md +7 -0
  45. PyPSA/source/docs/api/components/components.md +24 -0
  46. PyPSA/source/docs/api/components/types/buses.md +7 -0
  47. PyPSA/source/docs/api/components/types/carriers.md +7 -0
  48. PyPSA/source/docs/api/components/types/generators.md +7 -0
  49. PyPSA/source/docs/api/components/types/global-constraints.md +7 -0
  50. PyPSA/source/docs/api/components/types/lines.md +13 -0
.gitattributes CHANGED
@@ -33,3 +33,27 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ PyPSA/source/docs/assets/images/ac_dc_meshed.png filter=lfs diff=lfs merge=lfs -text
37
+ PyPSA/source/docs/assets/images/carbon_management-energy_balance-area_plot-AC-bus_carrier.png filter=lfs diff=lfs merge=lfs -text
38
+ PyPSA/source/docs/assets/images/carbon_management-energy_balance-area_plot.png filter=lfs diff=lfs merge=lfs -text
39
+ PyPSA/source/docs/assets/images/elec_s_256_lv1.09_Co2L-3H.png filter=lfs diff=lfs merge=lfs -text
40
+ PyPSA/source/docs/assets/images/lmp_and_line-loading.png filter=lfs diff=lfs merge=lfs -text
41
+ PyPSA/source/docs/assets/images/load-distribution.png filter=lfs diff=lfs merge=lfs -text
42
+ PyPSA/source/docs/assets/images/pypsa-animation.png filter=lfs diff=lfs merge=lfs -text
43
+ PyPSA/source/docs/assets/images/reactive-power.png filter=lfs diff=lfs merge=lfs -text
44
+ PyPSA/source/docs/assets/images/scigrid-curtailment.png filter=lfs diff=lfs merge=lfs -text
45
+ PyPSA/source/docs/assets/images/stacked-gen_and_storage-scigrid.png filter=lfs diff=lfs merge=lfs -text
46
+ PyPSA/source/docs/assets/images/stacked-gen.png filter=lfs diff=lfs merge=lfs -text
47
+ PyPSA/source/docs/assets/images/storage-scigrid.png filter=lfs diff=lfs merge=lfs -text
48
+ PyPSA/source/docs/assets/logo/logo-primary-dark.png filter=lfs diff=lfs merge=lfs -text
49
+ PyPSA/source/docs/assets/logo/logo-primary-light-white-bg.png filter=lfs diff=lfs merge=lfs -text
50
+ PyPSA/source/docs/assets/logo/logo-primary-light.png filter=lfs diff=lfs merge=lfs -text
51
+ PyPSA/source/docs/assets/logo/logo-secondary-dark.png filter=lfs diff=lfs merge=lfs -text
52
+ PyPSA/source/docs/assets/logo/logo-secondary-light.png filter=lfs diff=lfs merge=lfs -text
53
+ PyPSA/source/docs/assets/logo/logo-white-bg.png filter=lfs diff=lfs merge=lfs -text
54
+ PyPSA/source/docs/assets/logo/logo.png filter=lfs diff=lfs merge=lfs -text
55
+ PyPSA/source/examples/networks/ac-dc-meshed/ac-dc-meshed.nc filter=lfs diff=lfs merge=lfs -text
56
+ PyPSA/source/examples/networks/model-energy/model-energy.nc filter=lfs diff=lfs merge=lfs -text
57
+ PyPSA/source/examples/networks/scigrid-de/scigrid-de.nc filter=lfs diff=lfs merge=lfs -text
58
+ PyPSA/source/examples/networks/stochastic-network/stochastic-network.nc filter=lfs diff=lfs merge=lfs -text
59
+ PyPSA/source/examples/networks/storage-hvdc/storage-hvdc.nc filter=lfs diff=lfs merge=lfs -text
PyPSA/mcp_output/README_MCP.md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MCP Plugin README
2
+
3
+ ## Project Overview
4
+
5
+ The MCP Plugin is a component of the PyPSA (Python for Power System Analysis) ecosystem, designed to enhance the capabilities of power system modeling and analysis. PyPSA is an open-source toolbox for simulating and optimizing modern power systems over multiple periods. The MCP Plugin extends these functionalities by providing additional tools and features for more detailed and specific analyses.
6
+
7
+ ### Key Features
8
+
9
+ - **Advanced Power System Modeling**: Leverage the robust PyPSA framework for detailed power system simulations.
10
+ - **Optimization Capabilities**: Perform complex optimization tasks to improve system efficiency and reliability.
11
+ - **Extensible and Customizable**: Easily integrate with existing PyPSA setups and customize according to specific project needs.
12
+
13
+ ## Installation Instructions
14
+
15
+ To install the MCP Plugin, ensure you have Python installed on your system. The plugin requires Python 3.7 or later. Follow these steps to install:
16
+
17
+ 1. **Clone the Repository**:
18
+ ```bash
19
+ git clone https://github.com/PyPSA/PyPSA.git
20
+ cd PyPSA
21
+ ```
22
+
23
+ 2. **Install Dependencies**:
24
+ The MCP Plugin requires several Python packages. You can install them using `pip`:
25
+ ```bash
26
+ pip install numpy pandas matplotlib
27
+ ```
28
+
29
+ Optional dependencies for enhanced functionalities include:
30
+ ```bash
31
+ pip install geopandas plotly
32
+ ```
33
+
34
+ 3. **Install the Plugin**:
35
+ Navigate to the plugin directory and install it:
36
+ ```bash
37
+ pip install .
38
+ ```
39
+
40
+ ## Usage Methods
41
+
42
+ Once installed, the MCP Plugin can be used within the PyPSA framework to perform various analyses. Here’s a basic usage example:
43
+
44
+ 1. **Import the Plugin**:
45
+ ```python
46
+ import pypsa
47
+ ```
48
+
49
+ 2. **Create a Network**:
50
+ ```python
51
+ network = pypsa.Network()
52
+ ```
53
+
54
+ 3. **Add Components and Perform Analysis**:
55
+ Use the plugin’s extended functionalities to add components and perform analyses on the network.
56
+
57
+ ## Available Tool Endpoints
58
+
59
+ The MCP Plugin provides several endpoints for interacting with the power system models:
60
+
61
+ - **Network Optimization**: Optimize network configurations for efficiency.
62
+ - **Power Flow Analysis**: Conduct detailed power flow studies.
63
+ - **Statistical Analysis**: Perform statistical evaluations of network performance.
64
+
65
+ ## Notes and Troubleshooting
66
+
67
+ - **Compatibility**: Ensure that your Python environment is compatible with the required dependencies.
68
+ - **Performance**: For large-scale simulations, consider optimizing your system resources.
69
+ - **Common Issues**:
70
+ - **Installation Errors**: Ensure all dependencies are correctly installed.
71
+ - **Runtime Errors**: Check for compatibility issues with other installed packages.
72
+
73
+ For further assistance, refer to the [PyPSA documentation](https://pypsa.org/doc/) or reach out to the community via the [PyPSA GitHub repository](https://github.com/PyPSA/PyPSA).
74
+
75
+ ## Conclusion
76
+
77
+ The MCP Plugin is a powerful extension to the PyPSA framework, offering advanced tools for power system analysis and optimization. By following the installation and usage instructions, users can effectively integrate and utilize the plugin for their specific needs. For any issues or contributions, please refer to the official PyPSA repository.
PyPSA/mcp_output/analysis.json ADDED
@@ -0,0 +1,982 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "summary": {
3
+ "repository_url": "https://github.com/PyPSA/PyPSA",
4
+ "summary": "Imported via zip fallback, file count: 280",
5
+ "file_tree": {
6
+ ".github/ISSUE_TEMPLATE/bug_report.yaml": {
7
+ "size": 1876
8
+ },
9
+ ".github/ISSUE_TEMPLATE/config.yml": {
10
+ "size": 248
11
+ },
12
+ ".github/ISSUE_TEMPLATE/documentation_improvement.yaml": {
13
+ "size": 747
14
+ },
15
+ ".github/ISSUE_TEMPLATE/feature_request.md": {
16
+ "size": 480
17
+ },
18
+ ".github/dependabot.yml": {
19
+ "size": 536
20
+ },
21
+ ".github/pull_request_template.md": {
22
+ "size": 449
23
+ },
24
+ ".github/workflows/codeql.yml": {
25
+ "size": 4362
26
+ },
27
+ ".github/workflows/release.yml": {
28
+ "size": 5532
29
+ },
30
+ ".github/workflows/test-models.yml": {
31
+ "size": 5584
32
+ },
33
+ ".github/workflows/test.yml": {
34
+ "size": 5866
35
+ },
36
+ ".pre-commit-config.yaml": {
37
+ "size": 1494
38
+ },
39
+ ".readthedocs.yml": {
40
+ "size": 699
41
+ },
42
+ "CONTRIBUTING.md": {
43
+ "size": 430
44
+ },
45
+ "LICENSES/CC-BY-4.0.txt": {
46
+ "size": 16983
47
+ },
48
+ "LICENSES/MIT.txt": {
49
+ "size": 1078
50
+ },
51
+ "README.md": {
52
+ "size": 9772
53
+ },
54
+ "REUSE.toml": {
55
+ "size": 1508
56
+ },
57
+ "codecov.yml": {
58
+ "size": 210
59
+ },
60
+ "docs/CODE_OF_CONDUCT.md": {
61
+ "size": 5811
62
+ },
63
+ "docs/api/components/common.md": {
64
+ "size": 117
65
+ },
66
+ "docs/api/components/components.md": {
67
+ "size": 507
68
+ },
69
+ "docs/api/components/types/buses.md": {
70
+ "size": 116
71
+ },
72
+ "docs/api/components/types/carriers.md": {
73
+ "size": 119
74
+ },
75
+ "docs/api/components/types/generators.md": {
76
+ "size": 121
77
+ },
78
+ "docs/api/components/types/global-constraints.md": {
79
+ "size": 128
80
+ },
81
+ "docs/api/components/types/lines.md": {
82
+ "size": 224
83
+ },
84
+ "docs/api/components/types/links.md": {
85
+ "size": 116
86
+ },
87
+ "docs/api/components/types/loads.md": {
88
+ "size": 116
89
+ },
90
+ "docs/api/components/types/shapes.md": {
91
+ "size": 117
92
+ },
93
+ "docs/api/components/types/shunt-impedances.md": {
94
+ "size": 126
95
+ },
96
+ "docs/api/components/types/storage-units.md": {
97
+ "size": 123
98
+ },
99
+ "docs/api/components/types/stores.md": {
100
+ "size": 117
101
+ },
102
+ "docs/api/components/types/sub-networks.md": {
103
+ "size": 122
104
+ },
105
+ "docs/api/components/types/transformers.md": {
106
+ "size": 238
107
+ },
108
+ "docs/api/networks/cluster.md": {
109
+ "size": 129
110
+ },
111
+ "docs/api/networks/collection.md": {
112
+ "size": 265
113
+ },
114
+ "docs/api/networks/components.md": {
115
+ "size": 210
116
+ },
117
+ "docs/api/networks/descriptors.md": {
118
+ "size": 212
119
+ },
120
+ "docs/api/networks/indexing.md": {
121
+ "size": 200
122
+ },
123
+ "docs/api/networks/io.md": {
124
+ "size": 164
125
+ },
126
+ "docs/api/networks/network.md": {
127
+ "size": 236
128
+ },
129
+ "docs/api/networks/optimize.md": {
130
+ "size": 424
131
+ },
132
+ "docs/api/networks/plot.md": {
133
+ "size": 445
134
+ },
135
+ "docs/api/networks/power-flow.md": {
136
+ "size": 179
137
+ },
138
+ "docs/api/networks/statistics.md": {
139
+ "size": 348
140
+ },
141
+ "docs/api/networks/subnetwork.md": {
142
+ "size": 164
143
+ },
144
+ "docs/api/networks/transform.md": {
145
+ "size": 178
146
+ },
147
+ "docs/api/other/api-examples.md": {
148
+ "size": 267
149
+ },
150
+ "docs/api/other/common.md": {
151
+ "size": 669
152
+ },
153
+ "docs/api/other/consistency.md": {
154
+ "size": 624
155
+ },
156
+ "docs/api/other/options.md": {
157
+ "size": 627
158
+ },
159
+ "docs/assets/javascripts/gurubase-widget.js": {
160
+ "size": 1197
161
+ },
162
+ "docs/assets/javascripts/matjax.js": {
163
+ "size": 502
164
+ },
165
+ "docs/assets/javascripts/readthedocs.js": {
166
+ "size": 809
167
+ },
168
+ "docs/contributing/contributing.md": {
169
+ "size": 6313
170
+ },
171
+ "docs/contributing/contributors.md": {
172
+ "size": 1441
173
+ },
174
+ "docs/examples/examples.md": {
175
+ "size": 8698
176
+ },
177
+ "docs/home/citing.md": {
178
+ "size": 9740
179
+ },
180
+ "docs/home/features.md": {
181
+ "size": 7780
182
+ },
183
+ "docs/home/installation.md": {
184
+ "size": 5455
185
+ },
186
+ "docs/home/license.md": {
187
+ "size": 1282
188
+ },
189
+ "docs/home/models.md": {
190
+ "size": 5138
191
+ },
192
+ "docs/home/users.md": {
193
+ "size": 23810
194
+ },
195
+ "docs/hooks/cleanup.py": {
196
+ "size": 968
197
+ },
198
+ "docs/hooks/dynamic_inspect.py": {
199
+ "size": 1082
200
+ },
201
+ "docs/hooks/path_aliases.py": {
202
+ "size": 4223
203
+ },
204
+ "docs/hooks/shortcodes.py": {
205
+ "size": 16035
206
+ },
207
+ "docs/index.md": {
208
+ "size": 4839
209
+ },
210
+ "docs/release-notes.md": {
211
+ "size": 128422
212
+ },
213
+ "docs/requirements.txt": {
214
+ "size": 17102
215
+ },
216
+ "docs/user-guide/collection.md": {
217
+ "size": 7632
218
+ },
219
+ "docs/user-guide/components.md": {
220
+ "size": 9304
221
+ },
222
+ "docs/user-guide/components/buses.md": {
223
+ "size": 654
224
+ },
225
+ "docs/user-guide/components/carriers.md": {
226
+ "size": 682
227
+ },
228
+ "docs/user-guide/components/generators.md": {
229
+ "size": 1012
230
+ },
231
+ "docs/user-guide/components/global-constraints.md": {
232
+ "size": 353
233
+ },
234
+ "docs/user-guide/components/line-types.md": {
235
+ "size": 936
236
+ },
237
+ "docs/user-guide/components/lines.md": {
238
+ "size": 951
239
+ },
240
+ "docs/user-guide/components/links.md": {
241
+ "size": 3686
242
+ },
243
+ "docs/user-guide/components/loads.md": {
244
+ "size": 867
245
+ },
246
+ "docs/user-guide/components/shapes.md": {
247
+ "size": 337
248
+ },
249
+ "docs/user-guide/components/shunt-impedances.md": {
250
+ "size": 943
251
+ },
252
+ "docs/user-guide/components/storage-units.md": {
253
+ "size": 1551
254
+ },
255
+ "docs/user-guide/components/stores.md": {
256
+ "size": 2536
257
+ },
258
+ "docs/user-guide/components/sub-networks.md": {
259
+ "size": 893
260
+ },
261
+ "docs/user-guide/components/transformer-types.md": {
262
+ "size": 855
263
+ },
264
+ "docs/user-guide/components/transformers.md": {
265
+ "size": 683
266
+ },
267
+ "docs/user-guide/design.md": {
268
+ "size": 17819
269
+ },
270
+ "docs/user-guide/faq.md": {
271
+ "size": 10223
272
+ },
273
+ "docs/user-guide/import-export.md": {
274
+ "size": 7634
275
+ },
276
+ "docs/user-guide/learning-materials.md": {
277
+ "size": 1010
278
+ },
279
+ "docs/user-guide/linear-power-flow.md": {
280
+ "size": 3856
281
+ },
282
+ "docs/user-guide/network-optimization.md": {
283
+ "size": 9547
284
+ },
285
+ "docs/user-guide/optimization/capacity-limits.md": {
286
+ "size": 7284
287
+ },
288
+ "docs/user-guide/optimization/contingencies.md": {
289
+ "size": 6579
290
+ },
291
+ "docs/user-guide/optimization/custom-constraints.md": {
292
+ "size": 7494
293
+ },
294
+ "docs/user-guide/optimization/dispatch-limits.md": {
295
+ "size": 7222
296
+ },
297
+ "docs/user-guide/optimization/energy-balance.md": {
298
+ "size": 3791
299
+ },
300
+ "docs/user-guide/optimization/global-constraints.md": {
301
+ "size": 12604
302
+ },
303
+ "docs/user-guide/optimization/modelling-to-generate-alternatives.md": {
304
+ "size": 5313
305
+ },
306
+ "docs/user-guide/optimization/objective.md": {
307
+ "size": 10001
308
+ },
309
+ "docs/user-guide/optimization/overview.md": {
310
+ "size": 3517
311
+ },
312
+ "docs/user-guide/optimization/pathway-planning.md": {
313
+ "size": 10983
314
+ },
315
+ "docs/user-guide/optimization/power-flow.md": {
316
+ "size": 7236
317
+ },
318
+ "docs/user-guide/optimization/stochastic.md": {
319
+ "size": 22635
320
+ },
321
+ "docs/user-guide/optimization/storage.md": {
322
+ "size": 11229
323
+ },
324
+ "docs/user-guide/optimization/unit-commitment.md": {
325
+ "size": 16807
326
+ },
327
+ "docs/user-guide/options.md": {
328
+ "size": 5386
329
+ },
330
+ "docs/user-guide/plotting/charts.md": {
331
+ "size": 15305
332
+ },
333
+ "docs/user-guide/power-flow.md": {
334
+ "size": 10049
335
+ },
336
+ "docs/user-guide/statistics.md": {
337
+ "size": 6948
338
+ },
339
+ "docs/user-guide/support.md": {
340
+ "size": 973
341
+ },
342
+ "docs/user-guide/troubleshooting.md": {
343
+ "size": 5941
344
+ },
345
+ "docs/user-guide/user-guide.md": {
346
+ "size": 1165
347
+ },
348
+ "docs/user-guide/v1-guide.md": {
349
+ "size": 9077
350
+ },
351
+ "examples/networks/ac-dc-meshed/ac-dc-meshed/crs.json": {
352
+ "size": 920
353
+ },
354
+ "examples/networks/ac-dc-meshed/ac-dc-meshed/meta.json": {
355
+ "size": 2
356
+ },
357
+ "examples/networks/model-energy/model-energy/crs.json": {
358
+ "size": 920
359
+ },
360
+ "examples/networks/model-energy/model-energy/meta.json": {
361
+ "size": 2
362
+ },
363
+ "examples/networks/scigrid-de/scigrid-de/crs.json": {
364
+ "size": 920
365
+ },
366
+ "examples/networks/scigrid-de/scigrid-de/meta.json": {
367
+ "size": 2
368
+ },
369
+ "examples/networks/storage-hvdc/storage-hvdc/crs.json": {
370
+ "size": 920
371
+ },
372
+ "examples/networks/storage-hvdc/storage-hvdc/meta.json": {
373
+ "size": 2
374
+ },
375
+ "mkdocs.yml": {
376
+ "size": 15022
377
+ },
378
+ "pyproject.toml": {
379
+ "size": 6831
380
+ },
381
+ "pypsa/__init__.py": {
382
+ "size": 2807
383
+ },
384
+ "pypsa/_options.py": {
385
+ "size": 13897
386
+ },
387
+ "pypsa/clustering/__init__.py": {
388
+ "size": 3376
389
+ },
390
+ "pypsa/clustering/spatial.py": {
391
+ "size": 35407
392
+ },
393
+ "pypsa/clustering/temporal.py": {
394
+ "size": 132
395
+ },
396
+ "pypsa/collection.py": {
397
+ "size": 28144
398
+ },
399
+ "pypsa/common.py": {
400
+ "size": 27902
401
+ },
402
+ "pypsa/components/__init__.py": {
403
+ "size": 1130
404
+ },
405
+ "pypsa/components/_types/__init__.py": {
406
+ "size": 1419
407
+ },
408
+ "pypsa/components/_types/_patch.py": {
409
+ "size": 3265
410
+ },
411
+ "pypsa/components/_types/buses.py": {
412
+ "size": 1352
413
+ },
414
+ "pypsa/components/_types/carriers.py": {
415
+ "size": 1379
416
+ },
417
+ "pypsa/components/_types/generators.py": {
418
+ "size": 2298
419
+ },
420
+ "pypsa/components/_types/global_constraints.py": {
421
+ "size": 1456
422
+ },
423
+ "pypsa/components/_types/line_types.py": {
424
+ "size": 1393
425
+ },
426
+ "pypsa/components/_types/lines.py": {
427
+ "size": 3882
428
+ },
429
+ "pypsa/components/_types/links.py": {
430
+ "size": 3090
431
+ },
432
+ "pypsa/components/_types/loads.py": {
433
+ "size": 1277
434
+ },
435
+ "pypsa/components/_types/shapes.py": {
436
+ "size": 1205
437
+ },
438
+ "pypsa/components/_types/shunt_impedances.py": {
439
+ "size": 1273
440
+ },
441
+ "pypsa/components/_types/storage_units.py": {
442
+ "size": 2518
443
+ },
444
+ "pypsa/components/_types/stores.py": {
445
+ "size": 2178
446
+ },
447
+ "pypsa/components/_types/sub_networks.py": {
448
+ "size": 1408
449
+ },
450
+ "pypsa/components/_types/transformer_types.py": {
451
+ "size": 1449
452
+ },
453
+ "pypsa/components/_types/transformers.py": {
454
+ "size": 2366
455
+ },
456
+ "pypsa/components/abstract.py": {
457
+ "size": 2676
458
+ },
459
+ "pypsa/components/array.py": {
460
+ "size": 12538
461
+ },
462
+ "pypsa/components/common.py": {
463
+ "size": 1848
464
+ },
465
+ "pypsa/components/components.py": {
466
+ "size": 26324
467
+ },
468
+ "pypsa/components/descriptors.py": {
469
+ "size": 9148
470
+ },
471
+ "pypsa/components/index.py": {
472
+ "size": 4049
473
+ },
474
+ "pypsa/components/legacy.py": {
475
+ "size": 2654
476
+ },
477
+ "pypsa/components/store.py": {
478
+ "size": 6550
479
+ },
480
+ "pypsa/components/transform.py": {
481
+ "size": 6882
482
+ },
483
+ "pypsa/components/types.py": {
484
+ "size": 7435
485
+ },
486
+ "pypsa/consistency.py": {
487
+ "size": 37582
488
+ },
489
+ "pypsa/constants.py": {
490
+ "size": 458
491
+ },
492
+ "pypsa/definitions/components.py": {
493
+ "size": 2020
494
+ },
495
+ "pypsa/definitions/structures.py": {
496
+ "size": 2240
497
+ },
498
+ "pypsa/deprecations.py": {
499
+ "size": 593
500
+ },
501
+ "pypsa/descriptors.py": {
502
+ "size": 8736
503
+ },
504
+ "pypsa/examples.py": {
505
+ "size": 6607
506
+ },
507
+ "pypsa/geo.py": {
508
+ "size": 6227
509
+ },
510
+ "pypsa/guards.py": {
511
+ "size": 7156
512
+ },
513
+ "pypsa/network/__init__.py": {
514
+ "size": 138
515
+ },
516
+ "pypsa/network/abstract.py": {
517
+ "size": 2775
518
+ },
519
+ "pypsa/network/components.py": {
520
+ "size": 30570
521
+ },
522
+ "pypsa/network/descriptors.py": {
523
+ "size": 8052
524
+ },
525
+ "pypsa/network/graph.py": {
526
+ "size": 10946
527
+ },
528
+ "pypsa/network/index.py": {
529
+ "size": 40162
530
+ },
531
+ "pypsa/network/io.py": {
532
+ "size": 86634
533
+ },
534
+ "pypsa/network/power_flow.py": {
535
+ "size": 67785
536
+ },
537
+ "pypsa/network/transform.py": {
538
+ "size": 21288
539
+ },
540
+ "pypsa/networks.py": {
541
+ "size": 62697
542
+ },
543
+ "pypsa/optimization/__init__.py": {
544
+ "size": 393
545
+ },
546
+ "pypsa/optimization/abstract.py": {
547
+ "size": 24469
548
+ },
549
+ "pypsa/optimization/common.py": {
550
+ "size": 2361
551
+ },
552
+ "pypsa/optimization/constraints.py": {
553
+ "size": 64639
554
+ },
555
+ "pypsa/optimization/expressions.py": {
556
+ "size": 26869
557
+ },
558
+ "pypsa/optimization/global_constraints.py": {
559
+ "size": 32963
560
+ },
561
+ "pypsa/optimization/mga.py": {
562
+ "size": 28507
563
+ },
564
+ "pypsa/optimization/optimize.py": {
565
+ "size": 40975
566
+ },
567
+ "pypsa/optimization/variables.py": {
568
+ "size": 7716
569
+ },
570
+ "pypsa/plot/__init__.py": {
571
+ "size": 641
572
+ },
573
+ "pypsa/plot/accessor.py": {
574
+ "size": 1401
575
+ },
576
+ "pypsa/plot/maps/__init__.py": {
577
+ "size": 460
578
+ },
579
+ "pypsa/plot/maps/common.py": {
580
+ "size": 28329
581
+ },
582
+ "pypsa/plot/maps/interactive.py": {
583
+ "size": 76737
584
+ },
585
+ "pypsa/plot/maps/static.py": {
586
+ "size": 66061
587
+ },
588
+ "pypsa/plot/statistics/__init__.py": {
589
+ "size": 420
590
+ },
591
+ "pypsa/plot/statistics/base.py": {
592
+ "size": 2845
593
+ },
594
+ "pypsa/plot/statistics/charts.py": {
595
+ "size": 22037
596
+ },
597
+ "pypsa/plot/statistics/maps.py": {
598
+ "size": 12641
599
+ },
600
+ "pypsa/plot/statistics/plotter.py": {
601
+ "size": 31725
602
+ },
603
+ "pypsa/plot/statistics/schema.py": {
604
+ "size": 9371
605
+ },
606
+ "pypsa/statistics/__init__.py": {
607
+ "size": 510
608
+ },
609
+ "pypsa/statistics/abstract.py": {
610
+ "size": 10351
611
+ },
612
+ "pypsa/statistics/expressions.py": {
613
+ "size": 113146
614
+ },
615
+ "pypsa/statistics/grouping.py": {
616
+ "size": 13732
617
+ },
618
+ "pypsa/type_utils.py": {
619
+ "size": 1135
620
+ },
621
+ "pypsa/version.py": {
622
+ "size": 1410
623
+ },
624
+ "test/conftest.py": {
625
+ "size": 8906
626
+ },
627
+ "test/data/ac-dc-meshed/results-lopf/crs.json": {
628
+ "size": 921
629
+ },
630
+ "test/data/ac-dc-meshed/results-lopf/meta.json": {
631
+ "size": 3
632
+ },
633
+ "test/data/benchmark-sp/crs.json": {
634
+ "size": 921
635
+ },
636
+ "test/data/benchmark-sp/meta.json": {
637
+ "size": 3
638
+ },
639
+ "test/test_bugs.py": {
640
+ "size": 7722
641
+ },
642
+ "test/test_collection.py": {
643
+ "size": 14965
644
+ },
645
+ "test/test_collection_statistics.py": {
646
+ "size": 18943
647
+ },
648
+ "test/test_common.py": {
649
+ "size": 14154
650
+ },
651
+ "test/test_common_deprecations.py": {
652
+ "size": 6725
653
+ },
654
+ "test/test_components.py": {
655
+ "size": 2717
656
+ },
657
+ "test/test_components_array.py": {
658
+ "size": 9287
659
+ },
660
+ "test/test_components_custom.py": {
661
+ "size": 1695
662
+ },
663
+ "test/test_components_store.py": {
664
+ "size": 398
665
+ },
666
+ "test/test_components_utils.py": {
667
+ "size": 460
668
+ },
669
+ "test/test_consistency_check.py": {
670
+ "size": 16082
671
+ },
672
+ "test/test_constants.py": {
673
+ "size": 5967
674
+ },
675
+ "test/test_deprecations.py": {
676
+ "size": 2726
677
+ },
678
+ "test/test_descriptors.py": {
679
+ "size": 5230
680
+ },
681
+ "test/test_docs.py": {
682
+ "size": 7727
683
+ },
684
+ "test/test_examples.py": {
685
+ "size": 1442
686
+ },
687
+ "test/test_graph.py": {
688
+ "size": 6678
689
+ },
690
+ "test/test_guards.py": {
691
+ "size": 835
692
+ },
693
+ "test/test_indices.py": {
694
+ "size": 2754
695
+ },
696
+ "test/test_io.py": {
697
+ "size": 24161
698
+ },
699
+ "test/test_io_cloudpathlib.py": {
700
+ "size": 3414
701
+ },
702
+ "test/test_link_post_discretization.py": {
703
+ "size": 4230
704
+ },
705
+ "test/test_lopf_ac_dc.py": {
706
+ "size": 820
707
+ },
708
+ "test/test_lopf_activity_mask.py": {
709
+ "size": 14953
710
+ },
711
+ "test/test_lopf_and_subsequent_power_flow.py": {
712
+ "size": 313
713
+ },
714
+ "test/test_lopf_basic_constraints.py": {
715
+ "size": 11940
716
+ },
717
+ "test/test_lopf_global_constraints.py": {
718
+ "size": 4076
719
+ },
720
+ "test/test_lopf_iteratively.py": {
721
+ "size": 1226
722
+ },
723
+ "test/test_lopf_losses.py": {
724
+ "size": 770
725
+ },
726
+ "test/test_lopf_mga.py": {
727
+ "size": 6265
728
+ },
729
+ "test/test_lopf_modularity.py": {
730
+ "size": 1157
731
+ },
732
+ "test/test_lopf_multiinvest.py": {
733
+ "size": 35983
734
+ },
735
+ "test/test_lopf_multilink.py": {
736
+ "size": 3960
737
+ },
738
+ "test/test_lopf_quadratic_costs.py": {
739
+ "size": 687
740
+ },
741
+ "test/test_lopf_rolling_horizon.py": {
742
+ "size": 2715
743
+ },
744
+ "test/test_lopf_storage.py": {
745
+ "size": 2821
746
+ },
747
+ "test/test_lopf_unit_commitment.py": {
748
+ "size": 16924
749
+ },
750
+ "test/test_lopf_varying_inputs.py": {
751
+ "size": 1628
752
+ },
753
+ "test/test_lpf_ac_dc.py": {
754
+ "size": 1556
755
+ },
756
+ "test/test_lpf_against_pypower.py": {
757
+ "size": 2670
758
+ },
759
+ "test/test_meshed_threshold.py": {
760
+ "size": 3880
761
+ },
762
+ "test/test_network.py": {
763
+ "size": 22314
764
+ },
765
+ "test/test_network_cycles.py": {
766
+ "size": 12678
767
+ },
768
+ "test/test_network_index.py": {
769
+ "size": 14289
770
+ },
771
+ "test/test_network_transform.py": {
772
+ "size": 8491
773
+ },
774
+ "test/test_optimization_expressions.py": {
775
+ "size": 5421
776
+ },
777
+ "test/test_optional_dependencies.py": {
778
+ "size": 2196
779
+ },
780
+ "test/test_options.py": {
781
+ "size": 9946
782
+ },
783
+ "test/test_pf_activity_mask.py": {
784
+ "size": 1039
785
+ },
786
+ "test/test_pf_against_pandapower.py": {
787
+ "size": 2358
788
+ },
789
+ "test/test_pf_against_pypower.py": {
790
+ "size": 3229
791
+ },
792
+ "test/test_pf_distributed_slack.py": {
793
+ "size": 2579
794
+ },
795
+ "test/test_plot_maps_common.py": {
796
+ "size": 20887
797
+ },
798
+ "test/test_plot_maps_interactive.py": {
799
+ "size": 5380
800
+ },
801
+ "test/test_plot_maps_static.py": {
802
+ "size": 9255
803
+ },
804
+ "test/test_riskaversion.py": {
805
+ "size": 11021
806
+ },
807
+ "test/test_sclopf_scigrid.py": {
808
+ "size": 3089
809
+ },
810
+ "test/test_snapshot_weightings.py": {
811
+ "size": 1375
812
+ },
813
+ "test/test_spatial_clustering.py": {
814
+ "size": 7552
815
+ },
816
+ "test/test_stand_by_cost.py": {
817
+ "size": 1397
818
+ },
819
+ "test/test_statistics.py": {
820
+ "size": 9835
821
+ },
822
+ "test/test_statistics_plot.py": {
823
+ "size": 8051
824
+ },
825
+ "test/test_statistics_plot_interactive.py": {
826
+ "size": 10662
827
+ },
828
+ "test/test_statistics_plot_schema.py": {
829
+ "size": 1152
830
+ },
831
+ "test/test_stochastic.py": {
832
+ "size": 56214
833
+ },
834
+ "test/test_stochastic_not_implemented.py": {
835
+ "size": 1835
836
+ },
837
+ "test/test_subnetwork.py": {
838
+ "size": 2908
839
+ },
840
+ "test/test_version.py": {
841
+ "size": 1433
842
+ },
843
+ "test/test_warnings_cyclic_storage.py": {
844
+ "size": 7694
845
+ }
846
+ },
847
+ "processed_by": "zip_fallback",
848
+ "success": true
849
+ },
850
+ "structure": {
851
+ "packages": [
852
+ "source.pypsa",
853
+ "source.pypsa.clustering",
854
+ "source.pypsa.components",
855
+ "source.pypsa.network",
856
+ "source.pypsa.optimization",
857
+ "source.pypsa.plot",
858
+ "source.pypsa.statistics"
859
+ ]
860
+ },
861
+ "dependencies": {
862
+ "has_environment_yml": false,
863
+ "has_requirements_txt": false,
864
+ "pyproject": true,
865
+ "setup_cfg": false,
866
+ "setup_py": false
867
+ },
868
+ "entry_points": {
869
+ "imports": [],
870
+ "cli": [],
871
+ "modules": []
872
+ },
873
+ "llm_analysis": {
874
+ "core_modules": [
875
+ {
876
+ "package": "source.pypsa",
877
+ "module": "__init__",
878
+ "functions": [],
879
+ "classes": [],
880
+ "description": "Initialization module for the PyPSA package."
881
+ },
882
+ {
883
+ "package": "source.pypsa.clustering",
884
+ "module": "spatial",
885
+ "functions": [
886
+ "cluster_spatial"
887
+ ],
888
+ "classes": [],
889
+ "description": "Functions for spatial clustering of network components."
890
+ },
891
+ {
892
+ "package": "source.pypsa.components",
893
+ "module": "components",
894
+ "functions": [
895
+ "add_component",
896
+ "remove_component"
897
+ ],
898
+ "classes": [
899
+ "Component"
900
+ ],
901
+ "description": "Handles the addition and removal of components in the network."
902
+ },
903
+ {
904
+ "package": "source.pypsa.network",
905
+ "module": "io",
906
+ "functions": [
907
+ "import_network",
908
+ "export_network"
909
+ ],
910
+ "classes": [],
911
+ "description": "Functions for importing and exporting network data."
912
+ },
913
+ {
914
+ "package": "source.pypsa.optimization",
915
+ "module": "optimize",
916
+ "functions": [
917
+ "optimize_network"
918
+ ],
919
+ "classes": [],
920
+ "description": "Optimization routines for network operation and planning."
921
+ },
922
+ {
923
+ "package": "source.pypsa.plot",
924
+ "module": "maps",
925
+ "functions": [
926
+ "plot_static_map",
927
+ "plot_interactive_map"
928
+ ],
929
+ "classes": [],
930
+ "description": "Plotting functions for static and interactive maps."
931
+ },
932
+ {
933
+ "package": "source.pypsa.statistics",
934
+ "module": "expressions",
935
+ "functions": [
936
+ "calculate_statistics"
937
+ ],
938
+ "classes": [],
939
+ "description": "Functions for calculating various network statistics."
940
+ }
941
+ ],
942
+ "cli_commands": [],
943
+ "import_strategy": {
944
+ "primary": "import",
945
+ "fallback": "blackbox",
946
+ "confidence": 0.85
947
+ },
948
+ "dependencies": {
949
+ "required": [
950
+ "numpy",
951
+ "pandas",
952
+ "matplotlib"
953
+ ],
954
+ "optional": [
955
+ "geopandas",
956
+ "plotly"
957
+ ]
958
+ },
959
+ "risk_assessment": {
960
+ "import_feasibility": 0.8,
961
+ "intrusiveness_risk": "medium",
962
+ "complexity": "medium"
963
+ }
964
+ },
965
+ "deepwiki_analysis": {
966
+ "repo_url": "https://github.com/PyPSA/PyPSA",
967
+ "repo_name": "PyPSA",
968
+ "content": null,
969
+ "model": "gpt-4o",
970
+ "source": "selenium",
971
+ "success": true
972
+ },
973
+ "deepwiki_options": {
974
+ "enabled": true,
975
+ "model": "gpt-4o"
976
+ },
977
+ "risk": {
978
+ "import_feasibility": 0.8,
979
+ "intrusiveness_risk": "medium",
980
+ "complexity": "medium"
981
+ }
982
+ }
PyPSA/mcp_output/env_info.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "environment": {
3
+ "type": "conda",
4
+ "name": "PyPSA_558543_env",
5
+ "files": {},
6
+ "python": "3.10",
7
+ "exec_prefix": []
8
+ },
9
+ "original_tests": {
10
+ "passed": false,
11
+ "report_path": null
12
+ },
13
+ "timestamp": 1763558620.0246599,
14
+ "conda_available": true
15
+ }
PyPSA/mcp_output/mcp_logs/llm_statistics.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "total_calls": 5,
3
+ "failed_calls": 0,
4
+ "retry_count": 0,
5
+ "total_prompt_tokens": 27816,
6
+ "total_completion_tokens": 4358,
7
+ "total_tokens": 32174,
8
+ "average_prompt_tokens": 5563.2,
9
+ "average_completion_tokens": 871.6,
10
+ "average_tokens": 6434.8
11
+ }
PyPSA/mcp_output/mcp_logs/run_log.json ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "timestamp": 1763558886.5027742,
3
+ "node": "RunNode",
4
+ "test_result": {
5
+ "passed": false,
6
+ "report_path": null,
7
+ "stdout": "",
8
+ "stderr": "onda.cli.main_run:execute(41): `conda run python mcp_output/start_mcp.py` failed. (See above for error)\nTraceback (most recent call last):\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/start_mcp.py\", line 17, in <module>\n from mcp_service import create_app\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin/mcp_service.py\", line 8, in <module>\n from pypsa import Network, SubNetwork, clustering, common, components, descriptors, examples, geo, optimization, plot, statistics\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/source/pypsa/__init__.py\", line 21, in <module>\n from pypsa import (\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/source/pypsa/clustering/__init__.py\", line 10, in <module>\n import pandas as pd\nModuleNotFoundError: No module named 'pandas'\n\n"
9
+ },
10
+ "run_result": {
11
+ "success": false,
12
+ "test_passed": false,
13
+ "exit_code": 1,
14
+ "stdout": "",
15
+ "stderr": "onda.cli.main_run:execute(41): `conda run python mcp_output/start_mcp.py` failed. (See above for error)\nTraceback (most recent call last):\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/start_mcp.py\", line 17, in <module>\n from mcp_service import create_app\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin/mcp_service.py\", line 8, in <module>\n from pypsa import Network, SubNetwork, clustering, common, components, descriptors, examples, geo, optimization, plot, statistics\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/source/pypsa/__init__.py\", line 21, in <module>\n from pypsa import (\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/source/pypsa/clustering/__init__.py\", line 10, in <module>\n import pandas as pd\nModuleNotFoundError: No module named 'pandas'\n\n",
16
+ "timestamp": 1763558886.5027297,
17
+ "error_type": "ImportError",
18
+ "error": "Module import failed: ERROR conda.cli.main_run:execute(41): `conda run python mcp_output/start_mcp.py` failed. (See above for error)\nTraceback (most recent call last):\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/start_mcp.py\", line 17, in <module>\n from mcp_service import create_app\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin/mcp_service.py\", line 8, in <module>\n from pypsa import Network, SubNetwork, clustering, common, components, descriptors, examples, geo, optimization, plot, statistics\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/source/pypsa/__init__.py\", line 21, in <module>\n from pypsa import (\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/source/pypsa/clustering/__init__.py\", line 10, in <module>\n import pandas as pd\nModuleNotFoundError: No module named 'pandas'\n\n",
19
+ "details": {
20
+ "command": "/home/wshiah/code/miniconda3/bin/conda run -n PyPSA_558543_env --cwd /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA python mcp_output/start_mcp.py",
21
+ "working_directory": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA",
22
+ "environment_type": "conda"
23
+ }
24
+ },
25
+ "environment": {
26
+ "type": "conda",
27
+ "name": "PyPSA_558543_env",
28
+ "files": {},
29
+ "python": "3.10",
30
+ "exec_prefix": []
31
+ },
32
+ "plugin_info": {
33
+ "files": {
34
+ "mcp_output/start_mcp.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/start_mcp.py",
35
+ "mcp_output/mcp_plugin/__init__.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin/__init__.py",
36
+ "mcp_output/mcp_plugin/mcp_service.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin/mcp_service.py",
37
+ "mcp_output/mcp_plugin/adapter.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin/adapter.py",
38
+ "mcp_output/mcp_plugin/main.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin/main.py",
39
+ "mcp_output/requirements.txt": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/requirements.txt",
40
+ "mcp_output/README_MCP.md": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/README_MCP.md",
41
+ "mcp_output/tests_mcp/test_mcp_basic.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/tests_mcp/test_mcp_basic.py"
42
+ },
43
+ "adapter_mode": "import",
44
+ "endpoints": [
45
+ "cluster_spatial",
46
+ "add_component",
47
+ "remove_component",
48
+ "component",
49
+ "import_network",
50
+ "export_network",
51
+ "optimize_network",
52
+ "plot_static_map",
53
+ "plot_interactive_map",
54
+ "calculate_statistics"
55
+ ],
56
+ "mcp_dir": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/mcp_plugin",
57
+ "tests_dir": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/tests_mcp",
58
+ "main_entry": "start_mcp.py",
59
+ "readme_path": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/PyPSA/mcp_output/README_MCP.md",
60
+ "requirements": [
61
+ "fastmcp>=0.1.0",
62
+ "pydantic>=2.0.0"
63
+ ]
64
+ },
65
+ "fastmcp_installed": false
66
+ }
PyPSA/mcp_output/mcp_plugin/__init__.py ADDED
File without changes
PyPSA/mcp_output/mcp_plugin/__pycache__/adapter.cpython-310.pyc ADDED
Binary file (4.16 kB). View file
 
PyPSA/mcp_output/mcp_plugin/__pycache__/mcp_service.cpython-310.pyc ADDED
Binary file (5.98 kB). View file
 
PyPSA/mcp_output/mcp_plugin/adapter.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ # Path settings
5
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
6
+ sys.path.insert(0, source_path)
7
+
8
+ # Import statements
9
+ try:
10
+ from pypsa import Network
11
+ from pypsa.clustering import spatial
12
+ from pypsa.optimization import optimize
13
+ from pypsa.plot import maps
14
+ from pypsa.statistics import expressions
15
+ except ImportError as e:
16
+ print(f"ImportError: {e}. Ensure the PyPSA package is correctly installed and accessible.")
17
+ # Fallback mode can be implemented here if necessary
18
+
19
+ # Adapter class definition
20
+ class Adapter:
21
+ """
22
+ Adapter class for the MCP plugin, utilizing the PyPSA library.
23
+ Provides methods to interact with various components and functionalities of PyPSA.
24
+ """
25
+
26
+ def __init__(self):
27
+ self.mode = "import"
28
+
29
+ # Network Module
30
+ # -------------------------------------------------------------------------
31
+ def create_network(self, *args, **kwargs):
32
+ """
33
+ Create a new network instance.
34
+
35
+ Parameters:
36
+ - args: Positional arguments for Network initialization.
37
+ - kwargs: Keyword arguments for Network initialization.
38
+
39
+ Returns:
40
+ - dict: Status and network instance or error message.
41
+ """
42
+ try:
43
+ network = Network(*args, **kwargs)
44
+ return {"status": "success", "network": network}
45
+ except Exception as e:
46
+ return {"status": "error", "message": f"Failed to create network: {e}"}
47
+
48
+ # Clustering Module
49
+ # -------------------------------------------------------------------------
50
+ def perform_spatial_clustering(self, network, *args, **kwargs):
51
+ """
52
+ Perform spatial clustering on the given network.
53
+
54
+ Parameters:
55
+ - network: The network instance to cluster.
56
+ - args: Additional positional arguments for clustering.
57
+ - kwargs: Additional keyword arguments for clustering.
58
+
59
+ Returns:
60
+ - dict: Status and clustering result or error message.
61
+ """
62
+ try:
63
+ result = spatial(network, *args, **kwargs)
64
+ return {"status": "success", "result": result}
65
+ except Exception as e:
66
+ return {"status": "error", "message": f"Failed to perform spatial clustering: {e}"}
67
+
68
+ # Optimization Module
69
+ # -------------------------------------------------------------------------
70
+ def optimize_network(self, network, *args, **kwargs):
71
+ """
72
+ Optimize the given network.
73
+
74
+ Parameters:
75
+ - network: The network instance to optimize.
76
+ - args: Additional positional arguments for optimization.
77
+ - kwargs: Additional keyword arguments for optimization.
78
+
79
+ Returns:
80
+ - dict: Status and optimization result or error message.
81
+ """
82
+ try:
83
+ result = optimize(network, *args, **kwargs)
84
+ return {"status": "success", "result": result}
85
+ except Exception as e:
86
+ return {"status": "error", "message": f"Failed to optimize network: {e}"}
87
+
88
+ # Plotting Module
89
+ # -------------------------------------------------------------------------
90
+ def plot_network_map(self, network, *args, **kwargs):
91
+ """
92
+ Plot a map of the given network.
93
+
94
+ Parameters:
95
+ - network: The network instance to plot.
96
+ - args: Additional positional arguments for plotting.
97
+ - kwargs: Additional keyword arguments for plotting.
98
+
99
+ Returns:
100
+ - dict: Status and plot result or error message.
101
+ """
102
+ try:
103
+ result = maps(network, *args, **kwargs)
104
+ return {"status": "success", "result": result}
105
+ except Exception as e:
106
+ return {"status": "error", "message": f"Failed to plot network map: {e}"}
107
+
108
+ # Statistics Module
109
+ # -------------------------------------------------------------------------
110
+ def calculate_expressions(self, network, *args, **kwargs):
111
+ """
112
+ Calculate expressions for the given network.
113
+
114
+ Parameters:
115
+ - network: The network instance for which to calculate expressions.
116
+ - args: Additional positional arguments for calculation.
117
+ - kwargs: Additional keyword arguments for calculation.
118
+
119
+ Returns:
120
+ - dict: Status and calculation result or error message.
121
+ """
122
+ try:
123
+ result = expressions(network, *args, **kwargs)
124
+ return {"status": "success", "result": result}
125
+ except Exception as e:
126
+ return {"status": "error", "message": f"Failed to calculate expressions: {e}"}
127
+
128
+ # End of Adapter class definition
129
+ # -------------------------------------------------------------------------
PyPSA/mcp_output/mcp_plugin/main.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ MCP Service Auto-Wrapper - Auto-generated
3
+ """
4
+ from mcp_service import create_app
5
+
6
+ def main():
7
+ """Main entry point"""
8
+ app = create_app()
9
+ return app
10
+
11
+ if __name__ == "__main__":
12
+ app = main()
13
+ app.run()
PyPSA/mcp_output/mcp_plugin/mcp_service.py ADDED
@@ -0,0 +1,524 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import json
4
+ from pathlib import Path
5
+
6
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
7
+ sys.path.insert(0, source_path)
8
+
9
+ from fastmcp import FastMCP
10
+ from pypsa import Network
11
+ from pypsa.statistics import StatisticsAccessor, get_operation, get_transmission_branches
12
+ import logging
13
+
14
+ # Set up logging
15
+ logging.basicConfig(level=logging.WARNING)
16
+ logger = logging.getLogger(__name__)
17
+
18
+ mcp = FastMCP("pypsa_service")
19
+
20
+ # ============================================================================
21
+ # NETWORK I/O TOOLS
22
+ # ============================================================================
23
+
24
+ @mcp.tool(
25
+ name="load_network",
26
+ description="Load a PyPSA network from a file (netCDF, HDF5, CSV folder, or URL)"
27
+ )
28
+ def tool_load_network(file_path: str) -> dict:
29
+ """
30
+ Load a PyPSA network from a specified file path.
31
+
32
+ Supported formats:
33
+ - .nc (NetCDF)
34
+ - .h5 (HDF5)
35
+ - folder containing CSV files
36
+ - URL to remote network file
37
+
38
+ Parameters:
39
+ - file_path (str): Path to the network file or folder
40
+
41
+ Returns:
42
+ - dict: Network metadata and basic info
43
+ """
44
+ try:
45
+ network = Network(file_path)
46
+
47
+ # Extract network metadata
48
+ result = {
49
+ "success": True,
50
+ "result": {
51
+ "network_name": network.name,
52
+ "pypsa_version": network._pypsa_version,
53
+ "snapshots_count": len(network.snapshots),
54
+ "buses_count": len(network.buses),
55
+ "generators_count": len(network.generators),
56
+ "loads_count": len(network.loads),
57
+ "storage_units_count": len(network.storage_units),
58
+ "stores_count": len(network.stores),
59
+ "lines_count": len(network.lines),
60
+ "links_count": len(network.links),
61
+ "transformers_count": len(network.transformers),
62
+ "sub_networks_count": len(network.sub_networks),
63
+ "objective_value": float(network.objective) if hasattr(network, 'objective') else None,
64
+ "carriers": list(network.carriers.index) if len(network.carriers) > 0 else [],
65
+ "crs": str(network.crs),
66
+ "file_path": str(file_path),
67
+ "description": f"Network with {len(network.buses)} buses, {len(network.generators)} generators, {len(network.loads)} loads"
68
+ },
69
+ "error": None
70
+ }
71
+ return result
72
+ except Exception as e:
73
+ return {"success": False, "result": None, "error": f"Failed to load network: {str(e)}"}
74
+
75
+ @mcp.tool(
76
+ name="save_network",
77
+ description="Save a PyPSA network to a file"
78
+ )
79
+ def tool_save_network(network_path: str, output_path: str, format: str = "netcdf") -> dict:
80
+ """
81
+ Save a PyPSA network to a file in specified format.
82
+
83
+ Supported formats:
84
+ - netcdf (.nc)
85
+ - hdf5 (.h5)
86
+ - csv (folder)
87
+
88
+ Parameters:
89
+ - network_path (str): Path to load the network from
90
+ - output_path (str): Path to save the network to
91
+ - format (str): Output format (netcdf, hdf5, or csv)
92
+
93
+ Returns:
94
+ - dict: Save status and result information
95
+ """
96
+ try:
97
+ network = Network(network_path)
98
+
99
+ if format.lower() in ["netcdf", "nc"]:
100
+ network.export_to_netcdf(output_path)
101
+ format_used = "NetCDF (.nc)"
102
+ elif format.lower() in ["hdf5", "h5"]:
103
+ network.export_to_hdf5(output_path)
104
+ format_used = "HDF5 (.h5)"
105
+ elif format.lower() == "csv":
106
+ network.export_to_csv_folder(output_path)
107
+ format_used = "CSV (folder)"
108
+ else:
109
+ raise ValueError(f"Unsupported format: {format}")
110
+
111
+ return {
112
+ "success": True,
113
+ "result": {
114
+ "output_path": str(output_path),
115
+ "format": format_used,
116
+ "description": f"Network saved successfully as {format_used}"
117
+ },
118
+ "error": None
119
+ }
120
+ except Exception as e:
121
+ return {"success": False, "result": None, "error": f"Failed to save network: {str(e)}"}
122
+
123
+ # ============================================================================
124
+ # NETWORK ANALYSIS TOOLS
125
+ # ============================================================================
126
+
127
+ @mcp.tool(
128
+ name="get_network_statistics",
129
+ description="Calculate detailed statistics for the network"
130
+ )
131
+ def tool_get_network_statistics(file_path: str) -> dict:
132
+ """
133
+ Calculate comprehensive statistics for the network.
134
+
135
+ Includes:
136
+ - Component counts and attributes
137
+ - Capacity information
138
+ - Operating data
139
+ - Energy flows
140
+ - Network topology stats
141
+
142
+ Parameters:
143
+ - file_path (str): Path to the network file
144
+
145
+ Returns:
146
+ - dict: Detailed network statistics
147
+ """
148
+ try:
149
+ network = Network(file_path)
150
+
151
+ # Calculate basic statistics
152
+ stats = {
153
+ "success": True,
154
+ "result": {
155
+ "network_overview": {
156
+ "name": network.name,
157
+ "snapshots_count": len(network.snapshots),
158
+ "time_period": f"{network.snapshots[0]} to {network.snapshots[-1]}" if len(network.snapshots) > 0 else "N/A"
159
+ },
160
+ "components": {
161
+ "buses": len(network.buses),
162
+ "generators": len(network.generators),
163
+ "storage_units": len(network.storage_units),
164
+ "stores": len(network.stores),
165
+ "loads": len(network.loads),
166
+ "lines": len(network.lines),
167
+ "links": len(network.links),
168
+ "transformers": len(network.transformers),
169
+ "sub_networks": len(network.sub_networks)
170
+ },
171
+ "capacity_stats": {
172
+ "total_generator_capacity_mw": round(network.generators.p_nom.sum(), 2) if len(network.generators) > 0 else 0,
173
+ "total_storage_capacity_mwh": round(network.storage_units.e_nom.sum(), 2) if len(network.storage_units) > 0 else 0,
174
+ "total_store_capacity_mwh": round(network.stores.e_nom.sum(), 2) if len(network.stores) > 0 else 0,
175
+ "total_load_mw": round(network.loads.p_set.sum(), 2) if len(network.loads) > 0 else 0
176
+ },
177
+ "carrier_info": {
178
+ "unique_carriers": list(network.carriers.index) if len(network.carriers) > 0 else [],
179
+ "carrier_count": len(network.carriers)
180
+ },
181
+ "transmission_info": {
182
+ "total_line_capacity_mva": round(network.lines.s_nom.sum(), 2) if len(network.lines) > 0 else 0,
183
+ "total_link_count": len(network.links),
184
+ "total_line_count": len(network.lines)
185
+ },
186
+ "objective_value": float(network.objective) if hasattr(network, 'objective') else None
187
+ },
188
+ "error": None
189
+ }
190
+ return stats
191
+ except Exception as e:
192
+ return {"success": False, "result": None, "error": f"Failed to get statistics: {str(e)}"}
193
+
194
+ @mcp.tool(
195
+ name="optimize_network",
196
+ description="Run network optimization with linear optimal power flow (LOPF)"
197
+ )
198
+ def tool_optimize_network(
199
+ file_path: str,
200
+ snapshots: str = "all",
201
+ linearized_unit_commitment: bool = False,
202
+ multi_invest: bool = False,
203
+ solver: str = "glpk"
204
+ ) -> dict:
205
+ """
206
+ Run linear optimal power flow (LOPF) optimization on the network.
207
+
208
+ Parameters:
209
+ - file_path (str): Path to the network file
210
+ - snapshots (str): "all" or comma-separated snapshot indices
211
+ - linearized_unit_commitment (bool): Enable linearized unit commitment
212
+ - multi_invest (bool): Enable multi-period investment optimization
213
+ - solver (str): Solver to use (glpk, cbc, cplex, gurobi, scip, etc.)
214
+
215
+ Returns:
216
+ - dict: Optimization results with objective value and status
217
+ """
218
+ try:
219
+ network = Network(file_path)
220
+
221
+ # Set optimization options
222
+ if linearized_unit_commitment:
223
+ network._linearized_uc = 1
224
+ if multi_invest:
225
+ network._multi_invest = 1
226
+
227
+ # Run optimization
228
+ status, termination_condition = network.optimize(
229
+ solver_name=solver,
230
+ multi_investment_periods=multi_invest
231
+ )
232
+
233
+ result = {
234
+ "success": True,
235
+ "result": {
236
+ "status": status,
237
+ "termination_condition": termination_condition,
238
+ "objective_value": round(float(network.objective), 2),
239
+ "optimization_info": {
240
+ "snapshots_optimized": len(network.snapshots),
241
+ "linearzed_unit_commitment": linearized_unit_commitment,
242
+ "multi_period_investment": multi_invest,
243
+ "solver_used": solver
244
+ },
245
+ "description": f"Optimization completed with status: {status}, objective value: {network.objective:.2f}"
246
+ },
247
+ "error": None
248
+ }
249
+ return result
250
+ except Exception as e:
251
+ return {"success": False, "result": None, "error": f"Optimization failed: {str(e)}"}
252
+
253
+ # ============================================================================
254
+ # NETWORK COMPONENTS ANALYSIS TOOLS
255
+ # ============================================================================
256
+
257
+ @mcp.tool(
258
+ name="get_buses_info",
259
+ description="Get information about all buses in the network"
260
+ )
261
+ def tool_get_buses_info(file_path: str) -> dict:
262
+ """
263
+ Get detailed information about buses in the network.
264
+
265
+ Returns:
266
+ - Bus counts by carrier
267
+ - Bus locations (if available)
268
+ - Control types
269
+ - Voltage levels
270
+
271
+ Parameters:
272
+ - file_path (str): Path to the network file
273
+
274
+ Returns:
275
+ - dict: Detailed bus information
276
+ """
277
+ try:
278
+ network = Network(file_path)
279
+
280
+ buses_info = {
281
+ "success": True,
282
+ "result": {
283
+ "total_buses": len(network.buses),
284
+ "buses_by_carrier": dict(network.buses.carrier.value_counts()) if len(network.buses) > 0 else {},
285
+ "buses_with_generation": len(network.buses[network.buses.index.isin(network.generators.bus)]) if len(network.generators) > 0 else 0,
286
+ "buses_with_load": len(network.buses[network.buses.index.isin(network.loads.bus)]) if len(network.loads) > 0 else 0,
287
+ "buses_with_storage": len(network.buses[network.buses.index.isin(network.storage_units.bus)]) if len(network.storage_units) > 0 else 0,
288
+ "buses_list": list(network.buses.index[:20]), # First 20 buses
289
+ "description": f"Network contains {len(network.buses)} buses"
290
+ },
291
+ "error": None
292
+ }
293
+ return buses_info
294
+ except Exception as e:
295
+ return {"success": False, "result": None, "error": f"Failed to get buses info: {str(e)}"}
296
+
297
+ @mcp.tool(
298
+ name="get_generators_info",
299
+ description="Get information about all generators in the network"
300
+ )
301
+ def tool_get_generators_info(file_path: str) -> dict:
302
+ """
303
+ Get detailed information about generators.
304
+
305
+ Returns:
306
+ - Generator counts by carrier
307
+ - Total installed capacity
308
+ - Generator efficiency
309
+ - Marginal costs
310
+
311
+ Parameters:
312
+ - file_path (str): Path to the network file
313
+
314
+ Returns:
315
+ - dict: Detailed generator information
316
+ """
317
+ try:
318
+ network = Network(file_path)
319
+
320
+ if len(network.generators) == 0:
321
+ return {
322
+ "success": True,
323
+ "result": {
324
+ "total_generators": 0,
325
+ "description": "No generators in network"
326
+ },
327
+ "error": None
328
+ }
329
+
330
+ generators_info = {
331
+ "success": True,
332
+ "result": {
333
+ "total_generators": len(network.generators),
334
+ "generators_by_carrier": dict(network.generators.carrier.value_counts()),
335
+ "total_capacity_mw": round(network.generators.p_nom.sum(), 2),
336
+ "average_efficiency": round(network.generators.efficiency.mean(), 4),
337
+ "marginal_cost_range": {
338
+ "min": round(network.generators.marginal_cost.min(), 2),
339
+ "max": round(network.generators.marginal_cost.max(), 2),
340
+ "mean": round(network.generators.marginal_cost.mean(), 2)
341
+ },
342
+ "generators_by_bus": dict(network.generators.bus.value_counts().head(10)),
343
+ "description": f"Network contains {len(network.generators)} generators with total capacity {network.generators.p_nom.sum():.2f} MW"
344
+ },
345
+ "error": None
346
+ }
347
+ return generators_info
348
+ except Exception as e:
349
+ return {"success": False, "result": None, "error": f"Failed to get generators info: {str(e)}"}
350
+
351
+ @mcp.tool(
352
+ name="get_transmission_info",
353
+ description="Get information about transmission branches (lines and links)"
354
+ )
355
+ def tool_get_transmission_info(file_path: str) -> dict:
356
+ """
357
+ Get detailed information about transmission branches.
358
+
359
+ Returns:
360
+ - Line and link counts
361
+ - Total transmission capacity
362
+ - Voltage levels
363
+ - Transmission losses
364
+
365
+ Parameters:
366
+ - file_path (str): Path to the network file
367
+
368
+ Returns:
369
+ - dict: Detailed transmission information
370
+ """
371
+ try:
372
+ network = Network(file_path)
373
+
374
+ transmission_info = {
375
+ "success": True,
376
+ "result": {
377
+ "transmission_components": {
378
+ "total_lines": len(network.lines),
379
+ "total_links": len(network.links),
380
+ "total_transformers": len(network.transformers)
381
+ },
382
+ "transmission_capacity": {
383
+ "total_line_capacity_mva": round(network.lines.s_nom.sum(), 2) if len(network.lines) > 0 else 0,
384
+ "total_link_capacity_mw": round(network.links.p_nom.sum(), 2) if len(network.links) > 0 else 0,
385
+ "average_line_capacity_mva": round(network.lines.s_nom.mean(), 2) if len(network.lines) > 0 else 0
386
+ },
387
+ "transmission_losses": {
388
+ "ac_line_losses": round(network.lines.x.sum(), 4) if len(network.lines) > 0 else 0,
389
+ "transformer_losses": round(network.transformers.x.sum(), 4) if len(network.transformers) > 0 else 0
390
+ },
391
+ "description": f"Network has {len(network.lines)} transmission lines and {len(network.links)} links"
392
+ },
393
+ "error": None
394
+ }
395
+ return transmission_info
396
+ except Exception as e:
397
+ return {"success": False, "result": None, "error": f"Failed to get transmission info: {str(e)}"}
398
+
399
+ # ============================================================================
400
+ # NETWORK CLUSTERING/AGGREGATION TOOLS
401
+ # ============================================================================
402
+
403
+ @mcp.tool(
404
+ name="cluster_network_by_kmeans",
405
+ description="Cluster network buses using k-means algorithm"
406
+ )
407
+ def tool_cluster_network_by_kmeans(file_path: str, clusters_count: int = 5) -> dict:
408
+ """
409
+ Cluster network buses using k-means algorithm for network reduction.
410
+
411
+ Parameters:
412
+ - file_path (str): Path to the network file
413
+ - clusters_count (int): Number of clusters to create
414
+
415
+ Returns:
416
+ - dict: Clustering results and mapping
417
+ """
418
+ try:
419
+ network = Network(file_path)
420
+
421
+ # Use PyPSA's clustering accessor
422
+ busmap = network.clustering.busmap_by_kmeans(clusters_count)
423
+
424
+ return {
425
+ "success": True,
426
+ "result": {
427
+ "original_buses_count": len(network.buses),
428
+ "target_clusters": clusters_count,
429
+ "created_clusters": len(busmap.unique()),
430
+ "clustering_method": "k-means",
431
+ "buses_per_cluster_avg": round(len(network.buses) / clusters_count, 2),
432
+ "description": f"Network reduced from {len(network.buses)} buses to {len(busmap.unique())} clusters using k-means"
433
+ },
434
+ "error": None
435
+ }
436
+ except Exception as e:
437
+ return {"success": False, "result": None, "error": f"Clustering failed: {str(e)}"}
438
+
439
+ # ============================================================================
440
+ # NETWORK EXPORT TOOLS
441
+ # ============================================================================
442
+
443
+ @mcp.tool(
444
+ name="export_network_summary",
445
+ description="Export a detailed summary of the network to JSON"
446
+ )
447
+ def tool_export_network_summary(file_path: str, output_file: str = None) -> dict:
448
+ """
449
+ Export a comprehensive network summary to JSON format.
450
+
451
+ Parameters:
452
+ - file_path (str): Path to the network file
453
+ - output_file (str): Optional path to save JSON summary (if None, returns inline)
454
+
455
+ Returns:
456
+ - dict: Network summary data
457
+ """
458
+ try:
459
+ network = Network(file_path)
460
+
461
+ summary = {
462
+ "network_name": network.name,
463
+ "pypsa_version": network._pypsa_version,
464
+ "statistics": {
465
+ "snapshots": len(network.snapshots),
466
+ "buses": len(network.buses),
467
+ "generators": len(network.generators),
468
+ "loads": len(network.loads),
469
+ "storage_units": len(network.storage_units),
470
+ "stores": len(network.stores),
471
+ "lines": len(network.lines),
472
+ "links": len(network.links),
473
+ "transformers": len(network.transformers)
474
+ },
475
+ "capacity": {
476
+ "generator_capacity_mw": round(network.generators.p_nom.sum(), 2) if len(network.generators) > 0 else 0,
477
+ "storage_capacity_mwh": round(network.storage_units.e_nom.sum(), 2) if len(network.storage_units) > 0 else 0,
478
+ "transmission_capacity_mva": round(network.lines.s_nom.sum(), 2) if len(network.lines) > 0 else 0
479
+ },
480
+ "carriers": list(network.carriers.index) if len(network.carriers) > 0 else [],
481
+ "objective": float(network.objective) if hasattr(network, 'objective') else None
482
+ }
483
+
484
+ if output_file:
485
+ with open(output_file, 'w') as f:
486
+ json.dump(summary, f, indent=2)
487
+ return {
488
+ "success": True,
489
+ "result": {
490
+ "summary_saved": True,
491
+ "output_file": str(output_file),
492
+ "description": f"Network summary exported to {output_file}"
493
+ },
494
+ "error": None
495
+ }
496
+ else:
497
+ return {
498
+ "success": True,
499
+ "result": summary,
500
+ "error": None
501
+ }
502
+ except Exception as e:
503
+ return {"success": False, "result": None, "error": f"Export failed: {str(e)}"}
504
+
505
+ # ============================================================================
506
+ # APP CREATION
507
+ # ============================================================================
508
+
509
+ def create_app() -> FastMCP:
510
+ """
511
+ Create and return the FastMCP application instance.
512
+
513
+ Features:
514
+ - Network loading and saving (NetCDF, HDF5, CSV)
515
+ - Optimization with LOPF
516
+ - Network statistics and analysis
517
+ - Component information extraction
518
+ - Network clustering and reduction
519
+ - Comprehensive export capabilities
520
+
521
+ Returns:
522
+ - FastMCP: The configured FastMCP instance with 10+ PyPSA tools.
523
+ """
524
+ return mcp
PyPSA/mcp_output/requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ fastmcp>=0.1.0
2
+ pydantic>=2.0.0
3
+ numpy
4
+ pandas
5
+ matplotlib
6
+
7
+ # Optional Dependencies
8
+ # geopandas
9
+ # plotly
PyPSA/mcp_output/simple_revise_error_analysis.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "status": "FAIL",
3
+ "next_action": "fix_directly",
4
+ "confidence": 0.9,
5
+ "summary": "The error is due to a missing Python module 'pandas', which is required by the 'pypsa.clustering' module. This can be fixed directly by installing the 'pandas' package in the conda environment being used. Run 'conda install pandas' to resolve the issue. Additionally, ensure that the conda environment is activated correctly before running the script."
6
+ }
PyPSA/mcp_output/start_mcp.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ MCP Service Startup Entry
3
+ """
4
+ import sys
5
+ import os
6
+
7
+ project_root = os.path.dirname(os.path.abspath(__file__))
8
+ mcp_plugin_dir = os.path.join(project_root, "mcp_plugin")
9
+ if mcp_plugin_dir not in sys.path:
10
+ sys.path.insert(0, mcp_plugin_dir)
11
+
12
+ # Set path to source directory
13
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
14
+ sys.path.insert(0, source_path)
15
+
16
+ from mcp_plugin.mcp_service import create_app
17
+
18
+ def main():
19
+ """Start FastMCP service"""
20
+ app = create_app()
21
+ # Use environment variable to configure port, default 8000
22
+ port = int(os.environ.get("MCP_PORT", "8000"))
23
+
24
+ # Choose transport mode based on environment variable
25
+ transport = os.environ.get("MCP_TRANSPORT", "stdio")
26
+ if transport == "http":
27
+ app.run(transport="http", host="0.0.0.0", port=port)
28
+ else:
29
+ # Default to STDIO mode
30
+ app.run()
31
+
32
+ if __name__ == "__main__":
33
+ main()
PyPSA/mcp_output/tests_mcp/test_mcp_basic.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ MCP Service Basic Test
3
+ """
4
+ import sys
5
+ import os
6
+
7
+ project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
8
+ mcp_plugin_dir = os.path.join(project_root, "mcp_plugin")
9
+ if mcp_plugin_dir not in sys.path:
10
+ sys.path.insert(0, mcp_plugin_dir)
11
+
12
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
13
+ sys.path.insert(0, source_path)
14
+
15
+ def test_import_mcp_service():
16
+ """Test if MCP service can be imported normally"""
17
+ try:
18
+ from mcp_service import create_app
19
+ app = create_app()
20
+ assert app is not None
21
+ print("MCP service imported successfully")
22
+ return True
23
+ except Exception as e:
24
+ print("MCP service import failed: " + str(e))
25
+ return False
26
+
27
+ def test_adapter_init():
28
+ """Test if adapter can be initialized normally"""
29
+ try:
30
+ from adapter import Adapter
31
+ adapter = Adapter()
32
+ assert adapter is not None
33
+ print("Adapter initialized successfully")
34
+ return True
35
+ except Exception as e:
36
+ print("Adapter initialization failed: " + str(e))
37
+ return False
38
+
39
+ if __name__ == "__main__":
40
+ print("Running MCP service basic test...")
41
+ test1 = test_import_mcp_service()
42
+ test2 = test_adapter_init()
43
+
44
+ if test1 and test2:
45
+ print("All basic tests passed")
46
+ sys.exit(0)
47
+ else:
48
+ print("Some tests failed")
49
+ sys.exit(1)
PyPSA/mcp_output/tests_smoke/test_smoke.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib, sys
2
+ import os
3
+
4
+ # Add current directory to Python path
5
+ sys.path.insert(0, os.getcwd())
6
+
7
+ source_dir = os.path.join(os.getcwd(), "source")
8
+ if os.path.exists(source_dir):
9
+ sys.path.insert(0, source_dir)
10
+
11
+
12
+ try:
13
+ importlib.import_module("pypsa")
14
+ print("OK - Successfully imported pypsa")
15
+ except ImportError as e:
16
+ print(f"Failed to import pypsa: {e}")
17
+ fallback_packages = []
18
+
19
+ fallback_packages = ['pypsa']
20
+
21
+ for pkg in fallback_packages:
22
+ try:
23
+ importlib.import_module(pkg)
24
+ print(f"OK - Successfully imported {pkg}")
25
+ break
26
+ except ImportError:
27
+ continue
28
+ else:
29
+ print("All import attempts failed")
PyPSA/source/.codespell.ignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ ines
6
+ psace
7
+ datas
8
+ fom
9
+ esy
PyPSA/source/.git-blame-ignore-revs ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ # apply pre-commit setup to all files (including black)
6
+ 57099450d1df78f9d3571f4515721aa04613d456
PyPSA/source/.github/ISSUE_TEMPLATE/bug_report.yaml ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: Bug Report
6
+ description: Create a report if something doesn't work quite right.
7
+ labels: ["needs triage"]
8
+ type: "Bug"
9
+
10
+ body:
11
+ - type: markdown
12
+ attributes:
13
+ value: |
14
+ Thanks for taking the time to fill out this bug report!
15
+ Please do not post usage questions here. Ask them on the [PyPSA Discord server](https://discord.gg/AnuJBk23FU).
16
+
17
+ - type: checkboxes
18
+ id: checks
19
+ attributes:
20
+ label: Version Checks (indicate both or one)
21
+ options:
22
+ - label: >
23
+ I have confirmed this bug exists on the lastest
24
+ [release](https://github.com/pypsa/pypsa/releases) of PyPSA.
25
+ - label: >
26
+ I have confirmed this bug exists on the current
27
+ [`master`](https://github.com/pypsa/pypsa/tree/master) branch of PyPSA.
28
+
29
+ - type: textarea
30
+ id: problem
31
+ attributes:
32
+ label: Issue Description
33
+ description: >
34
+ Please provide a description of the issue.
35
+ validations:
36
+ required: true
37
+
38
+ - type: textarea
39
+ id: example
40
+ validations:
41
+ required: true
42
+ attributes:
43
+ label: Reproducible Example
44
+ description: >
45
+ Please provide a minimal reproduciable example. See how to [craft minimal bug reports](https://matthewrocklin.com/minimal-bug-reports).
46
+ placeholder: >
47
+ import pypsa
48
+
49
+ n = pypsa.Network()
50
+
51
+ render: python
52
+
53
+ - type: textarea
54
+ id: expected-behavior
55
+ validations:
56
+ required: true
57
+ attributes:
58
+ label: Expected Behavior
59
+ description: >
60
+ Please describe or show a code example of the expected behavior.
61
+
62
+ - type: textarea
63
+ id: version
64
+ attributes:
65
+ label: Installed Versions
66
+ description: >
67
+ Please share information on your environment. Paste the output below. For conda `conda env export` and for pip `pip freeze`.
68
+ value: >
69
+ <details>
70
+
71
+ Replace this line.
72
+
73
+ </details>
PyPSA/source/.github/ISSUE_TEMPLATE/config.yml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ blank_issues_enabled: true
6
+ contact_links:
7
+ - name: PyPSA Discord server
8
+ url: https://discord.gg/AnuJBk23FU
9
+ about: Please ask and answer general usage questions here.
PyPSA/source/.github/ISSUE_TEMPLATE/documentation_improvement.yaml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: Documentation Improvement
6
+ description: Report wrong or missing documentation
7
+ labels: ["needs triage"]
8
+ type: 'Docs'
9
+
10
+ body:
11
+ - type: textarea
12
+ id: location
13
+ attributes:
14
+ label: Location
15
+ description: >
16
+ Please provide the location of the documentation or docstring, e.g. `pypsa.Network.import_from_netcdf` or the link to the docs.
17
+ placeholder: https://docs.pypsa.org/latest/user-guide/linear-power-flow
18
+ required: true
19
+ - type: textarea
20
+ id: problem
21
+ attributes:
22
+ label: Documentation problem
23
+ description: >
24
+ Please provide a description of what you believe needs to be fixed/ improved/ explained.
25
+ validations:
26
+ required: true
PyPSA/source/.github/ISSUE_TEMPLATE/feature_request.md ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: Feature Request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ["needs triage"]
6
+ type: 'Feature'
7
+ assignees: ''
8
+
9
+ ---
10
+
11
+ <!-- Please do not post usage questions here. Ask them on the PyPSA Discord server: https://discord.gg/AnuJBk23FU -->
12
+
13
+ ## Describe the feature you'd like to see
14
+
15
+ *Please give a clear and concise description and provide context why the feature would be useful.*
16
+ *Also, we'd appreciate any implementation ideas and references you already have.*
PyPSA/source/.github/dependabot.yml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ # dependabot
6
+ # Ref: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
7
+ # ------------------------------------------------------------------------------
8
+ version: 2
9
+ updates:
10
+ - package-ecosystem: github-actions
11
+ directory: /
12
+ schedule:
13
+ interval: monthly
14
+ groups:
15
+ # open a single pull-request for all GitHub actions updates
16
+ github-actions:
17
+ patterns:
18
+ - '*'
PyPSA/source/.github/pull_request_template.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Closes # (if applicable).
2
+
3
+ ## Changes proposed in this Pull Request
4
+
5
+
6
+ ## Checklist
7
+
8
+ - [ ] Code changes are sufficiently documented; i.e. new functions contain docstrings and further explanations may be given in `docs`.
9
+ - [ ] Unit tests for new features were added (if applicable).
10
+ - [ ] A note for the release notes `docs/release-notes.md` of the upcoming release is included.
11
+ - [ ] I consent to the release of this PR's code under the MIT license.
PyPSA/source/.github/workflows/codeql.yml ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ # For most projects, this workflow file will not need changing; you simply need
6
+ # to commit it to your repository.
7
+ #
8
+ # You may wish to alter this file to override the set of languages analyzed,
9
+ # or to provide custom queries or build logic.
10
+ #
11
+ # ******** NOTE ********
12
+ # We have attempted to detect the languages in your repository. Please check
13
+ # the `language` matrix defined below to confirm you have the correct set of
14
+ # supported CodeQL languages.
15
+ #
16
+ name: "CodeQL"
17
+
18
+ on:
19
+ push:
20
+ branches: ["master"]
21
+ pull_request:
22
+ branches: ["master"]
23
+ schedule:
24
+ - cron: '36 6 * * 4'
25
+
26
+ jobs:
27
+ analyze:
28
+ name: Analyze (${{ matrix.language }})
29
+ # Runner size impacts CodeQL analysis time. To learn more, please see:
30
+ # - https://gh.io/recommended-hardware-resources-for-running-codeql
31
+ # - https://gh.io/supported-runners-and-hardware-resources
32
+ # - https://gh.io/using-larger-runners (GitHub.com only)
33
+ # Consider using larger runners or machines with greater resources for possible analysis time improvements.
34
+ runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
35
+ permissions:
36
+ # required for all workflows
37
+ security-events: write
38
+
39
+ # required to fetch internal or private CodeQL packs
40
+ packages: read
41
+
42
+ # only required for workflows in private repositories
43
+ actions: read
44
+ contents: read
45
+
46
+ strategy:
47
+ fail-fast: false
48
+ matrix:
49
+ include:
50
+ - language: python
51
+ build-mode: none
52
+ # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
53
+ # Use `c-cpp` to analyze code written in C, C++ or both
54
+ # Use 'java-kotlin' to analyze code written in Java, Kotlin or both
55
+ # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
56
+ # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
57
+ # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
58
+ # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
59
+ # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
60
+ steps:
61
+ - name: Checkout repository
62
+ uses: actions/checkout@v5
63
+
64
+ # Initializes the CodeQL tools for scanning.
65
+ - name: Initialize CodeQL
66
+ uses: github/codeql-action/init@v4
67
+ with:
68
+ languages: ${{ matrix.language }}
69
+ build-mode: ${{ matrix.build-mode }}
70
+ # If you wish to specify custom queries, you can do so here or in a config file.
71
+ # By default, queries listed here will override any specified in a config file.
72
+ # Prefix the list here with "+" to use these queries and those in the config file.
73
+
74
+ # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
75
+ # queries: security-extended,security-and-quality
76
+
77
+ # If the analyze step fails for one of the languages you are analyzing with
78
+ # "We were unable to automatically build your code", modify the matrix above
79
+ # to set the build mode to "manual" for that language. Then modify this step
80
+ # to build your code.
81
+ # ℹ️ Command-line programs to run using the OS shell.
82
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
83
+ - if: matrix.build-mode == 'manual'
84
+ shell: bash
85
+ run: |
86
+ echo 'If you are using a "manual" build mode for one or more of the' \
87
+ 'languages you are analyzing, replace this with the commands to build' \
88
+ 'your code, for example:'
89
+ echo ' make bootstrap'
90
+ echo ' make release'
91
+ exit 1
92
+
93
+ - name: Perform CodeQL Analysis
94
+ uses: github/codeql-action/analyze@v4
95
+ with:
96
+ category: "/language:${{matrix.language}}"
PyPSA/source/.github/workflows/release.yml ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: Release
6
+
7
+ on:
8
+ push:
9
+ tags:
10
+ - v*.*.*
11
+
12
+ env:
13
+ PREPARATION_COMMIT: '[github-actions.ci] prepare release ${{ github.ref_name }}'
14
+
15
+ jobs:
16
+ check-preparation:
17
+ name: Check if release is prepared
18
+ runs-on: ubuntu-latest
19
+ outputs:
20
+ prepared: ${{ steps.validate.outputs.prepared }}
21
+ steps:
22
+ - uses: actions/checkout@v5
23
+
24
+ - name: Validate commit message
25
+ id: validate
26
+ run: |
27
+ # Check if last commit is the expected commit message
28
+ COMMIT_MESSAGE=$(git log -1 --pretty=%B)
29
+ echo "Expected: '${{ env.PREPARATION_COMMIT }}'"
30
+ echo "Received: '$COMMIT_MESSAGE'"
31
+
32
+ prepared="false"
33
+ if [[ "$COMMIT_MESSAGE" == "${{ env.PREPARATION_COMMIT }}" ]]; then
34
+ prepared="true"
35
+ fi
36
+
37
+ echo "prepared=$prepared" >> $GITHUB_OUTPUT
38
+
39
+ prepare-release:
40
+ name: Prepare release
41
+ needs: [check-preparation]
42
+ if: ${{ needs.check-preparation.outputs.prepared == 'false' }}
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - name: Generate token for PyPSA Bot
46
+ id: generate-token
47
+ uses: actions/create-github-app-token@v2
48
+ with:
49
+ app-id: ${{ vars.PYPSA_BOT_ID }}
50
+ private-key: ${{ secrets.PYPSA_BOT_PRIVATE_KEY }}
51
+
52
+ - uses: actions/checkout@v5
53
+ with:
54
+ fetch-depth: 0
55
+
56
+ - name: Find the branch for commit/ tag
57
+ run: |
58
+ branch=$(git branch -r --contains ${{ github.sha }} | grep -v 'HEAD' | head -n 1 | sed 's|origin/||' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
59
+ echo "Branch found: $branch"
60
+ echo "BRANCH_NAME=$branch" >> $GITHUB_ENV
61
+
62
+ - uses: actions/checkout@v5
63
+ with:
64
+ fetch-depth: 0
65
+ ref: ${{ env.BRANCH_NAME }}
66
+ token: ${{ steps.generate-token.outputs.token }}
67
+
68
+ # Start of preparation script
69
+
70
+ - uses: actions/setup-python@v6
71
+ with:
72
+ python-version: 3.12
73
+
74
+ - name: Install packages
75
+ run: |
76
+ python -m pip install uv
77
+ uv pip install --system toml
78
+ uv pip install --system setuptools_scm
79
+ uv pip install --system .
80
+
81
+ - name: Update CITATION.cff
82
+ run: |
83
+ import re
84
+ from setuptools_scm import get_version
85
+
86
+ version = get_version()
87
+
88
+ with open('CITATION.cff', 'r') as file:
89
+ cff_content = file.read()
90
+ cff_content = open('CITATION.cff', 'r').read()
91
+
92
+ updated_cff_content = re.sub(r"(?<=version: ).+(?= #)",version,cff_content,flags=re.MULTILINE)
93
+
94
+ with open('CITATION.cff', 'w') as file:
95
+ file.write(updated_cff_content)
96
+ shell: python
97
+
98
+ - name: Update example notebooks
99
+ run: |
100
+ import pypsa
101
+ # ac-dc-meshed
102
+ n = pypsa.Network("examples/networks/ac-dc-meshed/ac-dc-meshed")
103
+ n.export_to_csv_folder("examples/networks/ac-dc-meshed/ac-dc-meshed")
104
+ n.export_to_netcdf("examples/networks/ac-dc-meshed/ac-dc-meshed.nc")
105
+ # storage-hvdc
106
+ n = pypsa.Network("examples/networks/storage-hvdc/storage-hvdc")
107
+ n.export_to_csv_folder("examples/networks/storage-hvdc/storage-hvdc")
108
+ n.export_to_netcdf("examples/networks/storage-hvdc/storage-hvdc.nc")
109
+ # scigrid-de
110
+ n = pypsa.Network("examples/networks/scigrid-de/scigrid-de")
111
+ n.export_to_csv_folder("examples/networks/scigrid-de/scigrid-de")
112
+ n.export_to_netcdf("examples/networks/scigrid-de/scigrid-de.nc")
113
+ # model-energy
114
+ n = pypsa.Network("examples/networks/model-energy/model-energy")
115
+ n.export_to_csv_folder("examples/networks/model-energy/model-energy")
116
+ n.export_to_netcdf("examples/networks/model-energy/model-energy.nc")
117
+ # stochastic-network
118
+ n = pypsa.Network("examples/networks/stochastic-network/stochastic-network.nc")
119
+ n.export_to_netcdf("examples/networks/stochastic-network/stochastic-network.nc")
120
+ shell: python
121
+
122
+ # End of preparation script
123
+
124
+ - name: Remove previous tag
125
+ run: |
126
+ git tag -d ${{ github.ref_name }}
127
+ git push origin --delete ${{ github.ref_name }}
128
+
129
+ - name: Commit changes
130
+ uses: stefanzweifel/git-auto-commit-action@v7
131
+ with:
132
+ branch: ${{ env.BRANCH_NAME }}
133
+ commit_message: '${{ env.PREPARATION_COMMIT }}'
134
+ tagging_message: '${{ github.ref_name }}' # add tag again
135
+ push_options: '${{ github.ref_name }}'
136
+ add_options: '-u' # Never add untracked files
137
+
138
+ build:
139
+ name: Build and verify package
140
+ needs: [check-preparation]
141
+ if: ${{ needs.check-preparation.outputs.prepared == 'true' }}
142
+ runs-on: ubuntu-latest
143
+ steps:
144
+ - uses: actions/checkout@v5
145
+ - uses: hynek/build-and-inspect-python-package@v2
146
+
147
+ release:
148
+ name: Create GitHub release
149
+ needs: [build]
150
+ runs-on: ubuntu-latest
151
+ steps:
152
+ - uses: actions/checkout@v5
153
+ - uses: softprops/action-gh-release@v2
154
+ with:
155
+ body: |
156
+ Revised release notes are available in the [documentation](https://${{ github.event.repository.name }}.readthedocs.io/en/latest/release-notes.html).
157
+ append_body: true
158
+ generate_release_notes: true
159
+
160
+ publish:
161
+ name: Publish to PyPI
162
+ needs: [build]
163
+ runs-on: ubuntu-latest
164
+ environment:
165
+ name: pypi
166
+ url: https://pypi.org/project/${{ github.event.repository.name }}
167
+ permissions:
168
+ id-token: write
169
+ steps:
170
+ - uses: actions/download-artifact@v6
171
+ with:
172
+ name: Packages
173
+ path: dist
174
+ - uses: pypa/gh-action-pypi-publish@release/v1
PyPSA/source/.github/workflows/test-models.yml ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: Test models
6
+
7
+ on:
8
+ push:
9
+ branches:
10
+ - master
11
+ - release-branch-v*
12
+ pull_request:
13
+ branches: ['*']
14
+ schedule:
15
+ - cron: "0 5 * * *"
16
+
17
+ env:
18
+ PACKAGE_NAME: 'pypsa'
19
+
20
+ # Cancel any in-progress runs when a new run is triggered
21
+ concurrency:
22
+ group: ${{ github.workflow }}-${{ github.ref }}
23
+ cancel-in-progress: true
24
+
25
+ jobs:
26
+ test-pypsa-eur:
27
+ name: PyPSA-Eur
28
+ runs-on: ubuntu-latest
29
+ strategy:
30
+ fail-fast: false
31
+ matrix:
32
+ version:
33
+ - master
34
+ # - latest
35
+
36
+ defaults:
37
+ run:
38
+ shell: bash -l {0}
39
+
40
+ steps:
41
+ - uses: actions/checkout@v5
42
+ with:
43
+ repository: PyPSA/pypsa-eur
44
+ ref: master
45
+
46
+ - name: Check out latest release
47
+ if: matrix.version == 'latest'
48
+ run: |
49
+ git fetch --tags
50
+ latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)
51
+ git checkout $latest_tag
52
+
53
+ - name: Setup Pixi
54
+ uses: prefix-dev/setup-pixi@v0.9.3
55
+ with:
56
+ pixi-version: v0.59.0
57
+ cache: true
58
+ # Do not cache in branches
59
+ cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
60
+
61
+ - name: Setup cache keys
62
+ run: |
63
+ echo "WEEK=$(date +'%Y%U')" >> $GITHUB_ENV # data and cutouts
64
+
65
+ # Only run check if package is not pinned
66
+ - name: Check if inhouse package is pinned
67
+ run: |
68
+ grep_line=$(grep -- '- pypsa' envs/environment.yaml)
69
+ if [[ $grep_line == *"<"* || $grep_line == *"=="* ]]; then
70
+ echo "pinned=true" >> $GITHUB_ENV
71
+ else
72
+ echo "pinned=false" >> $GITHUB_ENV
73
+ fi
74
+
75
+ - uses: actions/cache@v4
76
+ if: env.pinned == 'false'
77
+ with:
78
+ path: |
79
+ data
80
+ cutouts
81
+ key: data-cutouts-pypsa-eur-${{ env.WEEK }}
82
+
83
+ - name: Install package from ref
84
+ if: env.pinned == 'false'
85
+ run: |
86
+ pixi remove ${{ env.PACKAGE_NAME }}
87
+ pixi add --pypi --git https://github.com/${{ github.repository }}.git ${{ github.event.repository.name }} --rev ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
88
+
89
+ - name: Run snakemake test workflows
90
+ if: env.pinned == 'false'
91
+ run: |
92
+ pixi run integration-tests
93
+
94
+ - name: Run unit tests
95
+ if: env.pinned == 'false'
96
+ run: |
97
+ pixi run unit-tests
98
+
99
+ - name: Upload artifacts
100
+ if: env.pinned == 'false'
101
+ uses: actions/upload-artifact@v5
102
+ with:
103
+ name: results-pypsa-eur-${{ matrix.version }}
104
+ path: |
105
+ logs
106
+ .snakemake/log
107
+ results
108
+ retention-days: 3
109
+
110
+ # Temporarily disabled until PyPSA-DE issues are resolved. This is not a problem of PyPSA.
111
+ # test-pypsa-de:
112
+ # name: PyPSA-DE
113
+ # runs-on: ubuntu-latest
114
+ # strategy:
115
+ # fail-fast: false
116
+ # matrix:
117
+ # version:
118
+ # - master
119
+ # # - latest
120
+
121
+ # defaults:
122
+ # run:
123
+ # shell: bash -l {0}
124
+
125
+ # steps:
126
+ # - uses: actions/checkout@v5
127
+ # with:
128
+ # repository: PyPSA/pypsa-de
129
+ # ref: main
130
+
131
+ # - name: Check out latest release
132
+ # if: matrix.version == 'latest'
133
+ # run: |
134
+ # git fetch --tags
135
+ # latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)
136
+ # git checkout $latest_tag
137
+
138
+ # - name: Setup cache keys
139
+ # run: |
140
+ # echo "WEEK=$(date +'%Y%U')" >> $GITHUB_ENV # data and cutouts
141
+
142
+ # # Only run check if package is not pinned
143
+ # - name: Check if inhouse package is pinned
144
+ # run: |
145
+ # grep_line=$(grep -- '- pypsa' envs/environment.yaml)
146
+ # if [[ $grep_line == *"<"* || $grep_line == *"=="* ]]; then
147
+ # echo "pinned=true" >> $GITHUB_ENV
148
+ # else
149
+ # echo "pinned=false" >> $GITHUB_ENV
150
+ # fi
151
+
152
+ # - uses: actions/cache@v4
153
+ # if: env.pinned == 'false'
154
+ # with:
155
+ # path: |
156
+ # data
157
+ # cutouts
158
+ # resources/ariadne_database.csv
159
+ # key: data-cutouts-pypsa-de-${{ env.WEEK }}
160
+
161
+ # - uses: conda-incubator/setup-miniconda@v3
162
+ # if: env.pinned == 'false'
163
+ # with:
164
+ # miniforge-version: latest
165
+ # activate-environment: pypsa-de
166
+ # channel-priority: strict
167
+
168
+ # - name: Cache Conda env
169
+ # if: env.pinned == 'false'
170
+ # uses: actions/cache@v4
171
+ # with:
172
+ # path: ${{ env.CONDA }}/envs
173
+ # key: conda-pypsa-de-${{ env.WEEK }}-${{ hashFiles('envs/linux-64.lock.yaml') }}
174
+ # id: cache-env
175
+
176
+ # - name: Update environment
177
+ # if: env.pinned == 'false' && steps.cache-env.outputs.cache-hit != 'true'
178
+ # run: |
179
+ # conda env update -n pypsa-de -f envs/linux-64.lock.yaml
180
+ # echo "Run conda list" && conda list
181
+
182
+ # - name: Install package from ref
183
+ # if: env.pinned == 'false'
184
+ # run: |
185
+ # python -m pip install git+https://github.com/${{ github.repository }}@${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
186
+
187
+ # - name: Run snakemake test workflows
188
+ # if: env.pinned == 'false'
189
+ # run: |
190
+ # make test
191
+
192
+ # - name: Run unit tests
193
+ # if: env.pinned == 'false'
194
+ # run: |
195
+ # make unit-test
196
+
197
+ # - name: Upload artifacts
198
+ # if: env.pinned == 'false'
199
+ # uses: actions/upload-artifact@v5
200
+ # with:
201
+ # name: results-pypsa-de-${{ matrix.version }}
202
+ # path: |
203
+ # logs
204
+ # .snakemake/log
205
+ # results
206
+ # retention-days: 3
PyPSA/source/.github/workflows/test.yml ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: Tests
6
+
7
+ on:
8
+ push:
9
+ branches:
10
+ - master
11
+ - release-branch-v*
12
+ pull_request:
13
+ branches: ["*"]
14
+ schedule:
15
+ - cron: "0 5 * * *"
16
+
17
+ # Cancel any in-progress runs when a new run is triggered
18
+ concurrency:
19
+ group: ${{ github.workflow }}-${{ github.ref }}
20
+ cancel-in-progress: true
21
+
22
+ jobs:
23
+ build:
24
+ # Build the Python SDist and wheel, performs metadata and readme linting
25
+ name: Build and verify package
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v5
29
+ with:
30
+ fetch-depth: 0 # Needed for setuptools_scm
31
+ - uses: hynek/build-and-inspect-python-package@v2
32
+ id: baipp
33
+
34
+ outputs:
35
+ python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }}
36
+
37
+ test:
38
+ # Test package build in matrix of OS and Python versions
39
+ name: Test package
40
+ needs: [build]
41
+ runs-on: ${{ matrix.os }}
42
+ strategy:
43
+ fail-fast: false
44
+ matrix:
45
+ python-version: ${{ fromJSON(needs.build.outputs.python-versions) }}
46
+ os:
47
+ - ubuntu-latest
48
+ - macos-latest
49
+ - windows-latest
50
+ api: [default, new_api]
51
+ exclude:
52
+ - os: macos-latest
53
+ api: new_api
54
+ - os: windows-latest
55
+ api: new_api
56
+
57
+ env:
58
+ MPLBACKEND: Agg # https://github.com/orgs/community/discussions/26434
59
+ steps:
60
+ - uses: actions/checkout@v5
61
+ with:
62
+ fetch-depth: 0 # Needed for setuptools_scm
63
+
64
+ - name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
65
+ uses: actions/setup-python@v6
66
+ with:
67
+ python-version: ${{ matrix.python-version }}
68
+
69
+ - name: Install macos dependencies
70
+ if: matrix.os == 'macos-latest'
71
+ run: |
72
+ brew update
73
+ # pkg-config is deprecated but still installed in runner
74
+ # Can be removed once it is removed from the runner
75
+ brew unlink pkg-config@0.29.2 || true
76
+ brew install hdf5
77
+
78
+ - name: Download package
79
+ uses: actions/download-artifact@v6
80
+ with:
81
+ name: Packages
82
+ path: dist
83
+
84
+ - name: Install package and dependencies
85
+ run: |
86
+ python -m pip install uv
87
+ uv sync --all-extras --no-install-project
88
+ uv pip install "$(ls dist/*.whl)"
89
+
90
+ - name: Run unit tests (old API)
91
+ if: matrix.api == 'default'
92
+ run: >
93
+ uv run pytest --mpl --mpl-generate-summary=html --mpl-results-path=mpl-results
94
+ --cov=pypsa --junitxml=junit.xml -o junit_family=legacy
95
+ && uv run coverage xml
96
+
97
+ - name: Run unit tests (new API)
98
+ if: matrix.api == 'new_api'
99
+ run: >
100
+ uv run pytest
101
+ --new-components-api
102
+ --mpl --mpl-generate-summary=html --mpl-results-path=mpl-results
103
+ --cov=pypsa --junitxml=junit.xml -o junit_family=legacy
104
+ && uv run coverage xml
105
+
106
+ - name: Upload artifacts
107
+ if: matrix.api == 'default' && matrix.os == 'macos-latest' && matrix.python-version == '3.13'
108
+ uses: actions/upload-artifact@v5
109
+ with:
110
+ name: results-plotting
111
+ path: |
112
+ mpl-results
113
+ retention-days: 14
114
+ if-no-files-found: ignore
115
+
116
+ - name: Upload code coverage report
117
+ if: ${{ !cancelled() }}
118
+ uses: codecov/codecov-action@v5
119
+ with:
120
+ token: ${{ secrets.CODECOV_TOKEN }}
121
+ flags: >
122
+ unit-tests,
123
+ os-${{ matrix.os }},
124
+ python${{ matrix.python-version }},
125
+ api-${{ matrix.api }}
126
+
127
+ - name: Upload test results to Codecov
128
+ if: ${{ !cancelled() }}
129
+ uses: codecov/test-results-action@v1
130
+ with:
131
+ token: ${{ secrets.CODECOV_TOKEN }}
132
+ flags: >
133
+ unit-tests,
134
+ os-${{ matrix.os }},
135
+ python${{ matrix.python-version }},
136
+ api-${{ matrix.api }}
137
+
138
+ check-docs:
139
+ name: Check docs
140
+ needs: [build]
141
+ runs-on: ubuntu-latest
142
+
143
+ steps:
144
+ - uses: actions/checkout@v5
145
+ with:
146
+ fetch-depth: 0 # Needed for setuptools_scm
147
+
148
+ - name: Set up Python 3.13
149
+ uses: actions/setup-python@v6
150
+ with:
151
+ python-version: 3.13
152
+
153
+ - name: Download package
154
+ uses: actions/download-artifact@v6
155
+ with:
156
+ name: Packages
157
+ path: dist
158
+
159
+ - name: Install package and dependencies
160
+ run: |
161
+ python -m pip install uv
162
+ uv sync --all-extras --no-install-project
163
+ uv pip install "$(ls dist/*.whl)"
164
+
165
+ - name: Run doc tests
166
+ run: >
167
+ uv run pytest
168
+ test/test_docs.py --test-docs
169
+ --cov=pypsa --junitxml=junit.xml -o junit_family=legacy
170
+ && uv run coverage xml
171
+
172
+ - name: Upload code coverage report
173
+ if: ${{ !cancelled() }}
174
+ uses: codecov/codecov-action@v5
175
+ with:
176
+ token: ${{ secrets.CODECOV_TOKEN }}
177
+ flags: >
178
+ doc-tests,
179
+ os-ubuntu-latest,
180
+ python3.13,
181
+ api-old-api
182
+
183
+ - name: Upload test results to Codecov
184
+ if: ${{ !cancelled() }}
185
+ uses: codecov/test-results-action@v1
186
+ with:
187
+ token: ${{ secrets.CODECOV_TOKEN }}
188
+ flags: >
189
+ doc-tests,
190
+ os-ubuntu-latest,
191
+ python3.13,
192
+ api-old-api
193
+
194
+ check-types:
195
+ name: Check types
196
+ needs: [build]
197
+ runs-on: ubuntu-latest
198
+
199
+ steps:
200
+ - uses: actions/checkout@v5
201
+ with:
202
+ fetch-depth: 0 # Needed for setuptools_scm
203
+
204
+ - name: Set up Python 3.13
205
+ uses: actions/setup-python@v6
206
+ with:
207
+ python-version: 3.13
208
+
209
+ - name: Download package
210
+ uses: actions/download-artifact@v6
211
+ with:
212
+ name: Packages
213
+ path: dist
214
+
215
+ - name: Install package and dependencies
216
+ run: |
217
+ python -m pip install uv
218
+ uv sync --all-extras --no-install-project
219
+ uv pip install "$(ls dist/*.whl)"
220
+
221
+ - name: Run type checker (mypy)
222
+ run: |
223
+ uv run mypy .
PyPSA/source/.gitignore ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ *~
6
+ .~*
7
+ *.py[cod]
8
+ .ipynb_checkpoints/
9
+ *.log
10
+ old/
11
+
12
+ # Ignore all jupyter notebooks, except those for the docs
13
+ *.ipynb
14
+ !/docs/**/*.ipynb
15
+
16
+
17
+ test/.cache/
18
+ .cache/
19
+
20
+ test/results/*
21
+
22
+ pypsa.egg-info/
23
+
24
+ files.txt
25
+
26
+ tom_notes.org
27
+
28
+ *.pdf
29
+
30
+ *.aux
31
+
32
+ website/examples/*.py
33
+
34
+ *.zip
35
+
36
+ .vscode
37
+ .devcontainer
38
+ .github/copilot-instructions.md
39
+
40
+ .idea
41
+
42
+ .coverage
43
+
44
+ dev-scripts
45
+ dev
46
+
47
+ .venv
48
+ uv.lock
49
+ .aider*
50
+ CLAUDE.md
51
+ .claude
52
+ .github/copilot-instructions.md
53
+ site/
54
+ doc/_build/
PyPSA/source/.pre-commit-config.yaml ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ exclude: ^(docs/hooks|examples)
6
+
7
+ ci:
8
+ autoupdate_schedule: quarterly
9
+
10
+ repos:
11
+ - repo: https://github.com/pre-commit/pre-commit-hooks
12
+ rev: v6.0.0
13
+ hooks:
14
+ - id: check-added-large-files
15
+ args: ['--maxkb=2000']
16
+ - id: trailing-whitespace
17
+ - id: end-of-file-fixer
18
+
19
+ # Run ruff to lint and format
20
+ - repo: https://github.com/astral-sh/ruff-pre-commit
21
+ # Ruff version.
22
+ rev: v0.13.3
23
+ hooks:
24
+ # Run the linter.
25
+ - id: ruff
26
+ args: [--fix]
27
+ # Run the formatter.
28
+ - id: ruff-format
29
+
30
+ # Find common spelling mistakes in comments and docstrings
31
+ - repo: https://github.com/codespell-project/codespell
32
+ rev: v2.4.1
33
+ hooks:
34
+ - id: codespell
35
+ # Ignore capital case words, e.g. country codes
36
+ args: ['--ignore-regex="(\b[A-Z]+\b)"', '--ignore-words=.codespell.ignore']
37
+ types_or: [python, rst, markdown]
38
+ files: ^(scripts|doc)/
39
+
40
+ # Remove output from Jupyter notebooks
41
+ - repo: https://github.com/aflc/pre-commit-jupyter
42
+ rev: v1.2.1
43
+ hooks:
44
+ - id: jupyter-notebook-cleanup
45
+ args: ['--remove-kernel-metadata']
46
+
47
+ # Do YAML formatting (before the linter checks it for misses)
48
+ - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
49
+ rev: v2.15.0
50
+ hooks:
51
+ - id: pretty-format-yaml
52
+ args: [--autofix, --indent, '2', --preserve-quotes]
53
+
54
+ # Check for FSFE REUSE compliance (licensing)
55
+ - repo: https://github.com/fsfe/reuse-tool
56
+ rev: v6.0.0
57
+ hooks:
58
+ - id: reuse-lint-file
PyPSA/source/.readthedocs.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ version: 2
6
+
7
+ build:
8
+ os: ubuntu-24.04
9
+ tools:
10
+ python: "3.13"
11
+ jobs:
12
+ pre_system_dependencies:
13
+ - git fetch --unshallow # Needed to get version tags
14
+ pre_create_environment:
15
+ - asdf plugin add uv
16
+ - asdf install uv latest
17
+ - asdf global uv latest
18
+ create_environment:
19
+ - uv venv "${READTHEDOCS_VIRTUALENV_PATH}"
20
+ install:
21
+ - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv pip install -r docs/requirements.txt
22
+ pre_build:
23
+ # To create all doctest files
24
+ - uv run pytest test/test_docs.py --test-docs
25
+
26
+ mkdocs:
27
+ configuration: mkdocs.yml
28
+ fail_on_warning: true
PyPSA/source/CITATION.cff ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ cff-version: 1.2.0
6
+ message: "If you use this package, please cite the corresponding manuscript in Journal of Open Research Software."
7
+ title: "PyPSA: Python for Power System Analysis"
8
+ repository: https://github.com/pypsa/pypsa
9
+ version: 1.0.3 # Don't touch, will be updated by the release script
10
+ license: MIT
11
+ journal: Journal of Open Research Software
12
+ doi: 10.5334/jors.188
13
+ authors:
14
+ - family-names: Brown
15
+ given-names: Tom
16
+ orcid: https://orcid.org/0000-0001-5898-1911
17
+ - family-names: Hörsch
18
+ given-names: Jonas
19
+ orcid: https://orcid.org/0000-0001-9438-767X
20
+ - family-names: Schlachtberger
21
+ given-names: David
22
+ orcid: https://orcid.org/0000-0002-8167-8213
PyPSA/source/CONTRIBUTING.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: MIT
5
+ -->
6
+
7
+ 🎉 Thank you for your interest in contributing to PyPSA! 🎉
8
+
9
+ We strongly welcome anyone interested in contributing to PyPSA and it's related projects. All types of contributions are encouraged and valued!
10
+
11
+ Detailed guidelines can be found in the [Contributing](https://docs.pypsa.org/latest/contributing/contributing/) section of our documentation.
PyPSA/source/LICENSE ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) <year> <copyright holders>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
PyPSA/source/LICENSES/CC-BY-4.0.txt ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Creative Commons Attribution 4.0 International
2
+
3
+ Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
4
+
5
+ Using Creative Commons Public Licenses
6
+
7
+ Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
8
+
9
+ Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
10
+
11
+ Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
12
+
13
+ Creative Commons Attribution 4.0 International Public License
14
+
15
+ By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
16
+
17
+ Section 1 – Definitions.
18
+
19
+ a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
20
+
21
+ b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
22
+
23
+ c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
24
+
25
+ d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
26
+
27
+ e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
28
+
29
+ f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
30
+
31
+ g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
32
+
33
+ h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
34
+
35
+ i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
36
+
37
+ j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
38
+
39
+ k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
40
+
41
+ Section 2 – Scope.
42
+
43
+ a. License grant.
44
+
45
+ 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
46
+
47
+ A. reproduce and Share the Licensed Material, in whole or in part; and
48
+
49
+ B. produce, reproduce, and Share Adapted Material.
50
+
51
+ 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
52
+
53
+ 3. Term. The term of this Public License is specified in Section 6(a).
54
+
55
+ 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
56
+
57
+ 5. Downstream recipients.
58
+
59
+ A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
60
+
61
+ B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
62
+
63
+ 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
64
+
65
+ b. Other rights.
66
+
67
+ 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
68
+
69
+ 2. Patent and trademark rights are not licensed under this Public License.
70
+
71
+ 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
72
+
73
+ Section 3 – License Conditions.
74
+
75
+ Your exercise of the Licensed Rights is expressly made subject to the following conditions.
76
+
77
+ a. Attribution.
78
+
79
+ 1. If You Share the Licensed Material (including in modified form), You must:
80
+
81
+ A. retain the following if it is supplied by the Licensor with the Licensed Material:
82
+
83
+ i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
84
+
85
+ ii. a copyright notice;
86
+
87
+ iii. a notice that refers to this Public License;
88
+
89
+ iv. a notice that refers to the disclaimer of warranties;
90
+
91
+ v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
92
+
93
+ B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
94
+
95
+ C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
96
+
97
+ 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
98
+
99
+ 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
100
+
101
+ 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
102
+
103
+ Section 4 – Sui Generis Database Rights.
104
+
105
+ Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
106
+
107
+ a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
108
+
109
+ b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
110
+
111
+ c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
112
+ For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
113
+
114
+ Section 5 – Disclaimer of Warranties and Limitation of Liability.
115
+
116
+ a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
117
+
118
+ b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
119
+
120
+ c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
121
+
122
+ Section 6 – Term and Termination.
123
+
124
+ a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
125
+
126
+ b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
127
+
128
+ 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
129
+
130
+ 2. upon express reinstatement by the Licensor.
131
+
132
+ c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
133
+
134
+ d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
135
+
136
+ e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
137
+
138
+ Section 7 – Other Terms and Conditions.
139
+
140
+ a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
141
+
142
+ b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
143
+
144
+ Section 8 – Interpretation.
145
+
146
+ a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
147
+
148
+ b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
149
+
150
+ c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
151
+
152
+ d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
153
+
154
+ Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
155
+
156
+ Creative Commons may be contacted at creativecommons.org.
PyPSA/source/LICENSES/MIT.txt ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) <year> <copyright holders>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
PyPSA/source/MANIFEST.in ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ include pypsa/data/component_attrs/*.csv
6
+ include pypsa/data/standard_types/*.csv
7
+ include pypsa/data/components.csv
8
+ include pypsa/data/variables.csv
9
+ include README.rst LICENSE.txt
10
+ include requirements.yml
PyPSA/source/README.md ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: MIT
5
+ -->
6
+
7
+ <picture align="center">
8
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/PyPSA/PyPSA/refs/heads/master/docs/assets/logo/logo-primary-dark.svg">
9
+ <img alt="PyPSA Banner" src="https://raw.githubusercontent.com/PyPSA/PyPSA/refs/heads/master/docs/assets/logo/logo-primary-light.svg">
10
+ </picture>
11
+
12
+ # PyPSA - Python for Power System Analysis
13
+
14
+
15
+ [![PyPI version](https://img.shields.io/pypi/v/pypsa.svg)](https://pypi.python.org/pypi/pypsa)
16
+ [![Conda version](https://img.shields.io/conda/vn/conda-forge/pypsa.svg)](https://anaconda.org/conda-forge/pypsa)
17
+ ![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2FPyPSA%2FPyPSA%2Fmaster%2Fpyproject.toml)
18
+ [![Tests](https://github.com/PyPSA/PyPSA/actions/workflows/test.yml/badge.svg)](https://github.com/PyPSA/PyPSA/actions/workflows/test.yml)
19
+ [![Documentation Status](https://readthedocs.org/projects/pypsa/badge/?version=latest)](https://docs.pypsa.org/latest/?badge=latest)
20
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/PyPSA/PyPSA/master.svg)](https://results.pre-commit.ci/latest/github/PyPSA/PyPSA/master)
21
+ [![Code coverage](https://codecov.io/gh/PyPSA/PyPSA/branch/master/graph/badge.svg?token=kCpwJiV6Jr)](https://codecov.io/gh/PyPSA/PyPSA)
22
+ [![REUSE status](https://api.reuse.software/badge/github.com/pypsa/pypsa)](https://api.reuse.software/info/github.com/pypsa/pypsa)
23
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
24
+ [![License](https://img.shields.io/pypi/l/pypsa.svg)](LICENSE)
25
+ [![Zenodo](https://zenodo.org/badge/DOI/10.5281/zenodo.3946412.svg)](https://doi.org/10.5281/zenodo.3946412)
26
+ [![Discord](https://img.shields.io/discord/911692131440148490?logo=discord)](https://discord.gg/AnuJBk23FU)
27
+ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
28
+
29
+ PyPSA stands for **Python for Power System Analysis**. It is pronounced
30
+ **pipes-ah**.
31
+
32
+ PyPSA is an open-source Python framework for optimising and simulating modern
33
+ power and energy systems that include features such as conventional generators
34
+ with unit commitment, variable wind and solar generation, hydro-electricity,
35
+ inter-temporal storage, coupling to other energy sectors, elastic demands, and
36
+ linearised power flow with loss approximations in DC and AC networks. PyPSA is
37
+ designed to scale well with large networks and long time series. It is made for
38
+ researchers, planners and utilities with basic coding aptitude who need a fast,
39
+ easy-to-use and transparent tool for power and energy system analysis.
40
+
41
+ PyPSA is maintained by the [Department of Digital Transformation in Energy
42
+ Systems](https://tu.berlin/en/ensys) at the [Technical University of
43
+ Berlin](https://www.tu.berlin). Previous versions were developed at the
44
+ [Karlsruhe Institute of Technology](http://www.kit.edu/english/index.php) funded
45
+ by the [Helmholtz Association](https://www.helmholtz.de/en/), and at
46
+ [FIAS](https://fias.uni-frankfurt.de/) funded by the [German Federal Ministry
47
+ for Education and Research (BMBF)](https://www.bmbf.de/bmbf/en/).
48
+
49
+ ## Features
50
+
51
+ - **Economic Dispatch (ED):** Models short-term market-based dispatch including
52
+ unit commitment, renewable availability, short-duration and seasonal storage
53
+ including hydro reservoirs with inflow and spillage dynamics, elastic demands,
54
+ load shedding and conversion between energy carriers, using either perfect
55
+ operational foresight or rolling horizon time resolution.
56
+
57
+ - **Linear Optimal Power Flow (LOPF):** Extends economic dispatch to determine
58
+ the least-cost dispatch while respecting network constraints in meshed AC-DC
59
+ networks, using a linearised representation of power flow (KVL, KCL) with
60
+ optional loss approximations.
61
+
62
+ - **Security-Constrained LOPF (SCLOPF):** Extends LOPF by accounting for line
63
+ outage contingencies to ensure system reliability under $N-1$ conditions.
64
+
65
+ - **Capacity Expansion Planning (CEP):** Supports least-cost
66
+ long-term system planning with investment decisions for generation, storage,
67
+ conversion, and transmission infrastructure. Handles both single and multiple
68
+ investment periods. Continuous and discrete investments are supported.
69
+
70
+ - **Pathway Planning:** Supports co-optimisation of multiple investment periods to
71
+ plan energy system transitions over time with perfect planning foresight.
72
+
73
+ - **Stochastic Optimisation:** Implements two-stage stochastic programming
74
+ framework with scenario-weighted uncertain inputs, with investments as
75
+ first-stage decisions and dispatch as recourse decisions.
76
+
77
+ - **Modelling-to-Generate-Alternatives (MGA):** Explores near-optimal decision
78
+ spaces to provide insight into the range of feasible system configurations with
79
+ similar costs.
80
+
81
+ - **Sector-Coupling:** Modelling integrated energy systems with multiple energy
82
+ carriers (electricity, heat, hydrogen, etc.) and conversion between them.
83
+ Flexible representation of technologies such as heat pumps, electrolysers,
84
+ battery electric vehicles (BEVs), direct air capture (DAC), and synthetic
85
+ fuels production.
86
+
87
+ - **Static Power Flow Analysis:** Computes both full non-linear and linearised
88
+ load flows for meshed AC and DC grids using Newton-Raphson method.
89
+
90
+ ## Documentation
91
+
92
+ PyPSA has extensive [documentation](https://docs.pypsa.org) with tutorials, user guides, examples and an API reference.
93
+
94
+ ## Installation
95
+
96
+ pip:
97
+
98
+ ``` bash
99
+ pip install pypsa
100
+ ```
101
+
102
+ conda/mamba:
103
+
104
+ ``` bash
105
+ conda install -c conda-forge pypsa
106
+ ```
107
+
108
+ uv:
109
+
110
+ ``` bash
111
+ uv add pypsa
112
+ ```
113
+
114
+ ## Usage
115
+
116
+ ``` py
117
+ import pypsa
118
+
119
+ # create a new network
120
+ n = pypsa.Network()
121
+ n.add("Bus", "mybus")
122
+ n.add("Load", "myload", bus="mybus", p_set=100)
123
+ n.add("Generator", "mygen", bus="mybus", p_nom=100, marginal_cost=20)
124
+
125
+ # load an example network
126
+ n = pypsa.examples.ac_dc_meshed()
127
+
128
+ # run the optimisation
129
+ n.optimize()
130
+
131
+ # plot results
132
+ n.generators_t.p.plot()
133
+ n.plot()
134
+
135
+ # get statistics
136
+ n.statistics()
137
+ n.statistics.energy_balance()
138
+ ```
139
+
140
+ ## Dependencies
141
+
142
+ PyPSA relies heavily on other open-source Python packages. Some of them are:
143
+
144
+ * [pandas](http://pandas.pydata.org/) for storing data about components and time series
145
+ * [numpy](http://www.numpy.org/) and [scipy](http://scipy.org/) for linear algebra and matrix calculations
146
+ * [linopy](https://github.com/PyPSA/linopy) for preparing optimisation problems
147
+ * [matplotlib](https://matplotlib.org/), [seaborn](https://seaborn.pydata.org/) and [plotly](https://plotly.com/python/) for static and interactive plotting
148
+ * [networkx](https://networkx.github.io/) for network calculations
149
+ * [pytest](http://pytest.org/) for unit testing
150
+
151
+ Find the full list of dependencies in the [`pyproject.toml`](https://github.com/PyPSA/PyPSA/blob/master/pyproject.toml) file.
152
+
153
+ PyPSA can be used with different solvers. For instance, the free solvers
154
+ [HiGHS](https://highs.dev/) (installed by default), [GLPK](https://www.gnu.org/software/glpk/) and
155
+ [CBC](https://github.com/coin-or/Cbc/) or commercial solvers like
156
+ [Gurobi](http://www.gurobi.com/) or [FICO Xpress](https://www.fico.com/en/products/fico-xpress-optimization) for which free academic licenses are available.
157
+
158
+ ## Contributing and Support
159
+
160
+ We strongly welcome anyone interested in contributing to this project. If you have any ideas, suggestions or encounter problems, feel invited to file issues or make pull requests on GitHub.
161
+
162
+ - To **discuss** with other PyPSA users, organise projects, share news, and get in touch with the community you can use the [Discord server](https://discord.gg/AnuJBk23FU).
163
+ - For **bugs and feature requests**, please [open an issue](https://github.com/PyPSA/PyPSA/issues).
164
+ - For **troubleshooting and support**, please check the [troubleshooting](https://docs.pypsa.org/latest/user-guide/support/) and [support](https://docs.pypsa.org/latest/user-guide/support/) sectionsin the documentation.
165
+
166
+ Detailed guidelines can be found in the [Contributing](https://docs.pypsa.org/latest/contributing/contributing/) guidelines of our documentation.
167
+
168
+ ## Code of Conduct
169
+
170
+ Please respect our [Code of Conduct](https://docs.pypsa.org/latest/contributing/code-of-conduct/).
171
+
172
+ ## Citing PyPSA
173
+
174
+ If you use PyPSA for your research, we would appreciate it if you would
175
+ cite the following paper:
176
+
177
+ - T. Brown, J. Hörsch, D. Schlachtberger, [PyPSA: Python for Power
178
+ System Analysis](https://arxiv.org/abs/1707.09913), 2018, [Journal
179
+ of Open Research
180
+ Software](https://openresearchsoftware.metajnl.com/), 6(1),
181
+ [arXiv:1707.09913](https://arxiv.org/abs/1707.09913),
182
+ [DOI:10.5334/jors.188](https://doi.org/10.5334/jors.188)
183
+
184
+ Please use the following BibTeX:
185
+
186
+ @article{PyPSA,
187
+ author = {T. Brown and J. H\"orsch and D. Schlachtberger},
188
+ title = {{PyPSA: Python for Power System Analysis}},
189
+ journal = {Journal of Open Research Software},
190
+ volume = {6},
191
+ issue = {1},
192
+ number = {4},
193
+ year = {2018},
194
+ eprint = {1707.09913},
195
+ url = {https://doi.org/10.5334/jors.188},
196
+ doi = {10.5334/jors.188}
197
+ }
198
+
199
+ If you want to cite a specific PyPSA version, each release of PyPSA is archived
200
+ on [Zenodo](https://zenodo.org/) with a release-specific DOI:
201
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3946412.svg)](https://doi.org/10.5281/zenodo.3946412)
202
+
203
+ ## Licence
204
+
205
+ Copyright [PyPSA Contributors](https://docs.pypsa.org/latest/developers.html)
206
+
207
+ PyPSA is licensed under the open source [MIT License](LICENSES/MIT.txt).
208
+ The documentation is licensed under [CC-BY-4.0](LICENSES/CC-BY-4.0.txt).
209
+
210
+ The repository uses [REUSE](https://reuse.software/) to expose the licenses of its files.
PyPSA/source/REUSE.toml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version = 1
2
+ SPDX-PackageName = "PyPSA"
3
+ SPDX-PackageSupplier = "Tom Brown <t.brown@tu-berlin.de>"
4
+ SPDX-PackageDownloadLocation = "https://github.com/pypsa/pypsa"
5
+
6
+ [[annotations]]
7
+ # As an essential part of PyPSA package, these parts are licensed under the same MIT license as the code itself
8
+ path = [
9
+ ".github/**/*.md",
10
+ "pypsa/data/component_attrs/*.csv",
11
+ "pypsa/data/standard_types/*.csv",
12
+ "pypsa/data/*.csv",
13
+ "test/baseline/*.png",
14
+ "test/data/**/*.csv",
15
+ "test/data/**/*.json",
16
+ "docs/requirements.txt",
17
+ ]
18
+ SPDX-FileCopyrightText = "PyPSA Contributors"
19
+ SPDX-License-Identifier = "MIT"
20
+
21
+ [[annotations]]
22
+ # Data for examples, CC-BY-4.0 license for reuse by others
23
+ path = [
24
+ "examples/**.csv",
25
+ "examples/**.json",
26
+ "examples/**.nc",
27
+ ]
28
+ SPDX-FileCopyrightText = "PyPSA Contributors"
29
+ SPDX-License-Identifier = "CC-BY-4.0"
30
+
31
+ [[annotations]]
32
+ # All documentation figures and notebooks (including their code) are for simplicity licensed under CC-BY-4.0
33
+ path = [
34
+ "docs/**/*.ipynb",
35
+ "docs/**/*.png",
36
+ "docs/**/*.html",
37
+ "docs/**/*.svg",
38
+ "docs/**/*.jpg",
39
+ ]
40
+ SPDX-FileCopyrightText = "PyPSA Contributors"
41
+ SPDX-License-Identifier = "CC-BY-4.0"
42
+
43
+
44
+ [[annotations]]
45
+ # TODO find correct information for this external image
46
+ path = [
47
+ "docs/assets/images/reserve-power-funding.gif",
48
+ ]
49
+ # We think this is the correct attribution (copyright holder and license)
50
+ SPDX-FileCopyrightText = "Ministry for Economic Affairs and Climate Action"
51
+ SPDX-License-Identifier = "CC-BY-4.0"
PyPSA/source/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ PyPSA Project Package Initialization File
4
+ """
PyPSA/source/codecov.yml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-FileCopyrightText: PyPSA Contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ comment: false
6
+
7
+ coverage:
8
+ status:
9
+ project:
10
+ default:
11
+ threshold: 0.1%
12
+
13
+ codecov:
14
+ notify:
15
+ after_n_builds: 13
PyPSA/source/docs/CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: Organization for Ethical Source
3
+ SPDX-FileCopyrightText: PyPSA Contributors
4
+
5
+ SPDX-License-Identifier: CC-BY-4.0
6
+ -->
7
+
8
+ # Code of Conduct
9
+
10
+ !!! info
11
+
12
+ This Code of Conduct follows the [Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
13
+
14
+ ## Our Pledge
15
+
16
+ We as members, contributors, and leaders pledge to make participation in our
17
+ community a harassment-free experience for everyone, regardless of age, body
18
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
19
+ identity and expression, level of experience, education, socio-economic status,
20
+ nationality, personal appearance, race, caste, color, religion, or sexual
21
+ identity and orientation.
22
+
23
+ We pledge to act and interact in ways that contribute to an open, welcoming,
24
+ diverse, inclusive, and healthy community.
25
+
26
+ ## Our Standards
27
+
28
+ Examples of behavior that contributes to a positive environment for our
29
+ community include:
30
+
31
+ * Demonstrating empathy and kindness toward other people
32
+ * Being respectful of differing opinions, viewpoints, and experiences
33
+ * Giving and gracefully accepting constructive feedback
34
+ * Accepting responsibility and apologizing to those affected by our mistakes,
35
+ and learning from the experience
36
+ * Focusing on what is best not just for us as individuals, but for the overall
37
+ community
38
+
39
+ Examples of unacceptable behavior include:
40
+
41
+ * The use of sexualized language or imagery, and sexual attention or advances of
42
+ any kind
43
+ * Trolling, insulting or derogatory comments, and personal or political attacks
44
+ * Public or private harassment
45
+ * Publishing others' private information, such as a physical or email address,
46
+ without their explicit permission
47
+ * Other conduct which could reasonably be considered inappropriate in a
48
+ professional setting
49
+
50
+ ## Enforcement Responsibilities
51
+
52
+ Community leaders are responsible for clarifying and enforcing our standards of
53
+ acceptable behavior and will take appropriate and fair corrective action in
54
+ response to any behavior that they deem inappropriate, threatening, offensive,
55
+ or harmful.
56
+
57
+ Community leaders have the right and responsibility to remove, edit, or reject
58
+ comments, commits, code, wiki edits, issues, and other contributions that are
59
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
60
+ decisions when appropriate.
61
+
62
+ ## Scope
63
+
64
+ This Code of Conduct applies within all community spaces, and also applies when
65
+ an individual is officially representing the community in public spaces.
66
+ Examples of representing our community include using an official e-mail address,
67
+ posting via an official social media account, or acting as an appointed
68
+ representative at an online or offline event.
69
+
70
+ ## Enforcement
71
+
72
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
73
+ reported to the community leaders responsible for enforcement at
74
+ f.neumann@tu-berlin.de / m.hofmann@tu-berlin.de / t.brown@tu-berlin.de.
75
+ All complaints will be reviewed and investigated promptly and fairly.
76
+
77
+ All community leaders are obligated to respect the privacy and security of the
78
+ reporter of any incident.
79
+
80
+ ## Enforcement Guidelines
81
+
82
+ Community leaders will follow these Community Impact Guidelines in determining
83
+ the consequences for any action they deem in violation of this Code of Conduct:
84
+
85
+ ### 1. Correction
86
+
87
+ **Community Impact**: Use of inappropriate language or other behavior deemed
88
+ unprofessional or unwelcome in the community.
89
+
90
+ **Consequence**: A private, written warning from community leaders, providing
91
+ clarity around the nature of the violation and an explanation of why the
92
+ behavior was inappropriate. A public apology may be requested.
93
+
94
+ ### 2. Warning
95
+
96
+ **Community Impact**: A violation through a single incident or series of
97
+ actions.
98
+
99
+ **Consequence**: A warning with consequences for continued behavior. No
100
+ interaction with the people involved, including unsolicited interaction with
101
+ those enforcing the Code of Conduct, for a specified period of time. This
102
+ includes avoiding interactions in community spaces as well as external channels
103
+ like social media. Violating these terms may lead to a temporary or permanent
104
+ ban.
105
+
106
+ ### 3. Temporary Ban
107
+
108
+ **Community Impact**: A serious violation of community standards, including
109
+ sustained inappropriate behavior.
110
+
111
+ **Consequence**: A temporary ban from any sort of interaction or public
112
+ communication with the community for a specified period of time. No public or
113
+ private interaction with the people involved, including unsolicited interaction
114
+ with those enforcing the Code of Conduct, is allowed during this period.
115
+ Violating these terms may lead to a permanent ban.
116
+
117
+ ### 4. Permanent Ban
118
+
119
+ **Community Impact**: Demonstrating a pattern of violation of community
120
+ standards, including sustained inappropriate behavior, harassment of an
121
+ individual, or aggression toward or disparagement of classes of individuals.
122
+
123
+ **Consequence**: A permanent ban from any sort of public interaction within the
124
+ community.
125
+
126
+ ## Attribution
127
+
128
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
129
+ version 2.1, available at
130
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
131
+
132
+ Community Impact Guidelines were inspired by
133
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
134
+
135
+ For answers to common questions about this code of conduct, see the FAQ at
136
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
137
+ [https://www.contributor-covenant.org/translations][translations].
138
+
139
+ [homepage]: https://www.contributor-covenant.org
140
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
141
+ [Mozilla CoC]: https://github.com/mozilla/diversity
142
+ [FAQ]: https://www.contributor-covenant.org/faq
143
+ [translations]: https://www.contributor-covenant.org/translations
PyPSA/source/docs/api/components/common.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: CC-BY-4.0
5
+ -->
6
+
7
+ ::: pypsa.components.common
PyPSA/source/docs/api/components/components.md ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: CC-BY-4.0
5
+ -->
6
+
7
+ ::: pypsa.components.Components
8
+ options:
9
+ heading_level: 2
10
+ members_order: source
11
+ inherited_members: true
12
+ filters:
13
+ - "!^_[^_]"
14
+ - "!logger"
15
+ - "!iteration"
16
+ - "!__deepcopy__"
17
+ - "!__getitem__"
18
+ - "!__setitem__"
19
+ - "!add"
20
+ - "!get_bounds_pu"
21
+
22
+ ::: pypsa.components.components.ComponentsData
23
+ options:
24
+ heading_level: 2
PyPSA/source/docs/api/components/types/buses.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: CC-BY-4.0
5
+ -->
6
+
7
+ ::: pypsa.components.Buses
PyPSA/source/docs/api/components/types/carriers.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: CC-BY-4.0
5
+ -->
6
+
7
+ ::: pypsa.components.Carriers
PyPSA/source/docs/api/components/types/generators.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: CC-BY-4.0
5
+ -->
6
+
7
+ ::: pypsa.components.Generators
PyPSA/source/docs/api/components/types/global-constraints.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: CC-BY-4.0
5
+ -->
6
+
7
+ ::: pypsa.components.GlobalConstraints
PyPSA/source/docs/api/components/types/lines.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ SPDX-FileCopyrightText: PyPSA Contributors
3
+
4
+ SPDX-License-Identifier: CC-BY-4.0
5
+ -->
6
+
7
+ ::: pypsa.components.Lines
8
+ options:
9
+ heading_level: 2
10
+
11
+ ::: pypsa.components.LineTypes
12
+ options:
13
+ heading_level: 2