hydroserverpy 1.4.0b3__py3-none-any.whl → 1.4.1__py3-none-any.whl

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.

Potentially problematic release.


This version of hydroserverpy might be problematic. Click here for more details.

@@ -17,11 +17,8 @@ class HTTPExtractor(Extractor):
17
17
  url = self.resolve_placeholder_variables(payload, loader)
18
18
  logging.info(f"Requesting data from → {url}")
19
19
 
20
- try:
21
- response = requests.get(url)
22
- except Exception as e:
23
- logging.error(f"Failed to fetch {url}: {e}")
24
- raise
20
+ response = requests.get(url)
21
+ response.raise_for_status()
25
22
 
26
23
  data = BytesIO()
27
24
  for chunk in response.iter_content(chunk_size=8192):
@@ -1,6 +1,6 @@
1
1
  from datetime import datetime
2
2
  from typing import Literal, Optional
3
- from pydantic import BaseModel, Field, EmailStr
3
+ from pydantic import BaseModel, Field
4
4
 
5
5
 
6
6
  class Schedule(BaseModel):
@@ -73,7 +73,10 @@ class TimestampParser:
73
73
  return localized.dt.tz_convert(timezone.utc)
74
74
 
75
75
  def parse_series(self, raw_series: pd.Series) -> pd.Series:
76
- s = raw_series.str.strip()
76
+ if pd.api.types.is_datetime64_any_dtype(raw_series):
77
+ s = raw_series # already datetimes
78
+ else:
79
+ s = raw_series.astype("string", copy=False).str.strip()
77
80
  parsed = self._convert_series_to_UTC(s)
78
81
 
79
82
  if parsed.isna().any():
@@ -68,14 +68,21 @@ class Transformer(ABC):
68
68
  def standardize_dataframe(
69
69
  self, df: pd.DataFrame, mappings: List[SourceTargetMapping]
70
70
  ):
71
+ logging.info(f"Successfully read payload into dataframe:\n {df}")
72
+
71
73
  # 1) Normalize timestamp column
72
74
  df.rename(columns={self.timestamp.key: "timestamp"}, inplace=True)
73
75
  if "timestamp" not in df.columns:
74
76
  msg = f"Timestamp column '{self.timestamp.key}' not found in data."
75
77
  logging.error(msg)
76
78
  raise ValueError(msg)
79
+ logging.info(f"Renamed timestamp column to 'timestamp'")
80
+
77
81
  df["timestamp"] = self.timestamp_parser.parse_series(df["timestamp"])
82
+ logging.info(f"Normalized timestamp column \n {df}")
83
+
78
84
  df = df.drop_duplicates(subset=["timestamp"], keep="last")
85
+ logging.info(f"Removed duplicates\n")
79
86
 
80
87
  def _resolve_source_col(s_id: Union[str, int]) -> str:
81
88
  if isinstance(s_id, int) and s_id not in df.columns:
@@ -120,6 +127,8 @@ class Transformer(ABC):
120
127
  target_col = str(path.target_identifier)
121
128
  transformed_df[target_col] = _apply_transformations(base, path)
122
129
 
130
+ logging.info(f"Mapped payload sources to targets")
131
+
123
132
  # 6) Keep only timestamp + target columns
124
133
  df = pd.concat([df[["timestamp"]], pd.DataFrame(transformed_df)], axis=1)
125
134
 
@@ -24,7 +24,21 @@ class JSONTransformer(Transformer):
24
24
  Returns:
25
25
  pd.DataFrame: pandas DataFrames in the format pd.Timestamp, datastream_id_1, datastream_id_2, ...
26
26
  """
27
+ if data_file is None:
28
+ raise TypeError(
29
+ "JSONTransformer received None; expected file-like, bytes, or str"
30
+ )
31
+
27
32
  json_data = json.load(data_file)
33
+ logging.info(f"Read in json data: \n{data_file}")
34
+ logging.info(
35
+ "JSONTransformer cfg:\n jmespath=%r\n ts.key=%r\n ts.format=%r\n ts.custom=%r",
36
+ self.cfg.jmespath,
37
+ self.timestamp.key,
38
+ self.timestamp.format,
39
+ self.timestamp.custom_format,
40
+ )
41
+
28
42
  data_points = self.extract_data_points(json_data)
29
43
  if not data_points:
30
44
  logging.warning("No data points found in the JSON data.")
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.4
2
+ Name: hydroserverpy
3
+ Version: 1.4.1
4
+ Summary: A Python client for managing HydroServer data
5
+ Requires-Python: <4,>=3.9
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: requests>=2
9
+ Requires-Dist: pydantic>=2.6
10
+ Requires-Dist: pydantic[email]>=2.6
11
+ Requires-Dist: pandas>=2.2
12
+ Requires-Dist: numpy>=2.0
13
+ Requires-Dist: pyyaml>=5
14
+ Requires-Dist: simplejson>=3
15
+ Requires-Dist: crontab>=1
16
+ Requires-Dist: python-dateutil>=2.8.2
17
+ Requires-Dist: croniter>=2.0.1
18
+ Requires-Dist: jmespath>=1.0.1
19
+ Provides-Extra: docs
20
+ Requires-Dist: sphinx_autodoc_typehints; extra == "docs"
21
+ Dynamic: license-file
22
+
23
+ # HydroServer Python Client
24
+
25
+ The hydroserverpy Python package provides an interface for managing HydroServer data and metadata, loading observations, and performing data quality control. This guide will go over how to install the package and connect to a HydroServer instance. Full hydroserverpy documentation and examples can be found [here](https://hydroserver2.github.io/hydroserver/how-to/hydroserverpy/hydroserverpy-examples.html).
26
+
27
+ ## Installation
28
+
29
+ You can install the package via pip:
30
+
31
+ ```bash
32
+ pip install hydroserverpy
33
+ ```
34
+
35
+ ## Connecting to HydroServer
36
+
37
+ To connect to HydroServer, you need to initialize the client with the instance of HydroServer you're using and your user credentials if you want to access and modify your own data. If you don't provide authentication credentials you can read public data, but you will not be able to create or modify any data.
38
+
39
+ ### Example: Anonymous User
40
+
41
+ ```python
42
+ from hydroserverpy import HydroServer
43
+
44
+ # Initialize HydroServer connection.
45
+ hs_api = HydroServer(
46
+ host='https://playground.hydroserver.org'
47
+ )
48
+ ```
49
+
50
+ ### Example: Basic Authentication
51
+
52
+ ```python
53
+ from hydroserverpy import HydroServer
54
+
55
+ # Initialize HydroServer connection with credentials.
56
+ hs_api = HydroServer(
57
+ host='https://playground.hydroserver.org',
58
+ email='user@example.com',
59
+ password='******'
60
+ )
61
+ ```
62
+
63
+ ## Funding and Acknowledgements
64
+
65
+ Funding for this project was provided by the National Oceanic & Atmospheric Administration (NOAA), awarded to the Cooperative Institute for Research to Operations in Hydrology (CIROH) through the NOAA Cooperative Agreement with The University of Alabama (NA22NWS4320003). Utah State University is a founding member of CIROH and receives funding under subaward from the University of Alabama. Additional funding and support have been provided by the State of Utah Division of Water Rights, the World Meteorological Organization, and the Utah Water Research laboratory at Utah State University.
66
+
@@ -11,22 +11,22 @@ hydroserverpy/api/models/etl/etl_configuration.py,sha256=anD_0zlldJKogie15j9SIab
11
11
  hydroserverpy/api/models/etl/factories.py,sha256=-inTw_C694YieDU4vbrm1qyeZMEYZqVhHSyEQJLMueo,802
12
12
  hydroserverpy/api/models/etl/orchestration_configuration.py,sha256=ElSrgi7ioFZJFJg6aGogW5ZZk7fA17y4p--yWwiOhZ0,1367
13
13
  hydroserverpy/api/models/etl/orchestration_system.py,sha256=5wdGsXCMqHfE3--zG-3WAPAVPNMPIx99y-7UUhdCink,2060
14
- hydroserverpy/api/models/etl/schedule.py,sha256=b3ffBPFn5jVnEJnG8YlC_93_OKcmC_kpgwRpn1dNmCo,522
14
+ hydroserverpy/api/models/etl/schedule.py,sha256=-TxRpYSFbyYkzAPBWOh5udx1s6v1SvLl3_LE2j_b1uE,512
15
15
  hydroserverpy/api/models/etl/status.py,sha256=vYT7go7DMcOgy29w0yhHpKz6AdprLmOxWZE9G_DHVdw,503
16
- hydroserverpy/api/models/etl/timestamp_parser.py,sha256=MA_a0qPExbIQGt-ju7w6WflVDMzigW1LKUFCJ_jhkp4,4218
16
+ hydroserverpy/api/models/etl/timestamp_parser.py,sha256=lDnParK2j2M9TF7qspJDeKFGGpO4d1F2KJEKZ4xH5Yw,4374
17
17
  hydroserverpy/api/models/etl/types.py,sha256=4PY3CM-uoXIsf2lhcqtLC6HaRGXe7HKGDU22R8-H35c,135
18
18
  hydroserverpy/api/models/etl/extractors/__init__.py,sha256=Z0viw2vk96Ytpz3n7ODtkYz9Zx0I0NsZUbna2ZWvhkw,243
19
19
  hydroserverpy/api/models/etl/extractors/base.py,sha256=uLAdi1PrOVMtuCU1ZN_liBW_ElD2mklrBrQ_AZZQtNw,1949
20
20
  hydroserverpy/api/models/etl/extractors/ftp_extractor.py,sha256=5LwvHuvLk6LwRSVyE9EkV3DPgVlAvRrOBpl1a8B7dLg,1387
21
- hydroserverpy/api/models/etl/extractors/http_extractor.py,sha256=sZl9PVTU9QbAreEu5zrIFeMLyIUkkiUAT8AOrbde5gc,892
21
+ hydroserverpy/api/models/etl/extractors/http_extractor.py,sha256=AgS0vDmHhN3do1FII-hNEvkK40lDjlS1iftHplWd1No,805
22
22
  hydroserverpy/api/models/etl/extractors/local_file_extractor.py,sha256=AwC0T-F8D0S7zR0MUIQXKLfv9b0uU60YoUW615lgNl0,648
23
23
  hydroserverpy/api/models/etl/loaders/__init__.py,sha256=rEqYo1Tim7Fzrp1jPhV_yn3ll90dUGMAjcieEqh_4Pk,118
24
24
  hydroserverpy/api/models/etl/loaders/base.py,sha256=J3dqm_b6BmEsF7VR3sUxBVQpLJsRx7fTIir5v5TORE0,229
25
25
  hydroserverpy/api/models/etl/loaders/hydroserver_loader.py,sha256=0qdsSu4bLD4R86eSyQY2Qwg1HmMsruVjFhBKCrErsBU,3868
26
26
  hydroserverpy/api/models/etl/transformers/__init__.py,sha256=YQhjdoRdq4xikLWETnsRIaMvCae5flRpPrfw9lj9pOA,184
27
- hydroserverpy/api/models/etl/transformers/base.py,sha256=iFfoxsaq4IRiFZgcC2ooRikyGmPexTHIllvf4shf9F4,4662
27
+ hydroserverpy/api/models/etl/transformers/base.py,sha256=Qt9U6rRFS8aq142n0Cig1wMkVC9-4IBiXIE1nAjEPDY,4971
28
28
  hydroserverpy/api/models/etl/transformers/csv_transformer.py,sha256=06AWV9S9we4LRQLpn5WMVl7sX6ylDKPb2KHNC0Jiu7o,3478
29
- hydroserverpy/api/models/etl/transformers/json_transformer.py,sha256=em3tIoAmEnOFPfHzGmUTTGNMPeEoWRIksEMK702YHvI,1636
29
+ hydroserverpy/api/models/etl/transformers/json_transformer.py,sha256=puKQI8abWJEQTcw34lEHgHjuPOuzcSBv95_txErzchk,2116
30
30
  hydroserverpy/api/models/iam/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  hydroserverpy/api/models/iam/account.py,sha256=7COk_CPYFlthg1uFWTBlJESfnuqMW90TSjZoIcBb-_8,439
32
32
  hydroserverpy/api/models/iam/apikey.py,sha256=Z4iXg_K056naT3ogwc5wzyNnRpxHkOCz0lk-Gim4eL8,3146
@@ -61,9 +61,9 @@ hydroserverpy/api/services/sta/thing.py,sha256=Hyo3zTghSs7IIdsOGRu35i9w-aGOYlK9b
61
61
  hydroserverpy/api/services/sta/unit.py,sha256=NFToSAIGTwDfwYWe8Q-I_f5xsw_GYzFEkMnhSJ-ChvE,2178
62
62
  hydroserverpy/quality/__init__.py,sha256=GGBMkFSXciJLYrbV-NraFrj_mXWCy_GTcy9KKrKXU4c,84
63
63
  hydroserverpy/quality/service.py,sha256=U02UfLKVmFvr5ySiH0n0JYzUIabq5uprrHIiwcqBlqY,13879
64
- hydroserverpy-1.4.0b3.dist-info/licenses/LICENSE,sha256=xVqFxDw3QOEJukakL7gQCqIMTQ1dlSCTo6Oc1otNW80,1508
65
- hydroserverpy-1.4.0b3.dist-info/METADATA,sha256=NQ1axvaQ2Sh3BBMa4zK5TJZT10UO7aGuWRIH0BJf1i8,532
66
- hydroserverpy-1.4.0b3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
- hydroserverpy-1.4.0b3.dist-info/top_level.txt,sha256=Zf37hrncXLOYvXhgCrf5mZdeq81G9fShdE2LfYbtb7w,14
68
- hydroserverpy-1.4.0b3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
69
- hydroserverpy-1.4.0b3.dist-info/RECORD,,
64
+ hydroserverpy-1.4.1.dist-info/licenses/LICENSE,sha256=xVqFxDw3QOEJukakL7gQCqIMTQ1dlSCTo6Oc1otNW80,1508
65
+ hydroserverpy-1.4.1.dist-info/METADATA,sha256=2gL1FFOCPKeB7S-gzJ7wURCgYB9l5Q4F3uvPgFWLjT4,2582
66
+ hydroserverpy-1.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
+ hydroserverpy-1.4.1.dist-info/top_level.txt,sha256=Zf37hrncXLOYvXhgCrf5mZdeq81G9fShdE2LfYbtb7w,14
68
+ hydroserverpy-1.4.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
69
+ hydroserverpy-1.4.1.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: hydroserverpy
3
- Version: 1.4.0b3
4
- Requires-Python: <4,>=3.9
5
- License-File: LICENSE
6
- Requires-Dist: requests>=2
7
- Requires-Dist: pydantic>=2.6
8
- Requires-Dist: pydantic[email]>=2.6
9
- Requires-Dist: pandas>=2.2
10
- Requires-Dist: numpy>=2.0
11
- Requires-Dist: pyyaml>=5
12
- Requires-Dist: simplejson>=3
13
- Requires-Dist: crontab>=1
14
- Requires-Dist: python-dateutil>=2.8.2
15
- Requires-Dist: croniter>=2.0.1
16
- Requires-Dist: jmespath>=1.0.1
17
- Provides-Extra: docs
18
- Requires-Dist: sphinx_autodoc_typehints; extra == "docs"
19
- Dynamic: license-file