Skip to content

defined_namespace_creator

This rdflib Python script creates a DefinedNamespace Python file from a given RDF file

It is a very simple script: it finds all things defined in the RDF file within a given namespace:

<thing> a ?x

where ?x is anything and <thing> starts with the given namespace

Nicholas J. Car, Dec, 2021

Functions:

Attributes:

args module-attribute

args = parse_args()

elements module-attribute

elements = get_target_namespace_elements(g, target_namespace)

fmt module-attribute

fmt = guess_format(ontology_file)

g module-attribute

g = parse(ontology_file, format=fmt)

output_file_name module-attribute

output_file_name = cwd() / f'_{object_id}.py'

parser module-attribute

parser = ArgumentParser()

get_target_namespace_elements

get_target_namespace_elements(g: Graph, target_namespace: str) -> Tuple[List[Tuple[str, str]], List[str], List[str]]
Source code in rdflib/tools/defined_namespace_creator.py
def get_target_namespace_elements(
    g: Graph, target_namespace: str
) -> Tuple[List[Tuple[str, str]], List[str], List[str]]:
    namespaces = {"dcterms": DCTERMS, "owl": OWL, "rdfs": RDFS, "skos": SKOS}
    q = """
        SELECT ?s (GROUP_CONCAT(DISTINCT STR(?def)) AS ?defs)
        WHERE {
            # all things in the RDF data (anything RDF.type...)
            ?s a ?o .

            # get any definitions, if they have one
            OPTIONAL {
                ?s dcterms:description|rdfs:comment|skos:definition ?def
            }

            # only get results for the target namespace (supplied by user)
            FILTER STRSTARTS(STR(?s), "xxx")
            FILTER (STR(?s) != "xxx")
        }
        GROUP BY ?s
        """.replace(
        "xxx", target_namespace
    )
    elements: List[Tuple[str, str]] = []
    for r in g.query(q, initNs=namespaces):
        if TYPE_CHECKING:
            assert isinstance(r, ResultRow)
        elements.append((str(r[0]), str(r[1])))

    elements.sort(key=lambda tup: tup[0])

    elements_strs: List[str] = []
    non_python_elements_strs: List[str] = []
    for e in elements:
        name = e[0].replace(target_namespace, "")
        desc = e[1].replace("\n", " ")
        if name.isidentifier() and not keyword.iskeyword(name):
            elements_strs.append(f"    {name}: URIRef  # {desc}\n")
        else:
            non_python_elements_strs.append(f"""        "{name}",  # {desc}\n""")

    return elements, elements_strs, non_python_elements_strs

make_dn_file

make_dn_file(output_file_name: Path, target_namespace: str, elements_strs: Iterable[str], non_python_elements_strs: List[str], object_id: str, fail: bool) -> None
Source code in rdflib/tools/defined_namespace_creator.py
def make_dn_file(
    output_file_name: Path,
    target_namespace: str,
    elements_strs: Iterable[str],
    non_python_elements_strs: List[str],
    object_id: str,
    fail: bool,
) -> None:
    header = f'''from rdflib.namespace import DefinedNamespace, Namespace
from rdflib.term import URIRef


class {object_id}(DefinedNamespace):
    """
    DESCRIPTION_EDIT_ME_!

    Generated from: SOURCE_RDF_FILE_EDIT_ME_!
    Date: {datetime.datetime.utcnow()}
    """
'''
    with open(output_file_name, "w") as f:
        f.write(header)
        f.write("\n")
        f.write(f'    _NS = Namespace("{target_namespace}")')
        f.write("\n\n")
        if fail:
            f.write("    _fail = True")
            f.write("\n\n")
        f.writelines(elements_strs)

        if len(non_python_elements_strs) > 0:
            f.write("\n")
            f.write("    # Valid non-python identifiers")
            f.write("\n")
            f.write("    _extras = [")
            f.write("\n")
            f.writelines(non_python_elements_strs)
            f.write("    ]")
            f.write("\n")

validate_namespace

validate_namespace(namespace: str) -> None
Source code in rdflib/tools/defined_namespace_creator.py
def validate_namespace(namespace: str) -> None:
    if not namespace.endswith(("/", "#")):
        raise ValueError("The supplied namespace must end with '/' or '#'")

validate_object_id

validate_object_id(object_id: str) -> None
Source code in rdflib/tools/defined_namespace_creator.py
def validate_object_id(object_id: str) -> None:
    for c in object_id:
        if not c.isupper():
            raise ValueError("The supplied object_id must be an all-capitals string")