Issue and metric API examplesThese examples are written in Python, but should be simple enough to understand even without an in-depth knowledge of that language. All of the examples below use demosthenes, a C/C++ sample project installed with the Klocwork Server package at <server_install>/samples/demosthenes. See the README file in that directory for instructions on how to set up the sample project. You can try out the example scripts on the sample project, or on your own project. If you use them on your own project, you need to change the value for project. You may also need to change the value for host from localhost to your own Klocwork Server host. For additional information on request parameters, you can visit http(s)://<klocwork_server_host>:<klocwork_server_port>/review/api.
About error handling in these examplesWhen curl calls are made using the Web API, any errors that are encountered are printed to the console automatically. Note however, that the Python examples in this topic provide simplified error handling. For example: builds = report(url, project, user, action) print "Existing builds:" for build in builds: print build To better handle errors in your own python scripts, use a try block: try: builds = report(url, project, user, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Existing builds:" for build in builds: print build
Example: Search for all critical issuesThis example script searches for all critical issues (with severities 1, 2 and 3) in the latest build of the Demosthenes sample project. import urllib, urllib2, json, sys, os.path, getpass, time def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() class Issue(object) : def __init__(self, attrs) : self.id = attrs["id"] self.message = attrs["message"] self.file = attrs["file"] self.method = attrs["method"] self.code = attrs["code"] self.severity = attrs["severity"] self.severityCode = attrs["severityCode"] self.state = attrs["state"] self.status = attrs["status"] self.taxonomyName = attrs["taxonomyName"] self.url = attrs["url"] self.created=time.ctime(attrs["dateOriginated"]/1000) def __str__(self) : return "[%d] %s\n\t%s | %s\n\tCode %s | Severity: %s(%d) | State: %s | Status: %s | Taxonomy: %s | Created: %s\n\t%s" % ( self.id, self.message, self.file, self.method, self.code, self.severity, self.severityCode, self.state, self.status, self.taxonomyName, self.created, self.url ) def from_json(json_object) : if 'id' in json_object : return Issue(json_object) return json_object host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" url = "http://%s:%d/review/api" % (host, port) values = {"project": project, "user": user, "action": "search"} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken values["query"] = "severity:1-3" data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) for record in response : print json.loads(record, object_hook=from_json)
Example: Report detected issuesThis example shows the distribution of detected issues by component, grouped by state. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() class Key(object) : def __init__(self, attrs) : self.id = attrs["id"] self.name = attrs["name"] def __str__(self) : return "%s (%d)" % (self.name, self.id) class Report(object) : def __init__(self, attrs) : self.rows = attrs["rows"] self.columns = attrs["columns"] self.data = attrs["data"] def __str__(self) : result = "" maxRowName = 0 for r in self.rows : maxRowName = max(len(str(r)), maxRowName) maxRowName += 1 header = ' ' * maxRowName colPosition = [] for c in self.columns : colPosition.append(len(header) + len(str(r))) header += str(c) + ' ' result += header + '\n' for x in range(len(self.rows)) : rHead = ('%-' + str(maxRowName) + 's') % str(self.rows[x]) for y in range(len(self.columns)) : rHead += ('%' + str(len(str(self.columns[y]))) + 's') % str(self.data[x][y]) + ' ' result += rHead + '\n' return result def from_json(json_object) : if 'rows' in json_object : return Report(json_object) if 'id' in json_object : return Key(json_object) return json_object def report(url, project, user, x = None, y = None, view = None, xDrilldown = -1, yDrilldown = -1) : values = {"project": project, "user": user, "action": "report"} loginToken = getToken(host, port, user) if x is not None : values["x"] = x if y is not None : values["y"] = y loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken if view is not None : values["view"] = view if xDrilldown != -1 : values["xDrilldown"] = xDrilldown if yDrilldown != -1 : values["yDrilldown"] = yDrilldown data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) for record in response : return json.loads(record, object_hook=from_json) host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" url = "http://%s:%d/review/api" % (host, port) try reports = report(url, project, user, "Component", "State") except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print reports
Example: Retrieve issue detailsThis example shows how to get details about a specified issue ID. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() class Details(object): def __init__(self, attrs): self.id = attrs["id"] self.code = attrs["code"] self.name = attrs["name"] self.location = attrs["location"] self.build = attrs["build"] self.severity = attrs["severity"] self.owner = attrs["owner"] self.state = attrs["state"] self.status = attrs["status"] if "history" in attrs: self.history = attrs["history"] else: self.history = None if "xSync" in attrs: self.xsync = attrs["xsync"] else: self.xsync = None def __str__(self): result = "Id:%s, Code:%s, Name:%s, Location:%s, Build:%s, Severity:%s, Owner:%s, State:%s, Status:%s, History:%s" % (self.id, self.code, self.name, self.location, self.build, self.severity, self.owner, self.state, self.status, self.history) if self.xsync != None: result = result + ", XSyncInfo:%s" % self.xsync return result def from_json(json_object): #print json_object return Details(json_object) def report(url, user, action, project, id, xsync=None): values = {"user": user, "action": action, "project": project, "id": id} if xsync is not None: values['include_xsync'] = xsync loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response: #print "R:" ,record result.append(from_json(json.loads(record))) return result host = "localhost" port = 8080 user = getpass.getuser() action = "issue_details" url = "http://%s:%d/review/api" % (host, port) project = "myproject" id = "4" xsync="false" try: issue_details = report(url, user, action, project, id, xsync) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Issue Details:" for details in issue_details: print details
Example: Update issue statusThis example shows how to change issue status, comment(s), owner(s), and bug tracker ID for any specified issues.
Note: If you specify bug tracker ID, all other issue status values are ignored.
import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() class Status(object): def __init__(self, attrs): self.status_message = attrs["status_message"] def __str__(self): result = "Status message:%s" % self.status_message return result def from_json(json_object): return Status(json_object) def update_status(url, user, action, project, ids, status=None, comment=None, owner=None, bug_tracker_id=None): values = {'action': 'update_status', 'project': project, 'user': user, 'ids': ids} if status is not None: values['status'] = status if comment is not None: values['comment'] = comment if owner is not None: values['owner'] = owner if bug_tracker_id is not None: values['bug_tracker_id'] = bug_tracker_id loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response: result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() action = "update_status" url = "http://%s:%d/review/api" % (host, port) project = "demosthenes" id = "1" status = "Fix" comment = "Making a status change" owner = "jsmith" try: status_messages = update_status(url, user, action, project, id, status, comment, owner) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Update Status:" for message in status_messages: print message
Example: Print the project listThis example shows how to print the list of projects. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() class View(object): def __init__(self, attrs): self.name = attrs["name"] def __str__(self): result = "%s" % self.name return result def from_json(json_object): return View(json_object) def report(url, user, action): values = {"user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response: result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() action = "projects" url = "http://%s:%d/review/api" % (host, port) try: projects = report(url, user, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Existing projects:" for project in projects: print project
Example: Update projectsThis example shows how to update the name and description for a specified project. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() def updateProject(url, name, user, action, description, new_name) : values = {"name": name, "user": user, "action": action, "description": description, "new_name": new_name} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() name = "demosthenes" action = "update_project" description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." new_name = "demosthenes2" url = "http://%s:%d/review/api" % (host, port) try: updateProject(url, name, user, action, description, new_name) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Project updated!" You can also use this action to turn on auto-deletion of builds and set how many you would like to keep with the threshold parameter. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() def updateProject(url, name, user, action, auto_delete_builds, auto_delete_threshold) : values = {"name": name, "user": user, "action": action, "auto_delete_builds": auto_delete_builds, "auto_delete_threshold": auto_delete_threshold} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() name = "demosthenes" action = "update_project" auto_delete_builds = "true" auto_delete_threshold = "30" url = "http://%s:%d/review/api" % (host, port) try: updateProject(url, name, user, action, auto_delete_builds, auto_delete_threshold) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Project updated!"
Example: Generate a Project Configuration reportThis example shows how to generate a project configuration report for a specified project. The report displays project information such as creation date, Klocwork version and basic code metrics.
import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() class Config(object): def __init__(self, attrs): self.build = attrs["build"] self.creationDate = attrs["creationDate"] self.version = attrs["version"] self.numberOfFiles = attrs["numberOfFiles"] self.cFilesAnalyzed = attrs["cFilesAnalyzed"] self.systemFilesAnalyzed = attrs["systemFilesAnalyzed"] self.linesOfCode = attrs["linesOfCode"] self.linesOfComments = attrs["linesOfComments"] self.numberOfEntities = attrs["numberOfEntities"] self.numberOfFunctions = attrs["numberOfFunctions"] self.numberOfClasses = attrs["numberOfClasses"] self.taxonomies = attrs["taxonomies"] def __str__(self): result = "Build:%s, Creation Date:%s, Version:%s, Number of Files:%s, C Files Analyzed:%s, System Files Analyzed:%s, Lines of Code:%s, Lines of Comments:%s. Number of Entities:%s, Number of Functions:%s, Number of Classes:%s, Taxonomies:%s" % (self.build, self.creationDate, self.version, self.numberOfFiles, self.cFilesAnalyzed, self.systemFilesAnalyzed, self.linesOfCode, self.linesOfComments, self.numberOfEntities, self.numberOfFunctions, self.numberOfClasses, self.taxonomies) return result def from_json(json_object): return Config(json_object) def report(url, user, action, project, build=None): values = {"user": user, "action": action, "project": project} if build is not None: values['build'] = build loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response: result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() action = "project_configuration" url = "http://%s:%d/review/api" % (host, port) project = "demosthenes" build = "build_1" try: project_configuration = report(url, user, action, project, build) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Project Configuration:" for project_config in project_configuration: print project_config
Example: Print the list of viewsThis example shows how to print the list of views. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() class View(object): def __init__(self, attrs): self.name = attrs["name"] self.query = attrs["query"] self.creator = attrs["creator"] if "tags" in attrs: self.tags = attrs["tags"] else: self.tags = "" self.is_public = attrs["is_public"] def __str__(self): result = "Name:%s (Query:%s, Creator:%s, Public:%s) Tags: [" % ( self.name, self.query, self.creator, self.is_public) for x in range(len(self.tags)): if not x: result = result + self.tags[x] else: result = result + ',' + self.tags[x] result += ']' return result def from_json(json_object): return View(json_object) def report(url, project, user): values = {"project": project, "user": user, "action": "views"} loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response: result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" url = "http://%s:%d/review/api" % (host, port) try: views = report(url, project, user) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: for view in views: print view
Example: Create a viewThis example shows how to create views . import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() def createView(url, user, project, name, action, query, tags): values = {"project": project, "user": user, "name": name, "action": action, "query": query, "tags": tags} loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" name = "Sample View" action = "create_view" query = "severity:1-3" tags = "c,security" url = "http://%s:%d/review/api" % (host, port) try: createView(url, user, project, name, action, query, tags) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "View created!"
Example: Update viewsThis example shows how to update views . import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() def updateView(url, user, project, name, newname, action, query, ispublic, tags): values = {"project": project, "user": user, "name": name, "new_name": newname, "action": action, "query": query, "is_public": ispublic, "tags": tags} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" name = "Sample View" newname = "Updated Sample View" action = "update_view" query = "severity:1" tags = "c,security,important" ispublic = "true" url = "http://%s:%d/review/api" % (host, port) try: updateView(url, user, project, name, newname, action, query, ispublic, tags) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "View updated!"
Example: Delete a viewThis example shows how to delete views . import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() def deleteView(url, user, name, project, action): values = {"project": project, "name": name, "user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() name = "Sample View" project = "demosthenes" action = "delete_view" url = "http://%s:%d/review/api" % (host, port) try: deleteView(url, user, name, project, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "View deleted!"
Example: Print the list of modulesThis example shows how to print the list of modules. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() class Module(object) : def __init__(self, attrs) : self.name = attrs["name"] def __str__(self) : result = "%s" % (self.name) return result def from_json(json_object) : return Module(json_object) def listModules(url, project, user, action) : values = {"project": project, "user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response : result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" action = "modules" url = "http://%s:%d/review/api" % (host, port) try: modules = listModules(url, project, user, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Existing modules:" for module in modules : print module
Example: Create a moduleThis example shows how to create modules.
Note: If an access control method has been set, you must have the Project admin role or have the 'manage modules' permission to create and edit modules. In order to add or change access permissions on a module, you need the 'assign role' permission (which a Project admin has by default).
import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() def createModule(url, user, project, name, action, allow_all, paths) : values = {"project": project, "user": user, "name": name, "action": action, "allow_all": allow_all, "paths": paths} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" name = "mymodule" action = "create_module" allow_all = "true" paths= "**/test/*" url = "http://%s:%d/review/api" % (host, port) try: createModule(url, user, project, name, action, allow_all, paths) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Module created!"
Example: Update a moduleThis example shows how to update a module.
Note: If an access control method has been set, you must have the Project admin role or have the 'manage modules' permission to create and edit modules. In order to add or change access permissions on a module, you need the 'assign role' permission (which a Project admin has by default).
import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() def updateModule(url, user, project, name, new_name, action, allow_all) : values = {"project": project, "user": user, "name": name, "new_name": new_name, "action": action, "allow_all": allow_all} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" name = "mymodule" new_name = "mymodule2" action = "update_module" allow_all = "false" url = "http://%s:%d/review/api" % (host, port) try: updateModule(url, user, project, name, new_name, action, allow_all) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Module updated!"
Example: Delete a moduleThis example shows how to delete modules.
Note: If an access control method has been set, you must have the Project admin role or have the 'manage modules' permission to create and edit modules. In order to add or change access permissions on a module, you need the 'assign role' permission (which a Project admin has by default).
import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() def deleteModule(url, user, name, project, action) : values = {"project": project, "name": name, "user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() name = "mymodule" project = "demosthenes" action = "delete_module" url = "http://%s:%d/review/api" % (host, port) try: deleteModule(url, user, name, project, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Module deleted!"
Example: Print the list of buildsThis example shows how to print the list of builds. For information on build management, see Managing integration builds. import urllib, urllib2, json, sys, os.path, getpass, time def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() class Build(object): def __init__(self, attrs): self.id = attrs["id"] # build id self.name = attrs["name"] # build name self.date = time.ctime(attrs["date"] / 1000) # build date self.keepit = attrs["keepit"] # sticky flag def __str__(self): result = "%s: %s" % (self.name, self.date) return result def from_json(json_object): return Build(json_object) def report(url, project, user, action): values = {"project": project, "user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response: result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" action = "builds" url = "http://%s:%d/review/api" % (host, port) try: builds = report(url, project, user, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Existing builds:" for build in builds: print build
Example: Specify which builds to keepThis example specifies that every second build will not be deleted by the auto-delete feature.
Note: This action also allows you to toggle whether a specific build should be kept by specifying the 'keepit' option.
import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() class Build(object) : def __init__(self, attrs) : self.id = attrs["id"] self.name = attrs["name"] self.date = attrs["date"] def __str__(self) : return "Id: %s Name:%s Date:%i" % (self.id, self.name, self.date) def from_json(json_object) : return Build(json_object) def keepit(build_name, loginToken): print "retain " + build_name values = {"project": project, "user": user, "action": "update_build", "name": build_name, "keepit" : "true"} if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) def retain(url, project, user) : values = {"project": project, "user": user, "action": "builds"} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) i = 0 for record in response : build = json.loads(record, object_hook=from_json) i += 1 if not i % 2: keepit(build.name, loginToken) host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" url = "http://%s:%d/review/api" % (host, port) retain(url, project, user)
Example: Delete a buildThis example shows how to delete builds. For information on build management, see Managing integration builds. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user): ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() def deleteBuild(url, user, project, build, action): values = {"project": project, "name": build, "user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() build = "Sample Build" project = "demosthenes" build = "demosthenes_3" action = "delete_build" url = "http://%s:%d/review/api" % (host, port) try: deleteBuild(url, user, project, build, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Build deleted!"
Example: Print a list of enabled checkersThis example shows how to print a list of enabled checkers. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() class View(object) : def __init__(self, attrs) : self.code = attrs["code"] self.name = attrs["name"] self.enabled = attrs["enabled"] self.severity = attrs["severity"] def __str__(self) : result = "Code: %s\nName: %s\nEnabled: %s\nSeverity: %s\n" % (self.code, self.name, self.enabled, self.severity) return result def from_json(json_object) : return View(json_object) def report(url, project, user, action) : values = {"project": project, "user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response : result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" action = "defect_types" taxonomy = "C and C++" url = "http://%s:%d/review/api" % (host, port) try: defects = report(url, project, user, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Defect types:" for defect in defects : print defect
Example: Print a list of taxonomiesThis example shows how to print a list of taxonomies. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() class View(object) : def __init__(self, attrs) : self.name = attrs["name"] self.is_custom = attrs["is_custom"] def __str__(self) : result = "Name: %s\nIs Custom: %s\n" % (self.name, self.is_custom) return result def from_json(json_object) : return View(json_object) def report(url, project, user, action) : values = {"project": project, "user": user, "action": action} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) result = [] for record in response : result.append(json.loads(record, object_hook=from_json)) return result host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" action = "taxonomies" url = "http://%s:%d/review/api" % (host, port) try: taxonomies = report(url, project, user, action) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Taxonomies:" for taxonomy in taxonomies : print taxonomy
Example: Enable and disable checkersThis example shows how to enable and disable checkers. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() def set_defect(url, project, user, action, code, enabled, severity) : values = {"project": project, "user": user, "action": action, "code": code, "enabled": enabled, "severity": severity} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() project = "demosthenes" action = "update_defect_type" code = "VOIDRET" enabled = "True" severity = "1" url = "http://%s:%d/review/api" % (host, port) try: set_defect(url, project, user, action, code, enabled, severity) except urllib2.HTTPError as e: print "Request failed: " + e.reason + ": " + e.read() else: print "Defect type %s updated!\nEnabled: %s\nSeverity: %s" % (code, enabled, severity)
Example: Report metricsThe following example reports the number of lines of commented and non-commented lines, the number of executable statements, the maximum nesting level, and cyclomatic complexity metrics for each file in project from last build. See the Klocwork Metrics Reference for a list of valid metric codes. import urllib, urllib2, json, sys, os.path, getpass def getToken(host, port, user) : ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile : rd = r.strip().split(';') if rd[0] == host and rd[1] == str(port) and rd[2] == user : ltokenFile.close() return rd[3] ltokenFile.close() class Metric(object) : def __init__(self, attrs) : self.file = attrs["filePath"] self.entity = attrs["entity"] self.tag = attrs["tag"] self.value = attrs["metricValue"] def __str__(self) : return "%s;%s;%d" % (self.file, self.tag, self.value) def from_json(json_object) : if 'filePath' in json_object : return Metric(json_object) return json_object host = "localhost" port = 8080 user = getpass.getuser() project = "project" url = "http://%s:%d/review/api" % (host, port) values = {"project": project, "user": user, "action": "metrics"} loginToken = getToken(host, port, user) if loginToken is not None : values["ltoken"] = loginToken values["query"] = "metric:+RNOEXSTAT,+LINESCOMM,+NCNBLOC_FILE,+RMAXLEVEL,+RCYCLOMATIC" data = urllib.urlencode(values) req = urllib2.Request(url, data) try: response = urllib2.urlopen(req) for record in response : print json.loads(record, object_hook=from_json) except urllib2.HTTPError, error: sys.stderr.write('ERROR: %s\n' % str(error)) sys.stderr.write('%s\n' % error.read())
Aggregated search resultsBy default, the metrics API generates results on a per file basis. To generate aggregated search results for all files in a given query, specify the aggregate flag with a value of true (default is false). The following example shows aggregated search results: A query with the following values:
...returns the following aggregate results: {"tag":"LOC_FILE","sum":8113.0,"min":3.0,"max":966.0,"entries":47} Note: The aggregate flag is only really useful for data that has relative meaning. In other words, if a metric can be summed, or if max and min values can be determined.
Excluding system files from search resultsBy default, the metrics API generates results based on all files. You can have the query omit system files by specifying the exclude_system_files flag with a value of true (default is false), for example: A query with the following values:
Example curl request: curl --data "action=metrics&user=someone&project=demosthenes&exclude_system_files=true&query=metric:%2bLOC_FILE&aggregate=true" http://localhost:8080/review/api ...returns the following results: {"tag":"LOC_FILE","sum":322.0,"min":3.0,"max":68.0,"entries":13}
About the following examplesThis module (kwutil), which is used by the examples below, handles reading ltokens from your system. It has been made into a separate module for readability. Be sure to copy and paste the code below to create the kwutil module. import socket, re, platform, os.path def getToken(host, port, user): if host is "localhost": host = socket.gethostname() userHomePath = os.path.expanduser("~") if re.search("Windows", platform.platform()) != None: userHomePath = os.environ['UserProfile'] ltoken = os.path.normpath(os.path.join(userHomePath, ".klocwork", "ltoken")) ltokenFile = open(ltoken, 'r') for r in ltokenFile: rd = r.strip().split(';') if rd[0] == socket.getfqdn(host) and rd[1] == str(port) and rd[2] == user: ltokenFile.close() return rd[3] ltokenFile.close() return None
Importing server settings, projects and code reviewYou can also use the API to import server settings, projects or code reviews via the command line. This can be done for each of these methods as follows:
To import server settingsThe following example imports authentication configuration, permissions, custom metrics, reports definitions and e-mail subscription settings. import urllib, urllib2, json, sys, os.path, getpass, time import kwutil def import_server_configuration(url, user, sourceURL, sourceAdmin, sourcePassword): values = {"action": "import_server_configuration", "user": user, "sourceURL": sourceURL, "sourceAdmin": sourceAdmin} if sourcePassword is not None: values["sourcePassword"] = sourcePassword loginToken = kwutil.getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() sourceURL = "http://oldhost:8080" sourceAdmin = "old admin user name" sourcePassword = None url = "http://%s:%d/review/api" % (host, port) try: import_server_configuration(url, user, sourceURL, sourceAdmin, sourcePassword) print "Imported server configuration!" except urllib2.HTTPError, error: sys.stderr.write('ERROR: %s\n' % str(error)) sys.stderr.write('%s\n' % error.read())
To import a projectThe following example imports data collected by Klocwork for the specified project. import urllib, urllib2, json, sys, os.path, getpass, time import kwutil def import_project(url, user, project, sourceURL, sourceAdmin, sourcePassword): values = {"action": "import_project", "user": user, "project": project, "sourceURL": sourceURL, "sourceAdmin": sourceAdmin} if sourcePassword is not None: values["sourcePassword"] = sourcePassword loginToken = kwutil.getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) host = "localhost" port = 8080 user = getpass.getuser() project = "projectA" sourceURL = "http://oldhost:8080" sourceAdmin = "old admin user name" sourcePassword = None url = "http://%s:%d/review/api" % (host, port) try: import_project(url, user, project, sourceURL, sourceAdmin, sourcePassword) print "Imported project!" except urllib2.HTTPError, error: sys.stderr.write('ERROR: %s\n' % str(error)) sys.stderr.write('%s\n' % error.read())
To check import statusYou can use this API method to check the status of importing your server settings, project or code review. import urllib, urllib2, json, time, os.path, getpass, re, platform, sys, socket import kwutil class ImportStatus(object): def __init__(self, project, attrs): self.project = project self.stage = attrs["stage"] self.progress = attrs["progress"] self.failed = attrs["failed"] self.hasWarnings = attrs["hasWarnings"] self.projectReady = attrs["projectReady"] self.complete = attrs["complete"] def __str__(self): return "Project: %s\n\tStage: %s | Progress: %s%% | Failed: %s | Warnings: %s | Project Ready: %s | Complete: %s" % ( self.project, self.stage, self.progress, self.failed, self.hasWarnings, self.projectReady, self.complete) def import_status(url, user): values = {"action": "import_status", "user": user} loginToken = kwutil.getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) response = urllib2.urlopen(req) importStatus = [] for record in response: attrs = json.loads(record) for key in attrs.keys(): importStatus.append(ImportStatus(key, attrs[key])) return importStatus def import_project(url, user, project, sourceURL, sourceAdmin, sourcePassword=None, ): values = {"action": "import_project", "user": user, "project": project, "sourceURL": sourceURL, "sourceAdmin": sourceAdmin} if sourcePassword: values["sourcePassword"] = sourcePassword loginToken = kwutil.getToken(host, port, user) if loginToken is not None: values["ltoken"] = loginToken data = urllib.urlencode(values) req = urllib2.Request(url, data) urllib2.urlopen(req) def wait_for_import(url, user, project): isTimeout = False TIME_OUT = time.time() + 60 * 20 incomplete = [project] if len(incomplete) == 0: return while True: for status in import_status(url, user): if status.project != project: continue # If all operations are complete then exit the loop if len(incomplete) == 0: break if status.project in incomplete: isTimeout = time.time() > TIME_OUT if status.complete or status.failed: print status.stage incomplete.pop(incomplete.index(status.project)) break elif isTimeout: print "Import of project '%s' took longer than expected." % status.project print "Check if import is still progressing." sys.exit(-1) # If all projects are complete then exit the loop if len(incomplete) == 0: break time.sleep(10) host = "localhost" port = 8080 user = getpass.getuser() url = "http://%s:%d/review/api" % (host, port) project = "demosthenes" sourceURL = "http://oldhost:8080" sourceAdmin = "old admin user name" try: import_project(url, user, project, sourceURL, sourceAdmin) print "Import started" wait_for_import(url, user, project) except urllib2.HTTPError, error: sys.stderr.write('ERROR: %s\n' % str(error)) sys.stderr.write('%s\n' % error.read())
To check the Klocwork Server versionThis action allows you to retrieve the Klocwork Server version. Here is an example curl command for this action:
curl --data "action=version&user=myself&" http://jsmith.klocwork.com:8080/review/api The follow listing shows sample output from this command:
1 { 2 majorVersion: "10.1" 3 minorVersion: "1" 4 }
To list the statuses of all tasks running on the Klocwork ServerThis action allows you to list the status of each task running on your Klocwork Server. Here is an example curl command for this action:
curl --data "action=task_status&user=myself&" http://jsmith.klocwork.com:8080/review/api |