Source code for pynwb.validate

import os
import sys
from argparse import ArgumentParser

from hdmf.spec import NamespaceCatalog
from hdmf.build import BuildManager
from hdmf.build import TypeMap as TypeMap

from pynwb import validate, CORE_NAMESPACE, NWBHDF5IO
from pynwb.spec import NWBDatasetSpec, NWBGroupSpec, NWBNamespace


def _print_errors(validation_errors):
    if validation_errors:
        print(' - found the following errors:', file=sys.stderr)
        for err in validation_errors:
            print(str(err), file=sys.stderr)
    else:
        print(' - no errors found.')


def _validate_helper(**kwargs):
    errors = validate(**kwargs)
    _print_errors(errors)

    return (errors is not None and len(errors) > 0)


[docs]def main(): ep = """ use --nspath to validate against an extension. If --ns is not specified, validate against all namespaces in namespace file. """ parser = ArgumentParser(description="Validate an NWB file", epilog=ep) parser.add_argument("paths", type=str, nargs='+', help="NWB file paths") parser.add_argument('-p', '--nspath', type=str, help="the path to the namespace YAML file") parser.add_argument("-n", "--ns", type=str, help="the namespace to validate against") parser.add_argument("-lns", "--list-namespaces", dest="list_namespaces", action='store_true', help="List the available namespaces and exit.") feature_parser = parser.add_mutually_exclusive_group(required=False) feature_parser.add_argument("--cached-namespace", dest="cached_namespace", action='store_true', help="Use the cached namespace (default).") feature_parser.add_argument('--no-cached-namespace', dest="cached_namespace", action='store_false', help="Don't use the cached namespace.") parser.set_defaults(cached_namespace=True) args = parser.parse_args() ret = 0 if args.nspath: if not os.path.isfile(args.nspath): print("The namespace file {} is not a valid file.".format(args.nspath), file=sys.stderr) sys.exit(1) if args.cached_namespace: print("Turning off validation against cached namespace information " "as --nspath was passed.", file=sys.stderr) args.cached_namespace = False for path in args.paths: if not os.path.isfile(path): print("The file {} does not exist.".format(path), file=sys.stderr) ret = 1 continue if args.cached_namespace: catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace) ns_deps = NWBHDF5IO.load_namespaces(catalog, path) s = set(ns_deps.keys()) # determine which namespaces are the most for k in ns_deps: # specific (i.e. extensions) and validate s -= ns_deps[k].keys() # against those namespaces = list(sorted(s)) if len(namespaces) > 0: tm = TypeMap(catalog) manager = BuildManager(tm) specloc = "cached namespace information" else: manager = None namespaces = [CORE_NAMESPACE] specloc = "pynwb namespace information" print("The file {} has no cached namespace information. " "Falling back to {}.".format(path, specloc), file=sys.stderr) elif args.nspath: catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace) namespaces = catalog.load_namespaces(args.nspath) if len(namespaces) == 0: print("Could not load namespaces from file {}.".format(args.nspath), file=sys.stderr) sys.exit(1) tm = TypeMap(catalog) manager = BuildManager(tm) specloc = "--nspath namespace information" else: manager = None namespaces = [CORE_NAMESPACE] specloc = "pynwb namespace information" if args.list_namespaces: print("\n".join(namespaces)) ret = 0 continue if args.ns: if args.ns in namespaces: namespaces = [args.ns] else: print("The namespace {} could not be found in {} as only {} is present.".format( args.ns, specloc, namespaces), file=sys.stderr) ret = 1 continue with NWBHDF5IO(path, mode='r', manager=manager) as io: for ns in namespaces: print("Validating {} against {} using namespace {}.".format(path, specloc, ns)) ret = ret or _validate_helper(io=io, namespace=ns) sys.exit(ret)
if __name__ == '__main__': # pragma: no cover main()