This tutorial teaches you how to interact with Fisheye/Crucible's REST interface from a Python program.
We'll write a Python script which lists the users who are uncompleted reviewers of at least one open review.
This tutorial assumes that you have Python 2.6.3 installed. Note that the default version on Mac OS X 10.6 is 2.5.
Create a new directory to write your client in and cd
into it.
First you'll need to install the python-rest-client package. Download the 0.2 distribution and unpack it in your current directory.
Set your PYTHONPATH
environment variable to include the python-rest-client:
1 2export PYTHONPATH=./python-rest-client
To get all open reviews we use the URL /reviews-v1/filter/{filter}, setting {filter
} to allOpenReviews
, and to get the incomplete reviewers for each of these reviews we use the URL /reviews-v1/{id}/reviewers/uncompleted
When JSON produces lists of objects, the structures produced depend on the number of items in the list.
If the /reviews-v1/filter
URL returns a single review, the JSON will look like this:
1 2{"reviews": {"reviewData": {...attributes of review...}} }
but if several reviews are returned the JSON will be:
1 2{"reviews": {"reviewData": [{...first review...},{...second review},...]} }
and if there are no reviews it will simply be:
1 2{"reviews": ""}
1 2reviews = ...one of the dictionaries above... reviewList = toList(reviews["reviews"], "reviewData")
1 2# import the standard JSON parser import json # import the REST library from restful_lib import Connection base_url = "http://localhost:6060/foo/rest-service/reviews-v1" conn = Connection(base_url, username="admin", password="admin") # the rest library can't distinguish between a property and a list of properties with one element. # this function converts a json object into a list with many, one, or no elements # o is the dictionary containing the list # key is the key containing the list (if any) def toList(o, key): if isinstance(o,dict): elements = o[key] if not isinstance(elements,list): return [elements] else: return elements else: return [] # a function to get the uncompleted reviwers for a single review def uncompletedReviewers(review): id = review[u'permaId'][u'id'] resp = conn.request_get("/" + id + "/reviewers/uncompleted", args={}, headers={'content-type':'application/json', 'accept':'application/json'}) status = resp[u'headers']['status'] if status == '200' or status == '304': reviewers = toList(json.loads(resp[u'body'])[u'reviewers'],u'reviewer') return map(lambda r: r[u'displayName'], reviewers) else: return [] # get a dictionary containing the response to the GET request # we specify JSON as the format as that is easy to parse in Python resp = conn.request_get("/filter/allOpenReviews", args={}, headers={'content-type':'application/json', 'accept':'application/json'}) status = resp[u'headers']['status'] # check that we either got a successful response (200) or a previously retrieved, but still valid response (304) if status == '200' or status == '304': reviews = toList(json.loads(resp[u'body'])[u'reviews'],u'reviewData') reviewerLists = map(uncompletedReviewers,reviews) reviewers = reduce(lambda a, b: set(a).union(set(b)), reviewerLists, set()) print 'Incomplete Reviewers: ' for r in reviewers: print ' ',r else: print 'Error status code: ', status
Rate this page: