README.md 4.33 KB
Newer Older
davebshow's avatar
davebshow committed
1
2
3
# aiogremlin 0.0.9 [(gizmo grew up)](https://pypi.python.org/pypi/gizmo/0.1.12)

`aiogremlin` is a **Python 3** driver for the the [Tinkerpop 3 Gremlin Server](http://tinkerpop.incubator.apache.org/docs/3.0.0.M9-incubating/#gremlin-server). This module is built on [Asyncio](https://docs.python.org/3/library/asyncio.html) and [aiohttp](http://aiohttp.readthedocs.org/en/v0.15.3/index.html) `aiogremlin` is currently in **alpha** mode, but all major functionality has test coverage.
davebshow's avatar
davebshow committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


## Getting started

Since Python 3.4 is not the default version on many systems, it's nice to create a virtualenv that uses Python 3.4 by default. Then use pip to install `aiogremlin`. Using virtualenvwrapper on Ubuntu 14.04:

```bash
$ mkvirtualenv -p /usr/bin/python3.4 aiogremlin
$ pip install aiogremlin
```

Fire up the Gremlin Server:

```bash
$ ./bin/gremlin-server.sh
```

davebshow's avatar
davebshow committed
21
The `GremlinClient` communicates asynchronously with the Gremlin Server using websockets. The majority of `GremlinClient` methods are an `asyncio.coroutine`, so you will also need to use `asyncio`:
davebshow's avatar
davebshow committed
22

davebshow's avatar
davebshow committed
23
24
25
26
27
```python
>>> import asyncio
>>> from aiogremlin import GremlinClient
```

davebshow's avatar
davebshow committed
28
The Gremlin Server responds with messages in chunks, `GremlinClient.submit` submits a script to the server, and returns a `GremlinResponse` object. This object provides the methods: `get` and the property `stream`. `get` collects all of the response messages and returns them as a Python list. `stream` returns an object of the type `GremlinResponseStream` that implements a method `read`. This allows you to read the response without loading all of the messages into memory.
davebshow's avatar
davebshow committed
29

30
31
Note that the GremlinClient constructor and the create_client function take [keyword only arguments](https://www.python.org/dev/peps/pep-3102/) only!

davebshow's avatar
davebshow committed
32
33
34

```python
>>> loop = asyncio.get_event_loop()
35
>>> gc = GremlinClient(url='ws://localhost:8182/', loop=loop)  # Default url
36
# Or even better, use the constructor function. This will init pool connections.
davebshow's avatar
davebshow committed
37
# ***Must be done inside a coroutine***
38
>>> gc = yield from create_client(loop=loop)
davebshow's avatar
davebshow committed
39
40
# Or outside of a coroutine using the loop to help
>>> gc = loop.run_until_complete(create_client(loop=loop))
davebshow's avatar
davebshow committed
41
42
43
44
45
46
47

# Use get.
>>> @asyncio.coroutine
... def get(gc):
...     resp = yield from gc.submit("x + x", bindings={"x": 4})
...     result = yield from resp.get()
...     return result
48

davebshow's avatar
davebshow committed
49
>>> result = loop.run_until_complete(get(gc))
davebshow's avatar
davebshow committed
50
>>> result
davebshow's avatar
davebshow committed
51
[Message(status_code=200, data=[8], message={}, metadata='')]
52

davebshow's avatar
davebshow committed
53
54
55
>>> resp = result[0]
>>> resp.status_code
200
56

davebshow's avatar
davebshow committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
>>> resp  # Named tuple.
Message(status_code=200, data=[8], message={}, metadata='')

# Use stream.
>>> @asyncio.coroutine
... def stream(gc):
...     resp = yield from gc.submit("x + x", bindings={"x": 1})
...     while True:
...         result = yield from resp.stream.read()
...         if result is None:
...             break
...         print(result)
>>> loop.run_until_complete(stream(gc))
Message(status_code=200, data=[2], message={}, metadata='')
71
72
73

>>> loop.run_until_complete(gc.close())  # Explicitly close client!!!
>>> loop.close()
davebshow's avatar
davebshow committed
74
75
76
77
78
79
```

For convenience, `aiogremlin` also provides a method `execute`, which is equivalent to calling  `yield from submit()` and then `yield from get()` in the same coroutine.

```python
>>> loop = asyncio.get_event_loop()
80
>>> gc = GremlinClient(loop=loop)
davebshow's avatar
davebshow committed
81
82
83
84
>>> execute = gc.execute("x + x", bindings={"x": 4})
>>> result = loop.run_until_complete(execute)
>>> result
[Message(status_code=200, data=[8], message={}, metadata='')]
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
>>> loop.run_until_complete(gc.close())  # Explicitly close client!!!
>>> loop.close()
```

To avoid the explicit client close, `aiogremlin` provides a class called `ConnectionContextManager`. To create an instance of `ConnectionContextManager`, get a connection from a `WebSocketPool` instance as follows:

```python
>>> loop = asyncio.get_event_loop()
# Note that url is a required positional param here!
# Pool does not open any connections until requested.
>>> pool = aiogremlin.WebSocketPool('ws://localhost:8182/')
>>> @asyncio.coroutine
... def go(pool, loop):
...     with (yield from pool) as conn:
...         gc = aiogremlin.GremlinClient(connection=conn, loop=loop)
...         resp = yield from gc.execute("1 + 1")
...     return resp
>>> result = loop.run_until_complete(go(pool, loop))
>>> result
[Message(status_code=200, data=[2], message={}, metadata='')]
>>> loop.close()  # Close loop, but client connections will be closed.
davebshow's avatar
davebshow committed
106
```