Python library to parse, validate and create SPDX documents
—
Comprehensive object model representing all SPDX specification elements including documents, packages, files, relationships, and metadata with full type safety and validation support.
Main SPDX document containing all elements and metadata.
class Document:
"""
Main SPDX document containing all elements.
Represents a complete SPDX document with creation info,
packages, files, snippets, licensing info, relationships, and annotations.
"""
creation_info: CreationInfo
packages: List[Package]
files: List[File]
snippets: List[Snippet]
extracted_licensing_infos: List[ExtractedLicensingInfo]
relationships: List[Relationship]
annotations: List[Annotation]
class CreationInfo:
"""
Document creation metadata.
Contains information about how, when, and by whom the SPDX document was created.
"""
spdx_version: str # SPDX specification version
spdx_id: str # Document SPDX identifier
name: str # Document name
document_namespace: str # Unique document namespace URI
creators: List[Actor] # Document creators
created: datetime # Creation timestamp
creator_comment: Optional[str] = None # Creator comments
data_license: str = "CC0-1.0" # Data license (default CC0-1.0)
external_document_refs: List[ExternalDocumentRef] = [] # References to external documents
license_list_version: Optional[Version] = None # SPDX license list version
document_comment: Optional[str] = None # General document commentsSoftware package representation with comprehensive metadata.
class Package:
"""
Software package information.
Represents a software package with metadata including licensing,
verification, download location, and relationships.
"""
spdx_id: str # Package SPDX identifier
name: str # Package name
download_location: str # Download location URI or NOASSERTION/NONE
files_analyzed: bool # Whether files were analyzed
verification_code: Optional[PackageVerificationCode] = None # Package verification code
checksums: List[Checksum] = [] # Package checksums
homepage: Optional[str] = None # Package homepage URI
source_info: Optional[str] = None # Source information
license_concluded: Union[str, SpdxNoAssertion, SpdxNone] = None # Concluded license
license_info_from_files: List[str] = [] # Licenses found in files
license_declared: Union[str, SpdxNoAssertion, SpdxNone] = None # Declared license
license_comment: Optional[str] = None # License comments
copyright_text: Union[str, SpdxNoAssertion, SpdxNone] = None # Copyright text
summary: Optional[str] = None # Package summary
description: Optional[str] = None # Package description
comment: Optional[str] = None # General comments
external_package_refs: List[ExternalPackageRef] = [] # External package references
attribution_texts: List[str] = [] # Attribution texts
primary_package_purpose: Optional[PackagePurpose] = None # Primary purpose
built_date: Optional[datetime] = None # Build date
release_date: Optional[datetime] = None # Release date
valid_until_date: Optional[datetime] = None # Valid until date
version: Optional[str] = None # Package version
originator: Optional[Actor] = None # Package originator
supplier: Optional[Actor] = None # Package supplier
class PackageVerificationCode:
"""Package verification code for integrity checking."""
value: str # Verification code value
excluded_files: List[str] = [] # Files excluded from verification
class ExternalPackageRef:
"""Reference to external package information."""
category: ExternalPackageRefCategory # Reference category
package_ref_type: str # Reference type
locator: str # Package locator
comment: Optional[str] = None # Reference commentFile metadata and licensing information.
class File:
"""
File information and metadata.
Represents a file with checksums, licensing, copyright,
and other metadata information.
"""
name: str # File path/name
spdx_id: str # File SPDX identifier
checksums: List[Checksum] # File checksums
file_types: List[FileType] = [] # File types
license_concluded: Union[str, SpdxNoAssertion, SpdxNone] = None # Concluded license
license_info_in_file: List[str] = [] # Licenses found in file
license_comment: Optional[str] = None # License comments
copyright_text: Union[str, SpdxNoAssertion, SpdxNone] = None # Copyright text
comment: Optional[str] = None # General comments
notice: Optional[str] = None # Notice text
contributors: List[str] = [] # File contributors
attribution_texts: List[str] = [] # Attribution textsCode snippet information for partial file analysis.
class Snippet:
"""
Code snippet information.
Represents a portion of a file with its own licensing
and copyright information.
"""
spdx_id: str # Snippet SPDX identifier
file_spdx_id: str # Parent file SPDX ID
ranges: List[Range] # Snippet byte/line ranges
license_concluded: Union[str, SpdxNoAssertion, SpdxNone] = None # Concluded license
license_info_in_snippets: List[str] = [] # Licenses found in snippet
license_comment: Optional[str] = None # License comments
copyright_text: Union[str, SpdxNoAssertion, SpdxNone] = None # Copyright text
comment: Optional[str] = None # General comments
name: Optional[str] = None # Snippet name
attribution_texts: List[str] = [] # Attribution textsRelationships between SPDX elements.
class Relationship:
"""
Relationship between SPDX elements.
Defines semantic relationships between packages, files,
and other SPDX elements.
"""
spdx_element_id: str # Source element SPDX ID
relationship_type: RelationshipType # Type of relationship
related_spdx_element: Optional[str] # Target element SPDX ID
comment: Optional[str] = None # Relationship commentExtracted and declared licensing information.
class ExtractedLicensingInfo:
"""
License information extracted from files.
Represents license text found in files that is not
in the SPDX license list.
"""
license_id: str # License identifier
extracted_text: str # License text
license_name: Optional[str] = None # License name
cross_references: List[str] = [] # Cross references
license_comment: Optional[str] = None # License commentsComments and annotations on SPDX elements.
class Annotation:
"""
Annotation on SPDX elements.
Represents comments, reviews, or other annotations
on SPDX elements.
"""
spdx_id: str # Annotated element SPDX ID
annotation_type: AnnotationType # Annotation type
annotator: Actor # Who made the annotation
annotation_date: datetime # Annotation timestamp
annotation_comment: str # Annotation textActor information and other supporting data types.
class Actor:
"""
Actor (person, organization, or tool) information.
Represents an entity that can create SPDX documents
or be involved in package/file creation.
"""
actor_type: ActorType # Type of actor
name: str # Actor name
email: Optional[str] = None # Actor email
class Checksum:
"""
Cryptographic checksum information.
Represents file or package integrity checksums
using various algorithms.
"""
algorithm: ChecksumAlgorithm # Checksum algorithm
value: str # Checksum value
class ExternalDocumentRef:
"""
Reference to external SPDX document.
Represents a reference to another SPDX document
with verification checksum.
"""
document_ref_id: str # Reference identifier
document_uri: str # Document URI
checksum: Checksum # Document checksum
class Version:
"""
Version information for SPDX specifications.
Represents version numbers in semantic versioning format.
"""
major: int # Major version
minor: int # Minor version
micro: int # Micro version
class SpdxNoAssertion:
"""Represents 'no assertion' value in SPDX."""
pass
class SpdxNone:
"""Represents 'none' value in SPDX."""
passclass ActorType(Enum):
"""Types of actors/creators."""
PERSON = "Person"
ORGANIZATION = "Organization"
TOOL = "Tool"
class AnnotationType(Enum):
"""Types of annotations."""
REVIEW = "REVIEW"
OTHER = "OTHER"
class ChecksumAlgorithm(Enum):
"""Supported checksum algorithms."""
SHA1 = "SHA1"
SHA224 = "SHA224"
SHA256 = "SHA256"
SHA384 = "SHA384"
SHA512 = "SHA512"
MD2 = "MD2"
MD4 = "MD4"
MD5 = "MD5"
MD6 = "MD6"
SHA3_256 = "SHA3-256"
SHA3_384 = "SHA3-384"
SHA3_512 = "SHA3-512"
BLAKE2B_256 = "BLAKE2b-256"
BLAKE2B_384 = "BLAKE2b-384"
BLAKE2B_512 = "BLAKE2b-512"
BLAKE3 = "BLAKE3"
ADLER32 = "ADLER32"
class FileType(Enum):
"""Types of files."""
SOURCE = "SOURCE"
BINARY = "BINARY"
ARCHIVE = "ARCHIVE"
APPLICATION = "APPLICATION"
AUDIO = "AUDIO"
IMAGE = "IMAGE"
TEXT = "TEXT"
VIDEO = "VIDEO"
DOCUMENTATION = "DOCUMENTATION"
SPDX = "SPDX"
OTHER = "OTHER"
class PackagePurpose(Enum):
"""Primary purposes of packages."""
APPLICATION = "APPLICATION"
FRAMEWORK = "FRAMEWORK"
LIBRARY = "LIBRARY"
CONTAINER = "CONTAINER"
OPERATING_SYSTEM = "OPERATING-SYSTEM"
DEVICE = "DEVICE"
FIRMWARE = "FIRMWARE"
SOURCE = "SOURCE"
ARCHIVE = "ARCHIVE"
FILE = "FILE"
INSTALL = "INSTALL"
OTHER = "OTHER"
class ExternalPackageRefCategory(Enum):
"""Categories of external package references."""
SECURITY = "SECURITY"
PACKAGE_MANAGER = "PACKAGE-MANAGER"
PERSISTENT_ID = "PERSISTENT-ID"
OTHER = "OTHER"class RelationshipType(Enum):
"""Types of relationships between SPDX elements."""
# Core relationships
DESCRIBES = "DESCRIBES"
DESCRIBED_BY = "DESCRIBED_BY"
CONTAINS = "CONTAINS"
CONTAINED_BY = "CONTAINED_BY"
# Dependency relationships
DEPENDS_ON = "DEPENDS_ON"
DEPENDENCY_OF = "DEPENDENCY_OF"
BUILD_DEPENDENCY_OF = "BUILD_DEPENDENCY_OF"
DEV_DEPENDENCY_OF = "DEV_DEPENDENCY_OF"
OPTIONAL_DEPENDENCY_OF = "OPTIONAL_DEPENDENCY_OF"
PROVIDED_DEPENDENCY_OF = "PROVIDED_DEPENDENCY_OF"
TEST_DEPENDENCY_OF = "TEST_DEPENDENCY_OF"
RUNTIME_DEPENDENCY_OF = "RUNTIME_DEPENDENCY_OF"
# Generation relationships
EXAMPLE_OF = "EXAMPLE_OF"
GENERATES = "GENERATES"
GENERATED_FROM = "GENERATED_FROM"
# Hierarchical relationships
ANCESTOR_OF = "ANCESTOR_OF"
DESCENDANT_OF = "DESCENDANT_OF"
VARIANT_OF = "VARIANT_OF"
# Distribution relationships
DISTRIBUTION_ARTIFACT = "DISTRIBUTION_ARTIFACT"
PATCH_FOR = "PATCH_FOR"
PATCH_APPLIED = "PATCH_APPLIED"
COPY_OF = "COPY_OF"
# File relationships
FILE_ADDED = "FILE_ADDED"
FILE_DELETED = "FILE_DELETED"
FILE_MODIFIED = "FILE_MODIFIED"
EXPANDED_FROM_ARCHIVE = "EXPANDED_FROM_ARCHIVE"
# Linking relationships
DYNAMIC_LINK = "DYNAMIC_LINK"
STATIC_LINK = "STATIC_LINK"
# Metadata relationships
DATA_FILE_OF = "DATA_FILE_OF"
TEST_CASE_OF = "TEST_CASE_OF"
BUILD_TOOL_OF = "BUILD_TOOL_OF"
DEV_TOOL_OF = "DEV_TOOL_OF"
TEST_OF = "TEST_OF"
TEST_TOOL_OF = "TEST_TOOL_OF"
METAFILE_OF = "METAFILE_OF"
PACKAGE_OF = "PACKAGE_OF"
# Amendment relationships
AMENDS = "AMENDS"
PREREQUISITE_FOR = "PREREQUISITE_FOR"
HAS_PREREQUISITE = "HAS_PREREQUISITE"
REQUIREMENT_DESCRIPTION_FOR = "REQUIREMENT_DESCRIPTION_FOR"
SPECIFICATION_FOR = "SPECIFICATION_FOR"
# Generic
OTHER = "OTHER"from datetime import datetime
from spdx_tools.spdx.model import (
Document, CreationInfo, Package, File, Relationship, Actor, ActorType,
ChecksumAlgorithm, Checksum, RelationshipType
)
# Create document creation info
creation_info = CreationInfo(
spdx_version="SPDX-2.3",
spdx_id="SPDXRef-DOCUMENT",
name="Example Document",
document_namespace="https://example.com/spdx/example-doc",
creators=[Actor(ActorType.TOOL, name="spdx-tools")],
created=datetime.now()
)
# Create a package
package = Package(
spdx_id="SPDXRef-Package",
name="example-package",
download_location="https://github.com/example/package",
files_analyzed=True,
checksums=[Checksum(ChecksumAlgorithm.SHA256, "abc123...")]
)
# Create a file
file = File(
spdx_id="SPDXRef-File",
name="./src/main.py",
checksums=[Checksum(ChecksumAlgorithm.SHA1, "def456...")]
)
# Create relationship
relationship = Relationship(
spdx_element_id="SPDXRef-Package",
relationship_type=RelationshipType.CONTAINS,
related_spdx_element="SPDXRef-File"
)
# Create complete document
document = Document(
creation_info=creation_info,
packages=[package],
files=[file],
relationships=[relationship],
snippets=[],
extracted_licensing_infos=[],
annotations=[]
)# Access document information
print(f"Document: {document.creation_info.name}")
print(f"Namespace: {document.creation_info.document_namespace}")
print(f"Created: {document.creation_info.created}")
# Iterate through packages
for package in document.packages:
print(f"Package: {package.name} ({package.spdx_id})")
print(f" Download: {package.download_location}")
if package.checksums:
for checksum in package.checksums:
print(f" Checksum: {checksum.algorithm.value} = {checksum.value}")
# Find relationships
for rel in document.relationships:
print(f"Relationship: {rel.spdx_element_id} {rel.relationship_type.value} {rel.related_spdx_element}")from spdx_tools.spdx.validation.document_validator import validate_full_spdx_document
# Models are validated when used with validation functions
validation_messages = validate_full_spdx_document(document)
if validation_messages:
print("Model validation errors:")
for msg in validation_messages:
print(f" - {msg.validation_message}")Install with Tessl CLI
npx tessl i tessl/pypi-spdx-tools