Extending pyArchimate

Note

🔧 Intermediate / Architecture — Learn how to extend pyArchimate with custom readers, writers, properties, and profiles.

Introduction

PyArchimate is designed as an extensible platform. Rather than modifying the core library, you can hook into extension points to:

  • Add support for new file formats (custom readers)

  • Export to new formats (custom writers)

  • Extend models with domain-specific properties

  • Integrate with your own workflows

This guide explains the patterns and APIs for each extension point.

Custom Readers

What is a reader?

A reader is a class that parses a file in a specific format and returns a Model instance. PyArchimate includes built-in readers for:

  • ArchiMate XML format (.archimate files)

  • OpenGroup XML exchange format

How to create a custom reader

Create a class with a read(filepath: str) -> Model method:

from pyArchimate import Model
from pyArchimate.readers import MODEL_READER_REGISTRY

class CSVReader:
    """Read a simple CSV format into a Model."""
    def read(self, filepath: str) -> Model:
        model = Model(name="From CSV")
        # Parse CSV and populate model
        with open(filepath) as f:
            for line in f:
                # Parse line and add elements/relationships
                pass
        return model

How to register a custom reader

Register your reader in the MODEL_READER_REGISTRY dictionary:

from pyArchimate.readers import MODEL_READER_REGISTRY

MODEL_READER_REGISTRY['csv'] = CSVReader()

Using your custom reader

Once registered, you can read files using the extension key:

from pyArchimate import Model

model = Model.read("mymodel.csv", reader_key="csv")

Custom Writers

What is a writer?

A writer is a class that exports a Model to a specific file format. PyArchimate includes built-in writers for:

  • ArchiMate XML format (.archimate files)

How to create a custom writer

Create a class with a write(model: Model, filepath: str) -> None method:

from pyArchimate import Model

class JSONWriter:
    """Write a Model to JSON format."""
    def write(self, model: Model, filepath: str) -> None:
        import json
        data = {
            "name": model.name,
            "elements": [
                {"name": e.name, "type": e.element_type.value}
                for e in model.elements
            ],
        }
        with open(filepath, 'w') as f:
            json.dump(data, f, indent=2)

How to use a custom writer

Pass your writer instance to the model’s write method:

model = Model(name="My Model")
# ... add elements ...

writer = JSONWriter()
writer.write(model, "output.json")

Registering writers in the Writers enum (optional)

If you want to standardize your writer as part of the library, you can extend the Writers enum and add it to the model’s write workflow. Contact the pyArchimate maintainers for guidance on this advanced pattern.

Custom Properties and Profiles

What are properties?

Elements and relationships support arbitrary properties — key-value pairs for metadata beyond standard attributes. Properties allow you to attach domain-specific information without modifying the core model.

How to set properties

from pyArchimate import Model, ArchiType

model = Model(name="My Model")
element = model.add_element(
    name="Critical System",
    element_type=ArchiType.ApplicationService
)

# Set custom properties
element.set_property("owner", "John Doe")
element.set_property("cost", "500000")
element.set_property("risk_level", "high")

How to get properties

owner = element.get_property("owner")
cost = element.get_property("cost")

How to preserve properties during round-trip

When you read and write a model, properties are preserved in the native ArchiMate XML format. For custom formats, ensure your reader and writer handle the properties dictionary:

# In your custom reader
element.set_property("custom_field", value)

# In your custom writer
for key, value in element.get_properties().items():
    # Serialize property to your format

Logging Integration

PyArchimate uses Python’s standard logging module. To debug your extensions, configure logging:

import logging

# Set pyArchimate's logger to DEBUG level
logging.getLogger('pyArchimate').setLevel(logging.DEBUG)

# Add a console handler to see log output
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logging.getLogger('pyArchimate').addHandler(handler)

Common logging points:

  • Model.read() logs the reader and file being loaded

  • Model.write() logs the writer and file being written

  • Element and relationship operations log validation results

  • Readers/writers log parsing and serialization steps

Plugin Architecture Notes

Current plugin model

PyArchimate uses a registry-based plugin model:

  • Readers are registered in MODEL_READER_REGISTRY (a dictionary)

  • Writers are added as writer class instances

  • Validation rules are defined in checker_rules.yml

Extending the validation layer

To add custom validation rules, you can:

  1. Modify checker_rules.yml (for changes to allowed element/relationship types in specific contexts)

  2. Programmatically call validation functions and add your own checks

Example:

from pyArchimate import Model
from pyArchimate.validation import check_valid_relationship

model = Model.read("mymodel.archimate")

# Add custom validation
for relationship in model.relationships:
    if relationship.documentation is None:
        print(f"Warning: Relationship {relationship.id} has no documentation")

Future plugin roadmap

The pyArchimate team plans to support:

  • Event hooks for model changes (e.g., on_element_added, on_write)

  • Custom viewpoint definitions

  • Plugin discovery and dynamic loading

Check the project repository for the latest information on upcoming plugin features.

See Also