Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
f8b54fc
Update README sources to indicate all names and include links
jacob-a-brown Jan 13, 2025
debb02e
Separate analyte and water level sources to differentiate where data …
jacob-a-brown Jan 13, 2025
92e804d
Formatting changes
jacob-a-brown Jan 13, 2025
acb9fd0
Update CKAN to NM OSE Roswell in sources documentation
jacob-a-brown Jan 13, 2025
899a17e
Updated source names | Set source to False if not in use
jacob-a-brown Jan 14, 2025
bc9dc67
Updated README for clarity
jacob-a-brown Jan 14, 2025
66df2ff
Merge branch 'dev/jab' of https://github.com/DataIntegrationGroup/Dat…
jacob-a-brown Jan 14, 2025
f840436
Formatting changes
jacob-a-brown Jan 14, 2025
f8eb163
Write output.sites.csv for separated timeseries
jacob-a-brown Jan 14, 2025
4871b7e
Deprecate combined
jacob-a-brown Jan 14, 2025
cb08ca8
Updated README.md to indicate Bureau of Reclation (BoR)
jacob-a-brown Jan 14, 2025
6e1d864
Comment out all instances of combined
jacob-a-brown Jan 14, 2025
91cbb5a
Add --output flag for summary and timeseries
jacob-a-brown Jan 14, 2025
694e986
Formatting changes
jacob-a-brown Jan 14, 2025
bd6c7f2
Fix names for functions for writing different output files
jacob-a-brown Jan 15, 2025
8f6ae70
Update BOR for API changes
jacob-a-brown Jan 15, 2025
a55bbfa
Merge branch 'main' into dev/jab
jacob-a-brown Jan 27, 2025
215a39b
Use parameter flag to specify both waterlevels and analytes
jacob-a-brown Jan 27, 2025
c3a8d31
Formatting changes
jacob-a-brown Jan 27, 2025
a0cd1d6
Rearrange sources for alphabetical order
jacob-a-brown Jan 28, 2025
5ef2d0b
Call weave by the paramete name without any flags
jacob-a-brown Jan 28, 2025
59db062
Updated setup url
jacob-a-brown Jan 28, 2025
50cb939
Update version to 0.2.1
jacob-a-brown Jan 28, 2025
761f7e3
Formatting changes
jacob-a-brown Jan 28, 2025
ffd0729
Removed attestations for publishing to pypi
jacob-a-brown Jan 28, 2025
8305f31
Update version to 0.2.2
jacob-a-brown Jan 28, 2025
0374085
Merge branch 'dev/jab' of https://github.com/DataIntegrationGroup/Dat…
jacob-a-brown Jan 28, 2025
46309bc
Call weave as die command
jacob-a-brown Jan 28, 2025
0972992
Print sources when user calls die sources
jacob-a-brown Jan 28, 2025
42f2c32
Standardize waterlevel records to be the same as analyte records
jacob-a-brown Jan 28, 2025
057ff2f
Work on rounding water level values to 2 places
jacob-a-brown Jan 28, 2025
d1ce317
Round water level parameter values to 2 decimal places
jacob-a-brown Jan 28, 2025
66a1efc
Remove deprecated fields from record
jacob-a-brown Jan 28, 2025
4959fc5
Update water level summary parameter name to be consistent with times…
jacob-a-brown Jan 29, 2025
d86cd77
Formatting changes
jacob-a-brown Jan 29, 2025
4069dca
Remove combined write functions since it is deprecated
jacob-a-brown Jan 29, 2025
ac78b7b
Ignore all outputs
jacob-a-brown Jan 29, 2025
0e0397c
Put each output for each call into unique output directory
jacob-a-brown Jan 29, 2025
2e3d2eb
Formatting changes
jacob-a-brown Jan 29, 2025
c617789
Account for results for "< MDL" for NMED DWB
jacob-a-brown Jan 29, 2025
51b4ec6
Add __repr__ to all source.py files
jacob-a-brown Jan 29, 2025
0548f35
Set parameter options to lowercase for consistency
jacob-a-brown Jan 29, 2025
731e1be
Merge branch 'dev/jab' of https://github.com/DataIntegrationGroup/Dat…
jacob-a-brown Jan 29, 2025
bca689f
Formatting changes
jacob-a-brown Jan 29, 2025
ac96eb1
Work on README
jacob-a-brown Jan 29, 2025
ce70daa
Work on README
jacob-a-brown Jan 29, 2025
562441e
Updated README for die invocation
jacob-a-brown Jan 29, 2025
65a58f4
README clarification
jacob-a-brown Jan 29, 2025
63ab7ad
Fix most_recent_result in summary table
jacob-a-brown Jan 29, 2025
64ae177
Update README to indicate die sources and wells are in development
jacob-a-brown Jan 29, 2025
f0c29eb
Bump version to 0.3.0
jacob-a-brown Jan 29, 2025
f098587
Updated README for clarity
jacob-a-brown Jan 29, 2025
7c2b4ab
Make README better formatted
jacob-a-brown Jan 29, 2025
30f76d4
Bump version to 0.3.1 for README changes
jacob-a-brown Jan 29, 2025
bc414ea
Merge pull request #10 from DataIntegrationGroup/dev/jab
jacob-a-brown Jan 30, 2025
806f971
Added comments for internal documentation
jacob-a-brown Jan 30, 2025
30fe990
Public to PyPi on successful pull requests and merges to main
jacob-a-brown Jan 30, 2025
ef8a022
Update source padding in logging for long source names
jacob-a-brown Feb 4, 2025
69a8a8c
Merge pull request #11 from DataIntegrationGroup/dev/jab
jacob-a-brown Feb 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI

on:
push:
tags:
- '*'
pull_request:
branches:
- main
types:
- closed

jobs:
build-n-publish:
build-and-publish-if-merged:
if: github.event.pull_request.merged == true
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
runs-on: ubuntu-latest
permissions:
Expand Down Expand Up @@ -36,3 +39,5 @@ jobs:
- name: Publish distribution 📦 to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
attestations: false
8 changes: 1 addition & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,4 @@ cython_debug/
#.idea/

# outputs
output_timeseries
output.combined.csv
output.csv
output.sites.csv
output.timeseries.csv
output.logs.txt
output.warnings.txt
output*
346 changes: 154 additions & 192 deletions README.md

Large diffs are not rendered by default.

168 changes: 87 additions & 81 deletions backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,37 +57,37 @@
from .connectors.wqp.source import WQPSiteSource, WQPAnalyteSource

SOURCE_KEYS = (
"nmbgmr",
"wqp",
"iscsevenrivers",
"bernco",
"bor",
"nmbgmr_amp",
"nmed_dwb",
"nmose_isc_seven_rivers",
"nmose_roswell",
"nwis",
"oseroswell",
"pvacd",
"bor",
"dwb",
"bernco",
"wqp",
)


def get_source(source):
if source == "nmbgmr":
if source == "bernco":
return BernCoSiteSource()
elif source == "bor":
return BORSiteSource()
elif source == "nmbgmr_amp":
return NMBGMRSiteSource()
elif source == "wqp":
return WQPSiteSource()
elif source == "iscsevenrivers":
elif source == "nmed_dwb":
return DWBSiteSource()
elif source == "nmose_isc_seven_rivers":
return ISCSevenRiversSiteSource()
elif source == "nmose_roswell":
return OSERoswellSiteSource(HONDO_RESOURCE_ID)
elif source == "nwis":
return NWISSiteSource()
elif source == "oseroswell":
return OSERoswellSiteSource(HONDO_RESOURCE_ID)
elif source == "pvacd":
return PVACDSiteSource()
elif source == "bor":
return BORSiteSource()
elif source == "dwb":
return DWBSiteSource()
elif source == "bernco":
return BernCoSiteSource()
elif source == "wqp":
return WQPSiteSource()

return None

Expand All @@ -106,27 +106,29 @@ class Config(Loggable):
wkt: str = ""

# sources
use_source_nmbgmr: bool = True
use_source_wqp: bool = True
use_source_iscsevenrivers: bool = True
use_source_bernco: bool = True
use_source_bor: bool = True
use_source_nmbgmr_amp: bool = True
use_source_nmed_dwb: bool = True
use_source_nmose_isc_seven_rivers: bool = True
use_source_nmose_roswell: bool = True
use_source_nwis: bool = True
use_source_oseroswell: bool = True
use_source_pvacd: bool = True
use_source_bor: bool = True
use_source_dwb: bool = True
use_source_bernco: bool = True
use_source_wqp: bool = True

analyte: str = ""
# parameter
parameter: str = ""

# output
use_cloud_storage: bool = False
output_dir: str = ""
output_dir: str = "."
output_name: str = "output"
output_horizontal_datum: str = WGS84
output_elevation_units: str = FEET
output_well_depth_units: str = FEET
output_summary: bool = False
output_single_timeseries: bool = False
output_timeseries_unified: bool = False
output_timeseries_separated: bool = False

latest_water_level_only: bool = False

Expand Down Expand Up @@ -157,56 +159,54 @@ def __init__(self, model=None, payload=None):
self.wkt = payload.get("wkt", "")
self.county = payload.get("county", "")
self.output_summary = payload.get("output_summary", False)
self.output_timeseries_unified = payload.get(
"output_timeseries_unified", False
)
self.output_timeseries_separated = payload.get(
"output_timeseries_separated", False
)
self.output_name = payload.get("output_name", "output")
self.start_date = payload.get("start_date", "")
self.end_date = payload.get("end_date", "")
self.analyte = payload.get("analyte", "")
self.output_single_timeseries = payload.get(
"output_single_timeseries", False
)
self.parameter = payload.get("parameter", "")

for s in SOURCE_KEYS:
setattr(self, f"use_source_{s}", s in payload.get("sources", []))

def analyte_sources(self):
sources = []

# if self.use_source_wqp:
# sources.append((WQPSiteSource, WQPAnalyteSource))
if self.use_source_bor:
sources.append((BORSiteSource(), BORAnalyteSource()))
if self.use_source_wqp:
sources.append((WQPSiteSource(), WQPAnalyteSource()))
if self.use_source_iscsevenrivers:
if self.use_source_nmose_isc_seven_rivers:
sources.append((ISCSevenRiversSiteSource(), ISCSevenRiversAnalyteSource()))
if self.use_source_nmbgmr:
if self.use_source_nmbgmr_amp:
sources.append((NMBGMRSiteSource(), NMBGMRAnalyteSource()))
if self.use_source_dwb:
if self.use_source_nmed_dwb:
sources.append((DWBSiteSource(), DWBAnalyteSource()))

for s, ss in sources:
s.set_config(self)
ss.set_config(self)

# s.config = self
# ss.config = self

return sources

def water_level_sources(self):
sources = []
if self.use_source_nmbgmr:
if self.use_source_nmbgmr_amp:
sources.append((NMBGMRSiteSource(), NMBGMRWaterLevelSource()))

if self.use_source_iscsevenrivers:
if self.use_source_nmose_isc_seven_rivers:
sources.append(
(ISCSevenRiversSiteSource(), ISCSevenRiversWaterLevelSource())
)

if self.use_source_nwis:
sources.append((NWISSiteSource(), NWISWaterLevelSource()))

if self.use_source_oseroswell:
if self.use_source_nmose_roswell:
sources.append(
(
OSERoswellSiteSource(HONDO_RESOURCE_ID),
Expand All @@ -227,48 +227,15 @@ def water_level_sources(self):
)
if self.use_source_pvacd:
sources.append((PVACDSiteSource(), PVACDWaterLevelSource()))
# sources.append((EBIDSiteSource, EBIDWaterLevelSource))
if self.use_source_bernco:
sources.append((BernCoSiteSource(), BernCoWaterLevelSource()))
# if self.use_source_bor:
# sources.append((BORSiteSource(), BORWaterLevelSource()))

for s, ss in sources:
s.set_config(self)
ss.set_config(self)

return sources

# def site_sources(self):
# sources = [
# NMBGMRSiteSource(),
# WQPSiteSource(),
# ISCSevenRiversSiteSource(),
# NWISSiteSource(),
# DWBSiteSource(),
# BORSiteSource(),
# PVACDSiteSource(),
# EBIDSiteSource(),
# OSERoswellSiteSource(HONDO_RESOURCE_ID),
# OSERoswellSiteSource(FORT_SUMNER_RESOURCE_ID),
# OSERoswellSiteSource(ROSWELL_RESOURCE_ID),
# ]
#
# # if self.use_source_nmbgmr:
# # sources.append(NMBGMRSiteSource)
# # if self.use_source_isc_seven_rivers:
# # sources.append(ISCSevenRiversSiteSource)
# # if self.use_source_ose_roswell:
# # sources.append(OSERoswellSiteSource)
# # if self.use_source_nwis:
# # sources.append(USGSSiteSource)
# # if self.use_source_st2:
# # sources.append(PVACDSiteSource)
# # sources.append(EBIDSiteSource)
# # if self.use_source_bor:
# # sources.append(BORSiteSource)
# return sources

def bbox_bounding_points(self, bbox=None):
if bbox is None:
bbox = self.bbox
Expand Down Expand Up @@ -340,7 +307,7 @@ def _report_attributes(title, attrs):
"county",
"bbox",
"wkt",
"analyte",
"parameter",
"site_limit",
] + sources
# inputs
Expand All @@ -353,10 +320,10 @@ def _report_attributes(title, attrs):
_report_attributes(
"Outputs",
(
"output_dir",
"output_name",
"output_path",
"output_summary",
"output_single_timeseries",
"output_timeseries_unified",
"output_timeseries_separated",
"output_horizontal_datum",
"output_elevation_units",
),
Expand Down Expand Up @@ -415,6 +382,45 @@ def _validate_county(self):

return True

def _update_output_name(self):
"""
Generate a unique output name based on existing directories in the output directory.

If there are no directories with the string "output" in their name, the output name will be "output".

If there is a directory called "output", then output_name will be "output_1".

If there are directories called "output_{n}" where n is an integer, then output_name will be "output_{m+1}"
where m is the highest integer in the existing directories.
"""
output_name = self.output_name

# find if there are already directories with the string "output" their names
output_names = [
name
for name in os.listdir(self.output_dir)
if os.path.isdir(name) and output_name in name
]

if len(output_names) > 0:
max_count = 0
# find the highest number appended to directories with "output" in their name
counts = [
name.split("_")[-1]
for name in output_names
if name.split("_")[-1].isdigit()
]
counts = [int(count) for count in counts]
if len(counts) > 0:
max_count = max(counts)
output_name = f"{output_name}_{max_count + 1}"

self.output_name = output_name

def _make_output_path(self):
if not os.path.exists(self.output_path):
os.mkdir(self.output_path)

@property
def start_dt(self):
return self._extract_date(self.start_date)
Expand Down
15 changes: 13 additions & 2 deletions backend/connectors/bor/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
class BORSiteSource(BaseSiteSource):
transformer_klass = BORSiteTransformer

def __repr__(self):
return "BORSiteSource"

def health(self):
try:
self.get_records()
Expand All @@ -66,6 +69,9 @@ class BORAnalyteSource(BaseAnalyteSource):
transformer_klass = BORAnalyteTransformer
_catalog_item_idx = None

def __repr__(self):
return "BORAnalyteSource"

def _extract_parameter_record(self, record):
record[PARAMETER_VALUE] = record["attributes"]["result"]
record[PARAMETER_UNITS] = record["attributes"]["resultAttributes"]["units"]
Expand Down Expand Up @@ -102,9 +108,14 @@ def _reorder_catalog_items(self, items):
return items

def get_records(self, site_record):
code = get_analyte_search_param(self.config.analyte, BOR_ANALYTE_MAPPING)
code = get_analyte_search_param(self.config.parameter, BOR_ANALYTE_MAPPING)

catalog_record_data = self._execute_json_request(
f"https://data.usbr.gov{site_record.catalogRecords[0]['id']}"
)
catalog_items = catalog_record_data["relationships"]["catalogItems"]["data"]

for i, item in enumerate(self._reorder_catalog_items(site_record.catalogItems)):
for i, item in enumerate(self._reorder_catalog_items(catalog_items)):

data = self._execute_json_request(f'https://data.usbr.gov{item["id"]}')
if not data:
Expand Down
2 changes: 1 addition & 1 deletion backend/connectors/bor/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# limitations under the License.
# ===============================================================================
import pprint
import json

from backend.record import SiteRecord, WaterLevelRecord, AnalyteSummaryRecord
from backend.transformer import (
Expand Down Expand Up @@ -57,7 +58,6 @@ def _transform(self, record):
"well_depth": WELL_DEPTHS.get(props["_id"]),
"well_depth_units": "ft",
"catalogRecords": record["relationships"]["catalogRecords"]["data"],
"catalogItems": record["relationships"]["catalogItems"]["data"],
}
return rec

Expand Down
Loading