CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-packageurl-python

A purl aka. Package URL parser and builder

Pending
Overview
Eval results
Files

core-operations.mddocs/

Core PURL Operations

Essential PackageURL parsing, construction, and manipulation functionality. The core operations provide the fundamental capabilities for working with Package URLs including parsing strings, creating objects, and normalizing components.

Capabilities

PackageURL Class

The main class for representing Package URLs with full parsing, validation, and serialization capabilities.

class PackageURL:
    """
    A Package URL object representing a standardized package identifier.
    
    Attributes:
        type (str): Package type (e.g., 'maven', 'npm', 'pypi')
        namespace (str | None): Package namespace/group  
        name (str): Package name
        version (str | None): Package version
        qualifiers (dict[str, str]): Additional qualifiers as key-value pairs
        subpath (str | None): Subpath within package
    """
    
    def __init__(
        self,
        type: str | bytes | None = None,
        namespace: str | bytes | None = None, 
        name: str | bytes | None = None,
        version: str | bytes | None = None,
        qualifiers: str | bytes | dict[str, str] | None = None,
        subpath: str | bytes | None = None
    ):
        """
        Create a PackageURL object with normalized components.
        
        Args:
            type: Package type (required)
            namespace: Package namespace (optional)
            name: Package name (required)
            version: Package version (optional)
            qualifiers: Qualifiers as dict or string (optional)
            subpath: Subpath within package (optional)
            
        Raises:
            ValueError: If required fields (type, name) are missing or invalid
        """
    
    @classmethod
    def from_string(cls, purl: str) -> 'PackageURL':
        """
        Parse a PackageURL from a string.
        
        Args:
            purl: PURL string to parse
            
        Returns:
            PackageURL object
            
        Raises:
            ValueError: If purl string is invalid or malformed
        """
    
    def to_string(self, encode: bool = True) -> str:
        """
        Convert PackageURL to string representation.
        
        Args:
            encode: Whether to percent-encode components (default: True)
            
        Returns:
            PURL string representation
        """
    
    def to_dict(self, encode: bool = False, empty: any = None) -> dict[str, any]:
        """
        Convert PackageURL to dictionary representation.
        
        Args:
            encode: Whether to encode qualifiers as string (default: False)
            empty: Value to use for empty/None fields (default: None)
            
        Returns:
            Dictionary with PURL components
        """
    
    def __str__(self) -> str:
        """String representation (same as to_string())."""
    
    def __hash__(self) -> int:
        """Hash based on string representation."""
    
    def _asdict(self) -> dict[str, any]:
        """
        Return PackageURL fields as an ordered dictionary.
        
        Returns:
            Ordered dictionary of field names to values
        """
    
    SCHEME: str = "pkg"  # PURL scheme constant

Normalization Functions

Component-wise normalization and validation functions for PackageURL components.

def normalize(
    type: str | bytes | None,
    namespace: str | bytes | None,
    name: str | bytes | None, 
    version: str | bytes | None,
    qualifiers: str | bytes | dict[str, str] | None,
    subpath: str | bytes | None,
    encode: bool = True
) -> tuple[str | None, str | None, str | None, str | None, str | dict[str, str] | None, str | None]:
    """
    Normalize all PackageURL components.
    
    Args:
        type: Package type to normalize
        namespace: Namespace to normalize
        name: Name to normalize
        version: Version to normalize
        qualifiers: Qualifiers to normalize
        subpath: Subpath to normalize
        encode: Whether to encode components (default: True)
        
    Returns:
        Tuple of normalized components
    """

def normalize_type(type: str | bytes | None, encode: bool = True) -> str | None:
    """
    Normalize package type.
    
    Args:
        type: Package type to normalize
        encode: Whether to percent-encode (default: True)
        
    Returns:
        Normalized type string (lowercase, stripped)
    """

def normalize_namespace(
    namespace: str | bytes | None, 
    ptype: str | None, 
    encode: bool = True
) -> str | None:
    """
    Normalize package namespace.
    
    Args:
        namespace: Namespace to normalize
        ptype: Package type (affects normalization rules)
        encode: Whether to percent-encode (default: True)
        
    Returns:
        Normalized namespace string
    """

def normalize_name(
    name: str | bytes | None,
    ptype: str | None,
    encode: bool = True  
) -> str | None:
    """
    Normalize package name.
    
    Args:
        name: Package name to normalize
        ptype: Package type (affects normalization rules)
        encode: Whether to percent-encode (default: True)
        
    Returns:
        Normalized name string
    """

def normalize_version(version: str | bytes | None, encode: bool = True) -> str | None:
    """
    Normalize package version.
    
    Args:
        version: Version to normalize
        encode: Whether to percent-encode (default: True)
        
    Returns:
        Normalized version string
    """

def normalize_qualifiers(
    qualifiers: str | bytes | dict[str, str] | None,
    encode: bool = True
) -> str | dict[str, str] | None:
    """
    Normalize qualifiers.
    
    Args:
        qualifiers: Qualifiers as string or dict
        encode: Whether to encode as string (True) or return dict (False)
        
    Returns:
        Normalized qualifiers as string or dict
        
    Raises:
        ValueError: If qualifiers format is invalid
    """

def normalize_subpath(subpath: str | bytes | None, encode: bool = True) -> str | None:
    """
    Normalize subpath.
    
    Args:
        subpath: Subpath to normalize
        encode: Whether to percent-encode (default: True)
        
    Returns:
        Normalized subpath string
    """

Utility Functions

Low-level utility functions for encoding and decoding.

def quote(s: str | bytes) -> str:
    """
    Percent-encode string except for colons.
    
    Args:
        s: String or bytes to encode
        
    Returns:
        Percent-encoded string
    """

def unquote(s: str | bytes) -> str:
    """
    Percent-decode string.
    
    Args:
        s: String or bytes to decode
        
    Returns:
        Percent-decoded string
    """

def get_quoter(encode: bool | None = True) -> callable:
    """
    Get appropriate encoding/decoding function.
    
    Args:
        encode: True for quote, False for unquote, None for identity
        
    Returns:
        Encoding/decoding function
    """

Usage Examples

Creating PackageURLs

from packageurl import PackageURL

# Create from components
purl = PackageURL(
    type="maven",
    namespace="org.apache.commons",
    name="io", 
    version="1.3.4"
)

# Create with qualifiers
purl = PackageURL(
    type="npm",
    name="lodash",
    version="4.17.21",
    qualifiers={"arch": "x64", "os": "linux"}
)

Parsing PURLs

# Parse various PURL formats
maven_purl = PackageURL.from_string("pkg:maven/org.springframework/spring-core@5.3.21")
npm_purl = PackageURL.from_string("pkg:npm/%40angular/core@12.0.0")
pypi_purl = PackageURL.from_string("pkg:pypi/django@3.2.0?extra=security")

# Access components
print(maven_purl.type)       # "maven"
print(maven_purl.namespace)  # "org.springframework"
print(maven_purl.name)       # "spring-core"
print(maven_purl.version)    # "5.3.21"

Normalization

from packageurl import normalize, normalize_qualifiers

# Normalize all components
type_n, ns_n, name_n, ver_n, qual_n, sub_n = normalize(
    "MAVEN", 
    "Org.Apache.Commons",
    "IO",
    "1.3.4",
    "classifier=sources&type=jar",
    "src/main"
)

# Normalize qualifiers specifically
qualifiers_dict = normalize_qualifiers("key1=value1&key2=value2", encode=False)
qualifiers_str = normalize_qualifiers({"key1": "value1", "key2": "value2"}, encode=True)

Install with Tessl CLI

npx tessl i tessl/pypi-packageurl-python

docs

core-operations.md

ecosystem-utilities.md

framework-integrations.md

index.md

url-conversion.md

tile.json