Exemple #1
0
 def __init__(self):
     #watch("neo4j.bolt")
     self.graph = Graph(super().graph_url)
     tx = self.graph.begin()
     tx.run(SnomedConceptProcessor.create_index_concept_id)
     tx.run(SnomedConceptProcessor.create_index_term)
     tx.commit()
Exemple #2
0
def get_graph_context(config):
    if config is None:
        return Graph(auth=('neo4j', 'pass'), host='localhost')

    login = config.get('NEO4J_LOGIN', 'neo4j')
    password = config.get('NEO4J_PASS', 'pass')
    host = config.get('NEO4J_HOST', 'localhost')

    return Graph(auth=(login, password), host=host)
    def __init__(self, uri=None, **settings):
        self.output_file = settings.pop("file", None)
        verbose = settings.pop("verbose", False)
        connection_data = get_connection_data(uri, **settings)
        try:
            self.graph = Graph(uri, **settings)
        except ServiceUnavailable as error:
            raise ConsoleError("Could not connect to {} -- {}".format(
                connection_data["uri"], error))
        try:
            makedirs(HISTORY_FILE_DIR)
        except OSError:
            pass
        self.history = FileHistory(path_join(HISTORY_FILE_DIR, HISTORY_FILE))
        self.prompt_args = {
            "history":
            self.history,
            "lexer":
            PygmentsLexer(CypherLexer),
            "style":
            merge_styles([
                style_from_pygments_cls(NativeStyle),
                style_from_pygments_dict({
                    Token.Prompt:
                    "#ansi{}".format(self.prompt_colour.replace(
                        "cyan", "teal")),
                    Token.TxCounter:
                    "#ansi{} bold".format(
                        self.tx_colour.replace("cyan", "teal")),
                })
            ])
        }
        self.lexer = CypherLexer()
        self.result_writer = Table.write
        if verbose:
            from neobolt.diagnostics import watch
            self.watcher = watch("neo4j.%s" % connection_data["scheme"])

        self.commands = {
            "//": self.set_multi_line,
            "/e": self.edit,
            "/?": self.help,
            "/h": self.help,
            "/help": self.help,
            "/x": self.exit,
            "/exit": self.exit,
            "/play": self.play,
            "/csv": self.set_csv_result_writer,
            "/table": self.set_tabular_result_writer,
            "/tsv": self.set_tsv_result_writer,
            "/config": self.config,
            "/kernel": self.kernel,
        }
        self.tx = None
        self.tx_counter = 0
Exemple #4
0
    def __init__(self, profile=None, *_, **settings):
        super(ClientConsole, self).__init__(__name__, verbosity=settings.get("verbosity", 0))
        self.output_file = settings.pop("file", None)

        welcome = settings.get("welcome", True)
        if welcome:
            self.write(TITLE)
            self.write()
            self.write(dedent(QUICK_HELP))
            self.write()

        self.profile = ConnectionProfile(profile, **settings)
        try:
            self.graph = Graph(self.profile)
        except OSError as error:
            self.critical("Could not connect to <%s> (%s)", self.profile.uri, " ".join(map(str, error.args)))
            raise
        else:
            self.debug("Connected to <%s>", self.graph.service.uri)
        try:
            makedirs(HISTORY_FILE_DIR)
        except OSError:
            pass
        self.history = FileHistory(path_join(HISTORY_FILE_DIR, HISTORY_FILE))
        self.lexer = CypherLexer()
        self.result_writer = Table.write

        self.commands = {

            "//": self.set_multi_line,
            "/e": self.edit,

            "/?": self.help,
            "/h": self.help,
            "/help": self.help,

            "/x": self.exit,
            "/exit": self.exit,

            "/play": self.play,

            "/csv": self.set_csv_result_writer,
            "/table": self.set_tabular_result_writer,
            "/tsv": self.set_tsv_result_writer,

            "/config": self.config,
            "/kernel": self.kernel,

        }
        self.tx = None
        self.qid = 0
Exemple #5
0
class SnomedConceptProcessor(BaseItemProcessor):
    statement = Template(
        "CREATE (c:Concept:FSA:$label {conceptId: \"$id\", term: \"$term\", descType: $descType});"
    )
    create_index_concept_id = "CREATE INDEX ON :Concept(conceptId)"
    create_index_term = "CREATE INDEX ON :Concept(term)"

    def __init__(self):
        #watch("neo4j.bolt")
        self.graph = Graph(super().graph_url)
        tx = self.graph.begin()
        tx.run(SnomedConceptProcessor.create_index_concept_id)
        tx.run(SnomedConceptProcessor.create_index_term)
        tx.commit()

    def process(self, record, tx):
        label = self.extract_label(record['term'])
        if label is None or label[0].isdigit():
            label = 'NO_LABEL'
        term = record["term"].replace('"', '\\"')
        local_statement = SnomedConceptProcessor.statement.substitute(
            id=record["id"],
            term=term,
            descType=record["descType"],
            label=label)
        tx.run(local_statement)

    def extract_label(self, text):
        search_match = re.search(r"\([^)]*\)$", text.rstrip())
        if search_match is not None:
            match_text = re.sub(r"[^a-zA-Z0-9_\s]", "",
                                search_match.group(0)).upper()
            return "_".join(match_text.split())
        else:
            return None
 def __init__(self):
     #watch("neo4j.bolt")
     self.graph = Graph(super().graph_url)
     tx = self.graph.begin()
     tx.run(SnomedConceptProcessor.create_index_concept_id)
     tx.run(SnomedConceptProcessor.create_index_term)
     tx.commit()
class SnomedConceptProcessor(BaseItemProcessor):
    statement = Template("CREATE (c:Concept:FSA:$label {conceptId: \"$id\", term: \"$term\", descType: $descType});")
    create_index_concept_id = "CREATE INDEX ON :Concept(conceptId)"
    create_index_term = "CREATE INDEX ON :Concept(term)"

    def __init__(self):
        #watch("neo4j.bolt")
        self.graph = Graph(super().graph_url)
        tx = self.graph.begin()
        tx.run(SnomedConceptProcessor.create_index_concept_id)
        tx.run(SnomedConceptProcessor.create_index_term)
        tx.commit()

    def process(self, record, tx):
        label = self.extract_label(record['term'])
        if label is None or label[0].isdigit():
            label = 'NO_LABEL'
        term = record["term"].replace('"','\\"')
        local_statement = SnomedConceptProcessor.statement.substitute(id=record["id"], term=term,
                                                                      descType=record["descType"], label=label)
        tx.run(local_statement)

    def extract_label(self, text):
        search_match = re.search(r"\([^)]*\)$", text.rstrip())
        if search_match is not None:
            match_text = re.sub(r"[^a-zA-Z0-9_\s]", "", search_match.group(0)).upper()
            return "_".join(match_text.split())
        else:
            return None
Exemple #8
0
    def connectGraph(self):
        # graph = Graph(user = self.user, password = self.password)
        authenticate(self.service_ip, self.user, self.password)
        graph = Graph('http://%s/db/data/' % self.service_ip)
        #         authenticate("localhost:7474", self.user, self.password)
        #         graph = Graph("http://localhost:7474/db/data/")

        return graph
Exemple #9
0
 def __init__(self, content_type, uri, name=None):
     self._content_type = content_type
     key_value_pos = uri.find("/{key}/{value}")
     if key_value_pos >= 0:
         self._searcher = ResourceTemplate(uri)
         self.__remote__ = Resource(uri[:key_value_pos])
     else:
         self.__remote__ = Resource(uri)
         self._searcher = ResourceTemplate(uri.string + "/{key}/{value}")
     uri = remote(self).uri
     self._create_or_fail = Resource(
         uri.resolve("?uniqueness=create_or_fail"))
     self._get_or_create = Resource(
         uri.resolve("?uniqueness=get_or_create"))
     self._query_template = ResourceTemplate(uri.string + "{?query,order}")
     self._name = name or uri.path.segments[-1]
     self.__searcher_stem_cache = {}
     self.graph = Graph(uri.resolve("/db/data/").string)
Exemple #10
0
def setup():
    author_nodes = []
    pmid_nodes = []
    written_by = []

    count = 0
    g = Graph(uri="bolt://localhost:7687", auth=("neo4j", "justjournals"))
    g.schema.create_uniqueness_constraint('PMID', 'name')
    g.schema.create_uniqueness_constraint('Person', 'title')
    g.schema.create_uniqueness_constraint('Factor', 'dID')
    g.schema.create_uniqueness_constraint('Qualifier', 'qID')
Exemple #11
0
def main(args):
    logger = log.getdebuglogger("dbmanager")
    graph = Graph(host=NEO4J_HOST,
                  user=NEO4J_USERNAME,
                  password=NEO4J_PASSWORD)
    args_obj = parse_args(args)

    if args_obj.verbose:
        logger.setLevel(log.LEVELS[-1])
    else:
        logger.setLevel(log.LEVELS[0])

    args_obj.func(args_obj, graph, logger)
Exemple #12
0
def graph_session(yield_graph=False, *args, **kwargs):
    '''Generate a Neo4j graph transaction object with
    safe commit/rollback built-in.

    Args:
        {*args, **kwargs}: Any arguments for py2neo.database.Graph
    Yields:
        py2neo.database.Transaction
    '''
    graph = Graph(*args, **kwargs)
    transaction = graph.begin()
    try:
        if yield_graph:
            yield (graph, transaction)
        else:
            yield transaction
        transaction.commit()
    except:
        transaction.rollback()
        raise
    finally:
        del transaction
        del graph
Exemple #13
0
 def __init__(self, content_type, uri, name=None):
     self._content_type = content_type
     key_value_pos = uri.find("/{key}/{value}")
     if key_value_pos >= 0:
         self._searcher = ResourceTemplate(uri)
         self.__remote__ = Resource(uri[:key_value_pos])
     else:
         self.__remote__ = Resource(uri)
         self._searcher = ResourceTemplate(uri.string + "/{key}/{value}")
     uri = remote(self).uri
     self._create_or_fail = Resource(uri.resolve("?uniqueness=create_or_fail"))
     self._get_or_create = Resource(uri.resolve("?uniqueness=get_or_create"))
     self._query_template = ResourceTemplate(uri.string + "{?query,order}")
     self._name = name or uri.path.segments[-1]
     self.__searcher_stem_cache = {}
     self.graph = Graph(uri.resolve("/db/data/").string)
Exemple #14
0
import os
import sys
import pytest

from py2neo.database import Graph
from py2neo.data import Node, Relationship

ROOT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(ROOT_PATH)

from schemes.graph import GraphNode, GraphRelation
from graph.graph import NLMGraph

nlmg = NLMGraph(graph=Graph(port=7688))
nlmg.graph.delete_all()


def test_graph_connected():
    assert nlmg.graph.database.name != None


@pytest.fixture
def make_node():
    props = {"age": 20, "sex": "female"}
    node = GraphNode("Person", "Alice", props)
    return node


@pytest.fixture
def make_node_no_props():
    return GraphNode("Person", "Alice")
Exemple #15
0
import os
import sys
import pytest

ROOT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(ROOT_PATH)

from py2neo.database import Graph
from schemes.graph import GraphNode, GraphRelation
from schemes.extractor import Entity, ExtractorInput
from nlm import NLMLayer


graph = Graph(port=7688)
mem = NLMLayer(graph=graph)


def test_nlm_instance_call_graphnode():
    start = GraphNode("Person", "AliceThree")
    res = mem(start)
    query = res[0]
    assert isinstance(query, GraphNode) == True
    assert query.label == "Person"
    assert query.name == "AliceThree"
    assert query.props == {'age': 22, 'sex': 'male'}


def test_nlm_instance_call_graphrelation():
    start = GraphNode("Person", "AliceThree")
    end = GraphNode("Person", "AliceOne")
    relation = GraphRelation(start, end, "LOVES")
import os

from py2neo.database import Graph

h = os.environ.get('GRAPHENEDB_HOST', 'localhost')
u = os.environ.get('NEO4J_USERNAME', 'neo4j')
p = os.environ.get('NEO4J_PASSWORD', '111111')

graph = Graph(host=h, user=u, password=p)


def query_on_constraint(constraint):
    matcher = NodeMatcher(graph)
    return graph.nodes.match('Label', Constraint=constraint).first()


def list_all():
    return list(graph.nodes.match('Label'))
Exemple #17
0
            to_node = Node('manufacturer',
                           manuf_name=to_node_name[0],
                           manuf_comment=to_node_name[1])
    if None in [from_node, to_node]:
        raise Exception('Unknown connection type', connection)
    rel = Relationship(from_node, connection, to_node)
    graph.merge(rel)


def worker(mac_address):
    print(mac_address)
    manuf_data = mac_parser.get_all(mac_address)
    if manuf_data is None or manuf_data.manuf is None:
        return
    register_connection('ETHER/GEN/OUI/MANUFACTURED_BY', mac_address,
                        (manuf_data.manuf, manuf_data.comment))


graph = Graph(
    password='******')  # TODO: parameterize, don't hardcode password
mac_parser = manuf.MacParser(update=True)
if __name__ == '__main__':
    pool = multiprocessing.Pool(multiprocessing.cpu_count())
    manuf.MacParser(update=True)
    macs = [
        _['d.mac_address'] for _ in graph.run(
            'MATCH (d:device) WHERE NOT (d)-[:`ETHER/GEN/OUI/MANUFACTURED_BY`]-() RETURN d.mac_address'
        )
    ]
    pool.map(worker, macs)
Exemple #18
0
    def gdb(self):
        """The graph database service instance as a property, for convenience.

        Note: The property will use these configuration variables
        ``CONNECTION_RETRY``
        ``RETRY_INTERVAL``

        :return: the graph database service as a property
        """
        retry = False
        if 'CONNECTION_RETRY' in self.app.config:
            retry = self.app.config['CONNECTION_RETRY']
        retry_interval = 5
        if 'RETRY_INTERVAL' in self.app.config:
            retry_interval = self.app.config['RETRY_INTERVAL']
        retry_count = 0
        try:
            log.info("flask.ext.Neo4j gdb trying to connect to DB")
            host_port = ''
            host_database = self.app.config['GRAPH_DATABASE']
            neo_user = self.app.config['GRAPH_USER']
            neo_pass = self.app.config['GRAPH_PASSWORD']

            host_port_idx = host_database.find('://')
            if host_port_idx >= 0:
                # extract the host and port from the host_database
                host_port_idx = host_port_idx + 3
                host_port = host_database[host_port_idx:]
                host_port = host_port[:host_port.find('/')]
        except Exception as e:
            log.error(
                "Error with database parameters, they may not have been specified in your config: {}"
                .format(e))
        try:
            #authenticate(
            #    host_port,
            #    self.app.config['GRAPH_USER'],
            #    self.app.config['GRAPH_PASSWORD']
            #)
            #v4:
            #"bolt://myserver:7687", auth=("neo4j", "psswrd")
            self.graph_db = Graph(host_database, auth=(neo_user, neo_pass))
        except Exception as se:
            log.error('SocketError: {0}'.format(se))
            if retry:
                while retry_count < 3:
                    log.debug(
                        'Waiting {0}secs before Connection Retry to GraphDatabaseService'
                        .format(retry_interval))
                    time.sleep(retry_interval)
                    #time.sleep(1)
                    retry_count += 1
                    try:
                        self.graph_db = Graph(host_database,
                                              auth=(neo_user, neo_pass))
                    except Exception as sse:
                        log.error('SocketError: {0}'.format(sse.message))

        if not hasattr(self, 'index'):
            self.index = {}
            # add all the indexes as app attributes
            if self._indexes is not None:
                for i, i_type in iter(list(self._indexes.items())):
                    log.debug('getting or creating graph index:{0} {1}'.format(
                        i, i_type))
                    self.index[i] = \
                        self.graph_db.legacy.get_or_create_index(i_type, i)

        return self.graph_db
Exemple #19
0
class Console(object):
    def echo(self, text, file=None, nl=True, err=False, color=None, **styles):
        return click.secho(text,
                           file=file,
                           nl=nl,
                           err=err,
                           color=color,
                           **styles)

    def prompt(self, *args, **kwargs):
        return prompt(*args, **kwargs)

    multi_line = False
    watcher = None

    tx_colour = "yellow"
    err_colour = "reset"
    meta_colour = "cyan"
    prompt_colour = "cyan"

    def __init__(self, uri=None, **settings):
        self.output_file = settings.pop("file", None)
        verbose = settings.pop("verbose", False)
        connection_data = get_connection_data(uri, **settings)
        try:
            self.graph = Graph(uri, **settings)
        except ServiceUnavailable as error:
            raise ConsoleError("Could not connect to {} -- {}".format(
                connection_data["uri"], error))
        try:
            makedirs(HISTORY_FILE_DIR)
        except OSError:
            pass
        self.history = FileHistory(path_join(HISTORY_FILE_DIR, HISTORY_FILE))
        self.prompt_args = {
            "history":
            self.history,
            "lexer":
            PygmentsLexer(CypherLexer),
            "style":
            style_from_pygments(
                VimStyle, {
                    Token.Prompt:
                    "#ansi{}".format(self.prompt_colour.replace(
                        "cyan", "teal")),
                    Token.TxCounter:
                    "#ansi{} bold".format(
                        self.tx_colour.replace("cyan", "teal")),
                })
        }
        self.lexer = CypherLexer()
        self.result_writer = Table.write
        if verbose:
            from neo4j.util import watch
            self.watcher = watch("neo4j.%s" % connection_data["scheme"])

        self.commands = {
            "//": self.set_multi_line,
            "/e": self.edit,
            "/?": self.help,
            "/h": self.help,
            "/help": self.help,
            "/x": self.exit,
            "/exit": self.exit,
            "/play": self.play,
            "/csv": self.set_csv_result_writer,
            "/table": self.set_tabular_result_writer,
            "/tsv": self.set_tsv_result_writer,
            "/config": self.config,
            "/kernel": self.kernel,
        }
        self.tx = None
        self.tx_counter = 0

    def loop(self):
        self.echo(TITLE, err=True)
        self.echo("Connected to {}".format(self.graph.database.uri).rstrip(),
                  err=True)
        self.echo(u"", err=True)
        self.echo(dedent(QUICK_HELP), err=True)
        while True:
            try:
                source = self.read()
            except KeyboardInterrupt:
                continue
            except EOFError:
                return 0
            try:
                self.run(source)
            except ServiceUnavailable:
                return 1

    def run_all(self, sources):
        gap = False
        for s in sources:
            if gap:
                self.echo("")
            self.run(s)
            if not is_command(s):
                gap = True
        return 0

    def run(self, source):
        source = source.strip()
        if not source:
            return
        try:
            if is_command(source):
                self.run_command(source)
            else:
                self.run_source(source)
        except CypherError as error:
            if error.classification == "ClientError":
                pass
            elif error.classification == "DatabaseError":
                pass
            elif error.classification == "TransientError":
                pass
            else:
                pass
            self.echo("{}: {}".format(error.title, error.message), err=True)
        except TransactionError:
            self.echo("Transaction error", err=True, fg=self.err_colour)
        except ServiceUnavailable:
            raise
        except Exception as error:
            self.echo("{}: {}".format(error.__class__.__name__, str(error)),
                      err=True,
                      fg=self.err_colour)

    def begin_transaction(self):
        if self.tx is None:
            self.tx = self.graph.begin()
            self.tx_counter = 1
            self.echo(u"--- BEGIN at {} ---".format(datetime.now()),
                      err=True,
                      fg=self.tx_colour,
                      bold=True)
        else:
            self.echo(u"Transaction already open",
                      err=True,
                      fg=self.err_colour)

    def commit_transaction(self):
        if self.tx:
            try:
                self.tx.commit()
                self.echo(u"--- COMMIT at {} ---".format(datetime.now()),
                          err=True,
                          fg=self.tx_colour,
                          bold=True)
            finally:
                self.tx = None
                self.tx_counter = 0
        else:
            self.echo(u"No current transaction", err=True, fg=self.err_colour)

    def rollback_transaction(self):
        if self.tx:
            try:
                self.tx.rollback()
                self.echo(u"--- ROLLBACK at {} ---".format(datetime.now()),
                          err=True,
                          fg=self.tx_colour,
                          bold=True)
            finally:
                self.tx = None
                self.tx_counter = 0
        else:
            self.echo(u"No current transaction", err=True, fg=self.err_colour)

    def read(self):
        if self.multi_line:
            self.multi_line = False
            return self.prompt(u"", multiline=True, **self.prompt_args)

        def get_prompt_tokens(_):
            tokens = []
            if self.tx is None:
                tokens.append((Token.Prompt, "\n-> "))
            else:
                tokens.append((Token.Prompt, "\n-("))
                tokens.append((Token.TxCounter, "{}".format(self.tx_counter)))
                tokens.append((Token.Prompt, ")-> "))
            return tokens

        return self.prompt(get_prompt_tokens=get_prompt_tokens,
                           **self.prompt_args)

    def run_source(self, source):
        for i, statement in enumerate(self.lexer.get_statements(source)):
            if i > 0:
                self.echo(u"")
            if statement.upper() == "BEGIN":
                self.begin_transaction()
            elif statement.upper() == "COMMIT":
                self.commit_transaction()
            elif statement.upper() == "ROLLBACK":
                self.rollback_transaction()
            elif self.tx is None:
                self.run_cypher(self.graph.run, statement, {})
            else:
                self.run_cypher(self.tx.run,
                                statement, {},
                                line_no=self.tx_counter)
                self.tx_counter += 1

    def run_cypher(self, runner, statement, parameters, line_no=0):
        t0 = timer()
        result = runner(statement, parameters)
        record_count = self.write_result(result)
        status = u"{} record{} from {} in {:.3f}s".format(
            record_count,
            "" if record_count == 1 else "s",
            address_str(result.summary().server.address),
            timer() - t0,
        )
        if line_no:
            self.echo(u"(", err=True, fg=self.meta_colour, bold=True, nl=False)
            self.echo(u"{}".format(line_no),
                      err=True,
                      fg=self.tx_colour,
                      bold=True,
                      nl=False)
            self.echo(u")->({})".format(status),
                      err=True,
                      fg=self.meta_colour,
                      bold=True)
        else:
            self.echo(u"({})".format(status),
                      err=True,
                      fg=self.meta_colour,
                      bold=True)

    def write_result(self, result, page_size=50):
        table = Table(result)
        table_size = len(table)
        for skip in range(0, table_size, page_size):
            self.result_writer(table,
                               file=self.output_file,
                               header={
                                   "fg": "cyan",
                                   "bold": True
                               },
                               skip=skip,
                               limit=page_size)
            self.echo("\r\n", nl=False)
        return table_size

    def run_command(self, source):
        source = source.lstrip()
        assert source
        terms = shlex.split(source)
        command_name = terms[0]
        try:
            command = self.commands[command_name]
        except KeyError:
            self.echo("Unknown command: " + command_name,
                      err=True,
                      fg=self.err_colour)
        else:
            args = []
            kwargs = {}
            for term in terms[1:]:
                if "=" in term:
                    key, _, value = term.partition("=")
                    kwargs[key] = value
                else:
                    args.append(term)
            command(*args, **kwargs)

    def set_multi_line(self, **kwargs):
        self.multi_line = True

    def edit(self, **kwargs):
        initial_message = b""
        with NamedTemporaryFile(suffix=".cypher") as f:
            f.write(initial_message)
            f.flush()
            call([EDITOR, f.name])
            f.seek(0)
            source = f.read().decode("utf-8")
            self.echo(source)
            self.run(source)

    def help(self, **kwargs):
        self.echo(DESCRIPTION, err=True)
        self.echo(u"", err=True)
        self.echo(FULL_HELP.replace("\b\n", ""), err=True)

    def exit(self, **kwargs):
        exit(0)

    def play(self, file_name):
        work = self.load_unit_of_work(file_name=file_name)
        with self.graph.begin() as tx:
            work(tx)

    def load_unit_of_work(self, file_name):
        """ Load a transaction function from a cypher source file.
        """
        with open(expanduser(file_name)) as f:
            source = f.read()

        def unit_of_work(tx):
            for line_no, statement in enumerate(
                    self.lexer.get_statements(source), start=1):
                if line_no > 0:
                    self.echo(u"")
                self.run_cypher(tx.run, statement, {}, line_no=line_no)

        return unit_of_work

    def set_csv_result_writer(self, **kwargs):
        self.result_writer = Table.write_csv

    def set_tabular_result_writer(self, **kwargs):
        self.result_writer = Table.write

    def set_tsv_result_writer(self, **kwargs):
        self.result_writer = Table.write_tsv

    def config(self, **kwargs):
        result = self.graph.run("CALL dbms.listConfig")
        records = None
        last_category = None
        for record in result:
            name = record["name"]
            category, _, _ = name.partition(".")
            if category != last_category:
                if records is not None:
                    Table(records, ["name", "value"]).write(auto_align=False,
                                                            padding=0,
                                                            separator=u" = ")
                    self.echo(u"")
                records = []
            records.append((name, record["value"]))
            last_category = category
        if records is not None:
            Table(records, ["name", "value"]).write(auto_align=False,
                                                    padding=0,
                                                    separator=u" = ")

    def kernel(self, **kwargs):
        result = self.graph.run(
            "CALL dbms.queryJmx",
            {"query": "org.neo4j:instance=kernel#0,name=Kernel"})
        records = []
        for record in result:
            attributes = record["attributes"]
            for key, value_dict in sorted(attributes.items()):
                value = value_dict["value"]
                if key.endswith("Date") or key.endswith("Time"):
                    try:
                        value = datetime.fromtimestamp(value /
                                                       1000).isoformat(" ")
                    except:
                        pass
                records.append((key, value))
        Table(records, ["key", "value"]).write(auto_align=False,
                                               padding=0,
                                               separator=u" = ")
Exemple #20
0
class ClientConsole(Console):

    multi_line = False

    def __init__(self, profile=None, *_, **settings):
        super(ClientConsole,
              self).__init__("py2neo", verbosity=settings.get("verbosity", 0))
        self.output_file = settings.pop("file", None)

        welcome = settings.get("welcome", True)
        if welcome:
            self.write(TITLE)
            self.write()
            self.write(dedent(QUICK_HELP))
            self.write()

        self.profile = ConnectionProfile(profile, **settings)
        routing = settings.get("routing", False)
        try:
            self.graph = Graph(self.profile,
                               routing=routing)  # TODO: use Connector instead
        except OSError as error:
            self.critical("Could not connect to <%s> (%s)", self.profile.uri,
                          " ".join(map(str, error.args)))
            raise
        else:
            self.debug("Connected to <%s>", self.graph.service.uri)
        try:
            makedirs(HISTORY_FILE_DIR)
        except OSError:
            pass
        self.history = FileHistory(path_join(HISTORY_FILE_DIR, HISTORY_FILE))
        self.lexer = CypherLexer()
        self.result_writer = Table.write

        self.commands = {
            "//": self.set_multi_line,
            "/e": self.edit,
            "/?": self.help,
            "/h": self.help,
            "/help": self.help,
            "/x": self.exit,
            "/exit": self.exit,
            "/play": self.play,
            "/csv": self.set_csv_result_writer,
            "/table": self.set_tabular_result_writer,
            "/tsv": self.set_tsv_result_writer,
            "/config": self.config,
            "/kernel": self.kernel,
        }
        self.tx = None
        self.qid = 0

    def process_all(self, lines, times=1):
        gap = False
        for _ in range(times):
            for line in lines:
                if gap:
                    self.write("")
                self.process(line)
                if not is_command(line):
                    gap = True
        return 0

    def process(self, line):
        line = line.strip()
        if not line:
            return
        try:
            if is_command(line):
                self.run_command(line)
            else:
                self.run_source(line)
        except (Neo4jError, Failure) as error:
            # TODO: once this class wraps a Connector instead of a
            #   Graph and the errors raised by that class are only
            #   Failures and not Neo4jErrors, this only needs to
            #   catch Failure.
            if hasattr(error, "title") and hasattr(error, "message"):
                self.error("%s: %s", error.title, error.message)
            else:
                self.error("%s: %s", error.__class__.__name__,
                           " ".join(map(str, error.args)))
        except OSError as error:
            self.critical("Service Unavailable (%s)", error.args[0])
        except Exception as error:
            self.exception(*error.args)

    def begin_transaction(self):
        if self.tx is None:
            self.tx = self.graph.begin()
            self.qid = 1
        else:
            self.warning("Transaction already open")

    def commit_transaction(self):
        if self.tx:
            try:
                self.tx.commit()
                self.info("Transaction committed")
            finally:
                self.tx = None
                self.qid = 0
        else:
            self.warning("No current transaction")

    def rollback_transaction(self):
        if self.tx:
            try:
                self.tx.rollback()
                self.info("Transaction rolled back")
            finally:
                self.tx = None
                self.qid = 0
        else:
            self.warning("No current transaction")

    def read(self):
        prompt_args = {
            "history":
            self.history,
            "lexer":
            PygmentsLexer(CypherLexer),
            "style":
            merge_styles([
                style_from_pygments_cls(NativeStyle),
                style_from_pygments_dict({
                    Token.Prompt.User: "******",
                    Token.Prompt.At: "#ansiteal",
                    Token.Prompt.Host: "#ansiteal",
                    Token.Prompt.QID: "#ansiyellow",
                    Token.Prompt.Arrow: "#808080",
                })
            ])
        }

        self.write()
        if self.multi_line:
            self.multi_line = False
            return prompt(u"", multiline=True, **prompt_args)

        def get_prompt_tokens():
            tokens = [
                ("class:pygments.prompt.user", self.profile.user),
                ("class:pygments.prompt.at", "@"),
                ("class:pygments.prompt.host", self.profile.host),
            ]
            if self.tx is None:
                tokens.append(("class:pygments.prompt.arrow", " -> "))
            else:
                tokens.append(("class:pygments.prompt.arrow", " "))
                tokens.append(("class:pygments.prompt.qid", str(self.qid)))
                tokens.append(("class:pygments.prompt.arrow", "> "))
            return tokens

        return prompt(get_prompt_tokens, **prompt_args)

    def run_source(self, source):
        for i, statement in enumerate(self.lexer.get_statements(source)):
            if i > 0:
                self.write(u"")
            if statement.upper() == "BEGIN":
                self.begin_transaction()
            elif statement.upper() == "COMMIT":
                self.commit_transaction()
            elif statement.upper() == "ROLLBACK":
                self.rollback_transaction()
            elif self.tx is None:
                self.run_cypher(self.graph.run, statement, {})
            else:
                self.run_cypher(self.tx.run, statement, {}, query_id=self.qid)
                self.qid += 1

    def run_cypher(self, runner, statement, parameters, query_id=0):
        t0 = timer()
        result = runner(statement, parameters)
        record_count = self.write_result(result)
        summary = result.summary()
        if summary.connection:
            uri = summary.connection["uri"]
        else:
            uri = self.graph.service.uri

        msg = "Fetched %r %s from %r in %rs"
        args = [
            record_count,
            "record" if record_count == 1 else "records",
            uri,
            timer() - t0,
        ]
        if query_id:
            msg += " for query (%r)"
            args.append(query_id)
        self.debug(msg, *args)

    def write_result(self, result, page_size=50):
        table = Table(result)
        table_size = len(table)
        if self.verbosity >= 0:
            for skip in range(0, table_size, page_size):
                self.result_writer(table,
                                   file=self.output_file,
                                   header="cyan",
                                   skip=skip,
                                   limit=page_size)
                self.write("\r\n", end='')
        return table_size

    def run_command(self, source):
        source = source.lstrip()
        assert source
        terms = shlex.split(source)
        command_name = terms[0]
        try:
            command = self.commands[command_name]
        except KeyError:
            self.info("Unknown command: " + command_name)
        else:
            args = []
            kwargs = {}
            for term in terms[1:]:
                if "=" in term:
                    key, _, value = term.partition("=")
                    kwargs[key] = value
                else:
                    args.append(term)
            command(*args, **kwargs)

    def set_multi_line(self, **kwargs):
        self.multi_line = True

    def edit(self, **kwargs):
        initial_message = b""
        with NamedTemporaryFile(suffix=".cypher") as f:
            f.write(initial_message)
            f.flush()
            call([EDITOR, f.name])
            f.seek(0)
            source = f.read().decode("utf-8")
            self.write(source)
            self.process(source)

    def help(self, **kwargs):
        self.info(DESCRIPTION)
        self.info(u"")
        self.info(FULL_HELP.replace("\b\n", ""))

    def play(self, file_name):
        work = self.load_unit_of_work(file_name=file_name)
        with self.graph.begin() as tx:
            work(tx)

    def load_unit_of_work(self, file_name):
        """ Load a transaction function from a cypher source file.
        """
        with open(expanduser(file_name)) as f:
            source = f.read()

        def unit_of_work(tx):
            for line_no, statement in enumerate(
                    self.lexer.get_statements(source), start=1):
                if line_no > 0:
                    self.write(u"")
                self.run_cypher(tx.run, statement, {}, query_id=line_no)

        return unit_of_work

    def set_csv_result_writer(self, **kwargs):
        self.result_writer = Table.write_csv

    def set_tabular_result_writer(self, **kwargs):
        self.result_writer = Table.write

    def set_tsv_result_writer(self, **kwargs):
        self.result_writer = Table.write_tsv

    def config(self, **kwargs):
        result = self.graph.run("CALL dbms.listConfig")
        records = None
        last_category = None
        for record in result:
            name = record["name"]
            category, _, _ = name.partition(".")
            if category != last_category:
                if records is not None:
                    Table(records, ["name", "value"]).write(auto_align=False,
                                                            padding=0,
                                                            separator=u" = ")
                    self.write(u"")
                records = []
            records.append((name, record["value"]))
            last_category = category
        if records is not None:
            Table(records, ["name", "value"]).write(auto_align=False,
                                                    padding=0,
                                                    separator=u" = ")

    def kernel(self, **kwargs):
        result = self.graph.run(
            "CALL dbms.queryJmx",
            {"query": "org.neo4j:instance=kernel#0,name=Kernel"})
        records = []
        for record in result:
            attributes = record["attributes"]
            for key, value_dict in sorted(attributes.items()):
                value = value_dict["value"]
                if key.endswith("Date") or key.endswith("Time"):
                    try:
                        value = datetime.fromtimestamp(value /
                                                       1000).isoformat(" ")
                    except:
                        pass
                records.append((key, value))
        Table(records, ["key", "value"]).write(auto_align=False,
                                               padding=0,
                                               separator=u" = ")
 def __init__(self):
     #watch("neo4j.bolt")
     self.graph = Graph(super().graph_url)
Exemple #22
0
class ManualIndex(object):
    """ Searchable database index which can contain either nodes or
    relationships.
    """

    def __init__(self, content_type, uri, name=None):
        self._content_type = content_type
        key_value_pos = uri.find("/{key}/{value}")
        if key_value_pos >= 0:
            self._searcher = ResourceTemplate(uri)
            self.__remote__ = Resource(uri[:key_value_pos])
        else:
            self.__remote__ = Resource(uri)
            self._searcher = ResourceTemplate(uri.string + "/{key}/{value}")
        uri = remote(self).uri
        self._create_or_fail = Resource(uri.resolve("?uniqueness=create_or_fail"))
        self._get_or_create = Resource(uri.resolve("?uniqueness=get_or_create"))
        self._query_template = ResourceTemplate(uri.string + "{?query,order}")
        self._name = name or uri.path.segments[-1]
        self.__searcher_stem_cache = {}
        self.graph = Graph(uri.resolve("/db/data/").string)

    def __repr__(self):
        return "{0}({1}, {2})".format(
            self.__class__.__name__,
            self._content_type.__name__,
            repr(remote(self).uri.string)
        )

    def _searcher_stem_for_key(self, key):
        if key not in self.__searcher_stem_cache:
            stem = self._searcher.uri_template.string.partition("{key}")[0]
            self.__searcher_stem_cache[key] = stem + percent_encode(key) + "/"
        return self.__searcher_stem_cache[key]

    def add(self, key, value, entity):
        """ Add an entity to this index under the `key`:`value` pair supplied.

        Note that while Neo4j indexes allow multiple entities to be added under
        a particular key:value, the same entity may only be represented once;
        this method is therefore idempotent.

        :param key:
        :param value:
        :param entity:
        """
        remote(self).post({
            "key": key,
            "value": value,
            "uri": remote(entity).uri.string,
        })
        return entity

    def add_if_none(self, key, value, entity):
        """ Add an entity to this index under the `key`:`value` pair
        supplied if no entry already exists at that point.

        If added, this method returns the entity, otherwise :py:const:`None`
        is returned.
        """
        rs = self._get_or_create.post({
            "key": key,
            "value": value,
            "uri": remote(entity).uri.string,
        })
        if rs.status_code == CREATED:
            return entity
        else:
            return None

    @property
    def content_type(self):
        """ Return the type of entity contained within this index. Will return
        either :py:class:`Node` or :py:class:`Relationship`.
        """
        return self._content_type

    @property
    def name(self):
        """ Return the name of this index.
        """
        return self._name

    def get(self, key, value):
        """ Fetch a list of all entities from the index which are associated
        with the `key`:`value` pair supplied.

        :param key:
        :param value:
        """
        return [
            self.graph._hydrate(result)
            for result in self._searcher.expand(key=key, value=value).get().content
        ]

    def create(self, key, value, abstract):
        """ Create and index a new node or relationship using the abstract
        provided.

        :param key:
        :param value:
        :param abstract:
        """
        batch = ManualIndexWriteBatch(self.graph)
        if self._content_type is Node:
            batch.create(abstract)
            batch.add_to_index(Node, self, key, value, 0)
        elif self._content_type is Relationship:
            batch.create(abstract)
            batch.add_to_index(Relationship, self, key, value, 0)
        else:
            raise TypeError(self._content_type)
        entity, index_entry = batch.run()
        return entity

    def _create_unique(self, key, value, abstract):
        """ Internal method to support `get_or_create` and `create_if_none`.
        """
        if self._content_type is Node:
            body = {
                "key": key,
                "value": value,
                "properties": abstract
            }
        elif self._content_type is Relationship:
            body = {
                "key": key,
                "value": value,
                "start": abstract[0].uri.string,
                "type": abstract[1],
                "end": abstract[2].uri.string,
                "properties": abstract[3] if len(abstract) > 3 else None
            }
        else:
            raise TypeError(self._content_type)
        return self._get_or_create.post(body)

    def get_or_create(self, key, value, abstract):
        """ Fetch a single entity from the index which is associated with the
        `key`:`value` pair supplied, creating a new entity with the supplied
        details if none exists.
        """
        return self.graph._hydrate(self._create_unique(key, value, abstract).content)

    def create_if_none(self, key, value, abstract):
        """ Create a new entity with the specified details within the current
        index, under the `key`:`value` pair supplied, if no such entity already
        exists. If creation occurs, the new entity will be returned, otherwise
        :py:const:`None` will be returned.
        """
        rs = self._create_unique(key, value, abstract)
        if rs.status_code == CREATED:
            return self.graph._hydrate(rs.content)
        else:
            return None

    def remove(self, key=None, value=None, entity=None):
        """ Remove any entries from the index which match the parameters
        supplied. The allowed parameter combinations are:

        `key`, `value`, `entity`
            remove a specific entity indexed under a given key-value pair

        `key`, `value`
            remove all entities indexed under a given key-value pair

        `key`, `entity`
            remove a specific entity indexed against a given key but with
            any value

        `entity`
            remove all occurrences of a specific entity regardless of
            key and value

        """
        if key and value and entity:
            t = ResourceTemplate(remote(self).uri.string + "/{key}/{value}/{entity}")
            t.expand(key=key, value=value, entity=remote(entity)._id).delete()
        elif key and value:
            uris = [
                URI(remote(entity).metadata["indexed"])
                for entity in self.get(key, value)
            ]
            batch = ManualIndexWriteBatch(self.graph)
            for uri in uris:
                batch.append_delete(uri)
            batch.run()
        elif key and entity:
            t = ResourceTemplate(remote(self).uri.string + "/{key}/{entity}")
            t.expand(key=key, entity=remote(entity)._id).delete()
        elif entity:
            t = ResourceTemplate(remote(self).uri.string + "/{entity}")
            t.expand(entity=remote(entity)._id).delete()
        else:
            raise TypeError("Illegal parameter combination for index removal")

    def query(self, query):
        """ Query the index according to the supplied query criteria, returning
        a list of matched entities.

        The query syntax used should be appropriate for the configuration of
        the index being queried. For indexes with default configuration, this
        should be Apache Lucene query syntax.
        """
        resource = self._query_template.expand(query=query)
        for result in resource.get().content:
            yield self.graph._hydrate(result)

    def _query_with_score(self, query, order):
        resource = self._query_template.expand(query=query, order=order)
        for result in resource.get().content:
            yield self.graph._hydrate(result), result["score"]

    def query_by_index(self, query):
        return self._query_with_score(query, "index")

    def query_by_relevance(self, query):
        return self._query_with_score(query, "relevance")

    def query_by_score(self, query):
        return self._query_with_score(query, "score")
Exemple #23
0
 def connectGraph(self):
     authenticate(self.service_ip, self.user, self.password)
     graph = Graph('http://%s/db/data/' % self.service_ip)
     return graph
Exemple #24
0
 def graph(self):
     if self._graph is None:
         self._graph = Graph(**self.server)
     return self._graph
Exemple #25
0
class Repository(object):
    """ Storage container for :class:`.GraphObject` instances.
    """
    @classmethod
    def wrap(cls, graph):
        """ Wrap an existing :class:`.Graph` object as a
        :class:`.Repository`.
        """
        obj = object.__new__(Repository)
        obj.graph = graph
        return obj

    def __init__(self, profile=None, name=None, **settings):
        self.graph = Graph(profile, name=name, **settings)

    def reload(self, obj):
        """ Reload data from the remote graph into the local object.
        """
        self.graph.pull(obj)

    def save(self, *objects):
        """ Save data from the local object into the remote graph.
        """
        def push_all(tx):
            for obj in objects:
                tx.push(obj)

        self.graph.play(push_all)

    def delete(self, obj):
        """ Delete the object in the remote graph.
        """
        self.graph.delete(obj)

    def exists(self, obj):
        """ Check whether the object exists in the remote graph.
        """
        return self.graph.exists(obj)

    def match(self, ogm_class, primary_value=None):
        """ Select one or more objects from the remote graph.

        :param ogm_class: the :class:`.GraphObject` subclass to match
        :param primary_value: value of the primary property (optional)
        :rtype: :class:`.GraphObjectMatch`
        """
        return GraphObjectMatcher(ogm_class, self).match(primary_value)

    def get(self, ogm_class, primary_value=None):
        """ Match and return a single object from the remote graph.

        :param ogm_class: the :class:`.GraphObject` subclass to match
        :param primary_value: value of the primary property (optional)
        :rtype: :class:`.GraphObject`
        """
        return self.match(ogm_class, primary_value).first()

    @deprecated("Repository.create is a compatibility alias, "
                "please use Repository.save instead")
    def create(self, obj):
        self.graph.create(obj)

    @deprecated("Repository.merge is a compatibility alias, "
                "please use Repository.save instead")
    def merge(self, obj):
        self.graph.merge(obj)

    @deprecated("Repository.pull is a compatibility alias, "
                "please use Repository.load instead")
    def pull(self, obj):
        self.graph.pull(obj)

    @deprecated("Repository.push is a compatibility alias, "
                "please use Repository.save instead")
    def push(self, obj):
        self.graph.push(obj)
    def connectGraph(self):
        # graph = Graph(user = self.user, password = self.password)
        authenticate("localhost:7474", self.user, self.password)
        graph = Graph("http://localhost:7474/db/data/")

        return graph
 def __init__(self, profile=None, name=None, **settings):
     self.graph = Graph(profile, name=name, **settings)
Exemple #28
0
from flask import Flask
from py2neo.database import Graph
from settings import PLATFORM_DB, BLOWFISH_SECRET
from Crypto.Cipher import Blowfish

db = Graph(**PLATFORM_DB)
blowfish = Blowfish.new(BLOWFISH_SECRET)


def create_app():
    app = Flask('Platform')
    # Load common settings
    app.config.from_object('settings')

    # Register blueprints
    from .views import register_blueprints
    register_blueprints(app)

    @app.route('/healthcheck', methods=['GET'])
    def healthcheck():
        return 'HEALTHY'

    return app
Exemple #29
0
    If is, the props will never update.')
parser.add_argument('-ai',
                    dest='add_inexistence',
                    type=bool,
                    default=False,
                    help='Whether to add an inexistent Node or Relation.')
parser.add_argument('-up',
                    dest='update_props',
                    type=bool,
                    default=False,
                    help='Whether to update props of a Node or Relation.')
args = parser.parse_args()

graph = Graph(scheme=neo_sche,
              host=neo_host,
              port=neo_port,
              user=neo_user,
              password=neo_pass)
mem = NLMLayer(graph=graph,
               fuzzy_node=args.fuzzy_node,
               add_inexistence=args.add_inexistence,
               update_props=args.update_props)


class NLMService(nlm_pb2_grpc.NLMServicer):
    @raise_grpc_error(Exception, StatusCode.INTERNAL)
    @deco_log_error(logger)
    @convert_request_to(GraphNode)
    def NodeRecall(self, request, context):
        result = mem(request)
        gn = result[0] if result else request
class Repository(object):
    """ Storage container for :class:`.Model` instances.

    The constructor for this class has an identical signature to that
    for the :class:`.Graph` class. For example::

        >>> from py2neo.ogm import Repository
        >>> from py2neo.ogm.models.movies import Movie
        >>> repo = Repository("bolt://neo4j@localhost:7687", password="******")
        >>> repo.match(Movie, "The Matrix").first()
        <Movie title='The Matrix'>

    *New in version 2020.0. In earlier versions, a :class:`.Graph` was
    required to co-ordinate all reads and writes to the remote
    database. This class completely replaces that, removing the need
    to import from any other packages when using OGM.*
    """
    @classmethod
    def wrap(cls, graph):
        """ Wrap an existing :class:`.Graph` object as a
        :class:`.Repository`.
        """
        obj = object.__new__(Repository)
        obj.graph = graph
        return obj

    def __init__(self, profile=None, name=None, **settings):
        self.graph = Graph(profile, name=name, **settings)

    def __repr__(self):
        return "<Repository profile=%r>" % (self.graph.service.profile, )

    def reload(self, obj):
        """ Reload data from the remote graph into the local object.
        """
        self.graph.pull(obj)

    def save(self, *objects):
        """ Save data from the local object into the remote graph.
        """
        def push_all(tx):
            for obj in objects:
                tx.push(obj)

        self.graph.update(push_all)

    def delete(self, obj):
        """ Delete the object in the remote graph.
        """
        self.graph.delete(obj)

    def exists(self, obj):
        """ Check whether the object exists in the remote graph.
        """
        return self.graph.exists(obj)

    def match(self, model, primary_value=None):
        """ Select one or more objects from the remote graph.

        :param model: the :class:`.Model` subclass to match
        :param primary_value: value of the primary property (optional)
        :rtype: :class:`.ModelMatch`
        """
        return ModelMatcher(model, self).match(primary_value)

    def get(self, model, primary_value=None):
        """ Match and return a single object from the remote graph.

        :param model: the :class:`.Model` subclass to match
        :param primary_value: value of the primary property (optional)
        :rtype: :class:`.Model`
        """
        return self.match(model, primary_value).first()

    @deprecated("Repository.create is a compatibility alias, "
                "please use Repository.save instead")
    def create(self, obj):
        self.graph.create(obj)

    @deprecated("Repository.merge is a compatibility alias, "
                "please use Repository.save instead")
    def merge(self, obj):
        self.graph.merge(obj)

    @deprecated("Repository.pull is a compatibility alias, "
                "please use Repository.load instead")
    def pull(self, obj):
        self.graph.pull(obj)

    @deprecated("Repository.push is a compatibility alias, "
                "please use Repository.save instead")
    def push(self, obj):
        self.graph.push(obj)
Exemple #31
0
class ManualIndex(object):
    """ Searchable database index which can contain either nodes or
    relationships.
    """
    def __init__(self, content_type, uri, name=None):
        self._content_type = content_type
        key_value_pos = uri.find("/{key}/{value}")
        if key_value_pos >= 0:
            self._searcher = ResourceTemplate(uri)
            self.__remote__ = Resource(uri[:key_value_pos])
        else:
            self.__remote__ = Resource(uri)
            self._searcher = ResourceTemplate(uri.string + "/{key}/{value}")
        uri = remote(self).uri
        self._create_or_fail = Resource(
            uri.resolve("?uniqueness=create_or_fail"))
        self._get_or_create = Resource(
            uri.resolve("?uniqueness=get_or_create"))
        self._query_template = ResourceTemplate(uri.string + "{?query,order}")
        self._name = name or uri.path.segments[-1]
        self.__searcher_stem_cache = {}
        self.graph = Graph(uri.resolve("/db/data/").string)

    def __repr__(self):
        return "{0}({1}, {2})".format(self.__class__.__name__,
                                      self._content_type.__name__,
                                      repr(remote(self).uri.string))

    def _searcher_stem_for_key(self, key):
        if key not in self.__searcher_stem_cache:
            stem = self._searcher.uri_template.string.partition("{key}")[0]
            self.__searcher_stem_cache[key] = stem + percent_encode(key) + "/"
        return self.__searcher_stem_cache[key]

    def add(self, key, value, entity):
        """ Add an entity to this index under the `key`:`value` pair supplied.

        Note that while Neo4j indexes allow multiple entities to be added under
        a particular key:value, the same entity may only be represented once;
        this method is therefore idempotent.

        :param key:
        :param value:
        :param entity:
        """
        remote(self).post({
            "key": key,
            "value": value,
            "uri": remote(entity).uri.string,
        })
        return entity

    def add_if_none(self, key, value, entity):
        """ Add an entity to this index under the `key`:`value` pair
        supplied if no entry already exists at that point.

        If added, this method returns the entity, otherwise :py:const:`None`
        is returned.
        """
        rs = self._get_or_create.post({
            "key": key,
            "value": value,
            "uri": remote(entity).uri.string,
        })
        if rs.status_code == CREATED:
            return entity
        else:
            return None

    @property
    def content_type(self):
        """ Return the type of entity contained within this index. Will return
        either :py:class:`Node` or :py:class:`Relationship`.
        """
        return self._content_type

    @property
    def name(self):
        """ Return the name of this index.
        """
        return self._name

    def get(self, key, value):
        """ Fetch a list of all entities from the index which are associated
        with the `key`:`value` pair supplied.

        :param key:
        :param value:
        """
        return [
            self.graph._hydrate(result) for result in self._searcher.expand(
                key=key, value=value).get().content
        ]

    def create(self, key, value, abstract):
        """ Create and index a new node or relationship using the abstract
        provided.

        :param key:
        :param value:
        :param abstract:
        """
        batch = ManualIndexWriteBatch(self.graph)
        if self._content_type is Node:
            batch.create(abstract)
            batch.add_to_index(Node, self, key, value, 0)
        elif self._content_type is Relationship:
            batch.create(abstract)
            batch.add_to_index(Relationship, self, key, value, 0)
        else:
            raise TypeError(self._content_type)
        entity, index_entry = batch.run()
        return entity

    def _create_unique(self, key, value, abstract):
        """ Internal method to support `get_or_create` and `create_if_none`.
        """
        if self._content_type is Node:
            body = {"key": key, "value": value, "properties": abstract}
        elif self._content_type is Relationship:
            body = {
                "key": key,
                "value": value,
                "start": abstract[0].uri.string,
                "type": abstract[1],
                "end": abstract[2].uri.string,
                "properties": abstract[3] if len(abstract) > 3 else None
            }
        else:
            raise TypeError(self._content_type)
        return self._get_or_create.post(body)

    def get_or_create(self, key, value, abstract):
        """ Fetch a single entity from the index which is associated with the
        `key`:`value` pair supplied, creating a new entity with the supplied
        details if none exists.
        """
        return self.graph._hydrate(
            self._create_unique(key, value, abstract).content)

    def create_if_none(self, key, value, abstract):
        """ Create a new entity with the specified details within the current
        index, under the `key`:`value` pair supplied, if no such entity already
        exists. If creation occurs, the new entity will be returned, otherwise
        :py:const:`None` will be returned.
        """
        rs = self._create_unique(key, value, abstract)
        if rs.status_code == CREATED:
            return self.graph._hydrate(rs.content)
        else:
            return None

    def remove(self, key=None, value=None, entity=None):
        """ Remove any entries from the index which match the parameters
        supplied. The allowed parameter combinations are:

        `key`, `value`, `entity`
            remove a specific entity indexed under a given key-value pair

        `key`, `value`
            remove all entities indexed under a given key-value pair

        `key`, `entity`
            remove a specific entity indexed against a given key but with
            any value

        `entity`
            remove all occurrences of a specific entity regardless of
            key and value

        """
        if key and value and entity:
            t = ResourceTemplate(
                remote(self).uri.string + "/{key}/{value}/{entity}")
            t.expand(key=key, value=value, entity=remote(entity)._id).delete()
        elif key and value:
            uris = [
                URI(remote(entity).metadata["indexed"])
                for entity in self.get(key, value)
            ]
            batch = ManualIndexWriteBatch(self.graph)
            for uri in uris:
                batch.append_delete(uri)
            batch.run()
        elif key and entity:
            t = ResourceTemplate(remote(self).uri.string + "/{key}/{entity}")
            t.expand(key=key, entity=remote(entity)._id).delete()
        elif entity:
            t = ResourceTemplate(remote(self).uri.string + "/{entity}")
            t.expand(entity=remote(entity)._id).delete()
        else:
            raise TypeError("Illegal parameter combination for index removal")

    def query(self, query):
        """ Query the index according to the supplied query criteria, returning
        a list of matched entities.

        The query syntax used should be appropriate for the configuration of
        the index being queried. For indexes with default configuration, this
        should be Apache Lucene query syntax.
        """
        resource = self._query_template.expand(query=query)
        for result in resource.get().content:
            yield self.graph._hydrate(result)

    def _query_with_score(self, query, order):
        resource = self._query_template.expand(query=query, order=order)
        for result in resource.get().content:
            yield self.graph._hydrate(result), result["score"]

    def query_by_index(self, query):
        return self._query_with_score(query, "index")

    def query_by_relevance(self, query):
        return self._query_with_score(query, "relevance")

    def query_by_score(self, query):
        return self._query_with_score(query, "score")
Exemple #32
0
                        continue
                    existing_rels.append(job_value)
                    existing_rels = existing_rels[-100000:]
                    register_connection(get_connection(*job_value))
                elif job_type == 'update_rel':
                    pass
                else:
                    raise Exception('Unknown job_type', job_type)
            db_queue.task_done()
        except:
            pass


logger = logging.getLogger()
print('Connecting to graph')
graph = Graph(password='******')  # TODO: parameterize, don't hardcode password


def main():
    sniffer_count = min([cpu_count(), len(argv[1:])])
    sniffer_queue = JoinableQueue()
    db_queue = JoinableQueue()
    for filename in argv[1:]:
        if os.path.isfile(filename):
            print('Will be loading from file', filename)
        else:
            print('Will sniff from interface', filename)
        sniffer_queue.put(filename)
    if argv[1:] == []:
        sniffer_queue.put('*')
        if sniffer_count == 0:
Exemple #33
0
from dataclasses import dataclass
from pnlp import piop

from py2neo.database import Graph
from batch_scheme import (Disease, Department, Producer,
                          Symptom, Examination, Food, Drug)


graph = Graph(scheme="bolt", host="localhost", port=7687,
              user="******", password="******")


def create_node(item: dict):
    """
    One item of the given data to a node.
    """
    dise = Disease()
    dise.name = item.get("name", "")
    dise.description = item.get("desc", "")
    dise.prevent = item.get("prevent", "")
    dise.cause = item.get("cause", "")
    dise.susceptible = item.get("easy_get", "")
    dise.cause_prob = item.get("get_prob", "")
    dise.cured_prob = item.get("ured_prob", "")
    dise.method = item.get("cure_way", "")
    dise.cure_duration = item.get("cure_lasttime", "")
    return dise


@dataclass
class RelationUpdate: