Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: validate undeclared SigMF extensions in metadata #104

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
39 changes: 39 additions & 0 deletions sigmf/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,34 @@
from . import error, schema, sigmffile


def _get_extension_namespaces(metadata):
"""Get set of declared extension namespaces from global core:extensions."""
extensions = metadata.get("global", {}).get("core:extensions", [])
return {ext["name"].split(":")[0] for ext in extensions}

def _get_used_extensions(metadata):
"""Find all extension namespaces actually used in the metadata."""
used = set()

# Helper function to check keys in a dictionary
def check_dict(d):
for key in d:
if ":" in key:
namespace = key.split(":")[0]
if namespace != "core":
used.add(namespace)

# Check all sections
for section in ["global", "captures", "annotations"]:
if section in metadata:
if isinstance(metadata[section], dict):
check_dict(metadata[section])
elif isinstance(metadata[section], list):
for item in metadata[section]:
check_dict(item)

return used

def validate(metadata, ref_schema=schema.get_schema()) -> None:
"""
Check that the provided `metadata` dict is valid according to the `ref_schema` dict.
Expand All @@ -46,6 +74,17 @@ def validate(metadata, ref_schema=schema.get_schema()) -> None:
"""
jsonschema.validators.validate(instance=metadata, schema=ref_schema)

# Check extensions
declared_extensions = _get_extension_namespaces(metadata)
used_extensions = _get_used_extensions(metadata)

undeclared = used_extensions - declared_extensions
if undeclared:
raise jsonschema.exceptions.ValidationError(
f"Found undeclared extensions in use: {', '.join(sorted(undeclared))}. "
"All extensions must be declared in global:core:extensions."
)

# ensure captures and annotations have monotonically increasing sample_start
for key in ["captures", "annotations"]:
count = -1
Expand Down