maplib
1# r''' 2# # Overview 3# 4# ''' 5 6import logging 7logger = logging.getLogger(__name__) 8 9__all__ = [ 10 "Model", 11 "a", 12 "Triple", 13 "SolutionMappings", 14 "IndexingOptions", 15 "ValidationReport", 16 "Instance", 17 "Template", 18 "Argument", 19 "Parameter", 20 "Variable", 21 "RDFType", 22 "xsd", 23 "rdf", 24 "rdfs", 25 "owl", 26 "IRI", 27 "Literal", 28 "Prefix", 29 "BlankNode", 30 "explore", 31 "add_triples", 32 "generate_templates", 33 "MaplibException", 34] 35 36import pathlib 37from importlib.metadata import version 38from .maplib import * 39from .adding_triples import add_triples 40from .template_generator import generate_templates 41 42""" 43http://www.w3.org/1999/02/22-rdf-syntax-ns#type 44""" 45a = rdf.type 46 47if (pathlib.Path(__file__).parent.resolve() / "graph_explorer").exists(): 48 from .graph_explorer import explore as _explore 49else: 50 51 def _explore( 52 m: "Model", 53 host: str = "localhost", 54 port: int = 8000, 55 bind: str = "localhost", 56 popup=True, 57 fts=True, 58 fts_path:str="fts", 59 ): 60 print("Contact Data Treehouse to try!") 61 62 63def explore(*args, **kwargs): 64 """Deprecated way to start an explore session. 65Use the explore method on a Model object instead 66""" 67 logger.warn("Calling `maplib.explore` is deprecated, use `m.explore()` on a `Model` object instead") 68 if kwargs.get("popup") == None or kwargs.get("popup") == True: 69 logger.warn("""Calling explore without a popup argument defaults to it being on. 70The popup argument is deprecated, so if you are relying on explore() opening a browser window 71please change this to something like 72 73``` 74import webbrowser 75from maplib import Model 76 77m = Model() 78... 79s = m.explore() 80webbrowser.open(s.url, new=2) 81``` 82""") 83 kwargs["popup"] = True 84 elif kwargs.get("popup") == False: 85 logger.warn("The new explore function on a Model, no longer defaults to popping up the browser ") 86 87 88 return _explore(*args, **kwargs) 89 90__version__ = version("maplib")
class
Model:
def
map_default( self, /, df, primary_key_column, dry_run=None, graph=None, types=None, validate_iris=None):
def
explore(unknown):
Starts a graph explorer session.
To run from Jupyter Notebook use:
from maplib import Model
m = Model()
...
server = m.explore()
You can later stop the server with
server.stop()
Parameters
- host: The hostname that we will point the browser to.
- port: The port where the graph explorer webserver listens on.
- bind: Bind to the following host / ip.
- popup: Pop up the browser window.
- fts: Enable full text search indexing
- fts_path: Path to the fts index.
def
query( self, /, query, parameters=None, include_datatypes=None, native_dataframe=None, graph=None, streaming=None, return_json=None, include_transient=None, max_rows=None, debug=None):
def
update( self, /, update, parameters=None, graph=None, streaming=None, include_transient=None, max_rows=None, debug=None):
def
validate( self, /, shape_graph, data_graph=None, include_details=None, include_conforms=None, include_shape_graph=None, streaming=None, max_shape_constraint_results=None, only_shapes=None, deactivate_shapes=None, dry_run=None, max_rows=None, serial=None):
def
insert( self, /, query, parameters=None, include_datatypes=None, native_dataframe=None, transient=None, streaming=None, source_graph=None, target_graph=None, include_transient=None, max_rows=None, debug=None):
def
read( self, /, file_path, format=None, base_iri=None, transient=None, parallel=None, checked=None, graph=None, replace_graph=None):
def
reads( self, /, s, format, base_iri=None, transient=None, parallel=None, checked=None, graph=None, replace_graph=None):
a =
IRI(http://www.w3.org/1999/02/22-rdf-syntax-ns#type)
def
Triple(subject, predicate, object, list_expander=None):
class
SolutionMappings:
class
IndexingOptions:
class
ValidationReport:
class
Instance:
class
Template:
class
Argument:
class
Parameter:
class
Variable:
class
RDFType:
IRI =
RDFType.IRI()
BlankNode =
RDFType.BlankNode()
class
xsd:
class
rdf:
class
rdfs:
class
owl:
class
IRI:
class
Literal:
class
Prefix:
class
BlankNode:
def
explore(*args, **kwargs):
64def explore(*args, **kwargs): 65 """Deprecated way to start an explore session. 66Use the explore method on a Model object instead 67""" 68 logger.warn("Calling `maplib.explore` is deprecated, use `m.explore()` on a `Model` object instead") 69 if kwargs.get("popup") == None or kwargs.get("popup") == True: 70 logger.warn("""Calling explore without a popup argument defaults to it being on. 71The popup argument is deprecated, so if you are relying on explore() opening a browser window 72please change this to something like 73 74``` 75import webbrowser 76from maplib import Model 77 78m = Model() 79... 80s = m.explore() 81webbrowser.open(s.url, new=2) 82``` 83""") 84 kwargs["popup"] = True 85 elif kwargs.get("popup") == False: 86 logger.warn("The new explore function on a Model, no longer defaults to popping up the browser ") 87 88 89 return _explore(*args, **kwargs)
Deprecated way to start an explore session. Use the explore method on a Model object instead
def
add_triples( source: Model, target: Model, source_graph: str = None, target_graph: str = None):
5def add_triples( 6 source: Model, target: Model, source_graph: str = None, target_graph: str = None 7): 8 """(Zero) copy the triples from one Model into another. 9 10 :param source: The source model 11 :param target: The target model 12 :param source_graph: The named graph in the source model to copy from. None means default graph. 13 :param target_graph: The named graph in the target model to copy into. None means default graph. 14 """ 15 for p in source.get_predicate_iris(source_graph): 16 subject = Variable("subject") 17 object = Variable("object") 18 template = Template( 19 iri=IRI("urn:maplib:tmp"), 20 parameters=[subject, object], 21 instances=[Triple(subject, p, object)], 22 ) 23 sms = source.get_predicate(p, source_graph) 24 for sm in sms: 25 target.map( 26 template, 27 sm.mappings, 28 types=sm.rdf_types, 29 graph=target_graph, 30 )
(Zero) copy the triples from one Model into another.
Parameters
- source: The source model
- target: The target model
- source_graph: The named graph in the source model to copy from. None means default graph.
- target_graph: The named graph in the target model to copy into. None means default graph.
def
generate_templates(m: Model, graph: Optional[str]) -> Dict[str, Template]:
9def generate_templates(m: Model, graph: Optional[str]) -> Dict[str, Template]: 10 """Generate templates for instantiating the classes in an ontology 11 12 :param m: The model where the ontology is stored. We mainly rely on rdfs:subClassOf, rdfs:range and rdfs:domain. 13 :param graph: The named graph where the ontology is stored. 14 15 :return A dictionary of templates for instantiating the classes in the ontology, where the keys are the class URIs. 16 17 Usage example - note that it is important to add the templates to the Model you want to populate. 18 >>> from maplib import Model, create_templates 19 >>> 20 >>> m_ont = Model() 21 >>> m_ont.read("my_ontology.ttl") 22 >>> templates = generate_templates(m_ont) 23 >>> m = Model() 24 >>> for t in templates.values(): 25 >>> m.add_template(t) 26 >>> m.map("https://example.net/MyClass", df) 27 """ 28 29 properties = get_properties(m, graph=graph) 30 properties_by_domain = {} 31 properties_by_range = {} 32 for r in properties.iter_rows(named=True): 33 dom = r["domain"] 34 if dom in properties_by_domain: 35 properties_by_domain[dom].append(r) 36 else: 37 properties_by_domain[dom] = [r] 38 39 ran = r["range"] 40 if ran in properties_by_range: 41 properties_by_range[ran].append(r) 42 else: 43 properties_by_range[ran] = [r] 44 45 subclasses = get_subclasses(m, graph=graph) 46 47 subclass_of = {} 48 for r in ( 49 subclasses.group_by("child") 50 .agg(pl.col("parent").alias("parents")) 51 .iter_rows(named=True) 52 ): 53 subclass_of[r["child"]] = r["parents"] 54 55 class_ordering = topological_sort(subclasses) 56 57 templates_without_typing = generate_templates_without_typing( 58 properties_by_domain, properties_by_range, class_ordering, subclass_of 59 ) 60 templates_with_typing = generate_templates_with_typing(templates_without_typing) 61 templates = {} 62 for t, template in templates_without_typing.items(): 63 64 templates[t + "_notype"] = template 65 for t, template in templates_with_typing.items(): 66 templates[t] = template 67 68 return templates
Generate templates for instantiating the classes in an ontology
Parameters
- m: The model where the ontology is stored. We mainly rely on rdfs:subClassOf, rdfs:range and rdfs: domain.
- graph: The named graph where the ontology is stored.
:return A dictionary of templates for instantiating the classes in the ontology, where the keys are the class URIs.
Usage example - note that it is important to add the templates to the Model you want to populate.
>>> from maplib import Model, create_templates
>>>
>>> m_ont = Model()
>>> m_ont.read("my_ontology.ttl")
>>> templates = generate_templates(m_ont)
>>> m = Model()
>>> for t in templates.values():
>>> m.add_template(t)
>>> m.map("https://example.net/MyClass", df)
class
MaplibException(builtins.Exception):
Common base class for all non-exit exceptions.