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:
Modify
checker_rules.yml(for changes to allowed element/relationship types in specific contexts)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
Architecture Overview — How pyArchimate is organized
Element Hierarchies — Working with hierarchies
Visual Styling — Customizing diagram appearance
Getting Started — Quick start guide