Skip to content

H5json - #420

Draft
jreadey wants to merge 92 commits into
masterfrom
h5json
Draft

H5json#420
jreadey wants to merge 92 commits into
masterfrom
h5json

Conversation

@jreadey

@jreadey jreadey commented Apr 23, 2025

Copy link
Copy Markdown
Member

Use h5json package for typing and objids

Important

Migrated HSDS to use the h5json library for core utilities, restructured utility modules, added support for client-provided object IDs and timestamps, and updated dependencies to require Python 3.10+ with h5json 1.0.0+.

Library Migration and Utility Restructuring

  • h5json Library Integration: Migrated from local utility modules to h5json library for data type, array, object ID, shape, dataset, filter, link, and time utilities across 30+ files.
  • Deleted Utility Modules: Removed hsds/util/idUtil.py, hsds/util/timeUtil.py, hsds/util/hdf5dtype.py, and hsds/util/arrayUtil.py as their functionality is now provided by h5json.
  • New Utility Module: Created hsds/util/nodeUtil.py with node ID generation, partitioning, and datanode URL resolution functions.
  • Updated Imports: Changed all references from local util modules to h5json equivalents (e.g., util.idUtil â�� h5json.objid, util.timeUtil â�� h5json.time_util).

Object ID and Timestamp Handling

  • Client-Provided Object IDs: Added support for creating objects with client-specified IDs in POST_Dataset, POST_Group, POST_Datatype, and related functions in dset_dn.py, group_dn.py, ctype_dn.py, and dset_sn.py.
  • Timestamp Validation: Added max_timestamp_drift configuration parameter to validate client-provided timestamps in attr_dn.py, link_dn.py, and related modules, with fallback to server-generated timestamps when skew exceeds threshold.
  • Deleted Object Tracking: Added logic to check and remove previously deleted object IDs from deleted_ids set when creating new objects with the same ID.

Configuration and Dependencies

  • New Configuration Parameters: Added default_vlen_type_size, predate_maxtime, posix_delay, max_compact_dset_size, and max_timestamp_drift to admin/config/config.yml.
  • Updated Dependencies: Modified pyproject.toml to require Python 3.10+, add h5json 1.0.0+, update numpy to 2.0.0+, and constrain numcodecs to â�¤0.15.1.
  • Removed Python 3.9: Removed Python 3.9 from CI/CD test matrix in .github/workflows/python-package.yml.

API and Function Refactoring

  • Object Creation Functions: Refactored POST_Dataset, POST_Group, and POST_Datatype handlers to support batch creation of multiple objects using new helper functions (createDatasets, createGroups, createDatatypeObjs) and DomainCrawler for writing initial data.
  • Layout Handling: Changed getChunkLayout calls to getChunkDims throughout codebase; moved layout from top-level response to nested under creationProperties.
  • Link Handling: Changed external link field from h5domain to file in link_dn.py, link_sn.py, and servicenode_lib.py; added per-link timestamp validation in PUT_Links.
  • Attribute Initialization: Added support for initializing attributes from request body in POST_Dataset, POST_Group, and POST_Datatype instead of always creating empty objects.

New Functionality

  • PostCrawler Class: Added hsds/post_crawl.py with PostCrawler class for asynchronously creating multiple HDF5 objects with configurable worker count and error handling.
  • Domain Metadata Consolidation: Added getConsolidatedMetaData function in async_lib.py to create consolidated metadata summaries for all objects in a domain.
  • Data Writing: Added put_data method to DomainCrawler for writing one-chunk dataset values; added doPointWrite and doHyperslabWrite functions in dset_lib.py for writing point and hyperslab selections.
  • Domain Objects Retrieval: Added getobjs parameter to getDomainResponse function to optionally return domain objects from S3 summary file.

Bug Fixes and Improvements

  • Typo Fixes: Fixed multiple typos including "coniguous" â�� "contiguous", "seperated" â�� "separated", "heirarchy" â�� "hierarchy", "inital" â�� "initial", and various attribute/link-related typos.
  • Error Handling: Changed error responses from HTTPInternalServerError to HTTPBadRequest for duplicate object IDs and invalid configurations in ctype_dn.py, dset_dn.py, and group_dn.py.
  • Logging Improvements: Added debug logging for request bodies, object creation, and metadata processing; updated log message prefixes for consistency.
  • POSIX Delay Support: Added posix_delay configuration support to fileClient.py for simulating cloud storage latencies in get_object, put_object, and list_keys methods.
  • Version Update: Updated HSDS_VERSION from 0.9.2 to 1.0.0 in basenode.py.

Test Updates

  • New Test Methods: Added tests for client-provided object IDs (testPostDatasetWithId, testPostTypeWithId, testPostWithId), attribute initialization (testPostDatasetWithAttributes, testPostWithAttributes), timestamp handling (testUseTimestamp), and batch creation (testPostMulti, testDatasetPostMulti).
  • Test Refactoring: Updated tests to access layout from creationProperties instead of top-level; removed CHUNK_MIN/CHUNK_MAX constants and moved them to local scope; updated external link tests to use file field instead of h5domain.
  • Removed Tests: Deleted array_util_test.py, hdf5_dtype_test.py, and id_util_test.py as their functionality is now tested through h5json library.
  • Import Updates: Updated test imports to use h5json functions (e.g., createObjId, getFilterItem) instead of local utilities.

This description was created by Ellipsis for 2bafb51. You can customize this summary. It will automatically update as commits are pushed.

Comment thread hsds/util/nodeUtil.py
def _getIdHash(id):
"""Return md5 prefix based on id value"""
m = hashlib.new("md5")
m.update(id.encode("utf8"))

Check failure

Code scanning / CodeQL

Use of a broken or weak cryptographic hashing algorithm on sensitive data

[Sensitive data (id)](1) is used in a hashing algorithm (MD5) that is insecure.

Copilot Autofix

AI over 1 year ago

To fix the issue, replace the use of the MD5 hashing algorithm in _getIdHash with a stronger algorithm, such as SHA-256. This ensures that the hash function is resistant to pre-image and collision attacks. The change involves:

  1. Updating the _getIdHash function to use hashlib.sha256 instead of hashlib.new("md5").
  2. Ensuring that the rest of the code remains functional by keeping the truncation to the first 5 characters of the hash.

No additional imports are required since hashlib already supports SHA-256.


Suggested changeset 1
hsds/util/nodeUtil.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/hsds/util/nodeUtil.py b/hsds/util/nodeUtil.py
--- a/hsds/util/nodeUtil.py
+++ b/hsds/util/nodeUtil.py
@@ -25,4 +25,4 @@
 def _getIdHash(id):
-    """Return md5 prefix based on id value"""
-    m = hashlib.new("md5")
+    """Return sha256 prefix based on id value"""
+    m = hashlib.sha256()
     m.update(id.encode("utf8"))
EOF
@@ -25,4 +25,4 @@
def _getIdHash(id):
"""Return md5 prefix based on id value"""
m = hashlib.new("md5")
"""Return sha256 prefix based on id value"""
m = hashlib.sha256()
m.update(id.encode("utf8"))
Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread tests/integ/attr_test.py Outdated
Comment thread hsds/ctype_sn.py Outdated
Comment thread tests/unit/array_util_test.py
mattjala
mattjala previously approved these changes May 7, 2025

@mattjala mattjala left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides a few minor comments and questions, this is good to go in. I'll try to get the outstanding PRs on hdf5-json reviewed this week so that we can avoid having HSDS depend on a specific branch.

Comment thread hsds/group_sn.py Outdated
Comment thread openapi.yml
@@ -0,0 +1,2973 @@
openapi: 3.1.0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README points at HDFGroup/hdf5-rest-api as an authoritative description of the API, but it's now out of date. We should remove any references to it and flag it as out of date.

@brtnfld brtnfld added this to the HSDS 1.0.0 milestone Aug 21, 2026
Comment thread hsds/util/linkUtil.py
# link related functions
#
from h5json.time_util import getNow
from h5json.link_util import validateLinkName, getLinkClass, getLinkPath, getLinkFilePath

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateLinkName and isEqualLink moved to h5json.link_util, but their analogues for attributes (validateAttributeName and isEqualAttr) stayed behind in hsds/util/attrUtil.py. Is there a reason the two are split differently?

Comment thread admin/config/config.yml Outdated
Comment thread admin/config/config.yml Outdated
Comment thread hsds/post_crawl.py Outdated
Comment thread hsds/post_crawl.py Outdated
Comment thread hsds/post_crawl.py Outdated
Comment thread pyproject.toml
Comment thread openapi.yml
multiple groups in one request. `type` is not permitted in the body
(groups have no datatype).

**Bug:** `implicit` is only forwarded to argument construction for

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be moved to a GH issue instead of a note in openapi

Comment thread openapi.yml
(multi-item list) create; it is not restricted to non-batch
creates.

**Bug:** for a batch create (list with more than one item),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be moved to a GH issue instead of being in the openapi spec

Comment thread openapi.yml
schema: { type: boolean, default: false }
description: |
Include an `alias` list of h5paths that resolve to this
dataset. Bug: on this specific route, the flag that gates

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug desc should be moved to a GH issue

Comment thread openapi.yml
properties:
bytes_sent:
type: integer
description: "Note: a source-level bug (hsds/basenode.py) assigns bytes_recv over this key immediately after setting it, so this actually reports received bytes, and sent-byte count is not exposed."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug desc should be moved to a GH issue

Comment thread openapi.yml
description: |
Include an `alias` list of h5paths that resolve to this group.
Note: parsed with a raw truthiness check rather than real
boolean parsing, so `?getalias=0` is truthy and turns this on.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Truthiness issue seems like a bug and should be moved from here to a GH issue

Comment thread openapi.yml
description: |
Include an `alias` list of h5paths that resolve to this
datatype. Note: parsed with a raw truthiness check, so
`?getalias=0` is truthy and turns this on.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Truthiness issue seems like a bug and should be moved from here to a GH issue

Comment thread testall.py Outdated
Comment thread runall.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants