Namespaces

Namespaces adapter

Wraps the nwb_schema_language.Namespaces and other objects with convenience methods for extracting information and generating translated schema

class NamespacesAdapter(*, namespaces: Namespaces, schemas: List[SchemaAdapter], imported: List[NamespacesAdapter] = None)

Translate a NWB Namespace to a LinkML Schema

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

namespaces: Namespaces
schemas: List[SchemaAdapter]
imported: List[NamespacesAdapter]
classmethod from_yaml(path: Path) NamespacesAdapter

Create a NamespacesAdapter from a nwb schema language namespaces yaml file.

Also attempts to provide imported implicitly imported schema (using the namespace key, rather than source, eg. with hdmf-common)

build(skip_imports: bool = False, progress: AdapterProgress | None = None) BuildResult

Build the NWB namespace to the LinkML Schema

complete_namespaces() None

After loading the namespace, and after any imports have been added afterwards, this must be called to complete the definitions of the contained schema objects.

This is not automatic because NWB doesn’t have a formal dependency resolution system, so it is often impossible to know which imports are needed until after the namespace adapter has been instantiated.

It is automatically called if it hasn’t been already by the build() method.

find_type_source(cls: str | Dataset | Group, fast: bool = False) SchemaAdapter

Given some type (as neurodata_type_def), find the schema that it’s defined in.

Rather than returning as soon as a match is found, ensure that duplicates are not found within the primary schema, then so the same for all imported schemas.

Parameters:
  • cls (str | Dataset | Group) – The neurodata_type_def to look for the source of. If a Dataset or Group, look for the object itself (cls in schema.datasets), otherwise look for a class with a matching name.

  • fast (bool) – If True, return as soon as a match is found. If ``False`, return after checking all schemas for duplicates.

Returns:

SchemaAdapter

Raises:

KeyError – if multiple schemas or no schemas are found

to_yaml(base_dir: Path) None

Build the schemas, saving them to yaml files according to their name

Parameters:

base_dir (Path) – Directory to save yaml files

property needed_imports: Dict[str, List[str]]

List of other, external namespaces that we need to import. Usually provided as schema with a namespace but not a source

Returns:

[‘needed_import_0’, …]}

Return type:

{‘namespace_name’

property versions: Dict[str, str]

versions for each namespace

namespace_schemas(name: str) List[str]

Get the schemas that are defined in a given namespace

schema_namespace(name: str) str | None

Inverse of namespace_schemas() - given a schema name, get the namespace it’s in

all_schemas() Generator[SchemaAdapter, None, None]

Iterator over all schemas including imports

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'imported': FieldInfo(annotation=List[NamespacesAdapter], required=False, default_factory=list), 'namespaces': FieldInfo(annotation=Namespaces, required=True), 'schemas': FieldInfo(annotation=List[SchemaAdapter], required=True)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

roll_down_nwb_class(source: Group | Dataset | dict, target: Group | Dataset | dict, complete: bool = False) dict

Merge an ancestor (via neurodata_type_inc ) source class with a child target class.

On the first recursive pass, only those values that are set on the target are copied from the source class - this isn’t a true merging, what we are after is to recursively merge all the values that are modified in the child class with those of the parent class below the top level, the top-level attributes will be carried through via normal inheritance.

Rather than re-instantiating the child class, we return the dictionary so that this function can be used in series to merge a whole ancestry chain within NamespacesAdapter , but merging isn’t exposed in the function since ancestor class definitions can be spread out over many schemas, and we need the orchestration of the adapter to have them in all cases we’d be using this.

Parameters:
  • source (dict) – source dictionary

  • target (dict) – target dictionary (values merged over source)

  • complete (bool) – (default False)do a complete merge, merging everything from source to target without trying to minimize redundancy. Used to collapse ancestor classes before the terminal class.

References

https://github.com/NeurodataWithoutBorders/pynwb/issues/1954