-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathratings_spec.py
More file actions
216 lines (180 loc) · 7.09 KB
/
Copy pathratings_spec.py
File metadata and controls
216 lines (180 loc) · 7.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
from datetime import datetime
from typing import Optional
import pandas as pd
import cwms.api as api
from cwms.cwms_types import JSON, Data
def get_rating_spec(rating_id: str, office_id: str) -> Data:
"""Retrieves a single rating spec
Parameters
----------
rating_id: str
specify the rating id to grad
office_id: str
The owning office of the rating specifications.
Returns
-------
Data : Data
cwms data type that contains .json for json dictionary and .df for dataframe
"""
endpoint = f"ratings/spec/{rating_id}"
params = {
"office": office_id,
}
response = api.get(endpoint, params)
return Data(response)
def get_rating_specs(
office_id: Optional[str],
rating_id_mask: Optional[str] = None,
page_size: int = 500000,
) -> Data:
"""Retrieves a list of rating specification
Parameters
----------
office_id: string, optional
The owning office of the rating specifications. If no office is provided information from all offices will
be returned
rating-id-mask: string, optional
Posix regular expression that specifies the rating ids to be included in the response. If not specified all
rating specs shall be returned.
page-size: int, optional, default is 5000000: Specifies the number of records to obtain in
a single call.
Returns
-------
Data : Data
cwms data type that contains .json for json dictionary and .df for dataframe
"""
endpoint = "ratings/spec"
params = {
"office": office_id,
"rating-id-mask": rating_id_mask,
"page-size": page_size,
}
response = api.get(endpoint, params)
return Data(response, selector="specs")
def delete_rating_spec(rating_id: str, office_id: str, delete_method: str) -> None:
"""
Deletes rating spec for the given ID and office ID.
Parameters
----------
rating_id : str
The ID of the rating spec value to be deleted.
office_id : str
The ID of the office that the standard text belongs to.
delete_method : str
Delete method for the standard text id.
DELETE_ALL - deletes the key and the value from the rating table
DELETE_KEY - deletes the text id key, but leaves the value in the rating table
DELETE_DATA - deletes the value from the rating table but leaves the rating id key
Returns
-------
None
"""
delete_methods = ["DELETE_ALL", "DELETE_KEY", "DELETE_DATA"]
if rating_id is None:
raise ValueError("Deleting standard text requires an id")
if office_id is None:
raise ValueError("Deleting standard timeseries requires an office")
if delete_method not in delete_methods:
raise ValueError(
"Deleting standard timeseries requires a delete method of DELETE_ALL, DELETE_KEY, or DELETE_DATA"
)
endpoint = f"ratings/spec/{rating_id}"
params = {"office": office_id, "method": delete_method}
return api.delete(endpoint, params)
def rating_spec_df_to_xml(data: pd.DataFrame) -> str:
"""
Converts a dataframe containing rating specification parameters
into xml to be stored into the database.
Parameters
----------
data : pd_dataframe
pandas dataframe that contains rating specification parameters
should follow same formate the is returned from get_rating_spec function
Returns
-------
str: xml that can be used in store_rating_spec function
"""
spec_xml = f"""<?xml version="1.0" encoding="utf-8"?>
<rating-spec office-id="{data.loc[0,'office-id']}">
<rating-spec-id>{data.loc[0,'rating-id']}</rating-spec-id>
<template-id>{data.loc[0,'template-id']}</template-id>
<location-id>{data.loc[0,'location-id']}</location-id>
<version>{data.loc[0,'version']}</version>"""
try:
spec_xml += f"""
<source-agency>{data.loc[0,'source-agency']}</source-agency>"""
except Exception:
spec_xml += """
<source-agency/>"""
spec_xml += f"""
<in-range-method>{data.loc[0,'in-range-method']}</in-range-method>
<out-range-low-method>{data.loc[0,'out-range-low-method']}</out-range-low-method>
<out-range-high-method>{data.loc[0,'out-range-high-method']}</out-range-high-method>
<active>{str(data.loc[0,'active']).lower()}</active>
<auto-update>{str(data.loc[0,'auto-update']).lower()}</auto-update>
<auto-activate>{str(data.loc[0,'auto-activate']).lower()}</auto-activate>
<auto-migrate-extension>{str(data.loc[0,'auto-migrate-extension']).lower()}</auto-migrate-extension>
<ind-rounding-specs>"""
ind_rounding = data.loc[0, "independent-rounding-specs"]
if isinstance(ind_rounding, list):
i = 1
for rounding in ind_rounding:
spec_xml = (
spec_xml
+ f"""\n <ind-rounding-spec position="{i}">{rounding['value']}</ind-rounding-spec>"""
)
i = i + 1
spec_xml2 = f"""\n </ind-rounding-specs>
<dep-rounding-spec>{data.loc[0,'dependent-rounding-spec']}</dep-rounding-spec>"""
try:
spec_xml2 += f"""
<description>{data.loc[0,'description']}</description>"""
except Exception:
spec_xml2 += """
<description/>"""
spec_xml2 += """
</rating-spec>"""
spec_xml = spec_xml + spec_xml2
return spec_xml
def store_rating_spec(data: str, fail_if_exists: Optional[bool] = True) -> None:
"""
This method is used to store a new rating spec.
Parameters
----------
data : str
xml for saving a rating spec example
<?xml version="1.0" encoding="UTF-8"?>
<RatingSpec>
<office-id>string</office-id>
<rating-id>string</rating-id>
<template-id>string</template-id>
<location-id>string</location-id>
<version>string</version>
<source-agency>string</source-agency>
<in-range-method>string</in-range-method>
<out-range-low-method>string</out-range-low-method>
<out-range-high-method>string</out-range-high-method>
<active>true</active>
<auto-update>true</auto-update>
<auto-activate>true</auto-activate>
<auto-migrate-extension>true</auto-migrate-extension>
<independent-rounding-specs>
<position>0</position>
<value>string</value>
</independent-rounding-specs>
<dependent-rounding-spec>string</dependent-rounding-spec>
<description>string</description>
<effective-dates>2024-06-28T17:53:27.214Z</effective-dates>
</RatingSpec>
fail_if_exists : str, optional
Throw a ClientError if the text id already exists.
Default is `False`.
Returns
-------
None
"""
if data is None:
raise ValueError("Cannot store a standard text without a rating xml")
endpoint = "ratings/spec/"
params = {"fail-if-exists": fail_if_exists}
return api.post(endpoint, data, params, api_version=102)