cwms-cli 0.7.0__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/PKG-INFO +1 -1
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/blob.py +20 -9
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/clob.py +13 -10
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/__init__.py +61 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/pyproject.toml +1 -1
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/LICENSE +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/README.md +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/__main__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/_generated/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/_generated/ownership_data.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/callbacks/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/commands_cwms.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/.gitignore +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/README.md +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/__main__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/config.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/doclinks.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/examples/complete_config.json +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/parser.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/data/.gitignore +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/data/expected_brok_output.json +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/data/sample_brok.csv +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/data/sample_config.json +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/skip_test_integration_pipeline.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/test_dateutils.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/test_expressions.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/test_fileio.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/test_main.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/transform.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/utils/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/utils/dateutils.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/utils/expression.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/utils/fileio.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/utils/logging.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/writer.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/shef/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/shef/import_critfile.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/shef/import_infile.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/shef/shef_parameters.csv +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/users.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/README.md +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/__main__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/location/location.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/location/location_ids.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/location/location_ids_bygroup.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/root.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/timeseries/timeseries.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/timeseries/timeseries_data.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/load/timeseries/timeseries_ids.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/ownership.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/requirements.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/usgs/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/usgs/__main__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/usgs/getUSGS_ratings_cda.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/usgs/getusgs_cda.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/usgs/getusgs_measurements_cda.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/usgs/rating_ini_file_import.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/auth.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/callback_success.html +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/click_help.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/colors.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/deps.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/friendly_errors.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/intervals.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/io.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/links.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/logging/__init__.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/logging/formatters.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/ssl_errors.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/update.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/version.py +0 -0
- {cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/utils/version_cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cwms-cli
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Command line utilities for Corps Water Management Systems (CWMS) python scripts. This is a collection of shared scripts across the enterprise Water Management Enterprise System (WMES) teams.
|
|
5
5
|
License: LICENSE
|
|
6
6
|
License-File: LICENSE
|
|
@@ -11,10 +11,12 @@ from typing import Optional, Sequence, Tuple, Union
|
|
|
11
11
|
|
|
12
12
|
from cwmscli.utils import (
|
|
13
13
|
colors,
|
|
14
|
+
format_local_download_error,
|
|
14
15
|
get_api_key,
|
|
15
16
|
has_invalid_chars,
|
|
16
17
|
init_cwms_session,
|
|
17
18
|
log_scoped_read_hint,
|
|
19
|
+
validate_default_download_dest,
|
|
18
20
|
)
|
|
19
21
|
from cwmscli.utils.click_help import DOCS_BASE_URL
|
|
20
22
|
from cwmscli.utils.deps import requires
|
|
@@ -109,6 +111,14 @@ def _save_blob_content(
|
|
|
109
111
|
return dest
|
|
110
112
|
|
|
111
113
|
|
|
114
|
+
def _default_download_dest(blob_id: str) -> str:
|
|
115
|
+
return validate_default_download_dest(
|
|
116
|
+
blob_id,
|
|
117
|
+
resource_name="Blob",
|
|
118
|
+
docs_url=BLOB_DOCS_URL,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
112
122
|
def _blob_media_type(cwms_module, office: str, blob_id: str) -> Optional[str]:
|
|
113
123
|
try:
|
|
114
124
|
result = cwms_module.get_blobs(office_id=office, blob_id_like=blob_id)
|
|
@@ -602,7 +612,7 @@ def download_cmd(
|
|
|
602
612
|
|
|
603
613
|
try:
|
|
604
614
|
blob_content = cwms.get_blob(office_id=office, blob_id=bid)
|
|
605
|
-
target = dest or bid
|
|
615
|
+
target = dest or _default_download_dest(bid)
|
|
606
616
|
_save_blob_content(
|
|
607
617
|
blob_content,
|
|
608
618
|
dest=target,
|
|
@@ -621,14 +631,15 @@ def download_cmd(
|
|
|
621
631
|
)
|
|
622
632
|
sys.exit(1)
|
|
623
633
|
except Exception as e:
|
|
624
|
-
logging.error(
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
634
|
+
logging.error(format_local_download_error(e, BLOB_DOCS_URL))
|
|
635
|
+
if not isinstance(e, (OSError, ValueError)):
|
|
636
|
+
log_scoped_read_hint(
|
|
637
|
+
credential_kind=credential_kind,
|
|
638
|
+
anonymous=anonymous,
|
|
639
|
+
office=office,
|
|
640
|
+
action="download",
|
|
641
|
+
resource="blob content",
|
|
642
|
+
)
|
|
632
643
|
sys.exit(1)
|
|
633
644
|
|
|
634
645
|
|
|
@@ -9,7 +9,13 @@ import pandas as pd
|
|
|
9
9
|
import requests
|
|
10
10
|
from cwms import api as cwms_api
|
|
11
11
|
|
|
12
|
-
from cwmscli.utils import
|
|
12
|
+
from cwmscli.utils import (
|
|
13
|
+
format_local_download_error,
|
|
14
|
+
get_api_key,
|
|
15
|
+
has_invalid_chars,
|
|
16
|
+
log_scoped_read_hint,
|
|
17
|
+
validate_default_download_dest,
|
|
18
|
+
)
|
|
13
19
|
|
|
14
20
|
|
|
15
21
|
def _join_api_url(api_root: str, path: str) -> str:
|
|
@@ -29,6 +35,10 @@ def _write_clob_content(content: str, dest: str) -> str:
|
|
|
29
35
|
return dest
|
|
30
36
|
|
|
31
37
|
|
|
38
|
+
def _default_download_dest(clob_id: str) -> str:
|
|
39
|
+
return validate_default_download_dest(clob_id, resource_name="Clob")
|
|
40
|
+
|
|
41
|
+
|
|
32
42
|
def _clob_endpoint_id(clob_id: str) -> tuple[str, Optional[str]]:
|
|
33
43
|
normalized = clob_id.upper()
|
|
34
44
|
if has_invalid_chars(normalized):
|
|
@@ -198,7 +208,7 @@ def download_cmd(
|
|
|
198
208
|
content = str(payload)
|
|
199
209
|
else:
|
|
200
210
|
content = _get_special_clob_text(office=office, clob_id=query_id)
|
|
201
|
-
target = dest or bid
|
|
211
|
+
target = dest or _default_download_dest(bid)
|
|
202
212
|
_write_clob_content(content, target)
|
|
203
213
|
logging.info(f"Downloaded clob to: {target}")
|
|
204
214
|
except requests.HTTPError as e:
|
|
@@ -213,14 +223,7 @@ def download_cmd(
|
|
|
213
223
|
)
|
|
214
224
|
sys.exit(1)
|
|
215
225
|
except Exception as e:
|
|
216
|
-
logging.error(
|
|
217
|
-
log_scoped_read_hint(
|
|
218
|
-
api_key=resolved_api_key,
|
|
219
|
-
anonymous=anonymous,
|
|
220
|
-
office=office,
|
|
221
|
-
action="download",
|
|
222
|
-
resource="clob content",
|
|
223
|
-
)
|
|
226
|
+
logging.error(format_local_download_error(e, ""))
|
|
224
227
|
sys.exit(1)
|
|
225
228
|
|
|
226
229
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging as py_logging
|
|
2
|
+
import re
|
|
2
3
|
import time
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Optional, Union
|
|
@@ -235,6 +236,66 @@ def log_scoped_read_hint(
|
|
|
235
236
|
)
|
|
236
237
|
|
|
237
238
|
|
|
239
|
+
def format_local_download_error(error: Exception, docs_url: str) -> str:
|
|
240
|
+
if isinstance(error, (OSError, ValueError)):
|
|
241
|
+
message = (
|
|
242
|
+
f"{colors.c('Failed to download:', 'red', bright=True)} {error}. "
|
|
243
|
+
f"If this is a local destination/path issue, pass "
|
|
244
|
+
f"{colors.c('--dest', 'cyan', bright=True)} explicitly."
|
|
245
|
+
)
|
|
246
|
+
if docs_url:
|
|
247
|
+
message = (
|
|
248
|
+
f"{message} {colors.c('Docs:', 'blue', bright=True)} "
|
|
249
|
+
f"{colors.c(docs_url, 'blue', bright=True)}"
|
|
250
|
+
)
|
|
251
|
+
return message
|
|
252
|
+
return f"{colors.c('Failed to download:', 'red', bright=True)} {error}"
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def validate_default_download_dest(
|
|
256
|
+
raw_id: str,
|
|
257
|
+
*,
|
|
258
|
+
resource_name: str,
|
|
259
|
+
docs_url: str = "",
|
|
260
|
+
) -> str:
|
|
261
|
+
if raw_id is None:
|
|
262
|
+
raise ValueError(
|
|
263
|
+
f"{resource_name} ID must include a non-root destination name. "
|
|
264
|
+
f"Pass --dest explicitly if needed."
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
if raw_id.startswith("//") or raw_id.startswith("\\\\"):
|
|
268
|
+
raise ValueError(
|
|
269
|
+
f"{resource_name} ID must resolve to a relative local path. "
|
|
270
|
+
f"Pass --dest explicitly if needed."
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
target = raw_id.lstrip("/\\")
|
|
274
|
+
if not target:
|
|
275
|
+
message = (
|
|
276
|
+
f"{resource_name} ID must include a non-root destination name. "
|
|
277
|
+
f"Pass --dest explicitly if needed."
|
|
278
|
+
)
|
|
279
|
+
if docs_url:
|
|
280
|
+
message = f"{message} Docs: {docs_url}"
|
|
281
|
+
raise ValueError(message)
|
|
282
|
+
|
|
283
|
+
if re.match(r"^[A-Za-z]:", target):
|
|
284
|
+
raise ValueError(
|
|
285
|
+
f"{resource_name} ID must resolve to a relative local path. "
|
|
286
|
+
f"Pass --dest explicitly if needed."
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
parts = re.split(r"[\\/]", target)
|
|
290
|
+
if any(part in {"", ".", ".."} for part in parts):
|
|
291
|
+
raise ValueError(
|
|
292
|
+
f"{resource_name} ID must resolve to a relative local path. "
|
|
293
|
+
f"Pass --dest explicitly if needed."
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
return target
|
|
297
|
+
|
|
298
|
+
|
|
238
299
|
def common_api_options(f):
|
|
239
300
|
f = log_level_option(f)
|
|
240
301
|
f = office_option(f)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/data/expected_brok_output.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cwms_cli-0.7.0 → cwms_cli-0.7.1}/cwmscli/commands/csv2cwms/tests/skip_test_integration_pipeline.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|