Adding ontology converters - #147
Conversation
Added emission of ontology-level requires
There was a problem hiding this comment.
Pull request overview
Introduces a new standalone Python package under converters/ontology that implements OSI ontology converters and supporting parsing/model layers, enabling bidirectional conversion between Palantir exports, an OSI runtime model, and an OSI YAML spec format.
Changes:
- Added Pydantic DTO schema (
OsiSpec) plus YAML load/dump helpers for OSI spec serialization. - Added a runtime ontology + semantic model implementation and converters: Spec ↔ OSI model, Palantir → OSI model.
- Added Palantir ZIP parsing utilities/models and a CLI script + packaging/docs scaffolding for installable usage.
Reviewed changes
Copilot reviewed 16 out of 24 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| converters/ontology/src/osi/spec.py | Defines the Pydantic spec DTOs and YAML load/dump helpers. |
| converters/ontology/src/osi/model.py | Adds the runtime ontology/semantic/mapping model used by converters. |
| converters/ontology/src/osi/parser/init.py | Adds an OsiParser entrypoint for reading YAML/JSON into the runtime model. |
| converters/ontology/src/osi/converter/spec_to_osi/converter.py | Implements Spec → runtime model conversion (incl. mapping-expression resolution). |
| converters/ontology/src/osi/converter/osi_to_spec/converter.py | Implements runtime model → Spec DTO conversion and mapping-expression rendering. |
| converters/ontology/src/osi/external/palantir/parser/init.py | Adds Palantir export ZIP parsing (ontology + dataset specs). |
| converters/ontology/src/osi/external/palantir/model.py | Adds Palantir ontology/data model types used by the parser/converter. |
| converters/ontology/src/osi/converter/palantir_to_osi/converter.py | Implements Palantir → runtime model conversion (concepts, relationships, mappings, datasets). |
| converters/ontology/src/osi/common/utils.py | Adds small shared string/name utilities used by converters/parsers. |
| converters/ontology/src/osi/common/graph.py | Adds topo-sort utilities used for dependency ordering (incl. cycle breaking). |
| converters/ontology/src/osi/common/file_utils.py | Adds ZIP helpers for reading top-level and dataset JSON files. |
| converters/ontology/src/osi/init.py | Defines the package’s intended public API surface (osi.*). |
| converters/ontology/scripts/palantir_to_osi.py | Adds a runnable CLI script for Palantir ZIP → OSI YAML conversion. |
| converters/ontology/pyproject.toml | Adds Python project packaging/configuration for the new package. |
| converters/ontology/requirements.lock | Adds a pinned dependency lock file for reproducible installs. |
| converters/ontology/README.md | Adds setup and usage documentation for the package/script. |
| converters/ontology/.gitignore | Adds Python-focused ignores for the new project directory. |
| converters/ontology/src/osi/converter/init.py | Package init for converter modules. |
| converters/ontology/src/osi/converter/spec_to_osi/init.py | Package init for Spec → OSI converter. |
| converters/ontology/src/osi/converter/osi_to_spec/init.py | Package init for OSI → Spec converter. |
| converters/ontology/src/osi/converter/palantir_to_osi/init.py | Package init for Palantir → OSI converter. |
| converters/ontology/src/osi/external/init.py | Package init for external integrations. |
| converters/ontology/src/osi/external/palantir/init.py | Package init for Palantir integration. |
| converters/ontology/src/osi/common/init.py | Package init for common utilities. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jbonofre
left a comment
There was a problem hiding this comment.
License headers + CI workflow
Two blocking ASF-convention gaps from the review, with fixes attached.
1. License headers — 21 inline suggestions below add the standard Apache-2.0 header (one-click Apply). The 8 empty __init__.py files need it too but have no suggestable line; the generated requirements.lock, .gitignore, and the tests/snapshots/** files should stay header-less (a header in the round-trip snapshot would break that test — exclude them via RAT instead).
2. CI workflow — every other converter ships .github/workflows/converter-<name>-ci.yml; this PR has none, so the suite never runs on PRs. New file .github/workflows/converter-ontology-ci.yml (mirrors converter-omni-ci.yml, adapted to this converter's pip/requirements.lock setup and 3.11+ floor):
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
name: Converters Ontology CI
on:
push:
branches: [ "main" ]
paths:
- 'converters/ontology/**'
- '.github/workflows/converter-ontology-ci.yml'
pull_request:
branches: [ "main" ]
paths:
- 'converters/ontology/**'
- '.github/workflows/converter-ontology-ci.yml'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- name: Checkout project
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
working-directory: converters/ontology
run: |
python -m pip install --upgrade pip
pip install -r requirements.lock
pip install -e ".[dev]"
- name: Unit Tests
working-directory: converters/ontology
run: |
pytestI verified the header additions + these exact CI steps in a clean venv: 52 passed. (Couldn't push directly — Allow edits by maintainers is off on this PR.)
jbonofre
left a comment
There was a problem hiding this comment.
At least the ASF header is missing.
Also, are you sure about the name? Is it ontology converter or palantir converter?
Can you also rename from OSI to Ossie?
|
@jbonofre thank you for the detailed review — all points addressed.
The one remaining file without a header is the generated
Could you take another look when you get a chance? Thanks again. |
OSI Ontology Converters — Python Project
This PR introduces
converters/ontologyas a standalone, installable Python project providing bidirectional conversion between ontology formats used across the OSI ecosystem. It adds a complete package: the in-memory OSI ontology model, spec (de)serialisation, a Palantir ingestion layer, three converters, a runnable CLI script, and a test suite.34 files, ~8.2k lines added. Everything lands under
converters/ontology/— no existing files are modified.Model layer
src/osi/model.py— the in-memory OSI ontology model, organised in three layers:Concept(entity / value / component types),Relationship,Role,RelationshipMultiplicity,Formula,OntologyComponent,OsiOntologyDataset,DatasetField,Dimension,JoinPath,Metric,DialectExpression/DialectExpressionSet,SemanticModelObjectMapping,ReferentMapping,LinkMapping,ConceptMapping,OntologyMappingAlso includes verbalization parsing (
parse_verbalizations) that splits madlib-style relationship text into roles using the dash convention, andFormulaFactory/MappingFormulaFactoryextension points so downstream consumers can plug in their own expression parsers forderived_by/requiresand mapping expressions.src/osi/spec.py— pydantic DTOs mirroring the OSI YAML specification (OsiSpecand friends), used as the serialisation boundary.src/osi/__init__.py— a curated public API surface, so consumers import fromosirather than deep sub-paths.Converters
palantir_to_osiosi_to_specrequiresspec_to_osiOsiParser(src/osi/parser/) is the entrypoint for reading a spec file (YAML or JSON, UTF-8 pinned for reproducibility) and returning anOsiOntology.Palantir ingestion
src/osi/external/palantir/model.py— DTOs for a Palantir export:Ontology,ObjectType,Property,DataSet/DataSetColumn, and the relation hierarchy (ManyToOneRelation,ManyToManyRelation,IntermediaryRelation).src/osi/external/palantir/parser/—PalantirParseraccepts a.ziparchive or an already-extracted folder, and tolerates both top-level and single-root-directory layouts. It parses the ontology JSON plus adata_sets/folder of dataset specs, handles both old- and new-style relation encodings, and raises clear errors for ambiguous or missing inputs.Common utilities
common/graph.py— topological sort, cycle detection, and a cycle-breaking variant used to order concept and mapping dependencies.common/file_utils.py— zip/directory traversal helpers with input validation.common/utils.py— identifier and verbalization string normalisation.Tests
A pytest suite (
tests/, 7 files) driven off theflightsexample:test_osi_parser.py— spec → model conversion: document metadata, ontology- and concept-levelrequires, value-type inheritance, identifiers, relationship multiplicity, ontology mappings, YAML/JSON loading, error handling, formula-factory isolation between parsers, and round-trip structural invariantstest_palantir_parser.py— every supported export layout (top-level zip, single-root zip, extracted dir, single-root dir, dir wrapping a zip) plus the unsupported/invalid cases (missing path, non-zip file, missing or emptydata_sets, ambiguous top-level JSON)test_verbalization_parsing.py— prefix/postfix splitting, multi-word decoration, ternary relationships, built-in concept resolution, and error casestest_flights_snapshot.py— structure and round-trip YAML snapshots (pytest-snapshot), which also assert the output is deterministic for fixed inputtest_examples_in_sync.py— guards the vendoredtests/fixtures/flights.yamlagainst drift from the canonicalexamples/flights.yaml. Test inputs are vendored so the suite runs from an sdist/wheel or a subset checkout; this test skips whenexamples/isn't present.Run with
pytestfromconverters/ontology.Project setup
pyproject.toml— runtime deps (pydantic,pyyaml), dev extras (pytest,pytest-snapshot,pip-tools),src/layout, pytest and pyright config; requires Python ≥ 3.11requirements.lock— fully reproducible installs, generated frompyproject.tomlviapip-compilesrc/osi/layout — importable asosiafter installation.gitignore— Python artifacts, virtualenvs, pyenv, VS Code, JetBrainsREADME.md— pyenv/virtualenv setup, lock-file regeneration, usage, and script docsScript
scripts/palantir_to_osi.py— takes a Palantir export (.zipor extracted folder) and writes OSI YAML to stdout, warnings to stderr. Snowflake database and schema names used to qualify table references are configurable viaSNOWFLAKE_DATABASE_NAMEandSNOWFLAKE_SCHEMA_NAME(both default toPALANTIR).Not included
No CI wiring — the suite is currently run locally.