Repository navigation
feat(python): add ontology models to the shared SDK - #651
AndrewNepogoda wants to merge 5 commits into
Conversation
Add Pydantic models mirroring ontology/ontology.json so converters can share them instead of keeping their own DTOs (ossie_ontology.spec in apache/ossie-converters): - OssieOntologyDocument, OssieConcept, OssieOntologyRelationship, OssieRole, OssieConceptType, OssieMultiplicity - OssieConceptMapping, OssieObjectMapping, OssieReferentMapping, OssieLinkMapping and the deprecated embedded OssieOntologyMapping - OssieVersion, shared with OssieDocument The models are frozen and forbid unknown keys like the existing ones, and follow the schema's required fields and anyOf rules. OssieDocument is unchanged apart from typing its version as OssieVersion. Tests check each model against its schema node.
|
Thank you for your first contribution to Apache Ossie (incubating)! A committer will review your PR. In the meantime, please ensure:
No ICLA is required to contribute. If you are elected as a committer in the future, you will need an Individual Contributor License Agreement (ICLA) on file with the ASF. Questions? Ask in the PR comments or join us on Slack. We appreciate your contribution! |
There was a problem hiding this comment.
🟢 Approval recommended
Static review identified no blocking issues in the additive models, exports, documentation, or tests; tests were not executed during this review.
No open issues 🎉
What changed in this PR
Adds shared ontology data models to the Python SDK for future converter migration, without changing current converter dependencies or file I/O behavior.
Changes:
- Adds ontology and mapping models, including the deprecated embedded mapping form.
- Exports the new models and shares
OssieVersionbetween semantic-model and ontology documents. - Adds schema-parity, validation, nesting, and round-trip tests, plus a brief README description.
| File | Description |
|---|---|
python/tests/test_ontology_models.py |
Tests schema alignment, validation constraints, nesting, and round trips. |
python/src/ossie/models.py |
Defines ontology and mapping models and the shared version type. |
python/src/ossie/__init__.py |
Exports the new SDK types. |
python/README.md |
Documents ontology model coverage and distinguishes relationship types. |
Review effort: Balanced
…ontologies Make OssieDocument the base of every Ossie file root. It holds the version, version-first serialization and the to_ossie_* / from_ossie_* methods with their document checks (duplicate keys, nulls, non-finite numbers, cyclic aliases, missing version). - OssieSemanticModel extends OssieDocument and takes over the role of the old OssieDocument: it now carries version and the I/O methods. - OssieOntologyDocument is renamed OssieOntology and extends OssieDocument, so ontology files load with the same checks. - OssieOntologyMapping.semantic_model is typed OssieSemanticModel. This is a breaking change for code that builds or loads OssieDocument as a semantic model; it switches to OssieSemanticModel.
Pair the ontology file class with OssieSemanticModel, and avoid a clash with the ontology converter's runtime OssieOntology class in ossie_ontology/model.py, so both can be imported without an alias.
Match the ConceptComponent name the ontology converter already uses in ossie_ontology.spec, so the migration keeps the familiar name.
Summary
The ontology converter in apache/ossie-converters defines its own Pydantic models for ontology documents, in
ontology/src/ossie_ontology/spec.py(imported asossie_ontology.spec). The other converters already use the sharedossie.modelspackage from this repo for semantic models.This PR adds equivalent ontology models to
ossie.models, so the ontology converter can switch to the shared package instead of keeping its own copy. It also gives both document types one base class, andOssieDocumentbecomes that base (see below).Proposed document hierarchy
Before this PR, the same classes looked like this:
Why the new hierarchy is clearer:
ontology.jsoncalls its document an ontology, so the classes areOssieSemanticModelandOssieOntologyModel. Before, the general nameOssieDocumentwas used for one specific kind of file. That no longer works now that ontology files need a class too, and later mapping files will as well.OssieSemanticModelandOssieDocumentdescribed the same thing, with and withoutversion. Since 0.2.0.dev0 an embeddedsemantic_modelalso needs its ownversion, so a whole semantic model always has one. A standalone file and its embedded copy are now the same class.version, writingversionfirst, and the strict loaders (from_ossie_yaml/from_ossie_json) live inOssieDocument. The loaders reject duplicate keys, nulls, non-finite numbers, cyclic aliases and a missingversion. Ontology files get the same checks without copying the code.ontology/mapping.json), they become a thirdOssieDocumentsubclass, and nothing else changes.OssieDocument.name,descriptionandai_contextstay on each subclass rather than the base, because the schemas differ: the core schema requires a non-emptyname, whileontology.jsondoesn't.The cost is a breaking change for converters, described below.
What's added
New models that mirror
ontology/ontology.jsonnode for node:OssieOntologyModel,OssieConceptComponent(schemaOntologyComponent),OssieOntologyRelationship,OssieRole,OssieConceptType,OssieMultiplicityOssieConceptMapping,OssieObjectMapping,OssieReferentMapping,OssieLinkMapping,OssieOntologyMapping(the deprecated embedded form)OssieDocumentas the shared base ofOssieSemanticModelandOssieOntologyModel(see above)OssieOntologyModelgets the same I/O methods and document checks (duplicate keys, nulls, missingversion) that semantic model files already had. A new test checks that each model has the same properties, required set andadditionalProperties: falseas its schema node.The mapping classes are included because #458 has already merged, so they won't need to move a second time. The standalone mapping document (
ontology/mapping.json) is left out, because no converter reads it yet.Breaking change:
OssieDocumentis now the base classOssieSemanticModeltakes over the roleOssieDocumentused to have. It carriesversion(defaulting to0.2.0.dev0) and the I/O methods.Old code still imports, but fails at runtime:
OssieDocument(name=..., datasets=[...])andOssieDocument.from_ossie_yaml(...)on a semantic model file raiseValidationError, becausenameanddatasetsare not fields of the base.OssieDocument(name=..., datasets=[...])OssieSemanticModel(name=..., datasets=[...])OssieDocument.from_ossie_yaml(text)/from_ossie_json(text)OssieSemanticModel.from_ossie_yaml(text)/from_ossie_json(text)OssieSemanticModelwithoutversionOssieSemanticModelwithversion, which is serialized firstOssieOntologyMapping.semantic_model: OssieDocumentOssieOntologyMapping.semantic_model: OssieSemanticModelConverters that use
OssieDocumentneed the rename when they upgradeapache-ossie: dbt, hex, sigma, wisdom, and the ontology converter'sossie_to_spec/spec_to_ossie. Code that builds anOssieSemanticModeland serializes it now also gets aversionkey in the output.The ontology converter doesn't depend on the new ontology models yet and still uses its own
ossie_ontology.spec. The nameOssieOntologyModeldoesn't clash with the converter's runtime classOssieOntology(ossie_ontology/model.py), so both can be imported side by side when it migrates.Behaviour change when a converter moves from
ossie_ontology.spectoossie.modelsThe new models follow the existing
ossie.modelsapproach, notspec.py's. These are the deliberate differences:ossie_ontology.specossie.modelsValidationErrorextra="forbid"extra="forbid"(unchanged; onlyai_contextallows extras, per the schema)[]None; iterate withor []type, relationshipverbalizes,OntologyMap.concept_mappings.OntologyMap.namebecomes optionalanyOf: object and referent mappings needexpressionorreferent_mappings; concept mappings needobject_mappingsorlink_mappingsstrliteralsOssieConceptType,OssieMultiplicity,OssieDataTypeenumsai_contextobjectdictOssieAIContextObjectExpressiondialectsonlysqland/ordialects;{}is rejectedJoinPath.from_OssieRelationship.from_dataset(aliasfrom)OssieSpec.load_yaml/dump_yaml/dump_dictOssieOntologyModel.from_ossie_yaml/to_ossie_yaml/model_dump(mode="json", by_alias=True, exclude_none=True). Loading is stricter: duplicate keys, nulls and a missingversionare rejected19 of the 31 ontology fixtures in
ossie-converters/ontology/testsfail to validate under the new models. All 19 omitverbalizes, and 4 also haveexpression: {}. These fixtures already failossie validate, so the fix belongs in the fixtures, not the models.Two converter checks to keep in mind during the migration:
ossie_ontology/model.py) requires exactly one ofexpression/referent_mappings. The schema'sanyOfallows both, soossie.modelsdoes too, and the stricter check stays in the converter.OssieOntology.add_ontology_mapping(inossie_ontology/model.py) indexes mappings byname. Now thatnameis optional,spec_to_ossieshould either reject a missing name with a clear error or default it (for example tosemantic_model.name).Transition plan for
ossie_ontology.specWhen
ossie_ontologymoves toossie.models,ossie_ontology/spec.pystays as a thin re-export under the old names. That keeps open work (for example the LinkML converter, formerly #389) importing during the transition:ossie_ontology.specossie.modelsOssieSpecOssieOntologyModel(load_yaml→from_ossie_yaml,dump_yaml→to_ossie_yaml)ConceptComponentOssieConceptComponentRelationshipOssieOntologyRelationshipRoleOssieRoleOntologyMapping/ConceptMapping/ObjectMapping/ReferentMapping/LinkMappingOssieOntologyMapping/OssieConceptMapping/OssieObjectMapping/OssieReferentMapping/OssieLinkMappingSemanticModelOssieSemanticModelDataset/DatasetField/Metric/DimensionOssieDataset/OssieField/OssieMetric/OssieDimensionJoinPathOssieRelationshipExpression/DialectExpressionOssieExpression/OssieDialectExpressionCustomExtensionOssieCustomExtensionAiContext/DataType/CoreVersionOssieAIContext/OssieDataType/OssieVersionThe re-export keeps the names working; the behaviour still changes as described in the table above. The re-export is removed once nothing in progress imports the old path.
Related Issues
No linked issue. The converter-side migration will be tracked in apache/ossie-converters.
Checklist
Specification
core-spec/and follow the existing structure (N/A: no spec change)Ontology
ontology/are consistent with spec changes (N/A:ontology/is unchanged; the SDK now mirrors it)Converters
OssieDocumenttoOssieSemanticModelneeds a converters PR before they upgradeapache-ossie)Validation
validation/are updated if the spec changed (N/A)Documentation
docs/is updated to reflect any user-facing changes (N/A:python/README.mddocumentsOssieOntologyModel)CONTRIBUTING.mdis updated if the contribution process changed (N/A)Examples
examples/are added or updated for any new spec constructs (N/A: the tests validateexamples/flights.ontology.yaml)Tests
pytest/ CI green):uv run pytestinpython/gives 288 passedpython/tests/test_ontology_models.py)Compliance
dev/check-licensepasses)NOTICEand/orLICENSEhave been updated per ASF policy (N/A: nothing vendored)