Python utilities for ili2c (INTERLIS metamodel, parser, and repository helpers).
Project description
ili2c Python module
ili2c-python packages the Python helpers that accompany the ili2c
toolchain. It exposes a single import namespace, ili2c, which groups
utilities for working with INTERLIS repositories, the metamodel, and the
parser.
Features
ili2c.ilirepository– download and cache models from INTERLIS repositories.ili2c.pyili2c.metamodel– a lightweight Python view of the INTERLIS metamodel.ili2c.pyili2c.parser– parse INTERLIS 2 transfer descriptions.ili2c.pyili2c.mermaid– render INTERLIS structures to Mermaid diagrams.
Installation
pip install ili2c-python
You can also install directly from a clone of this repository:
pip install .
When developing locally, install the optional test extra to run the pytest suite:
pip install .[test]
Quick start
Discover models in an INTERLIS repository
from ili2c.ilirepository import IliRepositoryManager
manager = IliRepositoryManager(repositories=["https://models.interlis.ch/"])
model = manager.find_model("RoadsExgm2ien", schema_language="ili2_4")
print(model.name, model.version)
for dependency in model.dependencies:
print("requires", dependency)
Download a model file
from pathlib import Path
from ili2c.ilirepository import IliRepositoryManager
manager = IliRepositoryManager(repositories=["https://models.interlis.ch/"])
path = Path(manager.get_model_file("DMAV_Grundstuecke_V1_0", schema_language="ili2_4"))
print(path.read_text()[:200])
How repository caching works
The repository helpers mirror HTTP repositories onto the local file system via
RepositoryCache. The cache stores two kinds of artefacts:
ilimodels.xmlindex files for each configured repository. Metadata requests such asIliRepositoryManager.find_modelaskRepositoryAccessto retrieve the repository index.RepositoryAccessresolves the index by callingRepositoryCache.fetch(repository_uri, "ilimodels.xml", meta_ttl), which downloads the XML once and reuses the local copy until the metadata time-to-live (default: 24 hours) expires.ilisite.xmlrepository graph files. The manager walks repositories in breadth-first order and therefore callsRepositoryAccess.get_connected_repositoriesfor each site. The helper downloads and caches theilisite.xmlfile in the same way as the model index.- Individual model files. When
IliRepositoryManager.get_model_fileis invoked,RepositoryAccess.fetch_model_filedelegates toRepositoryCache.fetch(metadata.repository_uri, metadata.relative_path, model_ttl, metadata.md5). The cache saves the model under the repository folder and honours the model TTL (default: seven days) and MD5 checksum when deciding whether to re-download the file.
RepositoryCache maps each repository URL to a dedicated directory inside the
cache root ($ILI_CACHE or ~/.pyilicache). For HTTP repositories it sanitises
path components to create safe file names (or uses MD5 hashes when the
ILI_CACHE_FILENAME=MD5 environment variable is set). When asked to fetch a
resource it:
- Checks whether a cached file already exists.
- Validates the TTL and optional MD5 checksum.
- Downloads the remote file with
urllib.request.urlopenif the cache entry is missing, expired or fails the checksum. - Returns the local
Pathto the cached file for subsequent consumers.
The following sequence diagram illustrates IliRepositoryManager.get_model_file:
sequenceDiagram
actor User
participant Manager as IliRepositoryManager
participant Access as RepositoryAccess
participant Cache as RepositoryCache
participant Repo as INTERLIS Repository
User->>Manager: get_model_file(name)
loop Repositories (breadth-first)
Manager->>Access: get_models(repository)
Access->>Cache: fetch("ilimodels.xml", ttl=meta_ttl)
alt Cache miss or expired entry
Cache->>Repo: HTTP GET ilimodels.xml
Repo-->>Cache: Repository index
else Cached entry valid
Note right of Cache: Reuse cached metadata
end
Cache-->>Access: Path to ilimodels.xml
Access-->>Manager: ModelMetadata*
Manager->>Access: get_connected_repositories(repository)
Access->>Cache: fetch("ilisite.xml", ttl=meta_ttl)
alt Cache miss or expired entry
Cache->>Repo: HTTP GET ilisite.xml
Repo-->>Cache: Repository graph
else Cached entry valid
Note right of Cache: Reuse cached graph
end
Cache-->>Access: Path to ilisite.xml
Access-->>Manager: Connected URIs
end
Manager->>Access: fetch_model_file(metadata, ttl=model_ttl)
Access->>Cache: fetch(metadata.relative_path, ttl=model_ttl, md5)
alt Cache miss or expired entry
Cache->>Repo: HTTP GET model file
Repo-->>Cache: .ili content
else Cached entry valid
Note right of Cache: Reuse cached model
end
Access-->>Manager: Path
Manager-->>User: Local path string
Only the requested model file is downloaded. Imported models are listed in the
ModelMetadata.dependencies collection and can be fetched on demand by calling
get_model_file for each dependency. Any repositories linked through
ilisite.xml files are traversed in breadth-first order, and their metadata and
repository graph documents are cached alongside downloaded models.
Parse a transfer description
import logging
from pathlib import Path
from ili2c.pyili2c.parser import ParserSettings, parse
from ili2c.pyili2c.mermaid import render
logging.basicConfig(level=logging.INFO)
model_path = Path("path/to/model.ili")
transfer_description = parse(model_path)
print(f"Parsed {len(transfer_description.models)} models")
print(render(transfer_description))
parse accepts a ParserSettings instance that controls how imported models
are resolved. The parser searches the current model directory by default and
falls back to the standard repositories listed in the default ILIDIRS string,
"%ILI_DIR;https://models.interlis.ch". Imported models are first resolved next
to the referencing model, then across any additional directories from ILIDIRS,
and finally via IliRepositoryManager, which walks remote repositories in
breadth-first order using their ilisite.xml links. Downloaded metadata and
model files are cached on the local file system, while models discovered through
%ILI_DIR entries are read directly without being mirrored. To override the
lookup paths you can adjust the ILIDIRS configuration before invoking the
parser:
from pathlib import Path
from ili2c.pyili2c.parser import ParserSettings, parse
settings = ParserSettings()
settings.set_ilidirs("%ILI_DIR;https://models.interlis.ch;https://example.com/models")
transfer_description = parse(Path("path/to/model.ili"), settings=settings)
Enable parser logging
The parser emits diagnostic messages via Python's standard logging framework
under the ili2c.pyili2c.parser logger. Configure logging before invoking
parse to see the progress information:
import logging
from pathlib import Path
from ili2c.pyili2c.parser import parse
logging.basicConfig(level=logging.INFO)
model_path = Path("path/to/model.ili")
parse(model_path)
You can customise the output format or log level by adjusting the
logging.basicConfig call or by configuring handlers on the
ili2c.pyili2c.parser logger directly.
Once parsed you can iterate through the INTERLIS structure using the metamodel helpers. The example below prints every model, topic and class found in the transfer description, along with the attribute names defined on each class:
for model in transfer_description.getModels():
print("Model", model.getName())
for topic in model.getTopics():
print(" Topic", topic.getName())
for cls in topic.getClasses():
attribute_names = [attr.getName() for attr in cls.getAttributes()]
print(" Class", cls.getName(), "attributes:", ", ".join(attribute_names))
Understanding Model helpers
The Python metamodel mirrors the structure of the Java implementation quite
closely. Model inherits from the generic container base class and therefore
exposes helper methods only where they are broadly useful—such as getTopics,
which is simply a convenience wrapper. Model-level classes (for example,
tables or structures declared outside a topic) are still attached directly to
the model container and can be retrieved through
model.elements_of_type(Table) or any other elements_of_type(...) query.
Because the generic API already covers this access pattern, there is no
dedicated Model.getClasses() helper.
Repository layout
python/
├── ili2c/ # Python module published to PyPI
│ ├── ilirepository/ # Repository client utilities
│ └── pyili2c/ # Metamodel, parser, and visualisation helpers
├── tests/ # Pytest suite for the module
├── pyproject.toml # PEP 621 metadata and build configuration
├── setup.cfg # Legacy setuptools configuration
└── setup.py # Compatibility entry point for build backends
Additional developer documentation is available in
DEVELOPMENT.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ili2c_python-0.1.11.tar.gz.
File metadata
- Download URL: ili2c_python-0.1.11.tar.gz
- Upload date:
- Size: 56.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4e96965913796e90c63001edea76c188d4118d13f1a236d6aa5da1f9ed3f6d8
|
|
| MD5 |
26a656a5b7b002a0dfeaa77188549fb6
|
|
| BLAKE2b-256 |
83da4dcf85a3c0ffd596f6e16f00f841810d19af9123092da2b2f47f6a6d5721
|
File details
Details for the file ili2c_python-0.1.11-py3-none-any.whl.
File metadata
- Download URL: ili2c_python-0.1.11-py3-none-any.whl
- Upload date:
- Size: 62.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3104756b01bb5fd2b86a701e91cddf4b797efdb511e2d6af331eeb0130b8ac8
|
|
| MD5 |
18de7d31a98ad87cbf2ec7d7c402fa16
|
|
| BLAKE2b-256 |
a1ae1291688d0aeeaa2f52d2fad9fb51030cdde798e249d7040f8cb4205ab7e3
|