""" Plugin support for rdf. There are a number of plugin points for rdf: parser, serializer, store, query processor, and query result. Plugins can be registered either through setuptools entry_points or by calling rdf.plugin.register directly. If you have a package that uses a setuptools based setup.py you can add the following to your setup:: entry_points = { 'rdf.plugins.parser': [ 'nt = rdf.plugins.parsers.ntriples:NTParser', ], 'rdf.plugins.serializer': [ 'nt = rdf.plugins.serializers.NTSerializer:NTSerializer', ], } See the `setuptools dynamic discovery of services and plugins`__ for more information. .. __: http://peak.telecommunity.com/DevCenter/setuptools#dynamic-discovery-of-services-and-plugins """ from importlib.metadata import EntryPoint, entry_points from typing import ( TYPE_CHECKING, Any, Dict, Generic, Iterator, Optional, Tuple, Type, TypeVar, overload, ) import rdflib.plugins.stores.berkeleydb from rdflib.exceptions import Error from rdflib.parser import Parser from rdflib.query import ( Processor, Result, ResultParser, ResultSerializer, UpdateProcessor, ) from rdflib.serializer import Serializer from rdflib.store import Store __all__ = [ "register", "get", "plugins", "PluginException", "Plugin", "PluginT", "PKGPlugin", ] rdflib_entry_points = { "rdf.plugins.store": Store, "rdf.plugins.serializer": Serializer, "rdf.plugins.parser": Parser, "rdf.plugins.resultparser": ResultParser, "rdf.plugins.resultserializer": ResultSerializer, "rdf.plugins.queryprocessor": Processor, "rdf.plugins.queryresult": Result, "rdf.plugins.updateprocessor": UpdateProcessor, } _plugins: Dict[Tuple[str, Type[Any]], "Plugin"] = {} class PluginException(Error): pass #: A generic type variable for plugins PluginT = TypeVar("PluginT") class Plugin(Generic[PluginT]): def __init__( self, name: str, kind: Type[PluginT], module_path: str, class_name: str ): self.name = name self.kind = kind self.module_path = module_path self.class_name = class_name self._class: Optional[Type[PluginT]] = None def getClass(self) -> Type[PluginT]: # noqa: N802 if self._class is None: module = __import__(self.module_path, globals(), locals(), [""]) self._class = getattr(module, self.class_name) return self._class class PKGPlugin(Plugin[PluginT]): def __init__(self, name: str, kind: Type[PluginT], ep: "EntryPoint"): self.name = name self.kind = kind self.ep = ep self._class: Optional[Type[PluginT]] = None def getClass(self) -> Type[PluginT]: # noqa: N802 if self._class is None: self._class = self.ep.load() return self._class def register(name: str, kind: Type[Any], module_path, class_name): """ Register the plugin for (name, kind). The module_path and class_name should be the path to a plugin class. """ p = Plugin(name, kind, module_path, class_name) _plugins[(name, kind)] = p def get(name: str, kind: Type[PluginT]) -> Type[PluginT]: """ Return the class for the specified (name, kind). Raises a PluginException if unable to do so. """ try: p: Plugin[PluginT] = _plugins[(name, kind)] except KeyError: raise PluginException("No plugin registered for (%s, %s)" % (name, kind)) return p.getClass() all_entry_points = entry_points() if hasattr(all_entry_points, "select"): for entry_point, kind in rdflib_entry_points.items(): for ep in all_entry_points.select(group=entry_point): _plugins[(ep.name, kind)] = PKGPlugin(ep.name, kind, ep) else: # Prior to Python 3.10, this returns a dict instead of the selection interface, which is slightly slower if TYPE_CHECKING: assert isinstance(all_entry_points, dict) for entry_point, kind in rdflib_entry_points.items(): for ep in all_entry_points.get(entry_point, []): _plugins[(ep.name, kind)] = PKGPlugin(ep.name, kind, ep) @overload def plugins( name: Optional[str] = ..., kind: Type[PluginT] = ... ) -> Iterator[Plugin[PluginT]]: ... @overload def plugins(name: Optional[str] = ..., kind: None = ...) -> Iterator[Plugin]: ... def plugins( name: Optional[str] = None, kind: Optional[Type[PluginT]] = None ) -> Iterator[Plugin[PluginT]]: """ A generator of the plugins. Pass in name and kind to filter... else leave None to match all. """ for p in _plugins.values(): if (name is None or name == p.name) and (kind is None or kind == p.kind): yield p # Register Stores if rdflib.plugins.stores.berkeleydb.has_bsddb: # Checks for BerkeleyDB before registering it register( "BerkeleyDB", Store, "rdflib.plugins.stores.berkeleydb", "BerkeleyDB", ) register( "default", Store, "rdflib.plugins.stores.memory", "Memory", ) register( "Memory", Store, "rdflib.plugins.stores.memory", "Memory", ) register( "SimpleMemory", Store, "rdflib.plugins.stores.memory", "SimpleMemory", ) register( "Auditable", Store, "rdflib.plugins.stores.auditable", "AuditableStore", ) register( "Concurrent", Store, "rdflib.plugins.stores.concurrent", "ConcurrentStore", ) register( "SPARQLStore", Store, "rdflib.plugins.stores.sparqlstore", "SPARQLStore", ) register( "SPARQLUpdateStore", Store, "rdflib.plugins.stores.sparqlstore", "SPARQLUpdateStore", ) # Register Triple Serializers register( "application/rdf+xml", Serializer, "rdflib.plugins.serializers.rdfxml", "XMLSerializer", ) register( "xml", Serializer, "rdflib.plugins.serializers.rdfxml", "XMLSerializer", ) register( "pretty-xml", Serializer, "rdflib.plugins.serializers.rdfxml", "PrettyXMLSerializer", ) register( "text/n3", Serializer, "rdflib.plugins.serializers.n3", "N3Serializer", ) register( "n3", Serializer, "rdflib.plugins.serializers.n3", "N3Serializer", ) register( "text/turtle", Serializer, "rdflib.plugins.serializers.turtle", "TurtleSerializer", ) register( "turtle", Serializer, "rdflib.plugins.serializers.turtle", "TurtleSerializer", ) register( "ttl", Serializer, "rdflib.plugins.serializers.turtle", "TurtleSerializer", ) register( "longturtle", Serializer, "rdflib.plugins.serializers.longturtle", "LongTurtleSerializer", ) register( "application/n-triples", Serializer, "rdflib.plugins.serializers.nt", "NTSerializer", ) register( "ntriples", Serializer, "rdflib.plugins.serializers.nt", "NTSerializer", ) register( "nt", Serializer, "rdflib.plugins.serializers.nt", "NTSerializer", ) register( "nt11", Serializer, "rdflib.plugins.serializers.nt", "NT11Serializer", ) register( "json-ld", Serializer, "rdflib.plugins.serializers.jsonld", "JsonLDSerializer", ) register( "application/ld+json", Serializer, "rdflib.plugins.serializers.jsonld", "JsonLDSerializer", ) # Register Quad Serializers register( "application/n-quads", Serializer, "rdflib.plugins.serializers.nquads", "NQuadsSerializer", ) register( "nquads", Serializer, "rdflib.plugins.serializers.nquads", "NQuadsSerializer", ) register( "application/trix", Serializer, "rdflib.plugins.serializers.trix", "TriXSerializer", ) register( "trix", Serializer, "rdflib.plugins.serializers.trix", "TriXSerializer", ) register( "application/trig", Serializer, "rdflib.plugins.serializers.trig", "TrigSerializer", ) register( "trig", Serializer, "rdflib.plugins.serializers.trig", "TrigSerializer", ) register( "hext", Serializer, "rdflib.plugins.serializers.hext", "HextuplesSerializer", ) # Register Triple Parsers register( "application/rdf+xml", Parser, "rdflib.plugins.parsers.rdfxml", "RDFXMLParser", ) register( "xml", Parser, "rdflib.plugins.parsers.rdfxml", "RDFXMLParser", ) register( "text/n3", Parser, "rdflib.plugins.parsers.notation3", "N3Parser", ) register( "n3", Parser, "rdflib.plugins.parsers.notation3", "N3Parser", ) register( "text/turtle", Parser, "rdflib.plugins.parsers.notation3", "TurtleParser", ) register( "turtle", Parser, "rdflib.plugins.parsers.notation3", "TurtleParser", ) register( "ttl", Parser, "rdflib.plugins.parsers.notation3", "TurtleParser", ) register( "application/n-triples", Parser, "rdflib.plugins.parsers.ntriples", "NTParser", ) register( "ntriples", Parser, "rdflib.plugins.parsers.ntriples", "NTParser", ) register( "nt", Parser, "rdflib.plugins.parsers.ntriples", "NTParser", ) register( "nt11", Parser, "rdflib.plugins.parsers.ntriples", "NTParser", ) register( "application/ld+json", Parser, "rdflib.plugins.parsers.jsonld", "JsonLDParser", ) register( "json-ld", Parser, "rdflib.plugins.parsers.jsonld", "JsonLDParser", ) # Register Quad Parsers register( "application/n-quads", Parser, "rdflib.plugins.parsers.nquads", "NQuadsParser", ) register( "nquads", Parser, "rdflib.plugins.parsers.nquads", "NQuadsParser", ) register( "application/trix", Parser, "rdflib.plugins.parsers.trix", "TriXParser", ) register( "trix", Parser, "rdflib.plugins.parsers.trix", "TriXParser", ) register( "application/trig", Parser, "rdflib.plugins.parsers.trig", "TrigParser", ) register( "trig", Parser, "rdflib.plugins.parsers.trig", "TrigParser", ) register( "hext", Parser, "rdflib.plugins.parsers.hext", "HextuplesParser", ) # Register SPARQL Processors register( "sparql", Result, "rdflib.plugins.sparql.processor", "SPARQLResult", ) register( "sparql", Processor, "rdflib.plugins.sparql.processor", "SPARQLProcessor", ) register( "sparql", UpdateProcessor, "rdflib.plugins.sparql.processor", "SPARQLUpdateProcessor", ) # Register SPARQL Result Serializers register( "xml", ResultSerializer, "rdflib.plugins.sparql.results.xmlresults", "XMLResultSerializer", ) register( "application/sparql-results+xml", ResultSerializer, "rdflib.plugins.sparql.results.xmlresults", "XMLResultSerializer", ) register( "txt", ResultSerializer, "rdflib.plugins.sparql.results.txtresults", "TXTResultSerializer", ) register( "json", ResultSerializer, "rdflib.plugins.sparql.results.jsonresults", "JSONResultSerializer", ) register( "application/sparql-results+json", ResultSerializer, "rdflib.plugins.sparql.results.jsonresults", "JSONResultSerializer", ) register( "csv", ResultSerializer, "rdflib.plugins.sparql.results.csvresults", "CSVResultSerializer", ) register( "text/csv", ResultSerializer, "rdflib.plugins.sparql.results.csvresults", "CSVResultSerializer", ) # Register SPARQL Result Parsers register( "xml", ResultParser, "rdflib.plugins.sparql.results.xmlresults", "XMLResultParser", ) register( "application/sparql-results+xml", ResultParser, "rdflib.plugins.sparql.results.xmlresults", "XMLResultParser", ) register( "application/sparql-results+xml; charset=UTF-8", ResultParser, "rdflib.plugins.sparql.results.xmlresults", "XMLResultParser", ) register( "application/rdf+xml", ResultParser, "rdflib.plugins.sparql.results.graph", "GraphResultParser", ) register( "json", ResultParser, "rdflib.plugins.sparql.results.jsonresults", "JSONResultParser", ) register( "application/sparql-results+json", ResultParser, "rdflib.plugins.sparql.results.jsonresults", "JSONResultParser", ) register( "csv", ResultParser, "rdflib.plugins.sparql.results.csvresults", "CSVResultParser", ) register( "text/csv", ResultParser, "rdflib.plugins.sparql.results.csvresults", "CSVResultParser", ) register( "tsv", ResultParser, "rdflib.plugins.sparql.results.tsvresults", "TSVResultParser", ) register( "text/tab-separated-values", ResultParser, "rdflib.plugins.sparql.results.tsvresults", "TSVResultParser", )