Skip to content

Commit d04f3db

Browse files
committed
Revamp the library for 4.0.0.
1 parent 99a7269 commit d04f3db

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+16161
-14560
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
*.coverage
99
.cache/
1010
tests/__pycache__/
11+
*.DS_Store
12+
venv

.travis.yml

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
language: python
21
sudo: false
2+
language: python
33
python:
44
- 2.7
55
- 3.4
66
- 3.5
77
- 3.6
8+
services:
9+
- docker
810
before_install:
9-
- sh scripts/setup_arangodb.sh
11+
- docker run --name arango -d -p 8529:8529 -e ARANGO_ROOT_PASSWORD=passwd arangodb/arangodb:3.3.8
12+
- docker cp tests/static/service.zip arango:/tmp/service.zip
1013
install:
11-
- pip install coverage
12-
- pip install pytest
13-
- pip install pytest-cov
14-
- pip install python-coveralls
15-
- python setup.py install
14+
- pip install flake8 mock pytest pytest-cov python-coveralls sphinx
15+
- pip install .
1616
script:
17-
- py.test --cov-report= --cov=arango tests/
17+
- python -m flake8
18+
- python -m sphinx -b doctest docs build
19+
- py.test --complete -s -v --cov=arango
1820
after_success:
1921
- coveralls
20-
- pkill -9 -f arango

MANIFEST.in

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include README.rst LICENSE

README.rst

+80-58
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,28 @@
3232

3333
|
3434
35-
Welcome to the GitHub page for **python-arango**, a Python driver for
36-
`ArangoDB <https://www.arangodb.com/>`__.
35+
Welcome to the GitHub page for **python-arango**, a Python driver for ArangoDB_.
36+
37+
Announcements
38+
=============
39+
40+
- Python-arango version `4.0.0`_ is now out!
41+
- Please see the releases_ page for details on latest updates.
3742

3843
Features
3944
========
4045

41-
- Clean, Pythonic interface
46+
- Clean Pythonic interface
4247
- Lightweight
4348
- High ArangoDB REST API coverage
4449

4550
Compatibility
4651
=============
4752

48-
- Python versions 2.7.x, 3.4.x, 3.5.x and 3.6.x are supported
49-
- Latest version of python-arango (3.x) supports ArangoDB 3.x only
50-
- Older versions of python-arango support ArangoDB 1.x ~ 2.x only
53+
- Python versions 2.7, 3.4, 3.5 and 3.6 are supported
54+
- Python-arango 4.x supports ArangoDB 3.3+ (recommended)
55+
- Python-arango 3.x supports ArangoDB 3.0 ~ 3.2 only
56+
- Python-arango 2.x supports ArangoDB 1.x ~ 2.x only
5157

5258
Installation
5359
============
@@ -65,10 +71,7 @@ To install the latest version directly from GitHub_:
6571
6672
~$ pip install -e git+git@github.com:joowani/python-arango.git@master#egg=python-arango
6773
68-
You may need to use ``sudo`` depending on your environment setup.
69-
70-
.. _PyPi: https://pypi.python.org/pypi/python-arango
71-
.. _GitHub: https://github.com/joowani/python-arango
74+
You may need to use ``sudo`` depending on your environment.
7275

7376
Getting Started
7477
===============
@@ -79,79 +82,98 @@ Here is a simple usage example:
7982
8083
from arango import ArangoClient
8184
82-
# Initialize the client for ArangoDB
83-
client = ArangoClient(
84-
protocol='http',
85-
host='localhost',
86-
port=8529,
87-
username='root',
88-
password='',
89-
enable_logging=True
90-
)
85+
# Initialize the client for ArangoDB.
86+
client = ArangoClient(protocol='http', host='localhost', port=8529)
87+
88+
# Connect to "_system" database as root user.
89+
sys_db = client.db('_system', username='root', password='passwd')
9190
92-
# Create a new database named "my_database"
93-
db = client.create_database('my_database')
91+
# Create a new database named "test".
92+
sys_db.create_database('test')
9493
95-
# Create a new collection named "students"
94+
# Connect to "test" database as root user.
95+
db = client.db('test', username='root', password='passwd')
96+
97+
# Create a new collection named "students".
9698
students = db.create_collection('students')
9799
98-
# Add a hash index to the collection
100+
# Add a hash index to the collection.
99101
students.add_hash_index(fields=['name'], unique=True)
100102
101-
# Insert new documents into the collection
102-
students.insert({'name': 'jane', 'age': 19})
103+
# Insert new documents into the collection.
104+
students.insert({'name': 'jane', 'age': 39})
103105
students.insert({'name': 'josh', 'age': 18})
104-
students.insert({'name': 'jake', 'age': 21})
106+
students.insert({'name': 'judy', 'age': 21})
105107
106-
# Execute an AQL query
107-
result = db.aql.execute('FOR s IN students RETURN s')
108-
print([student['name'] for student in result])
108+
# Execute an AQL query and iterate through the result cursor.
109+
cursor = db.aql.execute('FOR doc IN students RETURN doc')
110+
student_names = [document['name'] for document in cursor]
109111
110112
111-
Here is another example involving graphs:
113+
Here is another example with graphs:
112114

113115
.. code-block:: python
114116
115117
from arango import ArangoClient
116118
117-
client = ArangoClient()
119+
# Initialize the client for ArangoDB.
120+
client = ArangoClient(protocol='http', host='localhost', port=8529)
121+
122+
# Connect to "test" database as root user.
123+
db = client.db('test', username='root', password='passwd')
118124
119-
# Create a new graph
120-
graph = client.db('my_database').create_graph('my_graph')
125+
# Create a new graph named "school".
126+
graph = db.create_graph('school')
127+
128+
# Create vertex collections for the graph.
121129
students = graph.create_vertex_collection('students')
122-
courses = graph.create_vertex_collection('courses')
123-
takes = graph.create_edge_definition(
124-
name='takes',
125-
from_collections=['students'],
126-
to_collections=['courses']
130+
lectures = graph.create_vertex_collection('lectures')
131+
132+
# Create an edge definition (relation) for the graph.
133+
register = graph.create_edge_definition(
134+
edge_collection='register',
135+
from_vertex_collections=['students'],
136+
to_vertex_collections=['lectures']
127137
)
128138
129-
# Insert vertices
139+
# Insert vertex documents into "students" (from) vertex collection.
130140
students.insert({'_key': '01', 'full_name': 'Anna Smith'})
131141
students.insert({'_key': '02', 'full_name': 'Jake Clark'})
132142
students.insert({'_key': '03', 'full_name': 'Lisa Jones'})
133143
134-
courses.insert({'_key': 'MAT101', 'title': 'Calculus'})
135-
courses.insert({'_key': 'STA101', 'title': 'Statistics'})
136-
courses.insert({'_key': 'CSC101', 'title': 'Algorithms'})
137-
138-
# Insert edges
139-
takes.insert({'_from': 'students/01', '_to': 'courses/MAT101'})
140-
takes.insert({'_from': 'students/01', '_to': 'courses/STA101'})
141-
takes.insert({'_from': 'students/01', '_to': 'courses/CSC101'})
142-
takes.insert({'_from': 'students/02', '_to': 'courses/MAT101'})
143-
takes.insert({'_from': 'students/02', '_to': 'courses/STA101'})
144-
takes.insert({'_from': 'students/03', '_to': 'courses/CSC101'})
145-
146-
# Traverse the graph in outbound direction, breadth-first
147-
traversal_results = graph.traverse(
144+
# Insert vertex documents into "lectures" (to) vertex collection.
145+
lectures.insert({'_key': 'MAT101', 'title': 'Calculus'})
146+
lectures.insert({'_key': 'STA101', 'title': 'Statistics'})
147+
lectures.insert({'_key': 'CSC101', 'title': 'Algorithms'})
148+
149+
# Insert edge documents into "register" edge collection.
150+
register.insert({'_from': 'students/01', '_to': 'lectures/MAT101'})
151+
register.insert({'_from': 'students/01', '_to': 'lectures/STA101'})
152+
register.insert({'_from': 'students/01', '_to': 'lectures/CSC101'})
153+
register.insert({'_from': 'students/02', '_to': 'lectures/MAT101'})
154+
register.insert({'_from': 'students/02', '_to': 'lectures/STA101'})
155+
register.insert({'_from': 'students/03', '_to': 'lectures/CSC101'})
156+
157+
# Traverse the graph in outbound direction, breadth-first.
158+
result = graph.traverse(
148159
start_vertex='students/01',
149-
strategy='bfs',
150-
direction='outbound'
160+
direction='outbound',
161+
strategy='breadthfirst'
151162
)
152-
print(traversal_results['vertices'])
153163
154-
Please read the full `API documentation`_ for more details!
164+
Check out the documentation_ for more details.
155165

156-
.. _API documentation:
166+
Contributing
167+
============
168+
169+
Please take a look at this page_ before submitting a pull request. Thanks!
170+
171+
.. _ArangoDB: https://www.arangodb.com
172+
.. _4.0.0: https://github.com/joowani/python-arango/releases/tag/4.0.0
173+
.. _releases: https://github.com/joowani/python-arango/releases
174+
.. _PyPi: https://pypi.python.org/pypi/python-arango
175+
.. _GitHub: https://github.com/joowani/python-arango
176+
.. _documentation:
157177
http://python-driver-for-arangodb.readthedocs.io/en/master/index.html
178+
.. _page:
179+
http://python-driver-for-arangodb.readthedocs.io/en/master/contributing.html

arango/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
from arango.client import ArangoClient
2-
from arango.client import ArangoError
1+
from arango.client import ArangoClient # noqa: F401
2+
from arango.exceptions import * # noqa: F401 F403
3+
from arango.http import * # noqa: F401 F403

arango/api.py

+50-32
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,58 @@
11
from __future__ import absolute_import, unicode_literals
22

3-
from functools import wraps
3+
__all__ = ['APIWrapper']
44

55

66
class APIWrapper(object):
7-
"""ArangoDB API wrapper base class.
7+
"""Base class for API wrappers.
88
9-
This class is meant to be used internally only.
9+
:param connection: HTTP connection.
10+
:type connection: arango.connection.Connection
11+
:param executor: API executor.
12+
:type executor: arango.executor.Executor
1013
"""
1114

12-
def __getattribute__(self, attr):
13-
method = object.__getattribute__(self, attr)
14-
conn = object.__getattribute__(self, '_conn')
15-
16-
if not getattr(method, 'api_method', False):
17-
return method
18-
19-
@wraps(method)
20-
def wrapped_method(*args, **kwargs):
21-
request, handler = method(*args, **kwargs)
22-
return conn.handle_request(request, handler)
23-
return wrapped_method
24-
25-
26-
def api_method(method):
27-
"""Decorator used to mark ArangoDB API methods.
28-
29-
Methods decorated by this should return two things:
30-
31-
- An instance of :class:`arango.request.Request`
32-
- A handler that takes an instance of :class:`arango.response.Response`
33-
34-
:param method: the method to wrap
35-
:type method: callable
36-
:returns: the wrapped method
37-
:rtype: callable
38-
"""
39-
setattr(method, 'api_method', True)
40-
return method
15+
def __init__(self, connection, executor):
16+
self._conn = connection
17+
self._executor = executor
18+
self._is_transaction = self.context == 'transaction'
19+
20+
@property
21+
def db_name(self):
22+
"""Return the name of the current database.
23+
24+
:return: Database name.
25+
:rtype: str | unicode
26+
"""
27+
return self._conn.db_name
28+
29+
@property
30+
def username(self):
31+
"""Return the username.
32+
33+
:returns: Username.
34+
:rtype: str | unicode
35+
"""
36+
return self._conn.username
37+
38+
@property
39+
def context(self):
40+
"""Return the API execution context.
41+
42+
:return: API execution context. Possible values are "default", "async",
43+
"batch" and "transaction".
44+
:rtype: str | unicode
45+
"""
46+
return self._executor.context
47+
48+
def _execute(self, request, response_handler):
49+
"""Execute an API per execution context.
50+
51+
:param request: HTTP request.
52+
:type request: arango.request.Request
53+
:param response_handler: HTTP response handler.
54+
:type response_handler: callable
55+
:return: API execution result.
56+
:rtype: str | unicode | bool | int | list | dict
57+
"""
58+
return self._executor.execute(request, response_handler)

0 commit comments

Comments
 (0)