Source code for pynxxas.nxdl.repo

"""NXDL repository"""

import os
import logging
import tempfile
import urllib.parse
import urllib.request
from glob import glob
from functools import lru_cache
from typing import Optional

import git
import xmlschema

DEFAULT_URL = "https://github.com/nexusformat/definitions.git"


[docs] @lru_cache(maxsize=1) def get_nxdl_schema(**repo_options): """Returns the NDXL schema""" repo = _get_repo(**repo_options) schema_file = os.path.join(repo.working_dir, "nxdl.xsd") # Lax because of: https://github.com/nexusformat/definitions/issues/1368 return xmlschema.XMLSchema(schema_file, validation="lax")
[docs] @lru_cache(maxsize=1) def get_nxdl_definition_names(**repo_options): """Returns all NXDL file names from the repo""" working_dir = _get_repo(**repo_options).working_dir pattern = os.path.join(working_dir, "*", "*.nxdl.xml") return [ os.path.basename(filename).replace(".nxdl.xml", "") for filename in glob(pattern) ]
[docs] def get_nxdl_definition(name: str, **repo_options) -> dict: """Load the content of an NXDL file""" schema = get_nxdl_schema(**repo_options) base_url = urllib.parse.urlparse(schema.base_url) assert base_url.scheme == "file" path = urllib.request.url2pathname(base_url.path) for dirname in ("base_classes", "applications", "contributed_definitions"): xml_file = os.path.join(path, dirname, f"{name}.nxdl.xml") if os.path.exists(xml_file): break else: raise ValueError(f"NXDL class '{name}' does not exist in '{base_url}'") return schema.to_dict(xml_file, process_namespaces=True, use_defaults=True)
@lru_cache(maxsize=1) def _get_repo( nxdl_version: Optional[str] = None, localdir: Optional[str] = None, url: Optional[str] = None, branch: Optional[str] = None, reset: Optional[bool] = True, ) -> git.Repo: """Git repository with NeXus definition files (*.nxdl.xml)""" if not localdir: localdir = os.path.join(tempfile.gettempdir(), "nexus_definitions") if not url: url = DEFAULT_URL if not branch: branch = "main" remote = "origin" if os.path.exists(localdir): repo = git.Repo(localdir) origin = repo.remotes[remote] if reset: origin.set_url(url) origin.fetch() else: logging.warning("cloning '%s' in '%s' ...", url, localdir) repo = git.Repo.clone_from(url, localdir) if reset: if nxdl_version: repo.git.checkout(f"v{nxdl_version}") else: repo.git.checkout(branch) repo.git.reset(f"{remote}/{branch}", hard=True) logging.info("NXDL repository '%s' in '%s'", url, localdir) return repo