# How to Use Semantica's Ontology Module for OWL and SHACL Generation

> Learn to generate OWL ontologies and SHACL shapes from Python dictionaries with Semantica's ontology module. Explore OWLGenerator and SHACLGenerator for seamless RDF serialization and constraint validation.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-09-05

---

**Semantica's ontology module converts Python dictionaries into valid OWL/RDF ontologies and SHACL validation shapes through two dedicated generators: `OWLGenerator` for RDF serialization and `SHACLGenerator` for constraint shapes.**

The `semantica-agi/semantica` repository provides a self-contained ontology package designed for developers who need programmatic ontology creation without deep RDF library expertise. The module splits functionality between OWL production and SHACL validation, sharing a common namespace management system for consistent IRI generation.

## Core Components Overview

Semantica's ontology architecture centers on three primary classes:

- **`OWLGenerator`** ([`semantica/ontology/owl_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/owl_generator.py)) — Serializes ontologies to OWL/RDF in multiple formats (Turtle, RDF/XML, JSON-LD, N3). Uses **rdflib** when available, with automatic fallback to a fast string formatter.
- **`SHACLGenerator`** ([`semantica/ontology/ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_generator.py)) — Produces SHACL shapes with support for class inheritance, three quality tiers (basic/standard/strict), and domain-less property attachment.
- **`NamespaceManager`** ([`semantica/ontology/namespace_manager.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/namespace_manager.py)) — Generates stable, human-readable IRIs using PascalCase for classes and camelCase for properties.

Both generators integrate with Semantica's internal progress tracker and logger, emitting status updates when verbose mode is enabled.

## Understanding the OWLGenerator Class

The `OWLGenerator` class in [`semantica/ontology/owl_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/owl_generator.py) handles the full OWL/RDF production pipeline. It accepts an ontology dictionary and produces either an **rdflib Graph** object or a serialized string.

### OWL Generation Workflow

1. **Prepare ontology data** — Define `classes`, `properties`, and optional metadata (`uri`, `namespace`, `description`, `version`).
2. **Configure namespace management** — Optionally pass a custom `NamespaceManager` or rely on the default base URI `https://semantica.dev/ontology/`.
3. **Instantiate and generate** — Create `OWLGenerator` with desired configuration, then call `generate_owl()` or `export_owl()`.

### OWL Code Example

```python
from semantica.ontology import OWLGenerator, NamespaceManager

# Define the ontology structure

ontology = {
    "uri": "https://example.org/ontology/",
    "name": "Demo Ontology",
    "version": "1.0",
    "classes": [
        {"name": "Person", "description": "A human being"},
        {"name": "Organization", "description": "A legal entity"},
    ],
    "properties": [
        {"name": "hasName", "domain": "Person", "range": "string"},
        {"name": "memberOf", "domain": "Person", "range": "Organization"},
    ],
}

# Optional: custom namespace manager

ns_manager = NamespaceManager(
    base_uri="https://example.org/ontology/", 
    version="1.0"
)

# Generate OWL graph (returns rdflib.Graph when rdflib is available)

owl_gen = OWLGenerator(namespace_manager=ns_manager)
graph = owl_gen.generate_owl(ontology)

# Serialize to Turtle string

turtle_output = owl_gen.generate_owl(ontology, format="turtle")
print(turtle_output)

# Export directly to file

owl_gen.export_owl(ontology, "demo_ontology.ttl", format="turtle")

```

The generator's fallback mode (lines 90-94 in [`owl_generator.py`](https://github.com/semantica-agi/semantica/blob/main/owl_generator.py)) ensures operation in minimal environments: if **rdflib** import fails, the class warns via logger and switches to a deterministic string formatter.

## Understanding the SHACLGenerator Class

The `SHACLGenerator` class in [`semantica/ontology/ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_generator.py) implements a six-stage pipeline for shape production: class indexing → node shape creation → property attachment → inheritance propagation → quality-tier enforcement → serialization.

### SHACL Quality Tiers

The `quality_tier` parameter controls validation strictness:

- **basic** — Open shapes, minimal constraints
- **standard** — Balanced validation with common constraints
- **strict** — Closed shapes (`sh:closed`), maximum constraint enforcement

### Namespace Isolation in SHACL

The generator maintains separation between two namespaces (lines 40-45 in [`ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/ontology_generator.py)):

- **`base_uri`** — IRI space for the shapes themselves
- **`target_namespace`** — IRI space of the ontology being validated

This prevents accidental validation against incorrect IRI spaces.

### SHACL Code Example

```python
from semantica.ontology import SHACLGenerator, NamespaceManager

ontology = {
    "uri": "https://example.org/ontology/",
    "classes": [
        {"name": "Person"},
        {"name": "Organization"},
    ],
    "properties": [
        {"name": "hasName", "domain": "Person", "range": "string"},
        {"name": "memberOf", "domain": "Person", "range": "Organization"},
    ],
}

ns_manager = NamespaceManager(
    base_uri="https://example.org/ontology/", 
    version="1.0"
)

# Configure SHACL generator with quality tier

shacl_gen = SHACLGenerator(
    base_uri="https://example.org/shapes/",
    target_namespace="https://example.org/ontology/",
    quality_tier="standard",
    namespace_manager=ns_manager,
)

# Build SHACL graph

shacl_graph = shacl_gen.generate(ontology)

# Serialize (default: Turtle)

shacl_turtle = shacl_gen.serialize(shacl_graph, format="turtle")
print(shacl_turtle)

# Write to file

with open("demo_shapes.ttl", "w", encoding="utf-8") as f:
    f.write(shacl_turtle)

```

## Using the NamespaceManager

The `NamespaceManager` class ([`semantica/ontology/namespace_manager.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/namespace_manager.py)) provides deterministic IRI creation across both generators. Key behaviors:

- **Class naming** — Converts to PascalCase automatically
- **Property naming** — Converts to camelCase automatically
- **Version incorporation** — Appends version strings to base URIs when specified

Both generators accept `namespace_manager` as an optional parameter, falling back to defaults with base URI `https://semantica.dev/ontology/` when omitted.

## CLI Interface for Batch Operations

Semantica exposes generator functionality through its CLI ([`semantica/cli.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py)):

```bash

# Generate OWL ontology (default Turtle output)

semantica ontology generate --output demo_ontology.ttl

# Generate SHACL shapes with strict validation tier

semantica ontology shacl generate --tier strict --output demo_shapes.ttl

```

The CLI wraps the same Python classes, forwarding all configuration options and respecting the `--verbose` flag for progress output.

## Configuration and Extensibility

Both generators accept a free-form `config` dictionary and keyword arguments, enabling:

- Custom `NamespaceManager` injection
- Default format specification
- Additional rdflib serialization options
- Downstream tool integration (LangChain connectors, custom pipelines)

This design allows the ontology module to serve as a foundation for specialized tooling while maintaining a simple interface for direct use.

## Summary

- **Import path** — All public classes (`OWLGenerator`, `SHACLGenerator`, `NamespaceManager`) are available from `semantica.ontology`.
- **OWL generation** — Use `OWLGenerator` in [`semantica/ontology/owl_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/owl_generator.py) for RDF/Turtle/JSON-LD output with automatic rdflib fallback.
- **SHACL generation** — Use `SHACLGenerator` in [`semantica/ontology/ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_generator.py) for validation shapes with tiered strictness control.
- **Namespace handling** — `NamespaceManager` in [`semantica/ontology/namespace_manager.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/namespace_manager.py) ensures consistent, versioned IRI generation.
- **Quality tiers** — SHACL supports "basic", "standard", and "strict" validation levels via the `quality_tier` parameter.
- **CLI availability** — Batch operations supported through `semantica ontology generate` and `semantica ontology shacl generate` commands.

## Frequently Asked Questions

### What Python dependencies are required for Semantica's ontology module?

The ontology module requires no mandatory external dependencies. **rdflib** enables full Graph object functionality but is not strictly required—`OWLGenerator` automatically falls back to a string formatter when rdflib is unavailable, emitting a warning through the internal logger.

### How does the SHACL quality tier affect generated shapes?

The `quality_tier` parameter in `SHACLGenerator` controls constraint strictness: "basic" produces open shapes with minimal validation, "standard" adds common property constraints, and "strict" marks shapes as `sh:closed` to reject unexpected properties. The tier is enforced during the fifth stage of the six-stage generation pipeline.

### Can I validate data against generated SHACL shapes using Semantica?

Semantica's ontology module focuses on shape *generation*, not validation execution. Generated SHACL shapes conform to standard SHACL specifications and can be validated using any compatible engine (pySHACL, TopBraid, Apache Jena). The [`semantica/visualization/ontology_visualizer.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/visualization/ontology_visualizer.py) module provides debugging visualizations for generated graphs.

### Why does SHACLGenerator use separate base_uri and target_namespace parameters?

This separation prevents validation against the wrong IRI space. The `base_uri` identifies the shapes themselves, while `target_namespace` identifies the ontology being validated. According to lines 40-45 in [`ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/ontology_generator.py), this isolation ensures that shape constraints reference the correct data model rather than accidentally self-referencing.