Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
452 changes: 452 additions & 0 deletions LOGGING.md

Large diffs are not rendered by default.

200 changes: 169 additions & 31 deletions poetry.lock

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "hec-dss-python"
version = "0.1.25"
version = "0.1.26"
description = "Python wrapper for the HEC-DSS file database C library."
authors = ["Hydrologic Engineering Center"]
license = "MIT"
Expand All @@ -10,6 +10,14 @@ packages = [{ include = "hecdss", from = "src" }]

[tool.poetry.dependencies]
python = "^3.9"
numpy = "^1.20.0"
# tzdata is needed for zoneinfo support on Windows
tzdata = { version = "*", markers = "sys_platform == 'win32'" }
# Optional dependency for downloading HEC-DSS binaries
requests = { version = "^2.25.0", optional = true }

[tool.poetry.extras]
download = ["requests"]

[tool.poetry.dev-dependencies]
# Python Syntax highlighter, assume
Expand Down Expand Up @@ -68,4 +76,4 @@ build-backend = "setuptools.build_meta"
log_cli = true
log_cli_level = 'INFO'
testpaths = ["tests"]
pythonpath = "./src"
pythonpath = ["./src", "./tests"]
9 changes: 9 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Core dependencies for hec-dss-python
numpy>=1.20.0

# Required for timezone support on Windows
tzdata; sys_platform == 'win32'

# Optional: For downloading HEC-DSS binary libraries
# Uncomment if you need to download the DLL/SO files:
requests>=2.25.0
6 changes: 3 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = hecdss
version = 0.1.25
version = 0.1.26
author = Hydrologic Engineering Center
author_email [email protected]
description = Python wrapper for the HEC-DSS file database C library.
Expand All @@ -19,8 +19,8 @@ packages = find:
python_requires = >=3.8
include_package_data = True
install_requires =
numpy
tzdata
numpy>=1.20.0
tzdata; sys_platform == 'win32'

[options.packages.find]
where=src
Expand Down
10 changes: 10 additions & 0 deletions src/hecdss/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@

import logging

from hecdss.catalog import Catalog
from hecdss.hecdss import HecDss
from hecdss.dsspath import DssPath
from hecdss.irregular_timeseries import IrregularTimeSeries
from hecdss.regular_timeseries import RegularTimeSeries
from hecdss.array_container import ArrayContainer
from hecdss.paired_data import PairedData
from hecdss.logging_config import (
configure_logging,
setup_default_logging,
DLL_MESSAGE
)

# Set up default logging configuration (NullHandler, no output by default)
setup_default_logging()

14 changes: 14 additions & 0 deletions src/hecdss/catalog.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import logging
from .record_type import RecordType
from .dsspath import DssPath
from datetime import datetime
import re

# Get logger for this module
logger = logging.getLogger(__name__)

class Catalog:
"""manage list of objects inside a DSS database"""
def __init__(self, uncondensed_paths, recordTypes):
Expand Down Expand Up @@ -76,9 +80,19 @@ def __create_condensed_catalog(self):
self.items.append(p)

def print(self):
"""Print all items in the catalog to stdout."""
for ds in self.items:
print(ds)

def log_items(self, level=logging.INFO):
"""Log all items in the catalog at the specified logging level.

Args:
level: Logging level (default: logging.INFO)
"""
for ds in self.items:
logger.log(level, "Catalog item: %s", ds)

def __iter__(self):
self.index = 0 # Initialize the index to 0
return self
Expand Down
17 changes: 13 additions & 4 deletions src/hecdss/download_hecdss.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"""Helper module to retrieve the binary libraries"""

import logging
from pathlib import Path
import shutil
import requests
import zipfile
import os

# Get logger for this module
logger = logging.getLogger(__name__)


def download_and_unzip(url, zip_file, destination_dir):
"""Retrieves a compressed archive from the URL and extracts it in the destination dir.
Expand All @@ -19,21 +23,26 @@ def download_and_unzip(url, zip_file, destination_dir):
destination_dir :
Path to the local directory where the archive content is extracted to.
"""
print(url)
print(url) # Keep for user feedback during download
logger.info("Downloading from URL: %s", url)
os.makedirs(destination_dir, exist_ok=True)
response = requests.get(zip_url, timeout=300)
if response.status_code == 200:
zip_file_path = os.path.join(destination_dir, zip_file)
with open(zip_file_path, "wb") as zip_file:
zip_file.write(response.content)
print("Zip file downloaded successfully.")
print("Zip file downloaded successfully.") # Keep for user feedback
logger.info("Zip file downloaded successfully")

with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
zip_ref.extractall(destination_dir)
print(f"Contents extracted successfully to.'{destination_dir}'")
print(f"Contents extracted successfully to.'{destination_dir}'") # Keep for user feedback
logger.info("Contents extracted successfully to '%s'", destination_dir)
os.remove(zip_file_path)
else:
print(f"Failed to download zip file. Status code: {response.status_code}")
error_msg = f"Failed to download zip file. Status code: {response.status_code}"
print(error_msg) # Keep for user feedback
logger.error(error_msg)

base_url = "https://www.hec.usace.army.mil/nexus/repository/maven-public/mil/army/usace/hec/hecdss/"
version = "7-IU-16"
Expand Down
32 changes: 25 additions & 7 deletions src/hecdss/dsspath.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import logging
from .dateconverter import DateConverter
from .dss_type import DssType
from .record_type import RecordType

# Get logger for this module
logger = logging.getLogger(__name__)

class DssPath:
"""
Manage parts of DSS path /A/B/C/D/E/F/
Expand Down Expand Up @@ -79,11 +83,25 @@ def is_time_series(self):

def print(self):
"""
Print the parts of the DSS path.
Print the parts of the DSS path to stdout.
"""
print("a:" + self.A)
print("b:" + self.B)
print("c:" + self.C)
print("d:" + self.D)
print("e:" + self.E)
print("f:" + self.F)

def log_path(self, level=logging.INFO):
"""Log the DSS path parts at the specified logging level.

Args:
level: Logging level (default: logging.INFO)
"""
print("a:" + self.path.A)
print("b:" + self.path.B)
print("c:" + self.path.C)
print("d:" + self.path.D)
print("e:" + self.path.E)
print("f:" + self.path.F)
logger.log(level, "DssPath: %s", str(self))
logger.log(level, " A (Group/Project/Watershed): %s", self.A)
logger.log(level, " B (Location): %s", self.B)
logger.log(level, " C (Parameter): %s", self.C)
logger.log(level, " D (Block Start Date/Time): %s", self.D)
logger.log(level, " E (Time Interval/Block Length): %s", self.E)
logger.log(level, " F (Descriptor): %s", self.F)
Loading
Loading