spdx_python_model

Python bindings for the SPDX 3 data model.

  1# SPDX-FileType: SOURCE
  2# SPDX-License-Identifier: Apache-2.0
  3"""
  4Python bindings for the SPDX 3 data model.
  5"""
  6
  7import importlib
  8import json
  9from pathlib import Path
 10from types import ModuleType
 11from typing import TYPE_CHECKING, Any, List, Tuple
 12
 13from .bindings import _CONTEXT_TABLE
 14from .version import VERSION
 15from .version import VERSION as __version__
 16
 17if TYPE_CHECKING:
 18    # Generated re-exports to give type checkers version types.
 19    # Not imported during runtime.
 20    from .bindings._reexport import *  # noqa: F403
 21
 22__all__ = [
 23    "bindings",  # generated # noqa: F405
 24    "LoadError",
 25    "VERSION",
 26    "__version__",
 27    "load",
 28    "load_data",
 29]
 30
 31# Version submodule names accepted by __getattr__ for top-level import.
 32_VERSION_MODULES = frozenset(_CONTEXT_TABLE.values())
 33
 34
 35class LoadError(Exception):
 36    """Raised when a SPDX document cannot be loaded."""
 37
 38
 39def __getattr__(name: str) -> ModuleType:
 40    """Lazily import a version's bindings on first top-level access (PEP 562)."""
 41    if name in _VERSION_MODULES:
 42        return importlib.import_module(f"{__name__}.bindings.{name}")
 43    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
 44
 45
 46def __dir__() -> List[str]:
 47    return sorted(set(globals()) | _VERSION_MODULES)
 48
 49
 50def load_data(data: Any) -> Tuple[ModuleType, Any]:
 51    """
 52    Automatically load a SPDX 3 JSON document with the correct model based on
 53    its context
 54
 55    :param data: The decoded JSON data as a Python dict
 56
 57    :returns: A tuple that contains the model and the decoded SHACLObjectSet
 58
 59    :raises LoadError: If the data is missing a context or if the context is
 60        not recognized
 61    :raises TypeError: If the data is not a dictionary
 62    """
 63
 64    if not isinstance(data, dict):
 65        raise TypeError("Data must be a dictionary")
 66
 67    context = data.get("@context")
 68    if not context:
 69        raise LoadError("No @context in data")
 70
 71    context_url = None
 72
 73    if isinstance(context, str):
 74        context_url = context
 75    elif isinstance(context, list):
 76        for item in context:
 77            if isinstance(item, str):
 78                context_url = item
 79                break
 80
 81    if not context_url:
 82        raise LoadError("No valid @context URL string found in data")
 83
 84    module_name = _CONTEXT_TABLE.get(context_url)
 85    if module_name is None:
 86        raise LoadError(f"Unknown context URL '{context_url}'")
 87
 88    model = importlib.import_module(f"{__name__}.bindings.{module_name}")
 89
 90    d = model.JSONLDDeserializer()
 91    objset = model.SHACLObjectSet()
 92
 93    d.deserialize_data(data, objset)
 94
 95    return model, objset
 96
 97
 98def load(path: Path) -> Tuple[ModuleType, Any]:
 99    """
100    Automatically load a SPDX 3 JSON document with the correct model based on
101    its context
102
103    :param path: The path to the SPDX 3 JSON file
104
105    :returns: A tuple that contains the model and the decoded SHACLObjectSet
106
107    :raises LoadError: If the data is missing a context or if the context is
108        not recognized
109    :raises TypeError: If the data is not a dictionary
110    """
111    with path.open("r") as f:
112        data = json.load(f)
113
114    return load_data(data)
class LoadError(builtins.Exception):
36class LoadError(Exception):
37    """Raised when a SPDX document cannot be loaded."""

Raised when a SPDX document cannot be loaded.

VERSION = '0.0.5'
__version__ = '0.0.5'
def load(path: pathlib.Path) -> Tuple[module, Any]:
 99def load(path: Path) -> Tuple[ModuleType, Any]:
100    """
101    Automatically load a SPDX 3 JSON document with the correct model based on
102    its context
103
104    :param path: The path to the SPDX 3 JSON file
105
106    :returns: A tuple that contains the model and the decoded SHACLObjectSet
107
108    :raises LoadError: If the data is missing a context or if the context is
109        not recognized
110    :raises TypeError: If the data is not a dictionary
111    """
112    with path.open("r") as f:
113        data = json.load(f)
114
115    return load_data(data)

Automatically load a SPDX 3 JSON document with the correct model based on its context

Parameters
  • path: The path to the SPDX 3 JSON file

:returns: A tuple that contains the model and the decoded SHACLObjectSet

Raises
  • LoadError: If the data is missing a context or if the context is not recognized
  • TypeError: If the data is not a dictionary
def load_data(data: Any) -> Tuple[module, Any]:
51def load_data(data: Any) -> Tuple[ModuleType, Any]:
52    """
53    Automatically load a SPDX 3 JSON document with the correct model based on
54    its context
55
56    :param data: The decoded JSON data as a Python dict
57
58    :returns: A tuple that contains the model and the decoded SHACLObjectSet
59
60    :raises LoadError: If the data is missing a context or if the context is
61        not recognized
62    :raises TypeError: If the data is not a dictionary
63    """
64
65    if not isinstance(data, dict):
66        raise TypeError("Data must be a dictionary")
67
68    context = data.get("@context")
69    if not context:
70        raise LoadError("No @context in data")
71
72    context_url = None
73
74    if isinstance(context, str):
75        context_url = context
76    elif isinstance(context, list):
77        for item in context:
78            if isinstance(item, str):
79                context_url = item
80                break
81
82    if not context_url:
83        raise LoadError("No valid @context URL string found in data")
84
85    module_name = _CONTEXT_TABLE.get(context_url)
86    if module_name is None:
87        raise LoadError(f"Unknown context URL '{context_url}'")
88
89    model = importlib.import_module(f"{__name__}.bindings.{module_name}")
90
91    d = model.JSONLDDeserializer()
92    objset = model.SHACLObjectSet()
93
94    d.deserialize_data(data, objset)
95
96    return model, objset

Automatically load a SPDX 3 JSON document with the correct model based on its context

Parameters
  • data: The decoded JSON data as a Python dict

:returns: A tuple that contains the model and the decoded SHACLObjectSet

Raises
  • LoadError: If the data is missing a context or if the context is not recognized
  • TypeError: If the data is not a dictionary