CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-xmp-toolkit

Python library for working with XMP (Extensible Metadata Platform) metadata in files.

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities and Constants

Utility functions for extracting XMP data to Python dictionaries, comprehensive XMP constants for namespaces and options, and library management functions.

Capabilities

Utility Functions

Data Extraction

def object_to_dict(xmp):
    """
    Extract all XMP data from XMPMeta object into standard Python dictionary.
    
    Parameters:
    - xmp: XMPMeta instance
    
    Returns:
    dict: Standard Python dictionary with XMP data organized by namespace
    """

def file_to_dict(file_path):
    """
    Extract XMP data from file into dictionary.
    
    Parameters:
    - file_path: str, path to file
    
    Returns:
    dict: Dictionary with XMP data (empty if no valid XMP found)
    
    Raises:
    IOError: if file doesn't exist
    """

Library Management

def terminate():
    """
    Terminate library usage for memory cleanup.
    
    Warning: Calling this crashes Python if libxmp methods are used afterward.
    Only call when completely done with XMP operations.
    """

XMP Constants

Standard Namespaces

# Core XMP namespaces
XMP_NS_XMP = "http://ns.adobe.com/xap/1.0/"
XMP_NS_XMP_Rights = "http://ns.adobe.com/xap/1.0/rights/"
XMP_NS_XMP_MM = "http://ns.adobe.com/xap/1.0/mm/"
XMP_NS_XMP_BJ = "http://ns.adobe.com/xap/1.0/bj/"

# Dublin Core
XMP_NS_DC = "http://purl.org/dc/elements/1.1/"

# IPTC Core
XMP_NS_IPTCCore = "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"

# Adobe application namespaces  
XMP_NS_Photoshop = "http://ns.adobe.com/photoshop/1.0/"
XMP_NS_CameraRaw = "http://ns.adobe.com/camera-raw-settings/1.0/"
XMP_NS_CameraRawSavedSettings = "http://ns.adobe.com/camera-raw-saved-settings/1.0/"

# Document formats
XMP_NS_PDF = "http://ns.adobe.com/pdf/1.3/"
XMP_NS_PDFX = "http://ns.adobe.com/pdfx/1.3/"

# Technical namespaces
XMP_NS_TIFF = "http://ns.adobe.com/tiff/1.0/"
XMP_NS_EXIF = "http://ns.adobe.com/exif/1.0/"
XMP_NS_EXIF_Aux = "http://ns.adobe.com/exif/1.0/aux/"

# Image formats
XMP_NS_PNG = "http://ns.adobe.com/png/1.0/"
XMP_NS_JPEG = "http://ns.adobe.com/jpeg/1.0/"
XMP_NS_JP2K = "http://ns.adobe.com/jp2k/1.0/"
XMP_NS_SWF = "http://ns.adobe.com/swf/1.0/"

# Media formats
XMP_NS_DM = "http://ns.adobe.com/xmp/1.0/DynamicMedia/"
XMP_NS_ASF = "http://ns.adobe.com/asf/1.0/"
XMP_NS_WAV = "http://ns.adobe.com/xmp/wav/1.0/"

# Adobe applications
XMP_NS_PSAlbum = "http://ns.adobe.com/album/1.0/"
XMP_NS_Lightroom = "http://ns.adobe.com/lightroom/1.0/"
XMP_NS_AdobeStockPhoto = "http://ns.adobe.com/StockPhoto/1.0/"
XMP_NS_CreatorAtom = "http://ns.adobe.com/creatorAtom/1.0/"

# XMP structure types
XMP_NS_XMP_Note = "http://ns.adobe.com/xmp/note/"
XMP_NS_XMP_IdentifierQual = "http://ns.adobe.com/xmp/Identifier/qual/1.0/"
XMP_NS_XMP_Dimensions = "http://ns.adobe.com/xap/1.0/sType/Dimensions#"
XMP_NS_XMP_Text = "http://ns.adobe.com/xap/1.0/t/"
XMP_NS_XMP_PagedFile = "http://ns.adobe.com/xap/1.0/t/pg/"
XMP_NS_XMP_Graphics = "http://ns.adobe.com/xap/1.0/g/"
XMP_NS_XMP_Image = "http://ns.adobe.com/xap/1.0/g/img/"
XMP_NS_XMP_Font = "http://ns.adobe.com/xap/1.0/sType/Font#"
XMP_NS_XMP_ResourceEvent = "http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
XMP_NS_XMP_ResourceRef = "http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
XMP_NS_XMP_ST_Version = "http://ns.adobe.com/xap/1.0/sType/Version#"
XMP_NS_XMP_ST_Job = "http://ns.adobe.com/xap/1.0/sType/Job#"
XMP_NS_XMP_ManifestItem = "http://ns.adobe.com/xap/1.0/sType/ManifestItem#"

# Standards and schemas
XMP_NS_DICOM = "http://ns.adobe.com/DICOM/"
XMP_NS_PDFA_Schema = "http://www.aiim.org/pdfa/ns/schema#"
XMP_NS_PDFA_Property = "http://www.aiim.org/pdfa/ns/property#"
XMP_NS_PDFA_Type = "http://www.aiim.org/pdfa/ns/type#"
XMP_NS_PDFA_Field = "http://www.aiim.org/pdfa/ns/field#"
XMP_NS_PDFA_ID = "http://www.aiim.org/pdfa/ns/id/"
XMP_NS_PDFA_Extension = "http://www.aiim.org/pdfa/ns/extension/"
XMP_NS_PDFX_ID = "http://www.npes.org/pdfx/ns/id/"
XMP_NS_CC = "http://creativecommons.org/ns#"
XMP_NS_AVM = "http://www.communicatingastronomy.org/avm/1.0/"

# XML and RDF
XMP_NS_XML = "http://www.w3.org/XML/1998/namespace"
XMP_NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
XMP_NS_XMPMeta = "adobe:ns:meta/"

File Format Constants

# Document formats
XMP_FT_PDF = 0x50444620      # 'PDF '
XMP_FT_PS = 0x50532020       # 'PS  ' PostScript
XMP_FT_EPS = 0x45505320      # 'EPS ' Encapsulated PostScript

# Image formats
XMP_FT_JPEG = 0x4A504547     # 'JPEG'
XMP_FT_JPEG2K = 0x4A505820   # 'JPX ' ISO 15444-1
XMP_FT_TIFF = 0x54494646     # 'TIFF'
XMP_FT_GIF = 0x47494620      # 'GIF '
XMP_FT_PNG = 0x504E4720      # 'PNG '

# Media formats
XMP_FT_SWF = 0x53574620      # 'SWF '
XMP_FT_FLA = 0x464C4120      # 'FLA '
XMP_FT_FLV = 0x464C5620      # 'FLV '
XMP_FT_MOV = 0x4D4F5620      # 'MOV ' Quicktime
XMP_FT_AVI = 0x41564920      # 'AVI '
XMP_FT_MPEG = 0x4D504547     # 'MPEG'
XMP_FT_MPEG2 = 0x4D503220    # 'MP2 '
XMP_FT_MPEG4 = 0x4D503420    # 'MP4 ' ISO 14494-12 and -14

# Audio formats
XMP_FT_WAV = 0x57415620      # 'WAV '
XMP_FT_MP3 = 0x4D503320      # 'MP3 '
XMP_FT_AIFF = 0x41494646     # 'AIFF'
XMP_FT_WMAV = 0x574D4156     # 'WMAV' Windows Media Audio and Video

# Adobe applications
XMP_FT_PHOTOSHOP = 0x50534420        # 'PSD '
XMP_FT_ILLUSTRATOR = 0x41492020      # 'AI  '
XMP_FT_INDESIGN = 0x494E4444         # 'INDD'
XMP_FT_AEPROJECT = 0x41455020        # 'AEP ' After Effects Project
XMP_FT_AEPROJTEMPLATE = 0x41455420   # 'AET ' After Effects Project Template
XMP_FT_AEFILTERPRESET = 0x46465820   # 'FFX ' After Effects Filter Preset
XMP_FT_ENCOREPROJECT = 0x4E434F52    # 'NCOR'
XMP_FT_PREMIEREPROJECT = 0x5052504A  # 'PRPJ'
XMP_FT_PREMIERETITLE = 0x5052544C    # 'PRTL'

# Other formats
XMP_FT_CIN = 0x43494E20      # 'CIN ' Cineon
XMP_FT_SES = 0x53455320      # 'SES ' Audition session
XMP_FT_CEL = 0x43454C20      # 'CEL ' Audition loop
XMP_FT_HTML = 0x48544D4C     # 'HTML'
XMP_FT_XML = 0x584D4C20      # 'XML '
XMP_FT_TEXT = 0x74657874     # 'text'
XMP_FT_UNKNOWN = 0x20202020  # Default/unknown

Property Options

# Property type flags
XMP_PROP_VALUE_IS_URI = 0x00000002
XMP_PROP_HAS_QUALIFIERS = 0x00000010
XMP_PROP_IS_QUALIFIER = 0x00000020
XMP_PROP_HAS_LANG = 0x00000040
XMP_PROP_HAS_TYPE = 0x00000080
XMP_PROP_VALUE_IS_STRUCT = 0x00000100
XMP_PROP_VALUE_IS_ARRAY = 0x00000200
XMP_PROP_ARRAY_IS_UNORDERED = 0x00000000
XMP_PROP_ARRAY_IS_ORDERED = 0x00000400
XMP_PROP_ARRAY_IS_ALT = 0x00000800
XMP_PROP_ARRAY_IS_ALTTEXT = 0x00001000

Serialization Options

XMP_SERIAL_OMITPACKETWRAPPER = 0x0010    # Omit XMP packet wrapper
XMP_SERIAL_READONLYPACKET = 0x0020       # Mark packet as read-only
XMP_SERIAL_USECOMPACTFORMAT = 0x0040     # Use compact RDF formatting
XMP_SERIAL_INCLUDETHUMBNAILPAD = 0x0100  # Include padding for thumbnail
XMP_SERIAL_EXACTPACKETLENGTH = 0x0200    # Exact packet length
XMP_SERIAL_WRITEALIASCOMMENTS = 0x0400   # Write alias comments
XMP_SERIAL_OMITALLFORMATTING = 0x0800    # Omit all formatting

Iterator Options

XMP_ITER_PROPERTIES = 0x0000      # Iterate all properties
XMP_ITER_JUSTCHILDREN = 0x0100    # Just immediate children
XMP_ITER_JUSTLEAFNODES = 0x0200   # Just leaf nodes
XMP_ITER_JUSTLEAFNAME = 0x0400    # Just leaf names
XMP_ITER_INCLUDEALIASES = 0x0800  # Include alias properties
XMP_ITER_OMITQUALIFIERS = 0x1000  # Omit qualifier properties

File Operation Options

# File open options
XMP_OPEN_NOOPTION = 0x00000000        # No open option
XMP_OPEN_READ = 0x00000001            # Open for read-only access
XMP_OPEN_FORUPDATE = 0x00000002       # Open for reading and writing
XMP_OPEN_ONLYXMP = 0x00000004         # Only XMP wanted, allows optimizations
XMP_OPEN_CACHETNAIL = 0x00000008      # Cache thumbnail if possible
XMP_OPEN_STRICTLY = 0x00000010        # Be strict about locating XMP
XMP_OPEN_USESMARTHANDLER = 0x00000020  # Require smart handler use
XMP_OPEN_USEPACKETSCANNING = 0x00000040 # Force packet scanning
XMP_OPEN_LIMITSCANNING = 0x00000080    # Only scan files known to need it
XMP_OPEN_INBACKGROUND = 0x10000000     # Set if calling from background thread

# File close options
XMP_CLOSE_NOOPTION = 0x0000           # No close option
XMP_CLOSE_SAFEUPDATE = 0x0001         # Write to temp file and swap for safety

Option Utility Functions

def has_option(xmp_option, bitmask):
    """
    Check if option bit is set in bitmask.
    
    Parameters:
    - xmp_option: int, option value to check
    - bitmask: int, bitmask to check against
    
    Returns:
    bool: True if option bit is set
    """

def options_mask(xmp_options, **kwargs):
    """
    Convert option dictionary and keyword arguments to bitmask.
    
    Parameters:
    - xmp_options: dict, option name to constant mappings
    - **kwargs: keyword arguments with option names
    
    Returns:
    int: Combined bitmask for all specified options
    """

Option Dictionaries

# Serialization options mapping
XMP_SERIAL_OPTIONS = {
    'omit_packet_wrapper': XMP_SERIAL_OMITPACKETWRAPPER,
    'read_only_packet': XMP_SERIAL_READONLYPACKET,
    'use_compact_format': XMP_SERIAL_USECOMPACTFORMAT,
    'include_thumbnail_pad': XMP_SERIAL_INCLUDETHUMBNAILPAD,
    'exact_packet_length': XMP_SERIAL_EXACTPACKETLENGTH,
    'write_alias_comments': XMP_SERIAL_WRITEALIASCOMMENTS,
    'omit_all_formatting': XMP_SERIAL_OMITALLFORMATTING
}

# Property options mapping
XMP_PROP_OPTIONS = {
    'value_is_uri': XMP_PROP_VALUE_IS_URI,
    'has_qualifiers': XMP_PROP_HAS_QUALIFIERS,
    'is_qualifier': XMP_PROP_IS_QUALIFIER,
    'has_lang': XMP_PROP_HAS_LANG,
    'has_type': XMP_PROP_HAS_TYPE,
    'value_is_struct': XMP_PROP_VALUE_IS_STRUCT,
    'value_is_array': XMP_PROP_VALUE_IS_ARRAY,
    'array_is_ordered': XMP_PROP_ARRAY_IS_ORDERED,
    'array_is_alt': XMP_PROP_ARRAY_IS_ALT,
    'array_is_alttext': XMP_PROP_ARRAY_IS_ALTTEXT
}

# Open file options mapping
XMP_OPEN_OPTIONS = {
    'open_nooption': XMP_OPEN_NOOPTION,
    'open_read': XMP_OPEN_READ,
    'open_forupdate': XMP_OPEN_FORUPDATE,
    'open_onlyxmp': XMP_OPEN_ONLYXMP,
    'open_cachetnail': XMP_OPEN_CACHETNAIL,
    'open_strictly': XMP_OPEN_STRICTLY,
    'open_usesmarthandler': XMP_OPEN_USESMARTHANDLER,
    'open_usepacketscanning': XMP_OPEN_USEPACKETSCANNING,
    'open_limitscanning': XMP_OPEN_LIMITSCANNING,
    'open_inbackground': XMP_OPEN_INBACKGROUND
}

# Close file options mapping
XMP_CLOSE_OPTIONS = {
    'close_nooption': XMP_CLOSE_NOOPTION,
    'close_safeupdate': XMP_CLOSE_SAFEUPDATE
}

Usage Examples

Data Extraction to Dictionary

from libxmp import XMPMeta
from libxmp.utils import object_to_dict, file_to_dict

# Extract from XMPMeta object
xmp = XMPMeta()
xmp.set_property("http://ns.adobe.com/xap/1.0/", "CreatorTool", "Python")
xmp.set_property("http://purl.org/dc/elements/1.1/", "creator", "John Doe")

# Convert to dictionary
xmp_dict = object_to_dict(xmp)
print(xmp_dict)
# Output: {
#   'http://ns.adobe.com/xap/1.0/': {'CreatorTool': 'Python'},
#   'http://purl.org/dc/elements/1.1/': {'creator': 'John Doe'}
# }

# Extract directly from file
file_dict = file_to_dict("photo.jpg")
if file_dict:
    print("File contains XMP metadata:")
    for namespace, properties in file_dict.items():
        print(f"  {namespace}:")
        for prop, value in properties.items():
            print(f"    {prop}: {value}")
else:
    print("No XMP metadata found in file")

Working with Constants and Options

from libxmp import XMPMeta
from libxmp.consts import *

# Using namespace constants
xmp = XMPMeta()
xmp.set_property(XMP_NS_DC, "creator", "John Doe")
xmp.set_property(XMP_NS_XMP, "CreatorTool", "Python XMP Toolkit")
xmp.set_property(XMP_NS_Photoshop, "ColorMode", "RGB")

# Using serialization options with keyword arguments
xmp_str = xmp.serialize_to_str(
    use_compact_format=True,
    omit_packet_wrapper=True
)

# Using property options
xmp.set_property(
    XMP_NS_DC, 
    "rights", 
    "Copyright 2024", 
    value_is_uri=False
)

# Create ordered array
xmp.append_array_item(
    XMP_NS_DC, 
    "creator", 
    "First Author",
    array_is_ordered=True
)

Option Utility Functions

from libxmp.consts import has_option, options_mask, XMP_PROP_OPTIONS

# Check if specific option is set
prop_options = 0x00000210  # Some combined options
if has_option(prop_options, XMP_PROP_HAS_QUALIFIERS):
    print("Property has qualifiers")

if has_option(prop_options, XMP_PROP_VALUE_IS_STRUCT):
    print("Property is a structure")

# Create option mask from keywords
mask = options_mask(XMP_PROP_OPTIONS, 
                   value_is_struct=True, 
                   has_qualifiers=True)
print(f"Combined option mask: {mask}")

Standard Namespace Usage

from libxmp import XMPMeta
from libxmp.consts import *

def set_image_metadata(file_path, metadata):
    """Set comprehensive image metadata using standard namespaces."""
    from libxmp import XMPFiles
    
    xmpfile = XMPFiles(file_path=file_path)
    xmp = xmpfile.get_xmp() or XMPMeta()
    
    # Dublin Core metadata
    if 'title' in metadata:
        xmp.set_localized_text(XMP_NS_DC, "title", "x-default", "en-US", metadata['title'])
    if 'creator' in metadata:
        xmp.set_property(XMP_NS_DC, "creator", metadata['creator'])
    if 'description' in metadata:
        xmp.set_localized_text(XMP_NS_DC, "description", "x-default", "en-US", metadata['description'])
    if 'keywords' in metadata:
        for keyword in metadata['keywords']:
            xmp.append_array_item(XMP_NS_DC, "subject", keyword)
    
    # XMP Basic metadata
    if 'creator_tool' in metadata:
        xmp.set_property(XMP_NS_XMP, "CreatorTool", metadata['creator_tool'])
    if 'create_date' in metadata:
        xmp.set_property_datetime(XMP_NS_XMP, "CreateDate", metadata['create_date'])
    
    # Rights management
    if 'rights' in metadata:
        xmp.set_localized_text(XMP_NS_XMP_Rights, "UsageTerms", "x-default", "en-US", metadata['rights'])
    
    # Photoshop-specific metadata
    if 'color_mode' in metadata:
        xmp.set_property(XMP_NS_Photoshop, "ColorMode", str(metadata['color_mode']))
    
    # IPTC Core metadata
    if 'location' in metadata:
        xmp.set_property(XMP_NS_IPTCCore, "Location", metadata['location'])
    
    xmpfile.put_xmp(xmp)
    xmpfile.close_file()

# Usage
metadata = {
    'title': 'Sunset Over Mountains',
    'creator': 'Jane Photographer',
    'description': 'Beautiful sunset photograph taken in the mountains',
    'keywords': ['sunset', 'mountains', 'landscape', 'nature'],
    'creator_tool': 'Python XMP Toolkit',
    'rights': 'Copyright 2024 Jane Photographer. All rights reserved.',
    'color_mode': 3,  # RGB
    'location': 'Rocky Mountains, Colorado'
}

set_image_metadata("sunset.jpg", metadata)

Memory Management

from libxmp.utils import terminate
from libxmp import XMPMeta, XMPFiles

# Process many files
files = ["img1.jpg", "img2.jpg", "img3.jpg"]  # ... many files

for file_path in files:
    try:
        xmpfile = XMPFiles(file_path=file_path)
        xmp = xmpfile.get_xmp()
        # ... process XMP data
        xmpfile.close_file()
    except Exception as e:
        print(f"Error processing {file_path}: {e}")

# When completely done with all XMP operations
# (only call this at program end)
try:
    terminate()
    print("XMP library terminated successfully")
except:
    pass  # Ignore termination errors

Install with Tessl CLI

npx tessl i tessl/pypi-python-xmp-toolkit

docs

core-metadata.md

file-operations.md

index.md

utilities.md

tile.json