From 6deaf40ade2bd9dbb5a9909e5d1b5a008312c223 Mon Sep 17 00:00:00 2001 From: davebshow <davebshow@gmail.com> Date: Thu, 22 Sep 2016 19:46:03 -0400 Subject: [PATCH] finished updating the docs, not perfect, but when are they ever --- docs/glv.rst | 91 ++++++++++++++++++++++++++++++++++++- docs/index.rst | 27 +++++++++-- goblin/driver/connection.py | 3 ++ 3 files changed, 117 insertions(+), 4 deletions(-) diff --git a/docs/glv.rst b/docs/glv.rst index a32f097..dd50e61 100644 --- a/docs/glv.rst +++ b/docs/glv.rst @@ -3,4 +3,93 @@ Using AsyncGraph (GLV) :py:mod:`Goblin` provides an asynchronous version of the gremlin-python Gremlin Language Variant (GLV) that is bundled with Apache TinkerPop beginning -with the 3.2.2 release. +with the 3.2.2 release. Traversal are generated using the class +:py:class:`AsyncGraph<goblin.driver.graph.AsyncGraph>` combined with a remote +connection class, either :py:class:`Connection<goblin.driver.connection.Connection>` or +:py:class:`DriverRemoteConnection<goblin.driver.connection.DriverRemoteConnection>`:: + + >>> import asyncio + >>> from goblin import driver + + >>> loop = asyncio.get_event_loop() + >>> remote_conn = loop.run_until_complete( + ... driver.Connection.open( + ... "http://localhost:8182/gremlin", loop)) + >>> graph = driver.AsyncGraph() + >>> g = graph.traversal().withRemote(remote_conn) + +Once you have a traversal source, it's all Gremlin...:: + + >>> traversal = g.addV('query_language').property('name', 'gremlin') + +`traversal` is in an instance of +:py:class:`AsyncGraphTraversal<goblin.driver.graph.AsyncGraphTraversal>`, which +implements the Python 3.5 asynchronous iterator protocol:: + + >>> async def iterate_traversal(traversal): + >>> async for msg in traversal: + >>> print(msg) + + >>> loop.run_until_complete(iterate_traversal(traversal)) + # v[0] + +:py:class:`AsyncGraphTraversal<goblin.driver.graph.AsyncGraphTraversal>` also +provides several convenience methods to help iterate over results: + +- :py:meth:`next<goblin.driver.graph.AsyncGraphTraversal.next>` +- :py:meth:`toList<goblin.driver.graph.AsyncGraphTraversal.toList>` +- :py:meth:`toSet<goblin.driver.graph.AsyncGraphTraversal.toSet>` +- :py:meth:`oneOrNone<goblin.driver.graph.AsyncGraphTraversal.oneOrNone>` + +Notice the mixedCase? Not very pythonic? Well no, but it maintains continuity +with the Gremlin query language, and that's what the GLV is all about... + +Note: Gremlin steps that are reserved words in Python, like `or`, `in`, use a +a trailing underscore `or_` and `in_`. + +The Side Effect Interface +------------------------- + +When using TinkerPop 3.2.2+ with the default +:py:class:`GraphSON2MessageSerializer<goblin.driver.serializer.GraphSON2MessageSerializer>`, +:py:mod:`Goblin` provides an asynchronous side effects interface using the +:py:class:`AsyncRemoteTraversalSideEffects<goblin.driver.graph.AsyncRemoteTraversalSideEffects>` +class. This allows side effects to be retrieved after executing the traversal:: + + >>> traversal = g.V().aggregate('a') + >>> results = loop.run_until_complete(traversal.toList()) + >>> print(results) + # [v[0]] + +Calling +:py:meth:`keys<goblin.driver.graph.AsyncRemoteTraversalSideEffects.keys>` +will then return an asynchronous iterator containing all keys for cached +side effects: + + >>> async def get_side_effect_keys(traversal): + ... resp = await traversal.side_effects.keys() + ... async for key in resp: + ... print(key) + + + >>> loop.run_until_complete(get_side_effect_keys(traversal)) + # 'a' + +Then calling +:py:meth:`get<goblin.driver.graph.AsyncRemoteTraversalSideEffects.get>` +using a valid key will return the cached side effects:: + + >>> async def get_side_effects(traversal): + ... resp = await traversal.side_effects.get('a') + ... async for side_effect in resp: + ... print(side_effect) + + + >>> loop.run_until_complete(get_side_effects(traversal)) + # v[0] + +And that's it! For more information on Gremlin Language Variants, please +visit the `Apache TinkerPop GLV Documentation`_. + + +.. _Apache TinkerPop GLV Documentation: http://tinkerpop.apache.org/docs/3.2.2/tutorials/gremlin-language-variants/ diff --git a/docs/index.rst b/docs/index.rst index 07ab996..1704c17 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -46,7 +46,8 @@ Submit scripts and bindings to the `Gremlin Server`_:: >>> async def go(loop): ... script = "g.addV('developer').property(k1, v1)" ... bindings = {'k1': 'name', 'v1': 'Leif'} - ... conn = await driver.Connection.open('ws://localhost:8182/gremlin', loop) + ... conn = await driver.Connection.open( + ... 'ws://localhost:8182/gremlin', loop) ... async with conn: ... resp = await conn.submit(gremlin=script, bindings=bindings) ... async for msg in resp: @@ -64,7 +65,8 @@ Generate and submit Gremlin traversals in native Python:: >>> remote_conn = loop.run_until_complete( - ... driver.Connection.open("http://localhost:8182/gremlin", loop)) + ... driver.Connection.open( + ... "http://localhost:8182/gremlin", loop)) >>> graph = driver.AsyncGraph() >>> g = graph.traversal().withRemote(remote_conn) @@ -79,7 +81,8 @@ Generate and submit Gremlin traversals in native Python:: >>> loop.run_until_complete(go(g)) # {'properties': {'name': [{'value': 'Leif', 'id': 3}]}, 'label': 'developer', 'id': 2, 'type': 'vertex'} -For more information on using the AsyncGraph, see the :doc:`GLV docs</glv>` +For more information on using the :py:class:`goblin.driver.graph.AsyncGraph<AsyncGraph>`, +see the :doc:`GLV docs</glv>` **OGM** @@ -143,12 +146,30 @@ for an element, that element will be updated to reflect these changes. For more information on using the OGM, see the :doc:`OGM docs</ogm>` +A note about GraphSON message serialization +------------------------------------------- + +The :py:mod:`goblin.driver` provides support for both GraphSON2 and GraphSON1 +out of the box. By default, it uses the +:py:class:`GraphSON2MessageSerializer<goblin.driver.serializer.GraphSON2MessageSerializer>`. +Since GraphSON2 was only recently included in the TinkerPop 3.2.2 release, +:py:mod:`goblin.driver` also ships with +:py:class:`GraphSONMessageSerializer<goblin.driver.serializer.GraphSONMessageSerializer>`. +In the near future (when projects like Titan and DSE support the 3.2 Gremlin +Server line), support for GraphsSON1 will be dropped. + +The :py:mod:`goblin<Goblin>` OGM still uses GraphSON1 by default and will do so +until :py:mod:`goblin.driver` support is dropped. It will then be updated to +use GraphSON2. + + Contents: .. toctree:: :maxdepth: 4 ogm + glv driver modules diff --git a/goblin/driver/connection.py b/goblin/driver/connection.py index efad382..1b63c42 100644 --- a/goblin/driver/connection.py +++ b/goblin/driver/connection.py @@ -291,3 +291,6 @@ class Connection(AbstractConnection): async def __aexit__(self, exc_type, exc, tb): await self.close() self._conn = None + + +DriverRemoteConnection = Connection -- GitLab