Source code for provit.agent

"""
Everything agent profile related


1. Classes

* Person
* SoftwareAgent
* Organization

Each class contains :to_json(): and :graph(): functions,
returning the data of the classes either as json-dict or
rdflib Graph.


2. Helper functions

* load_agent_profile(slug) 
  loads the yaml file of agent :slug: and initiates the 
  respective agent class (depending on type)

* load_agent_profiles() 
  loads all agent yaml files and returns a list of 
  agent classes

* agent_factory(slug, type_) 
  initializes an agent class of type :type_: with id/uri
  :slug:

"""

import os
import yaml

from rdflib import Graph, Literal
from rdflib.namespace import FOAF, URIRef, Namespace, RDF

from .namespaces import PROVIT, PROV, SCHEMA
from .config import get_config

cfg = get_config()


def _get_element_or_alt(data, element, alt):
    """
    if :element: is in dict :data: return it, otherwise 
    return :alt:
    """
    if element in data:
        return data[element]
    else:
        return alt


[docs]def load_agent_profile(slug): """ loads agent yaml profile (if available) and initiates agent class with the values obtained from the yaml file """ agent_file_path = cfg.get_agent_profile(slug) if not agent_file_path: return None with open(agent_file_path) as agent_file: data = yaml.safe_load(agent_file) if data["type"] == cfg.person: uri = _get_element_or_alt(data, "uri", "") name = _get_element_or_alt(data, "name", []) institution = _get_element_or_alt(data, "institution", []) homepage = _get_element_or_alt(data, "homepage", []) email = _get_element_or_alt(data, "email", []) return PersonAgent( slug=slug, name=name, uri=uri, institution=institution, homepage=homepage, email=email, ) elif data["type"] == cfg.organization: uri = _get_element_or_alt(data, "uri", "") name = _get_element_or_alt(data, "name", []) homepage = _get_element_or_alt(data, "homepage", []) return OrganizationAgent(slug=slug, name=name, uri=uri, homepage=homepage) elif data["type"] == cfg.software: uri = _get_element_or_alt(data, "uri", "") name = _get_element_or_alt(data, "name", "") version = _get_element_or_alt(data, "version", "") homepage = _get_element_or_alt(data, "homepage", "") return SoftwareAgent( slug=slug, uri=uri, name=name, version=version, homepage=homepage ) return None
[docs]def load_agent_profiles(): agents = [] for filename in sorted(os.listdir(cfg.agents_dir)): filepath = os.path.join(cfg.agents_dir, filename) slug = filename.replace(".yaml", "") profile = load_agent_profile(slug) if profile: agents.append(profile) return agents
[docs]def agent_factory(slug, type_): """ return "empty" agent class instance of the specified type """ if cfg.agent_profile_exists(slug): return load_agent_profile(slug) else: if type_ == cfg.person: return PersonAgent(slug) elif type_ == cfg.software: return SoftwareAgent(slug) elif type_ == cfg.organization: return OrganizationAgent(slug)
[docs]class OrganizationAgent(object): def __init__(self, slug, name=[], homepage=[], uri=""): self.type = cfg.organization self.slug = slug if uri: self.uri = uri else: self.uri = PROVIT[slug] self.name = name self.homepage = homepage
[docs] def update(self, data): self.name = list(set(self.name).union(set(data["name"]))) self.homepage = list(set(self.homepage).union(set(data["homepage"])))
[docs] def to_json(self): return { "uri": self.uri, "slug": self.slug, "type": self.type, "name": self.name, "homepage": self.homepage, }
[docs] def graph(self): uri = URIRef(self.uri) g = Graph() g.add((uri, RDF.type, PROV.Organization)) for name in self.name: g.add((uri, FOAF.name, Literal(name))) for homepage in self.homepage: g.add((uri, FOAF.homepage, Literal(homepage))) return g
[docs]class PersonAgent(object): def __init__(self, slug, name=[], institution=[], homepage=[], email=[], uri=""): self.type = cfg.person self.slug = slug if uri: self.uri = uri else: self.uri = PROVIT[slug] self.name = name self.institution = institution self.homepage = homepage self.email = email
[docs] def update(self, data): self.name = list(set(self.name).union(set(data["name"]))) self.homepage = list(set(self.homepage).union(set(data["homepage"]))) self.email = list(set(self.email).union(set(data["email"]))) self.institution = list(set(self.institution).union(set(data["institution"])))
[docs] def to_json(self): return { "uri": self.uri, "type": self.type, "slug": self.slug, "name": self.name, "institution": self.institution, "homepage": self.homepage, "email": self.email, }
[docs] def graph(self): uri = URIRef(self.uri) g = Graph() g.add((uri, RDF.type, PROV.Person)) for name in self.name: g.add((uri, FOAF.name, Literal(name))) for institution in self.institution: g.add((uri, FOAF.member, PROVIT[institution])) for homepage in self.homepage: g.add((uri, FOAF.homepage, Literal(homepage))) for email in self.email: g.add((uri, FOAF.mbox, Literal(email))) return g
[docs]class SoftwareAgent(object): def __init__(self, slug, name=[], version=[], homepage=[], uri=""): self.type = cfg.software self.slug = slug if uri: self.uri = uri else: self.uri = PROVIT[slug] self.name = name self.version = version self.homepage = homepage
[docs] def update(self, data): self.name = list(set(self.name).union(set(data["name"]))) self.homepage = list(set(self.homepage).union(set(data["homepage"]))) self.version = list(set(self.version).union(set(data["version"])))
[docs] def to_json(self): return { "uri": self.uri, "type": self.type, "slug": self.slug, "name": self.name, "version": self.version, "homepage": self.homepage, }
[docs] def graph(self): uri = URIRef(self.uri) g = Graph() g.add((uri, RDF.type, PROV.SoftwareAgent)) for name in self.name: g.add((uri, FOAF.name, Literal(name))) for version in self.version: g.add((uri, SCHEMA.softwareVersion, Literal(version))) for homepage in self.homepage: g.add((uri, FOAF.homepage, Literal(homepage))) return g