summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.rst14
-rw-r--r--README.rst63
-rw-r--r--pygerrit/events.py21
-rw-r--r--pygerrit/models.py2
-rw-r--r--pygerrit/rest/__init__.py8
-rwxr-xr-xrest_example.py17
6 files changed, 105 insertions, 20 deletions
diff --git a/AUTHORS.rst b/AUTHORS.rst
new file mode 100644
index 0000000..58941af
--- /dev/null
+++ b/AUTHORS.rst
@@ -0,0 +1,14 @@
+pygerrit is written and maintained by David Pursehouse and
+various contributors:
+
+Development Lead
+````````````````
+
+- David Pursehouse <david.pursehouse@sonymobile.com>
+
+
+Patches and Suggestions
+```````````````````````
+
+- Ernst Sjöstrand <ernst.sjostrand@sonymobile.com>
+- Jens Andersen <jens.andersen@gmail.com>
diff --git a/README.rst b/README.rst
index bb0f5cd..19cd2d5 100644
--- a/README.rst
+++ b/README.rst
@@ -2,7 +2,7 @@ Pygerrit - Client library for interacting with Gerrit Code Review
=================================================================
Pygerrit is a Python library to interact with the
-`Gerrit Code Review`_ system over ssh.
+`Gerrit Code Review`_ system over ssh or via the REST API.
Installation
------------
@@ -20,9 +20,9 @@ Prerequisites
Pygerrit runs on Ubuntu 10.4 and Mac OSX 10.8.4 with Python 2.6.x and 2.7.x.
Support for other platforms and Python versions is not guaranteed.
-To connect to the review server, pygerrit requires the ssh connection
-parameters (hostname, port, username) to be present in the ``.ssh/config``
-file for the current user:
+For easier connection to the review server over ssh, the ssh connection
+parameters (hostname, port, username) can be given in the user's ``.ssh/config``
+file:
.. code-block:: bash
@@ -31,6 +31,24 @@ file for the current user:
Port 29418
User username
+SSH Interface
+-------------
+
+The SSH interface can be used to run commands on the Gerrit server.
+
+.. code-block:: pycon
+
+ >>> from pygerrit.ssh import GerritSSHClient
+ >>> client = GerritSSHClient("review")
+ >>> result = client.run_gerrit_command("version")
+ >>> result
+ <GerritSSHCommandResult [version]>
+ >>> result.stdout
+ <paramiko.ChannelFile from <paramiko.Channel 2 (closed) -> <paramiko.Transport at 0xd2387d90L (cipher aes128-cbc, 128 bits) (active; 0 open channel(s))>>>
+ >>> result.stdout.read()
+ 'gerrit version 2.6.1\n'
+ >>>
+
Event Stream
------------
@@ -44,9 +62,41 @@ client to fetch them from a queue. It also allows users to easily add handling
of custom event types, for example if they are running a customised Gerrit
installation with non-standard events.
-Refer to the `example`_ script for a brief example of how the interface
-works.
+.. code-block:: pycon
+
+ >>> from pygerrit.client import GerritClient
+ >>> client = GerritClient("review")
+ >>> client.gerrit_version()
+ '2.6.1'
+ >>> client.start_event_stream()
+ >>> client.get_event()
+ <CommentAddedEvent>: <Change 12345, platform/packages/apps/Example, master> <Patchset 1, 5c4b2f76297f04fbab77eb8c3462e087bc4b6f90> <Account Bob Example (bob.example@example.com)>
+ >>> client.get_event()
+ <CommentAddedEvent>: <Change 67890, platform/frameworks/example, master> <Patchset 2, c7d4f9956c80b1df66a66d66dea3960e71de4910> <Account John Example (john.example@example.com)>
+ >>> client.stop_event_stream()
+ >>>
+
+
+Refer to the `example`_ script for a more detailed example of how the SSH
+event stream interface works.
+
+REST API
+--------
+
+Gerrit offers a feature-rich REST API. This library provides a simple
+interface for clients to interact with Gerrit via the REST API.
+
+.. code-block:: pycon
+
+ >>> from requests.auth import HTTPDigestAuth
+ >>> from pygerrit.rest import GerritRestAPI
+ >>> auth = HTTPDigestAuth('username', 'password')
+ >>> rest = GerritRestAPI(url='http://review.example.net', auth=auth)
+ >>> changes = rest.get("/changes/?q=owner:self%20status:open")
+
+Refer to the `rest_example`_ script for a more detailed example of how the
+REST API interface works.
Copyright and License
---------------------
@@ -60,4 +110,5 @@ license details.
.. _`Gerrit Code Review`: https://code.google.com/p/gerrit/
.. _example: https://github.com/sonyxperiadev/pygerrit/blob/master/example.py
+.. _rest_example: https://github.com/sonyxperiadev/pygerrit/blob/master/rest_example.py
.. _LICENSE: https://github.com/sonyxperiadev/pygerrit/blob/master/LICENSE
diff --git a/pygerrit/events.py b/pygerrit/events.py
index ebbb327..c6563cd 100644
--- a/pygerrit/events.py
+++ b/pygerrit/events.py
@@ -220,7 +220,8 @@ class MergeFailedEvent(GerritEvent):
self.change = Change(json_data["change"])
self.patchset = Patchset(json_data["patchSet"])
self.submitter = Account(json_data["submitter"])
- self.reason = json_data["reason"]
+ if 'reason' in json_data:
+ self.reason = json_data["reason"]
except KeyError as e:
raise GerritError("MergeFailedEvent: %s" % e)
@@ -239,16 +240,15 @@ class ChangeAbandonedEvent(GerritEvent):
super(ChangeAbandonedEvent, self).__init__(json_data)
try:
self.change = Change(json_data["change"])
- self.patchset = Patchset.from_json(json_data)
self.abandoner = Account(json_data["abandoner"])
- self.reason = json_data["reason"]
+ if 'reason' in json_data:
+ self.reason = json_data["reason"]
except KeyError as e:
raise GerritError("ChangeAbandonedEvent: %s" % e)
def __repr__(self):
- return u"<ChangeAbandonedEvent>: %s %s %s" % (self.change,
- self.patchset,
- self.abandoner)
+ return u"<ChangeAbandonedEvent>: %s %s" % (self.change,
+ self.abandoner)
@GerritEventFactory.register("change-restored")
@@ -260,16 +260,15 @@ class ChangeRestoredEvent(GerritEvent):
super(ChangeRestoredEvent, self).__init__(json_data)
try:
self.change = Change(json_data["change"])
- self.patchset = Patchset.from_json(json_data)
self.restorer = Account(json_data["restorer"])
- self.reason = json_data["reason"]
+ if 'reason' in json_data:
+ self.reason = json_data["reason"]
except KeyError as e:
raise GerritError("ChangeRestoredEvent: %s" % e)
def __repr__(self):
- return u"<ChangeRestoredEvent>: %s %s %s" % (self.change,
- self.patchset,
- self.restorer)
+ return u"<ChangeRestoredEvent>: %s %s" % (self.change,
+ self.restorer)
@GerritEventFactory.register("ref-updated")
diff --git a/pygerrit/models.py b/pygerrit/models.py
index ac9575a..22716ec 100644
--- a/pygerrit/models.py
+++ b/pygerrit/models.py
@@ -64,6 +64,8 @@ class Change(object):
self.subject = from_json(json_data, "subject")
self.url = from_json(json_data, "url")
self.owner = Account.from_json(json_data, "owner")
+ if 'sortKey' in json_data:
+ self.sortkey = from_json(json_data, "sortKey")
def __repr__(self):
return u"<Change %s, %s, %s>" % (self.number, self.project, self.branch)
diff --git a/pygerrit/rest/__init__.py b/pygerrit/rest/__init__.py
index 99364e1..b5cfd3a 100644
--- a/pygerrit/rest/__init__.py
+++ b/pygerrit/rest/__init__.py
@@ -74,7 +74,7 @@ class GerritRestAPI(object):
""" Interface to the Gerrit REST API. """
- def __init__(self, url, auth=None):
+ def __init__(self, url, auth=None, verify=True):
""" Constructor.
`url` is assumed to be the full URL to the server, including the
@@ -84,8 +84,12 @@ class GerritRestAPI(object):
class from the `requests` module. The `url` will be adjusted if
necessary to make sure it includes Gerrit's authentication suffix.
+ If `verify` is False, the underlying requests library will be
+ configured to not attempt to verify SSL certificates.
+
"""
- self.kwargs = {'auth': auth}
+ self.kwargs = {'auth': auth,
+ 'verify': verify}
self.url = url.rstrip('/')
self.session = requests.session()
diff --git a/rest_example.py b/rest_example.py
index 132765f..1c278c8 100755
--- a/rest_example.py
+++ b/rest_example.py
@@ -30,6 +30,11 @@ import optparse
import sys
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
+try:
+ from requests_kerberos import HTTPKerberosAuth, OPTIONAL
+ _kerberos_support = True
+except ImportError:
+ _kerberos_support = False
from pygerrit.rest import GerritRestAPI
from pygerrit.rest.auth import HTTPDigestAuthFromNetrc, HTTPBasicAuthFromNetrc
@@ -44,6 +49,10 @@ def _main():
parser.add_option('-b', '--basic-auth', dest='basic_auth',
action='store_true',
help='use basic auth instead of digest')
+ if HTTPKerberosAuth:
+ parser.add_option('-k', '--kerberos-auth', dest='kerberos_auth',
+ action='store_true',
+ help='use kerberos auth')
parser.add_option('-u', '--username', dest='username',
help='username')
parser.add_option('-p', '--password', dest='password',
@@ -64,7 +73,13 @@ def _main():
if not options.gerrit_url:
parser.error("Must specify Gerrit URL with --gerrit-url")
- if options.username and options.password:
+ if _kerberos_support and options.kerberos_auth:
+ if options.username or options.password \
+ or options.basic_auth or options.netrc:
+ parser.error("--kerberos-auth may not be used together with "
+ "--username, --password, --basic-auth or --netrc")
+ auth = HTTPKerberosAuth(mutual_authentication=OPTIONAL)
+ elif options.username and options.password:
if options.netrc:
logging.warning("--netrc option ignored")
if options.basic_auth: