Skip to main content

Architecture as code — build, query, validate, and analyze enterprise architecture models in Python

Project description

etcion

Architecture as code. Build, query, validate, and analyze enterprise architecture models in Python.

Why etcion?

Enterprise architecture models are rich data structures — typed elements, directed relationships, cross-layer dependencies, governance rules. But most EA tooling treats them as static diagrams locked inside proprietary formats.

etcion turns your architecture into a first-class Python data structure. Once it's code, you can query it, validate it against rules, test what-if scenarios, diff versions, and integrate it with the rest of your analytical toolkit — pandas, networkx, Jupyter notebooks, CI/CD pipelines, or anything else Python touches.

Built on the ArchiMate 3.2 metamodel. Compatible with Archi via the Open Group Exchange Format.

What you can do

Build models programmatically

from etcion import (
    BusinessProcess, ApplicationService, ApplicationComponent,
    Model, Serving, Assignment,
)

order_handling = BusinessProcess(name="Order Handling")
api = ApplicationService(name="Order API")
backend = ApplicationComponent(name="Order Service")

model = Model(concepts=[
    order_handling, api, backend,
    Serving(name="serves", source=api, target=order_handling),
    Assignment(name="runs", source=backend, target=api),
])

Query the model graph

model.elements_by_layer(Layer.BUSINESS)
model.elements_by_name("Order", regex=False)
model.connected_to(backend)
model.sources_of(order_handling)

Detect structural patterns

from etcion.patterns import Pattern, RequiredPatternRule

# Every BusinessService must be backed by an ApplicationService
service_backing = (
    Pattern()
    .node("biz", BusinessService)
    .node("app", ApplicationService)
    .edge("app", "biz", Serving)
)

# Find services missing their backing
gaps = service_backing.gaps(model, anchor="biz")

# Enforce as a validation rule
model.add_validation_rule(RequiredPatternRule(
    pattern=service_backing,
    anchor="biz",
    description="Every BusinessService must be served by an ApplicationService",
))

Detect anti-patterns

from etcion.patterns import AntiPatternRule

# Technology should not directly serve Business (must go through Application)
bad_pattern = (
    Pattern()
    .node("tech", TechnologyService)
    .node("biz", BusinessProcess)
    .edge("tech", "biz", Serving)
)

model.add_validation_rule(AntiPatternRule(
    pattern=bad_pattern,
    description="Technology must not directly serve Business layer",
))

Model what-if scenarios

from etcion import analyze_impact, chain_impacts

# What breaks if we decommission the legacy CRM?
impact = analyze_impact(model, remove=legacy_crm, max_depth=3)
for item in impact.affected:
    print(f"  depth={item.depth}  {item.concept.name}")
print(f"Broken relationships: {len(impact.broken_relationships)}")

# What happens if we consolidate three systems onto one platform?
impact = analyze_impact(model, merge=([sys_a, sys_b, sys_c], target_platform))
print(f"Permission violations: {len(impact.violations)}")

# Chain multiple changes and validate the result
i1 = analyze_impact(model, remove=old_system)
i2 = analyze_impact(i1.resulting_model, replace=(legacy_db, cloud_db))
errors = i2.resulting_model.validate()

Validate against the spec

errors = model.validate()           # Collect all errors
model.validate(strict=True)         # Raise on first error

from etcion import is_permitted, Serving, ApplicationService, BusinessProcess
is_permitted(Serving, ApplicationService, BusinessProcess)  # True

Exchange with Archi and other tools

from etcion.serialization.xml import write_model, read_model

write_model(model, "architecture.xml", model_name="My Architecture")
loaded = read_model("exported_from_archi.xml")

Compare model versions

from etcion import diff_models

diff = diff_models(baseline_model, proposed_model)
print(diff.summary())  # "ModelDiff: 3 added, 1 removed, 2 modified"

Build models with the fluent ModelBuilder API

from etcion import ModelBuilder

with ModelBuilder() as b:
    crm = b.application_component("CRM System", documentation="Main CRM")
    db = b.data_object("Customer Database")
    b.access(crm, db)

model = b.model

Merge model fragments from multiple sources

from etcion import merge_models

# Merge a CMDB fragment into the canonical model
result = merge_models(canonical, cmdb_fragment, strategy="prefer_base")
print(result.conflicts)      # ConceptChange tuples where IDs collided
print(result.violations)     # Post-merge validation issues
merged = result.merged_model

Track provenance through ingestion pipelines

from etcion import INGESTION_PROFILE, unreviewed_elements, low_confidence_elements

model.apply_profile(INGESTION_PROFILE)
needs_review = unreviewed_elements(model)
low_conf = low_confidence_elements(model, threshold=0.7)

Validate conformance against the spec

from etcion import CONFORMANCE, ConformanceProfile

# Check which conformance profile the model satisfies
profile = CONFORMANCE.evaluate(model)   # ConformanceProfile.FULL | CORE | ...

Export to graph, DataFrame, and visualization formats

from etcion.serialization.graph_data import to_cytoscape_json, to_echarts_graph

cyto = to_cytoscape_json(model)    # Ready for Cytoscape.js
echart = to_echarts_graph(model)   # Ready for Apache ECharts

Installation

pip install etcion              # Core library
pip install etcion[xml]         # + XML serialization (lxml)
pip install etcion[graph]       # + Pattern matching & impact analysis (networkx)
pip install etcion[xml,graph]   # Both

Requires Python 3.12 or later.

ArchiMate Coverage

58 concrete element types across all 7 layers, 11 relationship types, Junction, and 28 predefined viewpoints.

Layer Elements
Strategy Resource, Capability, ValueStream, CourseOfAction
Business BusinessActor, BusinessRole, BusinessCollaboration, BusinessInterface, BusinessProcess, BusinessFunction, BusinessInteraction, BusinessEvent, BusinessService, BusinessObject, Contract, Representation, Product
Application ApplicationComponent, ApplicationCollaboration, ApplicationInterface, ApplicationFunction, ApplicationInteraction, ApplicationProcess, ApplicationEvent, ApplicationService, DataObject
Technology Node, Device, SystemSoftware, TechnologyCollaboration, TechnologyInterface, Path, CommunicationNetwork, TechnologyFunction, TechnologyProcess, TechnologyInteraction, TechnologyEvent, TechnologyService, Artifact
Physical Equipment, Facility, DistributionNetwork, Material
Motivation Stakeholder, Driver, Assessment, Goal, Outcome, Principle, Requirement, Constraint, Meaning, Value
Implementation & Migration WorkPackage, Deliverable, ImplementationEvent, Plateau, Gap

Archi Compatibility

etcion reads and writes the Open Group ArchiMate Exchange Format, verified against Archi.

Import into Archi: File > Import > Open Exchange XML Model Export from Archi: File > Export > Open Exchange XML Model

Diagram layouts, folder organization, and visual styles survive round-trip as opaque XML.

Extending

# Custom validation rules
from etcion.validation.rules import ValidationRule

class RequireDocumentation:
    def validate(self, model):
        from etcion.exceptions import ValidationError
        return [
            ValidationError(f"'{e.name}' has no documentation")
            for e in model.elements if not e.description
        ]

model.add_validation_rule(RequireDocumentation())

# Language customization via profiles
from etcion.metamodel.profiles import Profile

cloud_profile = Profile(
    name="Cloud",
    specializations={ApplicationComponent: ["Microservice", "Lambda", "Container"]},
)
model.apply_profile(cloud_profile)

Development

git clone https://github.com/korpodevs/etcion.git
cd etcion
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest                    # 2685 tests
ruff check src/ test/     # Lint
mypy src/                 # Type check
mkdocs serve              # Local docs

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

etcion-0.14.0.tar.gz (1.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

etcion-0.14.0-py3-none-any.whl (131.5 kB view details)

Uploaded Python 3

File details

Details for the file etcion-0.14.0.tar.gz.

File metadata

  • Download URL: etcion-0.14.0.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for etcion-0.14.0.tar.gz
Algorithm Hash digest
SHA256 33a93861a0b1e271a2e1f25822954c14eb6dcb5ef3eb87d1938314604c262055
MD5 24ab5ebd9c5173f9c8cff4d3a827da7e
BLAKE2b-256 05842442deea67b2e4bc8a159a4e07968c0b1318a944aad6069a474252a45dfe

See more details on using hashes here.

Provenance

The following attestation bundles were made for etcion-0.14.0.tar.gz:

Publisher: release.yml on korpodevs/etcion

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file etcion-0.14.0-py3-none-any.whl.

File metadata

  • Download URL: etcion-0.14.0-py3-none-any.whl
  • Upload date:
  • Size: 131.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for etcion-0.14.0-py3-none-any.whl
Algorithm Hash digest
SHA256 78a0978bc2dce833b6844b312fcbce3a303aa7e6e1a979bc94ef54fd19a4b4fa
MD5 19cd58f210fb241617073421fdbb9c92
BLAKE2b-256 12361c8d5f596732f1bda8e6848e749e227aabfd0bde94b1ae29bb8f0094443c

See more details on using hashes here.

Provenance

The following attestation bundles were made for etcion-0.14.0-py3-none-any.whl:

Publisher: release.yml on korpodevs/etcion

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page