1
1
import io
2
2
from typing import Any , Dict
3
+ import pandas as pd
3
4
from pyetm .services .scenario_runners .base_runner import BaseRunner
4
5
from pyetm .services .scenario_runners .fetch_curves_generic import (
5
- GenericCurveBulkRunner ,
6
6
GenericCurveDownloadRunner ,
7
7
)
8
8
from ..service_result import ServiceResult
@@ -26,7 +26,6 @@ def run(
26
26
class FetchAllOutputCurvesRunner (BaseRunner [Dict [str , io .StringIO ]]):
27
27
"""Download all known output curves."""
28
28
29
- # Known curve types from the Rails controller
30
29
CURVE_TYPES = [
31
30
"merit_order" ,
32
31
"electricity_price" ,
@@ -45,9 +44,53 @@ def run(
45
44
client : BaseClient ,
46
45
scenario : Any ,
47
46
) -> ServiceResult [Dict [str , io .StringIO ]]:
48
- return GenericCurveBulkRunner .run (
49
- client ,
50
- scenario ,
51
- FetchAllOutputCurvesRunner .CURVE_TYPES ,
52
- curve_type = "output" ,
53
- )
47
+ """
48
+ Uses the bulk endpoint to fetch all output curves at once as a single CSV,
49
+ then splits them into their carrier groups
50
+ """
51
+ try :
52
+ path = f"/scenarios/{ scenario .id } /bulk_output_curves"
53
+ # Ask explicitly for CSV to avoid content negotiation issues
54
+ resp = client .session .get (path , headers = {"Accept" : "text/csv" })
55
+
56
+ if not resp .ok :
57
+ return ServiceResult .fail ([f"{ resp .status_code } : { resp .text } " ])
58
+
59
+ # Read the returned CSV; first column is an index (e.g., hour)
60
+ try :
61
+ csv_text = resp .content .decode ("utf-8" )
62
+ df = pd .read_csv (io .StringIO (csv_text ), index_col = 0 )
63
+ except Exception as e :
64
+ return ServiceResult .fail ([f"Failed to parse bulk CSV: { e } " ])
65
+
66
+ results : Dict [str , io .StringIO ] = {}
67
+ warnings : list [str ] = []
68
+
69
+ groups : Dict [str , list [str ]] = {}
70
+ for col in df .columns :
71
+ base = str (col )
72
+ for sep in (":" , "/" ):
73
+ if sep in base :
74
+ base = base .split (sep , 1 )[0 ]
75
+ break
76
+ groups .setdefault (base , []).append (col )
77
+
78
+ for base , cols in groups .items ():
79
+ try :
80
+ sub = df [cols ].dropna (how = "all" )
81
+ buf = io .StringIO ()
82
+ sub .to_csv (buf , index = True )
83
+ buf .seek (0 )
84
+ results [base ] = buf
85
+ except Exception as e :
86
+ warnings .append (f"{ base } : Failed to prepare CSV: { e } " )
87
+
88
+ if results :
89
+ return ServiceResult .ok (data = results , errors = warnings or None )
90
+ else :
91
+ return ServiceResult .fail (warnings or ["No curves present in CSV" ])
92
+
93
+ except (PermissionError , ValueError , ConnectionError ) as e :
94
+ return ServiceResult .fail ([str (e )])
95
+ except Exception as e :
96
+ return ServiceResult .fail ([str (e )])
0 commit comments