CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-sphinx-gallery

A Sphinx extension that builds an HTML gallery of examples from any set of Python scripts.

Overview
Eval results
Files

utilities.mddocs/

Utilities

Helper functions for image processing, file operations, and common tasks used throughout Sphinx-Gallery. These utilities provide core functionality for image manipulation, file handling, and system operations.

Capabilities

Image Processing

Function for scaling images while maintaining aspect ratio.

def scale_image(in_fname, out_fname, max_width, max_height):
    """
    Scales images while maintaining aspect ratio.
    
    Resizes an image to fit within the specified maximum dimensions
    while preserving the original aspect ratio. Uses high-quality
    resampling for optimal results.
    
    Parameters:
    - in_fname: str, input image filename
    - out_fname: str, output image filename
    - max_width: int, maximum width in pixels
    - max_height: int, maximum height in pixels
    
    Returns:
    None
    """

Usage Example

from sphinx_gallery.utils import scale_image

# Scale image to fit within 200x200 pixels
scale_image(
    'original_plot.png',
    'thumbnail_plot.png', 
    200, 
    200
)

# Create multiple sizes
scale_image('plot.png', 'plot_small.png', 150, 150)
scale_image('plot.png', 'plot_medium.png', 300, 300)
scale_image('plot.png', 'plot_large.png', 600, 600)

File Hash Operations

Functions for computing file hashes and checksums.

def md5sum_file(filename):
    """
    Calculate MD5 hash of a file.
    
    Computes the MD5 checksum of a file for content verification
    and change detection.
    
    Parameters:
    - filename: str, path to file
    
    Returns:
    str: MD5 hash as hexadecimal string
    """

def get_md5sum(src_file, mode='md5'):
    """
    Get file hash using specified algorithm.
    
    Parameters:
    - src_file: str, path to source file
    - mode: str, hash algorithm ('md5', 'sha1', 'sha256')
    
    Returns:
    str: File hash as hexadecimal string
    """

Usage Example

from sphinx_gallery.utils import md5sum_file, get_md5sum

# Check if file has changed
old_hash = md5sum_file('example.py')
# ... file potentially modified ...
new_hash = md5sum_file('example.py')

if old_hash != new_hash:
    print("File has been modified")

# Use different hash algorithms
md5_hash = get_md5sum('data.txt', 'md5')
sha256_hash = get_md5sum('data.txt', 'sha256')

File Path Operations

Functions for manipulating file paths and extensions.

def replace_py_ipynb(fname):
    """
    Replace .py extension with .ipynb.
    
    Converts Python script filename to Jupyter notebook filename.
    
    Parameters:
    - fname: str, filename with .py extension
    
    Returns:
    str: Filename with .ipynb extension
    """

Usage Example

from sphinx_gallery.utils import replace_py_ipynb

# Convert script name to notebook name
script_name = 'plot_example.py'
notebook_name = replace_py_ipynb(script_name)
# Result: 'plot_example.ipynb'

# Handle paths
script_path = '/examples/advanced/plot_demo.py'
notebook_path = replace_py_ipynb(script_path)
# Result: '/examples/advanced/plot_demo.ipynb'

String and Text Processing

Functions for processing text and string content.

def _complete_chunk(chunk_lines, lang):
    """
    Complete and validate code chunks.
    
    Parameters:
    - chunk_lines: list, lines of code
    - lang: str, programming language
    
    Returns:
    str: Completed code chunk
    """

def _get_docstring_and_rest(filename):
    """
    Extract docstring and remaining code from Python file.
    
    Parameters:
    - filename: str, path to Python file
    
    Returns:
    tuple: (docstring, remaining_code)
    """

Memory and Performance Utilities

Functions for monitoring memory usage and performance.

def _get_memory_usage():
    """
    Get current memory usage.
    
    Returns:
    float: Memory usage in MB
    """

def optipng(fname, args=None):
    """
    Optimize PNG image using optipng.
    
    Parameters:
    - fname: str, PNG filename to optimize
    - args: list, additional optipng arguments
    
    Returns:
    None
    """

System Integration

Functions for interacting with the system and external tools.

def _get_image_ext(image_path):
    """
    Get image file extension.
    
    Parameters:
    - image_path: str, path to image file
    
    Returns:
    str: File extension (e.g., '.png', '.jpg')
    """

def _has_optipng():
    """
    Check if optipng is available on the system.
    
    Returns:
    bool: True if optipng is available
    """

Advanced Utilities

Custom Image Processing

from sphinx_gallery.utils import scale_image
from PIL import Image
import os

def create_responsive_images(src_image, base_name, sizes):
    """
    Create multiple sizes of an image for responsive display.
    
    Parameters:
    - src_image: str, source image path
    - base_name: str, base name for output files
    - sizes: list, list of (width, height) tuples
    """
    for i, (width, height) in enumerate(sizes):
        suffix = f"_{width}x{height}" if i > 0 else ""
        output_name = f"{base_name}{suffix}.png"
        scale_image(src_image, output_name, width, height)

# Usage
create_responsive_images(
    'plot_large.png',
    'plot',
    [(200, 200), (400, 400), (800, 800)]
)

Batch File Processing

from sphinx_gallery.utils import md5sum_file
import os
import json

def create_file_manifest(directory):
    """
    Create manifest of all files with their hashes.
    
    Parameters:
    - directory: str, directory to process
    
    Returns:
    dict: Mapping of filenames to MD5 hashes
    """
    manifest = {}
    
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith(('.py', '.png', '.jpg')):
                filepath = os.path.join(root, file)
                relative_path = os.path.relpath(filepath, directory)
                manifest[relative_path] = md5sum_file(filepath)
    
    return manifest

# Usage
manifest = create_file_manifest('examples/')
with open('file_manifest.json', 'w') as f:
    json.dump(manifest, f, indent=2)

Image Optimization Pipeline

from sphinx_gallery.utils import scale_image, optipng, _has_optipng
import os

def optimize_gallery_images(image_dir, thumbnail_size=(200, 200)):
    """
    Optimize all images in gallery directory.
    
    Parameters:
    - image_dir: str, directory containing images
    - thumbnail_size: tuple, maximum thumbnail dimensions
    """
    
    for filename in os.listdir(image_dir):
        if filename.endswith('.png'):
            filepath = os.path.join(image_dir, filename)
            
            # Create thumbnail
            thumb_name = filename.replace('.png', '_thumb.png')
            thumb_path = os.path.join(image_dir, thumb_name)
            scale_image(filepath, thumb_path, *thumbnail_size)
            
            # Optimize with optipng if available
            if _has_optipng():
                optipng(filepath)
                optipng(thumb_path)
            
            print(f"Processed {filename}")

# Usage
optimize_gallery_images('_build/html/_images/')

File Change Detection

from sphinx_gallery.utils import md5sum_file
import pickle
import os

class FileChangeTracker:
    """Track file changes using MD5 hashes."""
    
    def __init__(self, cache_file='.file_hashes.pkl'):
        self.cache_file = cache_file
        self.hashes = self._load_hashes()
    
    def _load_hashes(self):
        """Load cached hashes from file."""
        if os.path.exists(self.cache_file):
            with open(self.cache_file, 'rb') as f:
                return pickle.load(f)
        return {}
    
    def _save_hashes(self):
        """Save hashes to cache file."""
        with open(self.cache_file, 'wb') as f:
            pickle.dump(self.hashes, f)
    
    def has_changed(self, filepath):
        """Check if file has changed since last check."""
        current_hash = md5sum_file(filepath)
        old_hash = self.hashes.get(filepath)
        
        changed = old_hash != current_hash
        self.hashes[filepath] = current_hash
        
        return changed
    
    def save(self):
        """Save current state to disk."""
        self._save_hashes()

# Usage
tracker = FileChangeTracker()

for example_file in os.listdir('examples/'):
    if example_file.endswith('.py'):
        filepath = os.path.join('examples/', example_file)
        if tracker.has_changed(filepath):
            print(f"File changed: {example_file}")

tracker.save()

Error Handling Utilities

import functools
import logging

def safe_image_operation(operation_name):
    """
    Decorator for safe image operations with error handling.
    
    Parameters:
    - operation_name: str, name of the operation for logging
    """
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                logging.warning(f"{operation_name} failed: {e}")
                return None
        return wrapper
    return decorator

@safe_image_operation("Image scaling")
def safe_scale_image(in_fname, out_fname, max_width, max_height):
    """Safe wrapper around scale_image."""
    from sphinx_gallery.utils import scale_image
    return scale_image(in_fname, out_fname, max_width, max_height)

# Usage
result = safe_scale_image('input.png', 'output.png', 200, 200)
if result is None:
    print("Image scaling failed")

Integration Patterns

With Sphinx Build Process

def process_images_during_build(app, env, updated_docs, updated_assets):
    """Process images during Sphinx build."""
    
    from sphinx_gallery.utils import scale_image
    
    image_dir = os.path.join(app.outdir, '_images')
    
    if os.path.exists(image_dir):
        for image_file in os.listdir(image_dir):
            if image_file.endswith('.png'):
                # Create thumbnail version
                base_name = image_file.replace('.png', '')
                thumb_file = f"{base_name}_thumb.png"
                
                scale_image(
                    os.path.join(image_dir, image_file),
                    os.path.join(image_dir, thumb_file),
                    150, 150
                )

# In conf.py
def setup(app):
    app.connect('env-updated', process_images_during_build)

Performance Monitoring

from sphinx_gallery.utils import _get_memory_usage
import time
import functools

def monitor_performance(func):
    """Decorator to monitor function performance."""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        start_memory = _get_memory_usage()
        
        result = func(*args, **kwargs)
        
        end_time = time.time()
        end_memory = _get_memory_usage()
        
        print(f"{func.__name__}:")
        print(f"  Time: {end_time - start_time:.2f}s")
        print(f"  Memory: {end_memory - start_memory:.1f}MB")
        
        return result
    return wrapper

@monitor_performance
def process_large_gallery():
    """Example of monitored function."""
    # Gallery processing code here
    pass

Best Practices

Image Processing

  • Use appropriate image formats (PNG for diagrams, JPEG for photos)
  • Optimize images for web display while maintaining quality
  • Create multiple sizes for responsive design
  • Cache processed images to avoid reprocessing

File Operations

  • Use hash-based change detection for efficiency
  • Implement proper error handling for file operations
  • Clean up temporary files after processing
  • Use atomic operations for critical file updates

Performance

  • Monitor memory usage for large galleries
  • Use lazy loading for expensive operations
  • Cache computed results when possible
  • Profile bottlenecks in custom utilities

Install with Tessl CLI

npx tessl i tessl/pypi-sphinx-gallery

docs

directives.md

extension-setup.md

index.md

notebooks.md

scrapers.md

sorting.md

utilities.md

tile.json