Template Registry

A thread-safe singleton registry for managing dataset templates in MDIO applications.

Overview

The TemplateRegistry implements the singleton pattern to ensure there’s only one instance managing all dataset templates throughout the application lifecycle. This provides a centralized registry for template management with thread-safe operations.

Features

  • Singleton Pattern: Ensures only one registry instance exists

  • Thread Safety: All operations are thread-safe using locks

  • Global Access: Convenient global functions for common operations

  • Advanced Support: Reset functionality for environment re-usability.

  • Default Templates: The registry is instantiated with the default set of templates:

    • PostStack2DTime

    • PostStack3DTime

    • PreStackCdpGathers3DTime

    • PreStackShotGathers3DTime

    • PostStack2DDepth

    • PostStack3DDepth

    • PreStackCdpGathers3DDepth

    • PreStackShotGathers3DDepth

Usage

Basic Usage

 1from mdio.builder.template_registry import TemplateRegistry
 2
 3# Get the singleton instance
 4registry = TemplateRegistry()
 5
 6# Or use the class method
 7registry = TemplateRegistry.get_instance()
 8
 9# Register a template
10template = MyDatasetTemplate()
11template_name = registry.register(template)
12print(f"Registered template named {template_name}")
13
14# Retrieve a template using a well-known name
15template = registry.get("my_template")
16# Retrieve a template using the name returned when the template was registered
17template = registry.get(template_name)
18
19# Check if template exists
20if registry.is_registered("my_template"):
21    print("Template is registered")
22
23# List all templates
24template_names = registry.list_all_templates()

Global Functions

For convenience, you can use global functions that operate on the singleton instance:

 1from mdio.builder.template_registry import (
 2    register_template,
 3    get_template,
 4    is_template_registered,
 5    list_templates
 6)
 7
 8# Register a template globally
 9register_template(Seismic3DTemplate())
10
11# Get a template
12template = get_template("seismic_3d")
13
14# Check registration
15if is_template_registered("seismic_3d"):
16    print("Template available")
17
18# List all registered templates
19templates = list_templates()

Multiple Instantiation

The singleton pattern ensures all instantiations return the same object:

1registry1 = TemplateRegistry()
2registry2 = TemplateRegistry()
3registry3 = TemplateRegistry.get_instance()
4
5# All variables point to the same instance
6assert registry1 is registry2 is registry3

API Reference

Template registry for MDIO v1 dataset templates.

class mdio.builder.template_registry.TemplateRegistry

A thread-safe singleton registry for dataset templates.

Return type:

TemplateRegistry

classmethod get_instance()

Get the singleton instance (alternative to constructor).

Returns:

The singleton instance of TemplateRegistry.

Return type:

TemplateRegistry

clear()

Clear all registered templates (useful for testing).

Return type:

None

get(template_name)

Get a template from the registry by its name.

Parameters:

template_name (str) – The name of the template to retrieve.

Returns:

The template instance if found.

Raises:

KeyError – If the template is not registered.

Return type:

AbstractDatasetTemplate

is_registered(template_name)

Check if a template is registered in the registry.

Parameters:

template_name (str) – The name of the template to check.

Returns:

True if the template is registered, False otherwise.

Return type:

bool

list_all_templates()

Get all registered template names.

Returns:

A list of all registered template names.

Return type:

list[str]

register(instance)

Register a template instance by its name.

Parameters:

instance (AbstractDatasetTemplate) – An instance of template to register.

Returns:

The name of the registered template.

Raises:

ValueError – If the template name is already registered.

Return type:

str

unregister(template_name)

Unregister a template from the registry.

Parameters:

template_name (str) – The name of the template to unregister.

Raises:

KeyError – If the template is not registered.

Return type:

None

mdio.builder.template_registry.get_template(name)

Get a template from the global registry.

Parameters:

name (str) – The name of the template to retrieve.

Returns:

The template instance if found.

Return type:

AbstractDatasetTemplate

mdio.builder.template_registry.get_template_registry()

Get the global template registry instance.

Returns:

The singleton instance of TemplateRegistry.

Return type:

TemplateRegistry

mdio.builder.template_registry.is_template_registered(name)

Check if a template is registered in the global registry.

Parameters:

name (str) – The name of the template to check.

Returns:

True if the template is registered, False otherwise.

Return type:

bool

mdio.builder.template_registry.list_templates()

List all registered template names.

Returns:

A list of all registered template names.

Return type:

list[str]

mdio.builder.template_registry.register_template(template)

Register a template in the global registry.

Parameters:

template (AbstractDatasetTemplate) – An instance of AbstractDatasetTemplate to register.

Returns:

The name of the registered template.

Return type:

str

Thread Safety

All operations on the registry are thread-safe:

 1import threading
 2
 3def register_templates():
 4    registry = TemplateRegistry()
 5    for i in range(10):
 6        template = MyTemplate(f"template_{i}")
 7        registry.register(template)
 8
 9# Multiple threads can safely access the registry
10threads = [threading.Thread(target=register_templates) for _ in range(5)]
11for thread in threads:
12    thread.start()
13for thread in threads:
14    thread.join()

Best Practices

  1. Use Global Functions: For simple operations, prefer the global convenience functions

  2. Register Early: Register all templates during application startup

  3. Thread Safety: The registry is thread-safe, but individual templates may not be

  4. Testing Isolation: Always reset the singleton in test setup/teardown

Example: Complete Template Management

 1from mdio.builder.template_registry import TemplateRegistry
 2from mdio.builder.templates.seismic_3d_poststack import Seismic3DPostStackTemplate
 3from mdio.builder.schemas.v1 import Seismic3DPostStackTimeTemplate
 4from mdio.builder.schemas.v1 import Seismic3DPreStackTemplate
 5
 6
 7def setup_templates():
 8    """Register MDIO templates runtime.
 9    Custom templates can be created in external projects and added without modifying the MDIO library code
10    """
11    # Use strongly-typed template
12    template_name = TemplateRegistry.register(Seismic3DPostStackTimeTemplate())
13    print(f"Registered template named {template_name}")
14    # Use parametrized template
15    template_name = TemplateRegistry.register(Seismic3DPostStackTemplate("Depth"))
16    print(f"Registered template named {template_name}")
17    template_name = TemplateRegistry.register(Seismic3DPreStackTemplate())
18    print(f"Registered template named {template_name}")
19
20    print(f"Registered templates: {list_templates()}")
21
22
23# Application startup
24setup_standard_templates()
25
26# Later in the application
27template = TemplateRegistry().get_template("PostStack3DDepth")
28dataset = template.create_dataset(name="Seismic 3d m/m/ft",
29                                  sizes=[256, 512, 384])

Error Handling

The registry provides clear error messages:

 1# Template not registered
 2try:
 3    template = get_template("nonexistent")
 4except KeyError as e:
 5    print(f"Error: {e}")  # "Template 'nonexistent' is not registered."
 6
 7# Duplicate registration
 8try:
 9    register_template("duplicate", template1)
10    register_template("duplicate", template2)
11except ValueError as e:
12    print(f"Error: {e}")  # "Template 'duplicate' is already registered."