Commit 11d008a2 authored by davebshow's avatar davebshow

updated docs

parent 1d93bc6b
......@@ -12,13 +12,13 @@ So, we decided to rewrite Goblin from scratch...
## Features
- Integration with the *official gremlin-python Gremlin Language Variant* (GLV)
- High level asynchronous *Object Graph Mapper* (OGM)
- Integration with the *official gremlin-python Gremlin Language Variant* (GLV) - now provided by [aiogremlin](http://aiogremlin.readthedocs.io/en/latest/)
- Native Python support for asynchronous programing including *coroutines*,
*iterators*, and *context managers* as specified in [PEP 492](https://www.python.org/dev/peps/pep-0492/)
- *Asynchronous Python driver* for the Gremlin Server
- *Asynchronous Python driver* for the Gremlin Server - now provided by [aiogremlin](http://aiogremlin.readthedocs.io/en/latest/)
- `AsyncRemoteGraph` implementation that produces *native Python GLV traversals*
- High level asynchronous *Object Graph Mapper* (OGM)
- Async `Graph` implementation that produces *native Python GLV traversals* - now provided by [aiogremlin](http://aiogremlin.readthedocs.io/en/latest/)
......@@ -365,4 +365,5 @@ texinfo_documents = [
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'https://docs.python.org/3/': None,
'aiohttp': ('http://aiohttp.readthedocs.org/en/stable/', None)}
'aiohttp': ('http://aiohttp.readthedocs.org/en/stable/', None),
'aiogremlin': ('http://aiogremlin.readthedocs.io/en/latest/', None)}
Using the Driver
================
At the its simplest, the driver provides the
:py:meth:`open<goblin.driver.connection.Connection.open>` coroutine classmethod,
which returns a :py:class:`Connection<goblin.driver.connection.Connection>` to the
Gremlin Server::
>>> import asyncio
>>> from goblin import driver
>>> loop = asyncio.get_event_loop()
>>> conn = await driver.Connection.open('ws://localhost:8182/gremlin', loop)
The :py:class:`Connection<goblin.driver.connection.Connection>` object can be
used to :py:meth:`submit<goblin.driver.connection.Connection.submit>` messages
to the Gremlin Server.
:py:meth:`submit<goblin.driver.connection.Connection.submit>` returns a
:py:class:`Response<goblin.driver.connection.Response>` object that implements
the PEP 492 asynchronous iterator protocol::
>>> resp = await conn.submit(gremlin='1 + 1')
>>> async for msg in resp:
... print(msg)
>>> await conn.close() # conn also implements async context manager interface
Connecting to a :py:class:`Cluster<goblin.driver.cluster.Cluster>`
------------------------------------------------------------------
......
Using AsyncGraph (GLV)
======================
Using Graph (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. 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>`::
:py:mod:`Goblin` provides access to the underlying :py:mod:`aiogremlin`
asynchronous version of the Gremlin-Python Gremlin Language Variant (GLV) that
is bundled with Apache TinkerPop beginning with the 3.2.2 release. Traversal are
generated using the class
:py:class:`Graph<aiogremlin.gremlin_python.structure.graph.Graph>` combined with a remote
connection class, either
:py:class:`DriverRemoteConnection<aiogremlin.remote.driver_remote_connection.DriverRemoteConnection>`::
>>> import asyncio
>>> from goblin import driver
>>> import goblin # provides aliases to common aiogremlin objects
>>> loop = asyncio.get_event_loop()
>>> remote_conn = loop.run_until_complete(
... driver.Connection.open(
... goblin.DriverRemoteConnection.open(
... "http://localhost:8182/gremlin", loop))
>>> graph = driver.AsyncGraph()
>>> g = graph.traversal().withRemote(remote_conn)
>>> graph = driver.Graph()
>>> g = goblin.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
`traversal` is in an child instance of
:py:class:`Traversal<aiogremlin.gremlin_python.process.traversal.Traversal>`, which
implements the Python 3.5 asynchronous iterator protocol::
>>> async def iterate_traversal(traversal):
......@@ -31,15 +32,13 @@ implements the Python 3.5 asynchronous iterator protocol::
>>> 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:class:`Traversal<aiogremlin.gremlin_python.process.traversal.Traversal>` also
provides several convenience coroutine 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>`
- :py:meth:`next<aiogremlin.gremlin_python.process.traversal.Traversal.next>`
- :py:meth:`toList<aiogremlin.gremlin_python.process.traversal.Traversal.toList>`
- :py:meth:`toSet<aiogremlin.gremlin_python.process.traversal.Traversal.toSet>`
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...
......@@ -51,42 +50,34 @@ The Side Effect Interface
-------------------------
When using TinkerPop 3.2.2+ with the default
:py:class:`GraphSONMessageSerializer<goblin.driver.serializer.GraphSONMessageSerializer>`,
:py:mod:`Goblin` provides an asynchronous side effects interface using the
:py:class:`AsyncRemoteTraversalSideEffects<goblin.driver.graph.AsyncRemoteTraversalSideEffects>`
:py:class:`RemoteTraversalSideEffects<aiogremlin.gremlin_python.driver.remote_connection.RemoteTraversalSideEffects>`
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]]
>>> loop.run_until_complete(traversal.iterate())
Calling
:py:meth:`keys<goblin.driver.graph.AsyncRemoteTraversalSideEffects.keys>`
:py:meth:`keys<aiogremlin.gremlin_python.driver.remote_connection.RemoteTraversalSideEffects.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)
... keys = await traversal.side_effects.keys()
... print(keys)
>>> loop.run_until_complete(get_side_effect_keys(traversal))
# 'a'
Then calling
:py:meth:`get<goblin.driver.graph.AsyncRemoteTraversalSideEffects.get>`
:py:meth:`get<aiogremlin.gremlin_python.driver.remote_connection.RemoteTraversalSideEffects.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)
... se = await traversal.side_effects.get('a')
... print(se)
>>> 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`_.
......
goblin.driver package
=====================
Submodules
----------
goblin.driver.client module
---------------------------
.. automodule:: goblin.driver.client
:members:
:undoc-members:
:show-inheritance:
goblin.driver.cluster module
----------------------------
.. automodule:: goblin.driver.cluster
:members:
:undoc-members:
:show-inheritance:
goblin.driver.connection module
-------------------------------
.. automodule:: goblin.driver.connection
:members:
:undoc-members:
:show-inheritance:
goblin.driver.graph module
--------------------------
.. automodule:: goblin.driver.graph
:members:
:undoc-members:
:show-inheritance:
goblin.driver.pool module
-------------------------
.. automodule:: goblin.driver.pool
:members:
:undoc-members:
:show-inheritance:
goblin.driver.serializer module
-------------------------------
.. automodule:: goblin.driver.serializer
:members:
:undoc-members:
:show-inheritance:
goblin.driver.server module
---------------------------
.. automodule:: goblin.driver.server
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: goblin.driver
:members:
:undoc-members:
:show-inheritance:
Contains aliases to classes from :py:mod:`aiogremlin`:
- :py:class:`Cluster<aiogremlin.driver.cluster.Cluster>`
- :py:class:`Graph<aiogremlin.gremlin_python.structure.graph.Graph>`
- :py:class:`DriverRemoteConnection<aiogremlin.remote.driver_remote_connection.DriverRemoteConnection>`
- :py:class:`Client<aiogremlin.driver.client.Client>`
- :py:class:`Connection<aiogremlin.driver.connection.Connection>`
- :py:class:`ConnectionPool<aiogremlin.driver.pool.ConnectionPool>`
- :py:class:`GremlinServer<aiogremlin.driver.server.GremlinServer>`
- :py:class:`GraphSONMessageSerializer<aiogremlin.gremlin_python.driver.serializer.GraphSONMessageSerializer>`
......@@ -27,14 +27,6 @@ goblin.app module
:undoc-members:
:show-inheritance:
goblin.cardinality module
-------------------------
.. automodule:: goblin.cardinality
:members:
:undoc-members:
:show-inheritance:
goblin.element module
---------------------
......
......@@ -9,80 +9,102 @@ Goblin - Async Python toolkit for the TinkerPop 3 Gremlin Server
:py:mod:`Goblin` is an asynchronous Python toolkit for the `TinkerPop 3`_
`Gremlin Server`_. In order to leverage Python's support for asynchronous
programming paradigms, :py:mod:`Goblin<goblin>` is implemented using the async/await
syntax introduced in Python 3.5, and does not support earlier Python versions.
syntax introduced in Python 3.5, and does not support earlier Python versions. Goblin
is built on top of `aiogremlin`_ and provides full compatibility with the `aiogremlin`_
GLV and driver.
**Main features**:
- Integration with the *official gremlin-python Gremlin Language Variant* (GLV)
- High level asynchronous *Object Graph Mapper* (OGM)
- Integration with the *official gremlin-python Gremlin Language Variant* (GLV) - now
provided by `aiogremlin`_
- Native Python support for asynchronous programing including *coroutines*,
*iterators*, and *context managers* as specified in `PEP 492`_
- *Asynchronous Python driver* for the `Gremlin Server`_
- *Asynchronous Python driver* for the `Gremlin Server`_ - now
provided by `aiogremlin`_
- :py:class:`AsyncRemoteGraph<goblin.driver.graph.AsyncRemoteGraph>`
implementation that produces *native Python GLV traversals*
- :py:class:`Graph<goblin.driver.Graph>`
implementation that produces *native Python GLV traversals* - now
provided by `aiogremlin`_
- High level asynchronous *Object Graph Mapper* (OGM)
Releases
========
The latest release of :py:mod:`goblin` is **2.0.0b1**.
The Basics
----------
Requirements
============
- Python 3.5+
- TinkerPop 3.2.4
Dependencies
============
- aiogremlin 3.2.4
- inflection 0.3.1
Installation
============
Install using pip::
$ pip install goblin
The Basics
----------
**Driver**
Submit scripts and bindings to the `Gremlin Server`_::
>>> import asyncio
>>> from goblin import driver
>>> from goblin import Cluster # alias for aiogremlin.Cluster
>>> loop = asyncio.get_event_loop()
>>> 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)
... async with conn:
... resp = await conn.submit(gremlin=script, bindings=bindings)
... cluster = await Cluster.open('ws://localhost:8182/gremlin', loop)
... client = await cluster.connect()
... resp = await client.submit(
... "g.addV('developer').property(k1, v1)",
... bindings={'k1': 'name', 'v1': 'Leif'})
... async for msg in resp:
... print(msg)
... await cluster.close()
>>> loop.run_until_complete(go(loop))
# {'type': 'vertex', 'id': 0, 'label': 'developer', 'properties': {'name': [{'id': 1, 'value': 'Leif'}]}}
For more information on using the driver, see the :doc:`Driver docs</driver>`
For more information on using the driver, see the `aiogremlin`_ documentation or the :doc:`Driver docs</driver>`
**AsyncGraph**
**Graph**
Generate and submit Gremlin traversals in native Python::
>>> from goblin import DriverRemoteConnection # alias for aiogremlin.DriverRemoteConnection
>>> from goblin import Graph # alias for aiogremlin.Graph
>>> remote_conn = loop.run_until_complete(
... driver.Connection.open(
... "http://localhost:8182/gremlin", loop))
>>> graph = driver.AsyncGraph()
>>> g = graph.traversal().withRemote(remote_conn)
>>> async def go(loop):
... remote_connection = await DriverRemoteConnection.open(
... 'ws://localhost:8182/gremlin', 'g')
... g = Graph().traversal().withRemote(remote_connection)
... vertices = await g.V().toList()
... await remote_connection.close()
... return vertices
>>> async def go(g):
... traversal = g.addV('developer').property('name', 'Leif')
... async for msg in traversal:
... print(msg)
... await remote_conn.close()
>>> results = loop.run_until_complete(go(loop))
>>> results
# [v[1], v[2], v[3], v[4], v[5], v[6]]
>>> loop.run_until_complete(go(g))
# {'properties': {'name': [{'value': 'Leif', 'id': 3}]}, 'label': 'developer', 'id': 2, 'type': 'vertex'}
For more information on using the :py:class:`AsyncGraph<goblin.driver.graph.AsyncGraph>`,
see the :doc:`GLV docs</glv>`
For more information on using the :py:class:`Graph<aiogremlin.gremlin_python.structure.graph.Graph>`,
see the `aiogremlin`_ documentation or the :doc:`GLV docs</glv>`
**OGM**
......@@ -107,7 +129,6 @@ Create a :py:class:`Goblin App<goblin.app.Goblin>` and register the element clas
>>> from goblin import Goblin
>>> app = loop.run_until_complete(
... Goblin.open(loop))
>>> app.register(Person, Knows)
......@@ -133,7 +154,6 @@ database::
... async for person in people:
... print(person)
>>> loop.run_until_complete(go(app))
# <__main__.Person object at 0x7fba0b7fa6a0>
# <__main__.Person object at 0x7fba0b7fae48>
......@@ -146,23 +166,6 @@ 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 GraphSON and GraphSON1
out of the box. By default, it uses the
:py:class:`GraphSONMessageSerializer<goblin.driver.serializer.GraphSONMessageSerializer>`.
Since GraphSON 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>`
for backwards compatibility. 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 GraphSON.
Contents:
.. toctree::
......@@ -190,3 +193,4 @@ Indices and tables
.. _`aiohttp`: http://aiohttp.readthedocs.org/en/stable/
.. _Github: https://github.com/davebshow/goblin/issues
.. _PEP 492: https://www.python.org/dev/peps/pep-0492/
.. _aiogremlin: http://aiogremlin.readthedocs.io/en/latest/
......@@ -21,6 +21,7 @@ modeling data, simply create *model* element classes that inherit from the
:py:mod:`goblin.element` classes. For example::
import goblin
from aiogremlin.gremlin_python import Cardinality
class Person(goblin.Vertex):
......@@ -138,7 +139,7 @@ to create multi-cardinality properties::
class Person(goblin.Vertex):
name = goblin.Property(goblin.String)
nicknames = goblin.VertexProperty(
goblin.String, card=goblin.Cardinality.list)
goblin.String, card=Cardinality.list)
>>> david = Person()
......@@ -149,7 +150,7 @@ to create multi-cardinality properties::
Notice that the cardinality of the
:py:class:`VertexProperty<goblin.element.VertexProperty>` must be explicitly
set using the `card` kwarg and the
:py:class:`Cardinality<goblin.cardinality.Cardinality>` enumerator.
:py:class:`Cardinality<aiogremlin.gremlin_python.Cardinality>` enumerator.
:py:class:`VertexProperty<goblin.element.VertexProperty>` provides a different
interface than the simple, key/value style
......@@ -210,7 +211,7 @@ vertex class, using any cardinality::
name = goblin.Property(goblin.String)
population = goblin.Property(goblin.Integer)
historical_name = HistoricalName(
goblin.String, card=goblin.Cardinality.list)
goblin.String, card=Cardinality.list)
Now, meta-properties can be set on the :py:class:`VertexProperty<goblin.element.VertexProperty>`
using the descriptor protocol::
......
......@@ -16,5 +16,6 @@
# along with Goblin. If not, see <http://www.gnu.org/licenses/>.
from goblin.app import Goblin
from goblin.driver import DriverRemoteConnection, AsyncGraph, Graph, Cluster
from goblin.element import Vertex, Edge, VertexProperty
from goblin.properties import Property, String, Integer, Float, Boolean
......@@ -143,7 +143,7 @@ class Goblin:
:returns: :py:class:`Session<goblin.session.Session>` object
"""
remote_connection = await aiogremlin.DriverRemoteConnection.using(
self._cluster, loop=self._loop, aliases=self._aliases)
self._cluster, aliases=self._aliases)
return session.Session(self,
remote_connection,
self._get_hashable_id)
......
aenum==1.4.5
aiohttp==1.1.5
alabaster==0.7.9
async-timeout==1.1.0
Babel==2.3.4
chardet==2.3.0
coverage==4.2
coveralls==1.1
docopt==0.6.2
docutils==0.12
imagesize==0.7.1
aiogremlin==3.2.4b1
inflection==0.3.1
Jinja2==2.8
MarkupSafe==0.23
multidict==2.1.2
Pygments==2.1.3
pytest==3.0.2
pytest-asyncio==0.5.0
pytest-runner==2.9
pytz==2016.7
PyYAML==3.12
requests==2.12.1
six==1.10.0
snowballstemmer==1.2.1
Sphinx==1.4.8
yarl==0.7.1
......@@ -3,19 +3,16 @@ from setuptools import setup
setup(
name="goblin",
version="1.0.0b2",
version="2.0.0b1",
url="",
license="AGPL",
author="davebshow",
author_email="davebshow@gmail.com",
description="Python toolkit for TP3 Gremlin Server",
packages=["goblin", "goblin.driver", "gremlin_python",
"gremlin_python.process", "gremlin_python.driver",
"gremlin_python.structure", "gremlin_python.structure.io"],
packages=["goblin", "goblin.driver"],
install_requires=[
"aiohttp==1.3.3",
"aiogremlin==3.2.4b1",
"inflection==0.3.1",
"PyYAML==3.12"
],
test_suite="tests",
setup_requires=['pytest-runner'],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment