diff --git a/docs/app.rst b/docs/app.rst index f5b504a9e0cd7a6ea628ae42bf4c8da7e990de0a..a2438173becc0318e803f3cd8bea673466df62b1 100644 --- a/docs/app.rst +++ b/docs/app.rst @@ -2,9 +2,9 @@ Configuring the :py:mod:`Goblin<goblin>` App Object =================================================== The :py:class:`Goblin<goblin.app.Goblin>` object generally supports the same -configuration options as :py:class:`Cluster<goblin.driver.Cluster>`. Please -see the :doc:`driver docs</driver>` for a complete list of configuration -parameters. +configuration options as +:py:class:`Cluster<aiogremlin.driver.cluster.Cluster>`. Please see the +:doc:`driver docs</driver>` for a complete list of configuration parameters. The :py:class:`Goblin<goblin.app.Goblin>` object should be created using the diff --git a/docs/conf.py b/docs/conf.py index 70f1ed98fcad2a267129dbd64e2783e29b4f1303..98f549ed5a5ddb3d2ec06dda6a09e4d76ea0e2a5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -179,7 +179,7 @@ html_theme_path = [alabaster.get_path()] # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +# html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied @@ -370,7 +370,8 @@ 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), - 'aiogremlin': ('http://aiogremlin.readthedocs.io/en/latest/', None), + 'python': ('https://docs.python.org/3.6/', None), + 'aiohttp': ('https://aiohttp.readthedocs.org/en/stable/', None), + 'aiogremlin': ('https://aiogremlin.readthedocs.io/en/latest/', None), + 'cython': ('http://cython.readthedocs.io/en/latest/', None), } diff --git a/docs/driver.rst b/docs/driver.rst index bbf0ebe4092f7f40cbb5f48f389313710d2275ce..2e1adebd552da3f57dd92113466a935ffc51efac 100644 --- a/docs/driver.rst +++ b/docs/driver.rst @@ -1,15 +1,15 @@ Using the Driver ================ -Connecting to a :py:class:`Cluster<goblin.driver.Cluster>` ----------------------------------------------------------- +Connecting to a :py:class:`Cluster<aiogremlin.driver.cluster.Cluster>` +---------------------------------------------------------------------- To take advantage of the higher level features of the :py:mod:`driver<goblin.driver>`, :py:mod:`~goblin.app.Goblin` provides the -:py:class:`Cluster<goblin.driver.Cluster>` object. -:py:class:`Cluster<goblin.driver.Cluster>` is used to create multi-host -clients that leverage connection pooling and sharing. Its interface is based -on the TinkerPop Java driver:: +:py:class:`Cluster<aiogremlin.driver.cluster.Cluster>` object. +:py:class:`Cluster<aiogremlin.driver.cluster.Cluster>` is used to create +multi-host clients that leverage connection pooling and sharing. Its interface +is based on the TinkerPop Java driver:: >>> async def print_results(gremlin='1+1'): ... # opens a cluster with default config @@ -21,20 +21,21 @@ on the TinkerPop Java driver:: ... print(msg) ... await cluster.close() # Close all connections to all hosts -And that is it. While :py:class:`Cluster<goblin.driver.Cluster>` -is simple to learn and use, it provides a wide variety of configuration options. +And that is it. While :py:class:`Cluster<aiogremlin.driver.cluster.Cluster>` is +simple to learn and use, it provides a wide variety of configuration options. -Configuring :py:class:`Cluster<goblin.driver.Cluster>` --------------------------------------------------------------- +Configuring :py:class:`Cluster<aiogremlin.driver.cluster.Cluster>` +------------------------------------------------------------------ Configuration options can be set on -:py:class:`Cluster<goblin.driver.Cluster>` in one of two ways, either -passed as keyword arguments to -:py:meth:`open<goblin.driver.Cluster.open>`, or stored in a configuration -file and passed to the :py:meth:`open<goblin.driver.Cluster.open>` -using the kwarg `configfile`. Configuration files can be either YAML or JSON -format. Currently, :py:class:`Cluster<goblin.driver.Cluster>` -uses the following configuration: +:py:class:`Cluster<aiogremlin.driver.cluster.Cluster>` in one of two ways, +either passed as keyword arguments to +:py:meth:`open<aiogremlin.driver.cluster.Cluster.open>`, or stored in +a configuration file and passed to the +:py:meth:`open<aiogremlin.driver.cluster.Cluster.open>` using the kwarg +`configfile`. Configuration files can be either YAML or JSON format. Currently, +:py:class:`Cluster<aiogremlin.driver.cluster.Cluster>` uses the following +configuration: +-------------------+----------------------------------------------+-------------+ |Key |Description |Default | diff --git a/docs/glv.rst b/docs/glv.rst index 527f61087caba6d0e7cd4a03383ba55dd35e8914..813e1f04abc3f28073143a277330f3065cc6db67 100644 --- a/docs/glv.rst +++ b/docs/glv.rst @@ -37,9 +37,9 @@ implements the Python 3.5 asynchronous iterator protocol:: :py:class:`AsyncGraphTraversal<aiogremlin.process.graph_traversal.AsyncGraphTraversal>` also provides several convenience coroutine methods to help iterate over results: -- :py:meth:`next<aiogremlin.process.traversal.AsyncGraphTraversal.next>` -- :py:meth:`toList<aiogremlin.process.traversal.AsyncGraphTraversal.toList>` -- :py:meth:`toSet<aiogremlin.process.traversal.AsyncGraphTraversal.toSet>` +- :py:meth:`next<aiogremlin.process.graph_traversal.AsyncGraphTraversal.next>` +- :py:meth:`toList<aiogremlin.process.graph_traversal.AsyncGraphTraversal.toList>` +- :py:meth:`toSet<aiogremlin.process.graph_traversal.AsyncGraphTraversal.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,8 +51,8 @@ The Side Effect Interface ------------------------- When using TinkerPop 3.2.2+ with the default -:py:mod:`Goblin` provides an asynchronous side effects interface using the -:py:class:`AsyncRemoteTraversalSideEffects<aiogremlin.driver_remote_side_effects.AsyncRemoteTraversalSideEffects>` +:py:mod:`Goblin<goblin.app.Goblin>` provides an asynchronous side effects interface using the +:py:class:`AsyncRemoteTraversalSideEffects<aiogremlin.remote.driver_remote_side_effects.AsyncRemoteTraversalSideEffects>` class. This allows side effects to be retrieved after executing the traversal:: >>> traversal = g.V().aggregate('a') @@ -60,7 +60,7 @@ class. This allows side effects to be retrieved after executing the traversal:: [['V'], ['aggregate', 'a']] Calling -:py:meth:`keys<aiogremlin.driver_remote_side_effects.AsyncRemoteTraversalSideEffects.keys>` +:py:meth:`keys<aiogremlin.remote.driver_remote_side_effects.AsyncRemoteTraversalSideEffects.keys>` will return an asynchronous iterator containing all keys for cached side effects: @@ -72,7 +72,7 @@ side effects: {'a'} Then calling -:py:meth:`get<aiogremlin.driver_remote_side_effects.AsyncRemoteTraversalSideEffects.get>` +:py:meth:`get<aiogremlin.remote.driver_remote_side_effects.AsyncRemoteTraversalSideEffects.get>` using a valid key will return the cached side effects:: >>> async def get_side_effects(traversal): diff --git a/docs/goblin.driver.rst b/docs/goblin.driver.rst index 98197d5cff0528a61c02cbbb869628f10e87fb80..47933c383dd54c0eb734bf846e145edb9fdf4773 100644 --- a/docs/goblin.driver.rst +++ b/docs/goblin.driver.rst @@ -4,9 +4,3 @@ goblin.driver package Contains aliases to classes from `aiogremlin`: .. automodule:: goblin.driver - -.. autoclass:: goblin.driver.Cluster - :members: - -.. autoclass:: goblin.driver.Connection - :members: diff --git a/docs/index.rst b/docs/index.rst index a5d5a834f4f1c88224c5d32c4d37e4aced33634c..255bf0b1cf2c0612b4d63b321b3de08e9aa4f0d8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,7 +6,7 @@ Goblin - Async Python toolkit for the TinkerPop 3 Gremlin Server ================================================================ -:py:mod:`Goblin` is an asynchronous Python toolkit for the `TinkerPop 3`_ +:py:mod:`Goblin<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. Goblin @@ -106,10 +106,11 @@ database:: <__main__.Person object at ...> ... -Note that a :py:mod:`Goblin` session does not necessarily correspond to a Gremlin Server session. -Instead, all elements created using a session are 'live' in the sense that if the -results of a traversal executed against the session result in different property values -for an element, that element will be updated to reflect these changes. +Note that a :py:mod:`Goblin session<goblin.session>` does not necessarily +correspond to a Gremlin Server session. Instead, all elements created using +a session are 'live' in the sense that if the results of a traversal executed +against the session result in different property values 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>` diff --git a/docs/ogm.rst b/docs/ogm.rst index 7eb07e2d43d50a969bba35bc90e9ba7ca78fd0f8..427cf8395f85dd38f0c9f55fc7f28e01a8babd7e 100644 --- a/docs/ogm.rst +++ b/docs/ogm.rst @@ -1,22 +1,25 @@ Using the OGM ============= -:py:mod:`Goblin` aims to provide a powerful Object Graph Mapper **(OGM)** while maintaining -a simple, transparent interface. This document describes the OGM components in -more detail. - -Modeling Graph Elements with :py:mod:`Goblin` ---------------------------------------------- - -At the core of the :py:mod:`Goblin` is the concept of the graph element. TinkerPop 3 (TP3) -uses three basic kinds of elements: Vertex, Edge, and Property. In order to achieve -consistent mapping between Python objects and TP3 elements, :py:mod:`Goblin` provides -three corresponding Python base classes that are used to model graph data: -:py:class:`Vertex<goblin.element.Vertex>`, :py:class:`Edge<goblin.element.Edge>`, and -:py:class:`Property<goblin.properties.Property>`. While these classes are created to interact -smoothly with TP3, it is important to remember that :py:mod:`Goblin` does not attempt -to implement the same element interface found in TP3. Indeed, other than user defined -properties, :py:mod:`Goblin` elements feature little to no interface. To begin +:py:mod:`Goblin<goblin>` aims to provide a powerful Object Graph Mapper +**(OGM)** while maintaining a simple, transparent interface. This document +describes the OGM components in more detail. + +Modeling Graph Elements with :py:mod:`Goblin<goblin>` +----------------------------------------------------- + +At the core of the :py:mod:`Goblin<goblin>` is the concept of the graph +element. TinkerPop 3 (TP3) uses three basic kinds of elements: Vertex, Edge, +and Property. In order to achieve consistent mapping between Python objects and +TP3 elements, :py:mod:`Goblin<goblin>` provides three corresponding Python base +classes that are used to model graph data: +:py:class:`Vertex<goblin.element.Vertex>`, +:py:class:`Edge<goblin.element.Edge>`, and +:py:class:`Property<goblin.properties.Property>`. While these classes are +created to interact smoothly with TP3, it is important to remember that +:py:mod:`Goblin<goblin>` does not attempt to implement the same element +interface found in TP3. Indeed, other than user defined properties, +:py:mod:`Goblin<goblin>` elements feature little to no interface. To begin modeling data, simply create *model* element classes that inherit from the :py:mod:`goblin.element` classes. For example:: @@ -45,14 +48,15 @@ this, add some properties to the classes. Using :py:mod:`goblin.properties` --------------------------------- -Using the :py:mod:`properties<goblin.properties>` module is a bit more involved, -but it is still pretty easy. It simply requires that you create properties that -are defined as Python class attributes, and each property requires that you pass -a :py:class:`DataType<goblin.abc.DataType>` class **or** instance as the first -positional argument. This data type, which is a concrete class that inherits from -:py:class:`DataType<goblin.abc.DataType>`, handles validation, as well as any necessary -conversion when data is mapped between the database and the OGM. :py:mod:`Goblin` -currently ships with 4 data types: :py:class:`String<goblin.properties.String>`, +Using the :py:mod:`properties<goblin.properties>` module is a bit more +involved, but it is still pretty easy. It simply requires that you create +properties that are defined as Python class attributes, and each property +requires that you pass a :py:class:`DataType<goblin.abc.DataType>` class **or** +instance as the first positional argument. This data type, which is a concrete +class that inherits from :py:class:`DataType<goblin.abc.DataType>`, handles +validation, as well as any necessary conversion when data is mapped between the +database and the OGM. :py:mod:`Goblin<goblin>` currently ships with 4 data +types: :py:class:`String<goblin.properties.String>`, :py:class:`Integer<goblin.properties.Integer>`, :py:class:`Float<goblin.properties.Float>`, and :py:class:`Boolean<goblin.properties.Boolean>`. Example property definition:: @@ -68,9 +72,9 @@ currently ships with 4 data types: :py:class:`String<goblin.properties.String>`, ... pass -:py:mod:`Goblin` :py:mod:`properties<goblin.properties.Property>` can also -be created with a default value, set by using the kwarg `default` in the class -definition:: +:py:mod:`Goblin<goblin>` :py:mod:`properties<goblin.properties.Property>` can +also be created with a default value, set by using the kwarg `default` in the +class definition:: >>> class BornIn(goblin.Edge): @@ -80,10 +84,12 @@ definition:: Creating Elements and Setting Property Values --------------------------------------------- -Behind the scenes, a small metaclass (the only metaclass used in :py:mod:`Goblin`), -substitutes a :py:class:`PropertyDescriptor<goblin.properties.PropertyDescriptor>` -for the :py:class:`Property<goblin.properties.Property>`, which provides a simple -interface for defining and updating properties using Python's descriptor protocol:: +Behind the scenes, a small metaclass (the only metaclass used in +:py:mod:`Goblin<goblin>`), substitutes +a :py:class:`PropertyDescriptor<goblin.properties.PropertyDescriptor>` for the +:py:class:`Property<goblin.properties.Property>`, which provides a simple +interface for defining and updating properties using Python's descriptor +protocol:: >>> leif = Person() >>> leif.name = 'Leif' @@ -105,14 +111,13 @@ a :py:class:`ValidationError<goblin.exception.ValidationError>` immediately:: goblin.exception.ValidationError: Not a valid integer: a lot of people -Creating Edges --------------- -Creating edges is very similar to creating vertices, except that edges require -that a source (outV) and target (inV) vertex be specified. Both source and -target nodes must be :py:mod:`Goblin vertices<goblin.element.Vertex>`. Furthermore, -they must be created in the database before the edge. This is further discussed -below in the :ref:`Session<session>` section. Source and target vertices may be -passed to the edge on instantiation, or added using the property interface:: +Creating Edges -------------- Creating edges is very similar to creating +vertices, except that edges require that a source (outV) and target (inV) +vertex be specified. Both source and target nodes must be :py:mod:`Goblin +vertices<goblin.element.Vertex>`. Furthermore, they must be created in the +database before the edge. This is further discussed below in the +:ref:`Session<session>` section. Source and target vertices may be passed to +the edge on instantiation, or added using the property interface:: >>> leif_born_in_detroit = BornIn(leif, detroit) >>> # or @@ -128,9 +133,9 @@ Vertex Properties In addition to the aforementioned elements, TP3 graphs also use a special kind of property, called a vertex property, that allows for list/set cardinality and -meta-properties. To accommodate this, :py:mod:`Goblin` provides a class -:py:class:`VertexProperty<goblin.element.VertexProperty>` that can be used directly -to create multi-cardinality properties:: +meta-properties. To accommodate this, :py:mod:`Goblin<goblin>` provides a class +:py:class:`VertexProperty<goblin.element.VertexProperty>` that can be used +directly to create multi-cardinality properties:: >>> from gremlin_python.process.traversal import Cardinality >>> class Person(goblin.Vertex): @@ -147,31 +152,39 @@ 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<gremlin_python.Cardinality>` enumerator. +:py:class:`Cardinality<gremlin_python.process.traversal.Cardinality>` +enumerator. + +.. autoclass:: gremlin_python.process.traversal.Cardinality + :members: + :undoc-members: :py:class:`VertexProperty<goblin.element.VertexProperty>` provides a different interface than the simple, key/value style -:py:class:`PropertyDescriptor<goblin.properties.PropertyDescriptor>` in order to -accomodate more advanced functionality. For accessing multi-cardinality -vertex properties, :py:mod:`Goblin` provides several helper classes called -:py:mod:`managers<goblin.manager>`. The +:py:class:`PropertyDescriptor<goblin.properties.PropertyDescriptor>` in order +to accomodate more advanced functionality. For accessing multi-cardinality +vertex properties, :py:mod:`Goblin<goblin>` provides several helper classes +called :py:mod:`managers<goblin.manager>`. The :py:class:`managers<goblin.manager.ListVertexPropertyManager>` inherits from :py:class:`list` or :py:class:`set` (depending on the specified cardinality), -and provide a simple API for accessing and appending vertex properties. To continue -with the previous example, we see the `dave` element's nicknames:: +and provide a simple API for accessing and appending vertex properties. To +continue with the previous example, we see the `dave` element's nicknames:: >>> david.nicknames [<VertexProperty(type=<...>, value=Dave), <VertexProperty(type=<...>, value=davebshow)] -To add a nickname without replacing the earlier values, we simple :py:meth:`append` as -if the manager were a Python :py:class:`list`:: +To add a nickname without replacing the earlier values, we simple +:py:meth:`append<goblin.manager.ListVertexPropertyManager.append>` as if the +manager were a Python :py:class:`list`:: >>> david.nicknames.append('db') >>> david.nicknames [<VertexProperty(type=<...>, value=Dave), <VertexProperty(type=<...>, value=davebshow), <VertexProperty(type=<...>, value=db)] If this were a :py:class:`VertexProperty<goblin.element.VertexProperty>` with -a set cardinality, we would simply use :py:meth:`add` to achieve similar functionality. +a set cardinality, we would simply use +:py:meth:`add<goblin.manager.SetVertexPropertyManager.add>` to achieve similar +functionality. Both :py:class:`ListVertexPropertyManager<goblin.manager.ListVertexPropertyManager>` and :py:class:`SetVertexPropertyManager<goblin.manager.SetVertexPropertyManager>` provide a simple @@ -221,19 +234,20 @@ Saving Elements to the Database Using :py:class:`Session<goblin.session.Session> --------------------------------------------------------------------------------- All interaction with the database is achieved using the -:py:class:`Session<goblin.session.Session>` object. A :py:mod:`Goblin` session -should not be confused with a Gremlin Server session, although in future releases -it will provide support for server sessions and transactions. Instead, -the :py:class:`Session<goblin.session.Session>` object is used to save elements -and spawn Gremlin traversals. Furthemore, any element created using a session is -*live* in the sense that a :py:class:`Session<goblin.session.Session>` object -maintains a reference to session elements, and if a traversal executed using a -session returns different property values for a session element, these values are -automatically updated on the session element. Note - the examples shown in this section -must be wrapped in coroutines and ran using the :py:class:`asyncio.BaseEventLoop`, -but, for convenience, they are shown as if they were run in a Python interpreter. -To use a :py:class:`Session<goblin.session.Session>`, first create a -:py:class:`Goblin App <goblin.app.Goblin>` using +:py:class:`Session<goblin.session.Session>` object. A :py:mod:`Goblin<goblin>` +session should not be confused with a Gremlin Server session, although in +future releases it will provide support for server sessions and transactions. +Instead, the :py:class:`Session<goblin.session.Session>` object is used to save +elements and spawn Gremlin traversals. Furthemore, any element created using +a session is *live* in the sense that +a :py:class:`Session<goblin.session.Session>` object maintains a reference to +session elements, and if a traversal executed using a session returns different +property values for a session element, these values are automatically updated +on the session element. Note - the examples shown in this section must be +wrapped in coroutines and ran using the :py:class:`asyncio.BaseEventLoop`, but, +for convenience, they are shown as if they were run in a Python interpreter. To +use a :py:class:`Session<goblin.session.Session>`, first create +a :py:class:`Goblin App <goblin.app.Goblin>` using :py:meth:`Goblin.open<goblin.app.Goblin.open>`, .. code-block:: python @@ -245,8 +259,8 @@ then register the defined element classes:: >>> app.register(Person, City, BornIn) -Goblin application support a variety of configuration options, for more information -see :doc:`the Goblin application documentation</app>`. +Goblin application support a variety of configuration options, for more +information see :doc:`the Goblin application documentation</app>`. The best way to create elements is by adding them to the session, and then flushing the `pending` queue, thereby creating the elements in the database. The order in which @@ -272,20 +286,21 @@ check that they now have unique ids assigned to them:: For more information on the :py:class:`Goblin App <goblin.app.Goblin>`, please see :doc:`Using the Goblin App</app>` -:py:class:`Session<goblin.session.Session>` provides a variety of other CRUD functions, -but all creation and updating can be achieved simply using the :py:meth:`add` and -:py:meth:`flush` methods. +:py:class:`Session<goblin.session.Session>` provides a variety of other CRUD +functions, but all creation and updating can be achieved simply using the +:py:meth:`add<goblin.session.Session.add>` and +:py:meth:`flush<goblin.session.Session.flush>` methods. Writing Custom Gremlin Traversals --------------------------------- Finally, :py:class:`Session<goblin.session.Session>` objects allow you to write -custom Gremlin traversals using the official gremlin-python Gremlin Language Variant -**(GLV)**. There are two methods available for writing session based traversals. The first, -:py:meth:`traversal<goblin.session.Session.traversal>`, accepts an element class as a -positional argument. This is merely for convenience, and generates this equivalent -Gremlin:: +custom Gremlin traversals using the official gremlin-python Gremlin Language +Variant **(GLV)**. There are two methods available for writing session based +traversals. The first, :py:meth:`traversal<goblin.session.Session.traversal>`, +accepts an element class as a positional argument. This is merely for +convenience, and generates this equivalent Gremlin:: >>> session = loop.run_until_complete(app.session()) >>> session.traversal(Person) @@ -313,18 +328,18 @@ So, to write a traversal:: Also, it is important to note that certain data types could be transformed -before they are written to the database. Therefore, the data type method `to_db` -may be required:: +before they are written to the database. Therefore, the data type method +`to_db` may be required:: >>> session.traversal(Person).has( ... Person.name, goblin.String().to_db('Leifur')) [['V'], ['hasLabel', 'person'], ['has', 'name', 'Leifur']] -While this is not the case with any of the simple data types shipped with :py:mod:`Goblin`, -custom data types or future additions may require this kind of operation. Because of -this, :py:mod:`Goblin` includes the convenience function -:py:func:`bindprop<goblin.traversal.bindprop>`, which also allows an optional binding for -the value to be specified:: +While this is not the case with any of the simple data types shipped with +:py:mod:`Goblin<goblin>`, custom data types or future additions may require +this kind of operation. Because of this, :py:mod:`Goblin<goblin>` includes the +convenience function :py:func:`bindprop<goblin.session.bindprop>`, which also +allows an optional binding for the value to be specified:: >>> from goblin.session import bindprop >>> traversal = session.traversal(Person) @@ -340,11 +355,13 @@ them as such will cause a traversal to be sent on the wire: async for msg in session.g.V().hasLabel('person'): print(msg) -Furthermore, :py:mod:`Goblin` provides several convenience methods that -submit a traversal as well as process the results :py:meth:`toList`, -:py:meth:`toSet` and :py:meth:`next`. These methods both submit a script -to the server and iterate over the results. Remember to `await` the traversal -when calling these methods: +Furthermore, :py:mod:`Goblin<goblin>` provides several convenience methods that +submit a traversal as well as process the results +:py:meth:`toList<aiogremlin.process.graph_traversal.AsyncGraphTraversal.toList>`, +:py:meth:`toSet<aiogremlin.process.graph_traversal.AsyncGraphTraversal.toSet>` +and :py:meth:`next<aiogremlin.process.graph_traversal.AsyncGraphTraversal.next>`. +These methods both submit a script to the server and iterate over the results. +Remember to `await` the traversal when calling these methods: .. code-block:: python @@ -352,4 +369,4 @@ when calling these methods: leif = await traversal.has( bindprop(Person, 'name', 'Leifur', binding='v1')).next() -And that is pretty much it. We hope you enjoy the :py:mod:`Goblin` OGM. +And that is pretty much it. We hope you enjoy the :py:mod:`Goblin<goblin>` OGM. diff --git a/docs/performance.rst b/docs/performance.rst index c103b888023e118c9be4409dda2422f79648e4a8..22a21d4be1165733f0e47958d96e44baeb1f4499 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -8,30 +8,30 @@ software stack i.e., the websocket client, the event loop implementation, etc. If necessary, a few tricks can boost its performance. -Use :py:mod:`Cython` --------------------- +Use ``cython`` +-------------- -Before installing :py:mod:`Goblin`, install :py:mod:`Cython`:: +Before installing :py:mod:`Goblin<goblin>`, install ``cython``:: $ pip install cython -Use :py:mod:`ujson` -------------------- +Use ``ujson`` +------------- -Install :py:mod:`ujson` to speed up serialzation:: +Install ``ujson`` to speed up serialzation:: $ pip install ujson -Use :py:mod:`uvloop` --------------------- +Use ``uvloop`` +-------------- -Install :py:mod:`uvloop`, a Cython implementation of an event loop:: +Install ``uvloop``, a Cython implementation of an event loop:: $ pip install uvloop -Then, in application code, set the :py:func:`asyncio.event_loop_policy`:: +Then, in application code, set the :py:func:`asyncio.set_event_loop_policy`:: >>> import asyncio >>> import uvloop diff --git a/goblin/session.py b/goblin/session.py index 6cb1832cc0a74664e1ba190fdc975dc84fd7a9d9..ca8093a39f8d642ba0b4844db0b0b4f0bdaa389e 100644 --- a/goblin/session.py +++ b/goblin/session.py @@ -47,7 +47,7 @@ class Session: instead use :py:meth:`Goblin.session<goblin.app.Goblin.session>`. :param goblin.app.Goblin app: - :param goblin.driver.Connection conn: + :param aiogremlin.driver.connection.Connection conn: """ def __init__(self, app, remote_connection, get_hashable_id):