CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-spdx-tools

Python library to parse, validate and create SPDX documents

Pending
Overview
Eval results
Files

cli.mddocs/

Command Line Tools

CLI tools for parsing, validating, converting, and analyzing SPDX documents with support for all major formats and comprehensive error reporting.

Capabilities

Main CLI Tool (pyspdxtools)

Primary command-line interface for SPDX document operations including validation, conversion, and relationship graph generation.

def main(infile: str, outfile: str, version: str, novalidation: bool, graph: bool):
    """
    CLI entry point for pyspdxtools command.
    
    Provides comprehensive SPDX document processing including:
    - Parsing documents in any supported format
    - Validating against SPDX specifications
    - Converting between formats
    - Generating relationship graphs
    
    Args:
        infile: Input SPDX file path (required)
        outfile: Output file path (optional, "-" for stdout)
        version: SPDX version to validate against ("SPDX-2.2" or "SPDX-2.3")
        novalidation: Skip validation if True
        graph: Generate relationship graph if True (requires networkx, pygraphviz)
    
    Exit Codes:
        0: Success
        1: Validation or processing error
    """

SPDX 3.0 CLI Tool (pyspdxtools3)

Experimental command-line interface for SPDX 3.0 document operations.

def main() -> None:
    """
    CLI entry point for pyspdxtools3 command.
    
    Experimental CLI for SPDX 3.0 document processing.
    Functionality and API subject to change.
    """

Graph Generation

Generate visual relationship graphs from SPDX documents.

def export_graph_from_document(document: Document, output_file: str) -> None:
    """
    Generate relationship graph visualization from SPDX document.
    
    Creates graphical representation of SPDX relationships showing
    connections between packages, files, and other elements.
    
    Args:
        document: SPDX document to visualize
        output_file: Output file path for graph image
        
    Raises:
        ImportError: If networkx or pygraphviz not installed
        
    Note:
        Requires optional dependencies: pip install "spdx-tools[graph_generation]"
    """

Usage Examples

Basic Command Line Usage

# Validate SPDX document
pyspdxtools --infile document.spdx

# Convert between formats
pyspdxtools --infile document.spdx --outfile document.json

# Skip validation for faster conversion
pyspdxtools --infile document.spdx --outfile document.json --novalidation

# Validate against specific SPDX version
pyspdxtools --infile document.spdx --version SPDX-2.3

# Output to stdout (Tag-Value format)
pyspdxtools --infile document.json --outfile -

# Generate relationship graph
pyspdxtools --infile document.spdx --outfile relationships.png --graph

Programmatic CLI Usage

import sys
from spdx_tools.spdx.clitools.pyspdxtools import main

# Simulate command line arguments
sys.argv = [
    "pyspdxtools",
    "--infile", "input.spdx",
    "--outfile", "output.json",
    "--version", "SPDX-2.3"
]

try:
    main()
    print("CLI operation completed successfully")
except SystemExit as e:
    if e.code == 0:
        print("Success")
    else:
        print(f"Failed with exit code: {e.code}")

Batch Processing Script

import os
import subprocess
import sys
from pathlib import Path

def process_spdx_files(input_dir: str, output_dir: str, target_format: str):
    """Process all SPDX files in directory using CLI tool."""
    input_path = Path(input_dir)
    output_path = Path(output_dir)
    output_path.mkdir(exist_ok=True)
    
    # Find all SPDX files
    spdx_files = []
    for ext in [".spdx", ".json", ".yaml", ".xml", ".rdf"]:
        spdx_files.extend(input_path.glob(f"*{ext}"))
    
    for input_file in spdx_files:
        output_file = output_path / f"{input_file.stem}.{target_format}"
        
        # Run pyspdxtools via subprocess
        cmd = [
            "pyspdxtools",
            "--infile", str(input_file),
            "--outfile", str(output_file)
        ]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True)
            if result.returncode == 0:
                print(f"✅ Converted {input_file.name} -> {output_file.name}")
            else:
                print(f"❌ Failed to convert {input_file.name}")
                print(f"   Error: {result.stderr}")
        except Exception as e:
            print(f"❌ Error processing {input_file.name}: {e}")

# Usage
process_spdx_files("input_documents/", "output_documents/", "json")

Validation Pipeline

import subprocess
import json
from pathlib import Path

def validate_spdx_collection(directory: str) -> dict:
    """Validate all SPDX files in directory and return results."""
    results = {
        "total_files": 0,
        "valid_files": 0,
        "invalid_files": 0,
        "errors": []
    }
    
    spdx_files = []
    for ext in [".spdx", ".json", ".yaml", ".xml", ".rdf"]:
        spdx_files.extend(Path(directory).glob(f"*{ext}"))
    
    results["total_files"] = len(spdx_files)
    
    for spdx_file in spdx_files:
        cmd = ["pyspdxtools", "--infile", str(spdx_file)]
        
        try:
            result = subprocess.run(cmd, capture_output=True, text=True)
            if result.returncode == 0:
                results["valid_files"] += 1
                print(f"✅ {spdx_file.name} is valid")
            else:
                results["invalid_files"] += 1
                results["errors"].append({
                    "file": spdx_file.name,
                    "error": result.stderr.strip()
                })
                print(f"❌ {spdx_file.name} is invalid")
        except Exception as e:
            results["invalid_files"] += 1
            results["errors"].append({
                "file": spdx_file.name,
                "error": str(e)
            })
            print(f"❌ Error validating {spdx_file.name}: {e}")
    
    return results

# Generate validation report
results = validate_spdx_collection("spdx_documents/")
print(f"\nValidation Summary:")
print(f"Total files: {results['total_files']}")
print(f"Valid files: {results['valid_files']}")
print(f"Invalid files: {results['invalid_files']}")

# Save detailed report
with open("validation_report.json", "w") as f:
    json.dump(results, f, indent=2)

Graph Generation Examples

# Generate relationship graph
pyspdxtools --infile complex_project.spdx --outfile project_graph.png --graph

# Generate graph with specific format conversion
pyspdxtools --infile document.json --outfile graph.svg --graph

CI/CD Integration

# GitHub Actions example
name: SPDX Validation
on: [push, pull_request]

jobs:
  validate-spdx:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v3
        with:
          python-version: '3.9'
      - name: Install spdx-tools
        run: pip install spdx-tools
      - name: Validate SPDX documents
        run: |
          for file in *.spdx *.json; do
            if [ -f "$file" ]; then
              echo "Validating $file..."
              pyspdxtools --infile "$file" || exit 1
            fi
          done
      - name: Convert to JSON for artifacts
        run: |
          for file in *.spdx; do
            if [ -f "$file" ]; then
              pyspdxtools --infile "$file" --outfile "${file%.*}.json"
            fi
          done

Docker Usage

FROM python:3.9-slim

RUN pip install spdx-tools[graph_generation]

# Copy SPDX documents
COPY *.spdx /app/
WORKDIR /app

# Validate and convert documents
RUN for file in *.spdx; do \
        pyspdxtools --infile "$file" --outfile "${file%.*}.json"; \
    done

# Generate graphs
RUN for file in *.spdx; do \
        pyspdxtools --infile "$file" --outfile "${file%.*}_graph.png" --graph; \
    done

Error Handling Patterns

import subprocess
import logging

def safe_spdx_operation(input_file: str, output_file: str = None, 
                       validate: bool = True, graph: bool = False) -> bool:
    """Safely perform SPDX operations with comprehensive error handling."""
    
    cmd = ["pyspdxtools", "--infile", input_file]
    
    if output_file:
        cmd.extend(["--outfile", output_file])
    
    if not validate:
        cmd.append("--novalidation")
        
    if graph:
        cmd.append("--graph")
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
        
        if result.returncode == 0:
            logging.info(f"Successfully processed {input_file}")
            if result.stdout:
                logging.info(f"Output: {result.stdout}")
            return True
        else:
            logging.error(f"Failed to process {input_file}")
            logging.error(f"Error output: {result.stderr}")
            return False
            
    except subprocess.TimeoutExpired:
        logging.error(f"Timeout processing {input_file}")
        return False
    except FileNotFoundError:
        logging.error("pyspdxtools command not found. Is spdx-tools installed?")
        return False
    except Exception as e:
        logging.error(f"Unexpected error processing {input_file}: {e}")
        return False

# Usage
success = safe_spdx_operation("document.spdx", "document.json")
if success:
    print("Operation completed successfully")
else:
    print("Operation failed")

Types

from typing import Optional

# CLI functions work with file paths and configuration options
# Return values are typically None (success) or sys.exit() calls

Install with Tessl CLI

npx tessl i tessl/pypi-spdx-tools

docs

cli.md

index.md

models.md

parsing.md

spdx3.md

validation.md

writing.md

tile.json