Exemple #1
0
def test_auto_run_with_pull_all(service_profile):
    cx = Connector(service_profile)
    result = cx.auto_run("UNWIND range(1, 5) AS n RETURN n")
    assert result.take() == [1]
    assert result.take() == [2]
    assert result.take() == [3]
    assert result.take() == [4]
    assert result.take() == [5]
    assert result.take() is None
    cx.close()
 def __init__(self, profile=None, **settings):
     from py2neo.client import Connector
     from py2neo.client.config import ConnectionProfile
     profile = ConnectionProfile(profile, **settings)
     connector_settings = {
         "user_agent": settings.get("user_agent"),
         "init_size": settings.get("init_size"),
         "max_size": settings.get("max_size"),
         "max_age": settings.get("max_age"),
         "routing": settings.get("routing"),
     }
     self._connector = Connector(profile, **connector_settings)
     self._graphs = {}
 def __init__(self, profile=None, **settings):
     from py2neo import ServiceProfile
     from py2neo.client import Connector
     connector_settings = {
         "user_agent": settings.pop("user_agent", None),
         "init_size": settings.pop("init_size", None),
         "max_size": settings.pop("max_size", None),
         "max_age": settings.pop("max_age", None),
         "routing_refresh_ttl": settings.pop("routing_refresh_ttl", None),
     }
     profile = ServiceProfile(profile, **settings)
     if connector_settings["init_size"] is None and not profile.routing:
         # Ensures credentials are checked on construction
         connector_settings["init_size"] = 1
     self._connector = Connector(profile, **connector_settings)
     self._graphs = {}
Exemple #4
0
 def __init__(self, profile=None, **settings):
     from py2neo.client import Connector
     from py2neo.client.config import ConnectionProfile
     profile = ConnectionProfile(profile, **settings)
     connector_settings = {
         "user_agent": settings.get("user_agent"),
         "init_size": settings.get("init_size"),
         "max_size": settings.get("max_size"),
         "max_age": settings.get("max_age"),
         "routing": settings.get("routing"),
     }
     if connector_settings["init_size"] is None and not connector_settings["routing"]:
         # Ensures credentials are checked on construction
         connector_settings["init_size"] = 1
     self._connector = Connector(profile, **connector_settings)
     self._graphs = {}
Exemple #5
0
 def process_01(self, *args):
     for arg in args:
         if isinstance(arg, dict):
             self.auth = arg
             if "user_agent" in self.auth:
                 self.user_agent = self.auth.pop("user_agent")
         else:
             self.user_agent = arg
     self.target = Connector(ServiceProfile(
         target,
         user=self.auth["principal"],
         password=self.auth["credentials"]),
                             init_size=1)
     self.client.write_message(
         0x70,
         [{
             "server": self.target.server_agent,
             "proxy": "py2neo.proxy/0.0.0",  # TODO: hardcoded
             "connection_id": "proxy-0"
         }])  # TODO: hardcoded
     self.client.send()
Exemple #6
0
def test_auto_run_with_pull_3_then_pull_all(service_profile):
    connector = Connector(service_profile)
    try:
        result = connector.auto_run("UNWIND range(1, 5) AS n RETURN n")
        connector.pull(result, 3)
    except IndexError as error:
        skip(str(error))
    else:
        assert result.take() == [1]
        assert result.take() == [2]
        assert result.take() == [3]
        assert result.take() is None
        connector.pull(result)
        assert result.take() == [4]
        assert result.take() == [5]
        assert result.take() is None
    finally:
        connector.close()
Exemple #7
0
 def __new__(cls, profile=None, **settings):
     profile = ConnectionProfile(profile, **settings)
     try:
         inst = cls._instances[profile]
     except KeyError:
         inst = super(GraphService, cls).__new__(cls)
         connector_settings = {
             "user_agent": settings.get("user_agent"),
             "init_size": settings.get("init_size"),
             "max_size": settings.get("max_size"),
             "max_age": settings.get("max_age"),
         }
         inst._connector = Connector.open(profile, **connector_settings)
         inst._graphs = {}
         cls._instances[profile] = inst
     return inst
Exemple #8
0
 def __new__(cls, profile=None, **settings):
     from py2neo.client import Connector
     from py2neo.client.config import ConnectionProfile
     profile = ConnectionProfile(profile, **settings)
     try:
         inst = cls._instances[profile]
     except KeyError:
         inst = super(GraphService, cls).__new__(cls)
         connector_settings = {
             "user_agent": settings.get("user_agent"),
             "init_size": settings.get("init_size"),
             "max_size": settings.get("max_size"),
             "max_age": settings.get("max_age"),
             "routing": settings.get("routing"),
         }
         inst._connector = Connector(profile, **connector_settings)
         inst._graphs = {}
         cls._instances[profile] = inst
     return inst
Exemple #9
0
 def rt(self, gdb):
     """ Display the routing table for a given graph database.
     """
     routers = self.service.routers()
     cx = Connector(
         ServiceProfile(routers[0].profiles["bolt"], routing=True))
     if gdb is None:
         click.echo(
             "Refreshing routing information for the default graph database..."
         )
     else:
         click.echo(
             "Refreshing routing information for graph database %r..." %
             gdb)
     rt = cx.refresh_routing_table(gdb)
     ro_profiles, rw_profiles, _ = rt.runners()
     click.echo("Routers: %s" %
                " ".join(map(str, cx.get_router_profiles())))
     click.echo("Readers: %s" % " ".join(map(str, ro_profiles)))
     click.echo("Writers: %s" % " ".join(map(str, rw_profiles)))
     cx.close()
Exemple #10
0
def connector(connection_profile):
    return Connector(connection_profile)
Exemple #11
0
def connector(service_profile):
    return Connector(service_profile)
class GraphService(object):
    """ The :class:`.GraphService` class is the top-level accessor for
    an entire Neo4j graph database management system (DBMS). Within the
    py2neo object hierarchy, a :class:`.GraphService` contains one or
    more :class:`.Graph` objects in which data storage and retrieval
    activity chiefly occurs.

    An explicit URI can be passed to the constructor::

        >>> from py2neo import GraphService
        >>> gs = GraphService("bolt://camelot.example.com:7687")

    Alternatively, the default value of ``bolt://localhost:7687`` is
    used::

        >>> default_gs = GraphService()
        >>> default_gs
        <GraphService uri='bolt://localhost:7687'>

    .. note::

        Some attributes of this class available in earlier versions of
        py2neo are no longer available, specifically
        ``kernel_start_time``, ``primitive_counts``,
        ``store_creation_time``, ``store_file_sizes`` and ``store_id``,
        along with the ``query_jmx`` method. This is due to a change in
        Neo4j 4.0 relating to how certain system metadata is exposed.
        Replacement functionality may be reintroduced in a future
        py2neo release.

    *Changed in 2020.0: this class was formerly known as 'Database',
    but was renamed to avoid confusion with the concept of the same
    name introduced with the multi-database feature of Neo4j 4.0.*

    .. describe:: iter(graph_service)

        Yield all named graphs.

        For Neo4j 4.0 and above, this yields the names returned by a
        ``SHOW DATABASES`` query. For earlier versions, this yields no
        entries, since the one and only graph in these versions is not
        named.

        *New in version 2020.0.*

    .. describe:: graph_service[name]

        Access a :class:`.Graph` by name.

        *New in version 2020.0.*

    """

    _connector = None

    _graphs = None

    def __init__(self, profile=None, **settings):
        from py2neo.client import Connector
        from py2neo.client.config import ConnectionProfile
        profile = ConnectionProfile(profile, **settings)
        connector_settings = {
            "user_agent": settings.get("user_agent"),
            "init_size": settings.get("init_size"),
            "max_size": settings.get("max_size"),
            "max_age": settings.get("max_age"),
            "routing": settings.get("routing"),
        }
        self._connector = Connector(profile, **connector_settings)
        self._graphs = {}

    def __repr__(self):
        class_name = self.__class__.__name__
        profile = self._connector.profile
        return "<%s uri=%r secure=%r user_agent=%r>" % (
            class_name, profile.uri, profile.secure,
            self._connector.user_agent)

    def __eq__(self, other):
        try:
            return self.uri == other.uri
        except AttributeError:
            return False

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash(self._connector)

    def __getitem__(self, graph_name):
        if graph_name is None:
            graph_name = self._connector.default_graph_name()
        elif graph_name not in self._connector.graph_names():
            raise KeyError("Graph {!r} does not exist for "
                           "service {!r}".format(graph_name,
                                                 self._connector.profile.uri))
        if graph_name not in self._graphs:
            graph_class = SystemGraph if graph_name == "system" else Graph
            self._graphs[graph_name] = graph_class(self.profile,
                                                   name=graph_name)
        return self._graphs[graph_name]

    def __iter__(self):
        return iter(self._connector.graph_names())

    @property
    def connector(self):
        """ The :class:`.Connector` providing communication for this
        graph service.

        *New in version 2020.0.*
        """
        return self._connector

    @property
    def profile(self):
        """ The :class:`.ConnectionProfile` for which this graph
        service is configured. This attribute is simply a shortcut
        for ``connector.profile``.

        *New in version 2020.0.*
        """
        return self.connector.profile

    @property
    def uri(self):
        """ The URI to which this graph service is connected. This
        attribute is simply a shortcut for ``connector.profile.uri``.
        """
        return self.profile.uri

    @property
    def default_graph(self):
        """ The default :class:`.Graph` exposed by this graph service.
        """
        return self[None]

    @property
    def system_graph(self):
        """ The :class:`.SystemGraph` exposed by this graph service.

        *New in version 2020.0.*
        """
        return self["system"]

    def keys(self):
        """ Return a list of all :class:`.Graph` names exposed by this
        graph service.

        *New in version 2020.0.*
        """
        return list(self)

    @property
    def kernel_version(self):
        """ The :class:`~packaging.version.Version` of Neo4j running.
        """
        from packaging.version import Version
        components = self.default_graph.call("dbms.components").data()
        kernel_component = [
            component for component in components
            if component["name"] == "Neo4j Kernel"
        ][0]
        version_string = kernel_component["versions"][0]
        return Version(version_string)

    @property
    def product(self):
        """ The product name.
        """
        record = next(self.default_graph.call("dbms.components"))
        return "%s %s (%s)" % (record[0], " ".join(
            record[1]), record[2].title())

    @property
    def config(self):
        """ A dictionary of the configuration parameters used to
        configure Neo4j.

            >>> gs.config['dbms.connectors.default_advertised_address']
            'localhost'

        """
        return {
            record["name"]: record["value"]
            for record in self.default_graph.call("dbms.listConfig")
        }
Exemple #13
0
class BoltRouter(WireRequestHandler):
    def __init__(self, *args, **kwargs):
        self.client = None
        self.target = None
        self.user_agent = None
        self.auth = {}
        self.transaction = None
        self.results = {}
        WireRequestHandler.__init__(self, *args, **kwargs)

    def setup(self):
        self.client = Bolt.accept(self.wire, min_protocol_version=(4, 0))

    def handle(self):
        try:
            while True:
                tag, args = self.client.read_message()
                try:
                    handler = self.handlers[tag]
                except KeyError:
                    raise Exception("Unknown message tag %r" % tag)
                else:
                    handler(self, *args)
        except ConnectionBroken as error:
            print("[%s] Client gone" % (self.wire.remote_address, ))

    def finish(self):
        self.client.close()
        self.target.close()

    def process_01(self, *args):
        for arg in args:
            if isinstance(arg, dict):
                self.auth = arg
                if "user_agent" in self.auth:
                    self.user_agent = self.auth.pop("user_agent")
            else:
                self.user_agent = arg
        self.target = Connector(ServiceProfile(
            target,
            user=self.auth["principal"],
            password=self.auth["credentials"]),
                                init_size=1)
        self.client.write_message(
            0x70,
            [{
                "server": self.target.server_agent,
                "proxy": "py2neo.proxy/0.0.0",  # TODO: hardcoded
                "connection_id": "proxy-0"
            }])  # TODO: hardcoded
        self.client.send()

    def process_02(self, *_):
        self.target.close()
        self.client.close()

    def process_0f(self, *_):
        self.results.clear()
        self.transaction = None
        # TODO: self.error = None
        self.client.write_message(0x70, [{}])
        self.client.send()

    def process_10(self, cypher, parameters, metadata=None):
        try:
            graph_name = metadata["db"]
        except (KeyError, TypeError):
            graph_name = None
        try:
            mode = metadata["mode"]
        except (KeyError, TypeError):
            mode = None
        self.results[-1] = result = self.target.auto_run(
            cypher, parameters, graph_name=graph_name, readonly=(mode == "r"))
        self.client.write_message(0x70, [{"fields": result.fields()}])
        self.client.send()

    def process_2f(self, args=None, *_):
        result = self.results[-1]
        while result.take() is not None:
            pass
        self.client.write_message(0x70, [{}])
        self.client.send()

    def process_3f(self, args=None, *_):
        result = self.results[-1]
        while True:
            record = result.take()
            if record is None:
                break
            self.client.write_message(0x71, record)
        self.client.write_message(0x70, [{}])
        self.client.send()

    handlers = {
        0x01: process_01,
        0x02: process_02,
        0x0F: process_0f,
        0x10: process_10,
        0x2F: process_2f,
        0x3F: process_3f
    }