Skip to content

BYOD Function Implementation (MM)

Scenarios

Scenarios Diagram

SystemCombined DataRDF Data ModelClient DataCore DataSchema (RDFS)EntitiesAttributesTypesValidation RulesLookup ListsSimple Knowledge Organization System (SKOS)SearchAdvanced InsightsNatural Language InterfaceVisualisationABACNotificationsClientCoreSystemUserprovidesprovidesextendsusesrequiresrequiresimplementsdepends ondepends oninterfaces withinterfaces withdepends ondepends ondepends onhashashascan beimplementsvalidated byimplements (RDFS)implements (RDFS)
520. plantuml.com | 520: Web server is returning an unknown error

Web server is returning an unknown error Error code 520

Visit cloudflare.com for more information.
2025-08-13 11:03:58 UTC
You

Browser

Working
London

Cloudflare

Working
www.plantuml.com

Host

Error

What happened?

There is an unknown connection issue between Cloudflare and the origin web server. As a result, the web page can not be displayed.

What can I do?

If you are a visitor of this website:

Please try again in a few minutes.

If you are the owner of this website:

There is an issue between Cloudflare's cache and your origin web server. Cloudflare monitors for these errors and automatically investigates the cause. To help support the investigation, you can pull the corresponding error log from your web server and submit it our support team. Please include the Ray ID (which is at the bottom of this error page). Additional troubleshooting resources.

Query Core and Custom Data Together (Custom Insights)

Outline Use Cases (Stories)

Create lookup lists -> SKOS

  • A top-level concept (like "Material Type")
  • Narrower concepts under it (like "Broadcast" and "Online")
  • And even narrower subtypes under those (like "TV", "Cinema", "YouTube", "VOD")

Structure:

Material Type
β”œβ”€β”€ Broadcast
β”‚   β”œβ”€β”€ TV
β”‚   └── Cinema
└── Online
    β”œβ”€β”€ YouTube
    └── VOD

DB Table: uuid, list_name, skos_blob (jsonb) port: RDFLIB adapter: read file from into rdflib

Example in Turtle (RDF)

CREATE TABLE material_type_schemes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    skos_namespace text, -- http://clearcast.co.uk/schema#
    list_name TEXT NOT NULL,
    skos_blob JSONB NOT NULL
);

Create List Use Case

import asyncio
import uuid
from sqlalchemy import (
    Column, Text, JSON, text
)
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# --- Database setup ---
DATABASE_URL = "postgresql+asyncpg://user:password@localhost:5432/your_database"

engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
Base = declarative_base()

# --- Model ---
class MaterialTypeScheme(Base):
    __tablename__ = "lookup_lists"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    list_name = Column(Text, nullable=False)
    skos_blob = Column(JSONB, nullable=False)

# --- CRUD Functions ---
async def init_db():
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

async def create_scheme(session: AsyncSession, list_name: str, skos_blob: dict):
    scheme = MaterialTypeScheme(list_name=list_name, skos_blob=skos_blob)
    session.add(scheme)
    await session.commit()
    return scheme

async def get_scheme(session: AsyncSession, scheme_id: uuid.UUID):
    return await session.get(MaterialTypeScheme, scheme_id)

async def update_scheme(session: AsyncSession, scheme_id: uuid.UUID, updated_blob: dict):
    scheme = await session.get(MaterialTypeScheme, scheme_id)
    if scheme:
        scheme.skos_blob = updated_blob
        await session.commit()
    return scheme

async def delete_scheme(session: AsyncSession, scheme_id: uuid.UUID):
    scheme = await session.get(MaterialTypeScheme, scheme_id)
    if scheme:
        await session.delete(scheme)
        await session.commit()
        return True
    return False

# --- Sample usage ---
async def main():
    await init_db()

    async with AsyncSessionLocal() as session:
        # Sample SKOS JSON blob (you can insert your actual JSON-LD here)

        # TODO use real SKOS here from RDFLib
        sample_skos = {
            "@context": {"skos": "http://www.w3.org/2004/02/skos/core#"},
            "@graph": [{"@id": "example", "prefLabel": "Example"}]
        }

        # Create
        scheme = await create_scheme(session, "Example List", sample_skos)
        print("Created:", scheme.id)

        # Read
        fetched = await get_scheme(session, scheme.id)
        print("Fetched:", fetched.list_name)

        # Update
        sample_skos["@graph"][0]["prefLabel"] = "Updated Example"
        updated = await update_scheme(session, scheme.id, sample_skos)
        print("Updated:", updated.skos_blob)

        # Delete
        deleted = await delete_scheme(session, scheme.id)
        print("Deleted:", deleted)

if __name__ == "__main__":
    asyncio.run(main())

Maintain List Use Case

import asyncio
import uuid
from typing import Optional

from sqlalchemy import Column, Text
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

from rdflib import Graph, Namespace, URIRef, Literal
from rdflib.namespace import SKOS

# --- DB Setup ---
DATABASE_URL = "postgresql+asyncpg://user:password@localhost:5432/your_database"

engine = create_async_engine(DATABASE_URL, echo=False)
AsyncSessionLocal = sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
Base = declarative_base()

# --- RDF Setup ---
CLEARCAST = Namespace("http://clearcast.co.uk/schema#")

# --- Model ---
class MaterialTypeScheme(Base):
    __tablename__ = "material_type_schemes"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    list_name = Column(Text, nullable=False)
    skos_blob = Column(JSONB, nullable=False)

# --- Helper Functions ---
def load_graph(jsonld_blob: dict) -> Graph:
    g = Graph()
    g.parse(data=str(jsonld_blob), format="json-ld")
    return g

def graph_to_jsonld(graph: Graph) -> dict:
    return graph.serialize(format="json-ld", indent=2)

# --- CRUD for RDF Concepts ---
async def get_graph_from_db(session: AsyncSession, scheme_id: uuid.UUID) -> tuple[MaterialTypeScheme, Graph]:
    scheme = await session.get(MaterialTypeScheme, scheme_id)
    graph = load_graph(scheme.skos_blob)
    return scheme, graph

async def add_concept(session: AsyncSession, scheme_id: uuid.UUID, concept_id: str, label: str):
    scheme, graph = await get_graph_from_db(session, scheme_id)
    concept_uri = CLEARCAST[concept_id]

    graph.add((concept_uri, SKOS.prefLabel, Literal(label, lang='en')))
    graph.add((concept_uri, SKOS.inScheme, URIRef(CLEARCAST["MaterialTypeScheme"])))
    graph.add((concept_uri, SKOS.broader, URIRef(CLEARCAST["MaterialType"])))

    scheme.skos_blob = graph_to_jsonld(graph)
    await session.commit()

async def update_concept_label(session: AsyncSession, scheme_id: uuid.UUID, concept_id: str, new_label: str):
    scheme, graph = await get_graph_from_db(session, scheme_id)
    concept_uri = CLEARCAST[concept_id]

    # Remove old labels
    graph.remove((concept_uri, SKOS.prefLabel, None))
    # Add new label
    graph.add((concept_uri, SKOS.prefLabel, Literal(new_label, lang='en')))

    scheme.skos_blob = graph_to_jsonld(graph)
    await session.commit()

async def delete_concept(session: AsyncSession, scheme_id: uuid.UUID, concept_id: str):
    scheme, graph = await get_graph_from_db(session, scheme_id)
    concept_uri = CLEARCAST[concept_id]

    graph.remove((concept_uri, None, None))
    graph.remove((None, None, concept_uri))  # Clean any incoming links

    scheme.skos_blob = graph_to_jsonld(graph)
    await session.commit()

async def get_concept(session: AsyncSession, scheme_id: uuid.UUID, concept_id: str) -> Optional[dict]:
    _, graph = await get_graph_from_db(session, scheme_id)
    concept_uri = CLEARCAST[concept_id]

    result = {}
    for p, o in graph.predicate_objects(concept_uri):
        result[str(p)] = str(o)
    return result if result else None

# --- Example Usage ---
async def main():
    async with AsyncSessionLocal() as session:
        example_id = uuid.UUID("PUT-YOUR-SCHEME-ID-HERE")

        await add_concept(session, example_id, "SocialMedia", "Social Media")
        print("Added.")

        concept = await get_concept(session, example_id, "SocialMedia")
        print("Fetched:", concept)

        await update_concept_label(session, example_id, "SocialMedia", "Updated Social Media")
        print("Updated.")

        await delete_concept(session, example_id, "SocialMedia")
        print("Deleted.")

if __name__ == "__main__":
    asyncio.run(main())
{
  "@context": {
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "clearcast": "http://clearcast.co.uk/schema#",
    "prefLabel": "skos:prefLabel",
    "inScheme": "skos:inScheme",
    "broader": "skos:broader",
    "Concept": "skos:Concept",
    "ConceptScheme": "skos:ConceptScheme"
  },
  "@graph": [
    {
      "@id": "clearcast:MaterialTypeScheme",
      "@type": "ConceptScheme",
      "prefLabel": {
        "@value": "Material Types",
        "@language": "en"
      }
    },
    {
      "@id": "clearcast:MaterialType",
      "@type": "Concept",
      "prefLabel": {
        "@value": "Material Type",
        "@language": "en"
      },
      "inScheme": {
        "@id": "clearcast:MaterialTypeScheme"
      }
    },
    {
      "@id": "clearcast:Broadcast",
      "@type": "Concept",
      "prefLabel": {
        "@value": "Broadcast",
        "@language": "en"
      },
      "broader": {
        "@id": "clearcast:MaterialType"
      },
      "inScheme": {
        "@id": "clearcast:MaterialTypeScheme"
      }
    },
    {
      "@id": "clearcast:Online",
      "@type": "Concept",
      "prefLabel": {
        "@value": "Online",
        "@language": "en"
      },
      "broader": {
        "@id": "clearcast:MaterialType"
      },
      "inScheme": {
        "@id": "clearcast:MaterialTypeScheme"
      }
    },
    {
      "@id": "clearcast:TV",
      "@type": "Concept",
      "prefLabel": {
        "@value": "TV",
        "@language": "en"
      },
      "broader": {
        "@id": "clearcast:Broadcast"
      },
      "inScheme": {
        "@id": "clearcast:MaterialTypeScheme"
      }
    },
    {
      "@id": "clearcast:Cinema",
      "@type": "Concept",
      "prefLabel": {
        "@value": "Cinema",
        "@language": "en"
      },
      "broader": {
        "@id": "clearcast:Broadcast"
      },
      "inScheme": {
        "@id": "clearcast:MaterialTypeScheme"
      }
    },
    {
      "@id": "clearcast:YouTube",
      "@type": "Concept",
      "prefLabel": {
        "@value": "YouTube",
        "@language": "en"
      },
      "broader": {
        "@id": "clearcast:Online"
      },
      "inScheme": {
        "@id": "clearcast:MaterialTypeScheme"
      }
    },
    {
      "@id": "clearcast:VOD",
      "@type": "Concept",
      "prefLabel": {
        "@value": "VOD",
        "@language": "en"
      },
      "broader": {
        "@id": "clearcast:Online"
      },
      "inScheme": {
        "@id": "clearcast:MaterialTypeScheme"
      }
    }
  ]
}
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix clearcast: <http://clearcast.co.uk/schema#> .

# Concept scheme
clearcast:MaterialTypeScheme a skos:ConceptScheme ;
    skos:prefLabel "Material Types"@en .

# Top-level concept
clearcast:MaterialType a skos:Concept ;
    skos:prefLabel "Material Type"@en ;
    skos:inScheme clearcast:MaterialTypeScheme .

# First-level children
clearcast:Broadcast a skos:Concept ;
    skos:prefLabel "Broadcast"@en ;
    skos:broader clearcast:MaterialType ;
    skos:inScheme clearcast:MaterialTypeScheme .

clearcast:Online a skos:Concept ;
    skos:prefLabel "Online"@en ;
    skos:broader clearcast:MaterialType ;
    skos:inScheme clearcast:MaterialTypeScheme .

# Second-level children
clearcast:TV a skos:Concept ;
    skos:prefLabel "TV"@en ;
    skos:broader clearcast:Broadcast ;
    skos:inScheme clearcast:MaterialTypeScheme .

clearcast:Cinema a skos:Concept ;
    skos:prefLabel "Cinema"@en ;
    skos:broader clearcast:Broadcast ;
    skos:inScheme clearcast:MaterialTypeScheme .

clearcast:YouTube a skos:Concept ;
    skos:prefLabel "YouTube"@en ;
    skos:broader clearcast:Online ;
    skos:inScheme clearcast:MaterialTypeScheme .

clearcast:VOD a skos:Concept ;
    skos:prefLabel "VOD"@en ;
    skos:broader clearcast:Online ;
    skos:inScheme clearcast:MaterialTypeScheme .

Bonus Tips:

  • Use skos:broader and skos:narrower to create hierarchical relationships.
  • In UI dropdowns, you can render this as nested menus or tree selectors.
  • Use skos:prefLabel for display, and use the URIs as stored values.

You have a Card, and it has a custom property clearcast:materialType.
Instead of just using a plain string (e.g. "TV"), you link it to a SKOS Concept URI, e.g. clearcast:TV.


Example in Turtle (RDF format)

@prefix flow: <http://northell.com/media-magic/flow#> .
@prefix clearcast: <http://clearcast.co.uk/schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix ex: <http://example.org/instance#> .

# Instance of a Card
ex:Card123 a flow:Card ;
    clearcast:materialType clearcast:TV .

# TV is a concept in the SKOS scheme
clearcast:TV a skos:Concept ;
    skos:inScheme clearcast:MaterialTypeScheme ;
    skos:prefLabel "TV"@en ;
    skos:definition "Television broadcast format"@en .

Why This Matters

  • Your UI can show a dropdown by querying skos:Concept in clearcast:MaterialTypeScheme.
  • Users pick from this list.
  • The selected URI (like clearcast:TV) is saved as the value.
  • This allows for controlled vocabularies, multilingual labels, definitions, and compatibility with SPARQL-based systems.

Extend Core Schema (entities and attributes) -> RDFS ()

MM Core Data Model

πŸ” Strategy Pattern in Media Magic Flow

The Strategy Pattern allows the behavior of a class to be selected at runtime. In the context of your kanban-style system, this means:

  • Core entities like Card can have different behaviors or roles, e.g., VideoCard, ScriptCard, etc.
  • These specialisms are interchangeable, allowing dynamic configuration without altering the core logic.
  • Each specialism adds domain-specific functionality.

βœ… Functional Enhancements via Strategy Pattern

  • VideoCard: adds video format metadata, preview rendering
  • ScriptCard: supports rich text editing, versioning, and language tagging
  • StoryBoardCard: image sequences, transitions
  • BriefCard: links to global guidelines and references

Each specialism extends Card but with unique, pluggable behaviors.


🧠 RDFS + SKOS Schema (with Namespace)

Let’s define: - RDFS for your data model - SKOS for taxonomy (e.g., types of Cards) - Namespace:
- northell: β†’ http://northell.com/
- mm: β†’ http://northell.com/media-magic#
- flow: β†’ http://northell.com/media-magic/flow#
- skos: β†’ http://www.w3.org/2004/02/skos/core#


🧩 RDF Schema Definition (Turtle Syntax)

@prefix northell: <http://northell.com/> .
@prefix mm: <http://northell.com/media-magic#> .
@prefix flow: <http://northell.com/media-magic/flow#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

# Core Classes
flow:Workspace a rdfs:Class .
flow:Board a rdfs:Class .
flow:Card a rdfs:Class .
flow:Lane a rdfs:Class .

# Core Properties
flow:name a rdf:Property ; rdfs:domain rdfs:Resource ; rdfs:range xsd:string .
flow:description a rdf:Property ; rdfs:domain rdfs:Resource ; rdfs:range xsd:string .
flow:category a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:string .
flow:type a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:string .
flow:language a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:string .
flow:upload a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:anyURI .
flow:status a rdf:Property ; rdfs:domain flow:Lane ; rdfs:range xsd:string .
flow:dueDate a rdf:Property ; rdfs:domain flow:Lane ; rdfs:range xsd:date .

# Specializations (Strategy Pattern)
flow:VideoCard a rdfs:Class ; rdfs:subClassOf flow:Card .
flow:ScriptCard a rdfs:Class ; rdfs:subClassOf flow:Card .
flow:BriefCard a rdfs:Class ; rdfs:subClassOf flow:Card .
flow:StoryboardCard a rdfs:Class ; rdfs:subClassOf flow:Card .

# SKOS Specialism Taxonomy
mm:CardTypeScheme a skos:ConceptScheme ; skos:prefLabel "Card Specialisms"@en .

mm:VideoCard a skos:Concept ;
    skos:inScheme mm:CardTypeScheme ;
    skos:prefLabel "Video Card"@en ;
    skos:definition "Card used for video asset handling and metadata." .

mm:ScriptCard a skos:Concept ;
    skos:inScheme mm:CardTypeScheme ;
    skos:prefLabel "Script Card"@en ;
    skos:definition "Card used for managing scripts with language and versioning support." .

mm:BriefCard a skos:Concept ;
    skos:inScheme mm:CardTypeScheme ;
    skos:prefLabel "Brief Card"@en ;
    skos:definition "Used for creative briefs and global guideline linkage." .

mm:StoryboardCard a skos:Concept ;
    skos:inScheme mm:CardTypeScheme ;
    skos:prefLabel "Storyboard Card"@en ;
    skos:definition "Visual planning card for storytelling and shot sequencing." .

🧰 Implementation Notes

  • UI Picklists: can query the SKOS taxonomy via SPARQL to build dropdowns for Card types.
  • Strategy Mapping: in code, associate each SKOS concept with a class implementing the behavior (e.g., VideoCardBehavior implements CardBehavior).
  • Pluggability: new types can be added just by defining new subclasses and SKOS concepts.

from rdflib import Graph, Namespace, RDF, RDFS, XSD, SKOS, Literal, URIRef

# Define Namespaces
northell = Namespace("http://northell.com/")
mm = Namespace("http://northell.com/media-magic#")
flow = Namespace("http://northell.com/media-magic/flow#")

# Create Graph
g = Graph()

# Bind namespaces for readability
g.bind("northell", northell)
g.bind("mm", mm)
g.bind("flow", flow)
g.bind("skos", SKOS)

# Define core classes
core_classes = ['Workspace', 'Board', 'Card', 'Lane']
for cls in core_classes:
    g.add((flow[cls], RDF.type, RDFS.Class))

# Define properties
properties = {
    'name': RDFS.Resource,
    'description': RDFS.Resource,
    'category': flow.Card,
    'type': flow.Card,
    'language': flow.Card,
    'upload': flow.Card,
    'status': flow.Lane,
    'dueDate': flow.Lane
}
ranges = {
    'name': XSD.string,
    'description': XSD.string,
    'category': XSD.string,
    'type': XSD.string,
    'language': XSD.string,
    'upload': XSD.anyURI,
    'status': XSD.string,
    'dueDate': XSD.date
}
for prop, domain in properties.items():
    g.add((flow[prop], RDF.type, RDF.Property))
    g.add((flow[prop], RDFS.domain, domain))
    g.add((flow[prop], RDFS.range, ranges[prop]))

# Define specializations
specializations = ['VideoCard', 'ScriptCard', 'BriefCard', 'StoryboardCard']
for spec in specializations:
    g.add((flow[spec], RDF.type, RDFS.Class))
    g.add((flow[spec], RDFS.subClassOf, flow.Card))

# Define SKOS ConceptScheme
g.add((mm.CardTypeScheme, RDF.type, SKOS.ConceptScheme))
g.add((mm.CardTypeScheme, SKOS.prefLabel, Literal("Card Specialisms", lang="en")))

# Define SKOS concepts
concepts = {
    'VideoCard': "Card used for video asset handling and metadata.",
    'ScriptCard': "Card used for managing scripts with language and versioning support.",
    'BriefCard': "Used for creative briefs and global guideline linkage.",
    'StoryboardCard': "Visual planning card for storytelling and shot sequencing."
}
for concept, definition in concepts.items():
    g.add((mm[concept], RDF.type, SKOS.Concept))
    g.add((mm[concept], SKOS.inScheme, mm.CardTypeScheme))
    g.add((mm[concept], SKOS.prefLabel, Literal(concept.replace("Card", " Card"), lang="en")))
    g.add((mm[concept], SKOS.definition, Literal(definition, lang="en")))

# Serialize the graph to a Turtle file
file_path = "/mnt/data/media_magic_flow_schema.ttl"
g.serialize(destination=file_path, format="turtle")

file_path

Custom Clearcast Attributes

Clearcast Data Model

from rdflib import Namespace, Graph, RDF, RDFS, SKOS, XSD, Literal

# Define Namespaces
northell = Namespace("http://northell.com/")
mm = Namespace("http://northell.com/media-magic#")
flow = Namespace("http://northell.com/media-magic/flow#")
clearcast = Namespace("http://clearcast.co.uk/schema#")

# Create RDF graph
g = Graph()

# Bind namespaces
g.bind("northell", northell)
g.bind("mm", mm)
g.bind("flow", flow)
g.bind("clearcast", clearcast)
g.bind("skos", SKOS)

# Extend Card and Board with custom Clearcast metadata

# Clearcast additions to Board
board_custom_attrs = {
    "agency": XSD.string,
    "advertiser": XSD.string
}
for attr, datatype in board_custom_attrs.items():
    g.add((clearcast[attr], RDF.type, RDF.Property))
    g.add((clearcast[attr], RDFS.domain, flow.Board))
    g.add((clearcast[attr], RDFS.range, datatype))

# Clearcast additions to Card
card_custom_attrs = {
    "materialType": XSD.string,
    "duration": XSD.duration,
    "clockNumber": XSD.string,
    "submitForClearance": XSD.boolean
}
for attr, datatype in card_custom_attrs.items():
    g.add((clearcast[attr], RDF.type, RDF.Property))
    g.add((clearcast[attr], RDFS.domain, flow.Card))
    g.add((clearcast[attr], RDFS.range, datatype))

# Accessibility extensions
accessibility_attrs = {
    "intentionallyQuiet": XSD.boolean,
    "audioDescription": XSD.boolean,
    "subtitles": XSD.boolean,
    "subtitleProvider": XSD.string
}
for attr, datatype in accessibility_attrs.items():
    g.add((clearcast[attr], RDF.type, RDF.Property))
    g.add((clearcast[attr], RDFS.domain, flow.Card))
    g.add((clearcast[attr], RDFS.range, datatype))

# SKOS Concept Scheme for Material Types
g.add((clearcast.MaterialTypeScheme, RDF.type, SKOS.ConceptScheme))
g.add((clearcast.MaterialTypeScheme, SKOS.prefLabel, Literal("Material Types", lang="en")))

material_types = [
    ("TV", "Television broadcast format"),
    ("VOD", "Video on demand format"),
    ("Cinema", "Cinema release format"),
    ("Online", "Online or digital format")
]

for code, definition in material_types:
    uri = clearcast[code]
    g.add((uri, RDF.type, SKOS.Concept))
    g.add((uri, SKOS.inScheme, clearcast.MaterialTypeScheme))
    g.add((uri, SKOS.prefLabel, Literal(code, lang="en")))
    g.add((uri, SKOS.definition, Literal(definition, lang="en")))

# Serialize to file
file_path = "/mnt/data/clearcast_extension.ttl"
g.serialize(destination=file_path, format="turtle")

file_path

``` text @prefix clearcast: http://clearcast.co.uk/schema# . @prefix flow: http://northell.com/media-magic/flow# . @prefix rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# . @prefix rdfs: http://www.w3.org/2000/01/rdf-schema# . @prefix skos: http://www.w3.org/2004/02/skos/core# . @prefix xsd: http://www.w3.org/2001/XMLSchema# .

clearcast:Cinema a skos:Concept ; skos:definition "Cinema release format"@en ; skos:inScheme clearcast:MaterialTypeScheme ; skos:prefLabel "Cinema"@en .

clearcast:Online a skos:Concept ; skos:definition "Online or digital format"@en ; skos:inScheme clearcast:MaterialTypeScheme ; skos:prefLabel "Online"@en .

clearcast:TV a skos:Concept ; skos:definition "Television broadcast format"@en ; skos:inScheme clearcast:MaterialTypeScheme ; skos:prefLabel "TV"@en .

clearcast:VOD a skos:Concept ; skos:definition "Video on demand format"@en ; skos:inScheme clearcast:MaterialTypeScheme ; skos:prefLabel "VOD"@en .

clearcast:advertiser a rdf:Property ; rdfs:domain flow:Board ; rdfs:range xsd:string .

clearcast:agency a rdf:Property ; rdfs:domain flow:Board ; rdfs:range xsd:string .

clearcast:audioDescription a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:boolean .

clearcast:clockNumber a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:string .

clearcast:duration a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:duration .

clearcast:intentionallyQuiet a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:boolean .

clearcast:materialType a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:string .

clearcast:submitForClearance a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:boolean .

clearcast:subtitleProvider a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:string .

clearcast:subtitles a rdf:Property ; rdfs:domain flow:Card ; rdfs:range xsd:boolean .

clearcast:MaterialTypeScheme a skos:ConceptScheme ; skos:prefLabel "Material Types"@en . ```