Source code for pyldapi.helpers

# -*- coding: utf-8 -*-
import os
import logging
from rdflib import Graph
from pyldapi.exceptions import CofCTtlError

[docs]def setup(app, api_home_dir, api_uri): """ This is used to set up the :class:`.RegisteC of CegistersRenderer` for this pyLDAPI instance. .. note:: This must run before Flask's :func:`` like this: :code:`pyldapi.setup(app, '.', conf.URI_BASE)`. See the example below. :param app: The Flask app containing this pyLDAPI instance. :type app: :class:`flask.Flask` :param api_home_dir: The path of the API's hom directory. :type api_home_dir: str :param api_uri: The URI base of the API. :type api_uri: str :return: None :rtype: None """ return _make_cofc_rdf(app, api_home_dir, api_uri)
def _make_cofc_rdf(app, api_home_dir, api_uri): """ The setup function that creates the Register of Registers. Do not call from outside setup :param app: the Flask app containing this LDAPI :type app: Flask app :param api_home_dir: The path of the API's hom directory. :type api_home_dir: str :param api_uri: URI base of the API :type api_uri: string :return: none :rtype: None """ from time import sleep cofc_file_path = os.path.join(api_home_dir, 'cofc.ttl') try: os.remove(cofc_file_path) except FileNotFoundError: pass sleep(1) # to ensure that this occurs after the Flask boot g = Graph() # get the RDF for each Register, extract the bits we need, write them to graph g for rule in app.url_map.iter_rules(): # no containers can have a Flask variable in their path and they must end in / if '<' in str(rule) or not str(rule).endswith('/') or str(rule) == '/': pass else: # make the container profile URI for each possible container try: endpoint_func = app.view_functions[rule.endpoint] except (AttributeError, KeyError): continue try: dummy_request_uri = 'http://localhost:5000' + str(rule) + \ '?_profile=mem&_format=text/turtle&page=1&per_page=1' test_context = app.test_request_context(dummy_request_uri) with test_context: resp = endpoint_func() g = g + Graph().parse(data=resp.response[0].decode('utf-8'), format='turtle') except CofCTtlError: # usually an C of C renderer cannot find its cofc.ttl. continue except Exception as e: raise e # get all the child Container from the in-memory graph # which is the set of all the Container end point's first pages of Container profile content q = ''' CONSTRUCT {{ ?uri a rdf:Bag ; rdfs:label ?label . ?parent a rdf:Bag ; rdfs:label ?parent_label ; rdfs:member ?uri . }} WHERE {{ ?uri a rdf:Bag ; rdfs:label ?label . OPTIONAL {{ ?parent rdfs:label ?parent_label ; rdfs:member ?uri . }} }} ORDER BY ?label '''.format(api_uri) gg = Graph() for r in g.query(q): gg.add(r) # serialise gg with open(cofc_file_path, 'w') as f: f.write(gg.serialize(format='text/turtle').decode('utf-8')) def _filter_members_graph(container_uri, r, g): if 'text/turtle' in r.headers.get('Content-Type'): logging.debug('{} is a register '.format(container_uri)) # it is a valid endpoint returning RDF (turtle) so... # import all its content into the in-memory graph g2 = Graph().parse('utf-8'), format='text/turtle') # extract out only the Register details # make a query to get all the vars we need q = ''' CONSTRUCT {{ <{0}> a rdf:Bag ; rdfs:label ?label ; rdfs:comment ?comment ; reg:subregister ?subregister . }} WHERE {{ <{0}> a rdf:Bag ; rdfs:label ?label ; rdfs:comment ?comment ; }} '''.format(container_uri) g += g2.query(q) return True else: logging.debug( '{} returns no RDF'.format(container_uri)) return False # no RDF (turtle) response from endpoint so not register # def get_filtered_register_graph(register_uri, g): # """ # Gets a filtered version (label, comment, contained item classes & subregisters only) of the each register for the # Register of Registers # # :param register_uri: the public URI of the register # :type register_uri: string # :param g: the rdf graph to append registers to # :type g: Graph # :return: True if ok, else False # :rtype: boolean # """ # import requests # from pyldapi.exceptions import ViewsFormatsException # assert isinstance(g, Graph) # logging.debug('assessing register candidate ' + register_uri.replace('?_profile=reg&_format=text/turtle', '')) # try: # r = requests.get(register_uri) # except ViewsFormatsException as e: # return False # ignore these exceptions as are just a result of requesting a profile/format combo of something like a page # if r.status_code == 200: # return _filter_register_graph(register_uri.replace('?_profile=reg&_format=text/turtle', ''), r, g) # logging.debug('{} returns no HTTP 200'.format(register_uri)) # return False # no valid response from endpoint so not register # resp.format in Renderer.RDF_MIMETYPES: # from pyldapi.rendered import Rendered.RDF_MIMETYPES