py_jama_rest_client.client
1import json 2import logging 3 4from .core import Core, CoreException 5 6# This is the py_jama_rest_client logger. 7py_jama_rest_client_logger = logging.getLogger('py_jama_rest_client') 8 9 10class APIException(Exception): 11 """This is the base class for all exceptions raised by the JamaClient""" 12 13 def __init__(self, message, status_code=None, reason=None): 14 super(APIException, self).__init__(message) 15 self.status_code = status_code 16 self.reason = reason 17 18 19class UnauthorizedException(APIException): 20 """This exception is thrown whenever the api returns a 401 unauthorized response.""" 21 pass 22 23 24class TooManyRequestsException(APIException): 25 """This exception is thrown whenever the api returns a 429 too many requests response.""" 26 pass 27 28 29class ResourceNotFoundException(APIException): 30 """This exception is raised whenever the api returns a 404 not found response.""" 31 pass 32 33 34class AlreadyExistsException(APIException): 35 """This exception is thrown when the API returns a 400 response with a message that the resource already exists.""" 36 pass 37 38 39class APIClientException(APIException): 40 """This exception is thrown whenever a unknown 400 error is encountered.""" 41 pass 42 43 44class APIServerException(APIException): 45 """This exception is thrown whenever an unknown 500 response is encountered.""" 46 pass 47 48 49class JamaClient: 50 """A class to abstract communication with the Jama Connect API""" 51 52 __allowed_results_per_page = 20 # Default is 20, Max is 50. if set to greater than 50, only 50 will items return. 53 54 def __init__(self, host_domain, 55 credentials=('username|clientID', 'password|clientSecret'), 56 api_version='/rest/v1/', 57 oauth=False, 58 verify=True, 59 allowed_results_per_page=20): 60 """Jama Client initializer 61 :rtype: JamaClient 62 :param host_domain: String The domain associated with the Jama Connect host 63 :param credentials: the user name and password as a tuple or client id and client secret if using Oauth. 64 :param api_version: valid args are '/rest/[v1|latest|labs]/' 65 :param verify: Defaults to True, Setting this to False will skip SSL Certificate verification""" 66 self.__credentials = credentials 67 self.__allowed_results_per_page = allowed_results_per_page 68 try: 69 self.__core = Core(host_domain, credentials, api_version=api_version, oauth=oauth, verify=verify) 70 except CoreException as err: 71 py_jama_rest_client_logger.error(err) 72 raise APIException(str(err)) 73 74 # Log client creation 75 py_jama_rest_client_logger.info('Created a new JamaClient instance. Domain: {} ' 76 'Connecting via Oauth: {}'.format(host_domain, oauth)) 77 78 def get_available_endpoints(self): 79 """ 80 Returns a list of all the available endpoints. 81 82 Returns: an array of available endpoints for this API 83 84 """ 85 try: 86 response = self.__core.get('') 87 except CoreException as err: 88 py_jama_rest_client_logger.error(err) 89 raise APIException(str(err)) 90 JamaClient.__handle_response_status(response) 91 return response.json()['data'] 92 93 def get_baselines(self, project_id, allowed_results_per_page=__allowed_results_per_page): 94 """ 95 Returns a list of Baseline objects 96 Args: 97 project_id: the Id of the project to fetch baselines for 98 allowed_results_per_page: number of results per page 99 100 Returns: a list of Baseline objects 101 """ 102 resource_path = 'baselines' 103 params = {'project': project_id} 104 baseline_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 105 return baseline_data 106 107 def get_baseline(self, baseline_id): 108 """ 109 This method will return a baseline 110 Args: 111 baseline_id: the id of the baseline to fetch 112 113 Returns: a dictionary object representing the baseline 114 115 """ 116 resource_path = 'baselines/' + str(baseline_id) 117 try: 118 response = self.__core.get(resource_path) 119 except CoreException as err: 120 py_jama_rest_client_logger.error(err) 121 raise APIException(str(err)) 122 JamaClient.__handle_response_status(response) 123 return response.json()['data'] 124 125 def get_baselines_versioneditems(self, baseline_id, allowed_results_per_page=__allowed_results_per_page): 126 """ 127 Get all baseline items in a baseline with the specified ID 128 Args: 129 baseline_id: The id of the baseline to fetch items for. 130 allowed_results_per_page: Number of results per page 131 Returns: A list of versioned items belonging to the baseline 132 """ 133 resource_path = 'baselines/' + str(baseline_id) + '/versioneditems' 134 baseline_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 135 return baseline_items 136 137 def get_projects(self, allowed_results_per_page=__allowed_results_per_page): 138 """This method will return all projects as JSON object 139 :return: JSON Array of Item Objects. 140 """ 141 resource_path = 'projects' 142 project_data = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 143 return project_data 144 145 def get_filter_results(self, filter_id, project_id=None, allowed_results_per_page=__allowed_results_per_page): 146 """ 147 Get all results items for the filter with the specified ID 148 149 Args: 150 filter_id: The ID of the filter to fetch the results for. 151 project_id: Use this only for filters that run on any project, where projectScope is CURRENT 152 allowed_results_per_page: Number of results per page 153 154 Returns: 155 A List of items that match the filter. 156 157 """ 158 resource_path = 'filters/' + str(filter_id) + '/results' 159 params = None 160 if project_id is not None: 161 params = {'project': str(project_id)} 162 filter_results = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 163 return filter_results 164 165 def get_items(self, project_id, allowed_results_per_page=__allowed_results_per_page): 166 """ 167 This method will return all items in the specified project. 168 Args: 169 project_id: the project ID 170 allowed_results_per_page: number of results per page 171 172 Returns: a Json array of item objects 173 174 """ 175 resource_path = 'items' 176 params = {'project': project_id} 177 item_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 178 return item_data 179 180 def get_item(self, item_id): 181 """ 182 This method will return a singular item of a specified item id 183 Args: 184 item_id: the item id of the item to fetch 185 186 Returns: a dictonary object representing the item 187 188 """ 189 resource_path = 'items/' + str(item_id) 190 try: 191 response = self.__core.get(resource_path) 192 except CoreException as err: 193 py_jama_rest_client_logger.error(err) 194 raise APIException(str(err)) 195 JamaClient.__handle_response_status(response) 196 return response.json()['data'] 197 198 def get_item_lock(self, item_id): 199 """ 200 Get the locked state, last locked date, and last locked by user for the item with the specified ID 201 Args: 202 item_id: The API ID of the item to get the lock info for. 203 204 Returns: 205 A JSON object with the lock information for the item with the specified ID. 206 207 """ 208 resource_path = 'items/' + str(item_id) + '/lock' 209 try: 210 response = self.__core.get(resource_path) 211 except CoreException as err: 212 py_jama_rest_client_logger.error(err) 213 raise APIException(str(err)) 214 JamaClient.__handle_response_status(response) 215 return response.json()['data'] 216 217 def put_item_lock(self, item_id, locked): 218 """ 219 Update the locked state of the item with the specified ID 220 Args: 221 item_id: the API id of the item to be updated 222 locked: boolean lock state to apply to this item 223 224 Returns: 225 response status 200 226 227 """ 228 body = { 229 "locked": locked, 230 } 231 resource_path = 'items/' + str(item_id) + '/lock' 232 headers = {'content-type': 'application/json'} 233 try: 234 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 235 except CoreException as err: 236 py_jama_rest_client_logger.error(err) 237 raise APIException(str(err)) 238 return self.__handle_response_status(response) 239 240 def get_item_tags(self, item_id, allowed_results_per_page=__allowed_results_per_page): 241 """ 242 Return all tags for the item with the specified ID 243 244 Args: 245 item_id: the item id of the item to fetch 246 allowed_results_per_page: number of results 247 248 Returns: a dictionary object representing the item's tags 249 250 """ 251 resource_path = 'items/' + str(item_id) + '/tags' 252 item_tags = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 253 return item_tags 254 255 def get_attachment(self, attachment_id): 256 """ 257 This method will return a singular attachment of a specified attachment id 258 Args: 259 attachment_id: the attachment id of the attachment to fetch 260 261 Returns: a dictonary object representing the attachment 262 263 """ 264 resource_path = 'attachments/' + str(attachment_id) 265 try: 266 response = self.__core.get(resource_path) 267 except CoreException as err: 268 py_jama_rest_client_logger.error(err) 269 raise APIException(str(err)) 270 JamaClient.__handle_response_status(response) 271 return response.json()['data'] 272 273 def get_abstract_items_from_doc_key(self, doc_key_list, allowed_results_per_page=__allowed_results_per_page): 274 """ DEPRECATED INSTEAD USE get_abstract_items below. 275 This method will take in a list of document keys and return an array of JSON Objects associated with the 276 document keys.""" 277 resource_path = 'abstractitems' 278 params = {'documentKey': doc_key_list} 279 abstract_items = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 280 return abstract_items 281 282 def get_relationship_rule_sets(self): 283 """ 284 This method will return all relationship rule sets across all projects of the Jama Connect instance. 285 286 Returns: An array of dictionary objects representing a rule set and its associated rules 287 288 """ 289 resource_path = 'relationshiprulesets/' 290 rule_sets = self.__get_all(resource_path) 291 return rule_sets 292 293 def get_relationship_rule_set(self, id): 294 """ 295 This method will return the relationship rule sets by id. 296 297 Returns: A dictionary object representing a rule set and its associated rules 298 299 """ 300 resource_path = 'relationshiprulesets/' + str(id) 301 response = self.__core.get(resource_path) 302 JamaClient.__handle_response_status(response) 303 return response.json()['data'] 304 305 def get_relationship_rule_set_projects(self, id): 306 """ 307 This method will return the projects that have a given relationship rule set defined. 308 309 Returns: An array of the dictionary objects representing the projects with a given rule set assigned 310 311 """ 312 resource_path = 'relationshiprulesets/' + str(id) + '/projects' 313 projects = self.__get_all(resource_path) 314 return projects 315 316 def get_relationship_types(self, allowed_results_per_page=__allowed_results_per_page): 317 """ 318 This method will return all relationship types of the across all projects of the Jama Connect instance. 319 320 Args: 321 allowed_results_per_page: Number of results per page 322 323 Returns: An array of dictionary objects 324 325 """ 326 resource_path = 'relationshiptypes/' 327 item_types = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 328 return item_types 329 330 def get_relationship_type(self, relationship_type_id): 331 """ 332 Gets relationship type information for a specific relationship type id. 333 334 Args: 335 relationship_type_id: The api id of the item type to fetch 336 337 Returns: JSON object 338 339 """ 340 resource_path = 'relationshiptypes/' + str(relationship_type_id) 341 try: 342 response = self.__core.get(resource_path) 343 except CoreException as err: 344 py_jama_rest_client_logger.error(err) 345 raise APIException(str(err)) 346 JamaClient.__handle_response_status(response) 347 return response.json()['data'] 348 349 def get_item_types(self, allowed_results_per_page=__allowed_results_per_page): 350 """ 351 This method will return all item types of the across all projects of the Jama Connect instance. 352 353 Args: 354 allowed_results_per_page: Number of results per page 355 356 Returns: An array of dictionary objects 357 358 """ 359 resource_path = 'itemtypes/' 360 item_types = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 361 return item_types 362 363 def get_item_type(self, item_type_id): 364 """ 365 Gets item type information for a specific item type id. 366 367 Args: 368 item_type_id: The api id of the item type to fetch 369 370 Returns: JSON object 371 372 """ 373 resource_path = 'itemtypes/' + str(item_type_id) 374 try: 375 response = self.__core.get(resource_path) 376 except CoreException as err: 377 py_jama_rest_client_logger.error(err) 378 raise APIException(str(err)) 379 JamaClient.__handle_response_status(response) 380 return response.json()['data'] 381 382 def get_items_synceditems(self, item_id, allowed_results_per_page=__allowed_results_per_page): 383 """ 384 Get all synchronized items for the item with the specified ID 385 386 Args: 387 item_id: The API id of the item being 388 allowed_results_per_page: Number of results per page 389 390 Returns: A list of JSON Objects representing the items that are in the same synchronization group as the 391 specified item. 392 393 """ 394 resource_path = 'items/' + str(item_id) + '/synceditems' 395 synced_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 396 return synced_items 397 398 def get_items_synceditems_status(self, item_id, synced_item_id): 399 """ 400 Get the sync status for the synced item with the specified ID 401 402 Args: 403 item_id: The id of the item to compare against 404 synced_item_id: the id of the item to check if it is in sync 405 406 Returns: The response JSON from the API which contains a single field 'inSync' with a boolean value. 407 408 """ 409 resource_path = 'items/' + str(item_id) + '/synceditems/' + str(synced_item_id) + '/syncstatus' 410 try: 411 response = self.__core.get(resource_path) 412 except CoreException as err: 413 py_jama_rest_client_logger.error(err) 414 raise APIException(str(err)) 415 JamaClient.__handle_response_status(response) 416 return response.json()['data'] 417 418 def get_item_versions(self, item_id): 419 """ 420 Get all versions for the item with the specified ID 421 422 Args: 423 item_id: the item id of the item to fetch 424 425 Returns: JSON array with all versions for the item 426 """ 427 resource_path = 'items/' + str(item_id) + '/versions' 428 versions = self.__get_all(resource_path) 429 return versions 430 431 def get_item_version(self, item_id, version_num): 432 """ 433 Get the numbered version for the item with the specified ID 434 435 Args: 436 item_id: the item id of the item to fetch 437 version_num: the version number for the item 438 439 Returns: a dictionary object representing the numbered version 440 """ 441 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) 442 try: 443 response = self.__core.get(resource_path) 444 except CoreException as err: 445 py_jama_rest_client_logger.error(err) 446 raise APIException(str(err)) 447 JamaClient.__handle_response_status(response) 448 return response.json()['data'] 449 450 def get_versioned_item(self, item_id, version_num): 451 """ 452 Get the snapshot of the item at the specified version 453 454 Args: 455 item_id: the item id of the item to fetch 456 version_num: the version number for the item 457 458 Returns: a dictionary object representing the versioned item 459 """ 460 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 461 try: 462 response = self.__core.get(resource_path) 463 except CoreException as err: 464 py_jama_rest_client_logger.error(err) 465 raise APIException(str(err)) 466 JamaClient.__handle_response_status(response) 467 return response.json()['data'] 468 469 def get_item_versions(self, item_id, allowed_results_per_page=__allowed_results_per_page): 470 """ 471 Get all versions for the item with the specified ID 472 473 Args: 474 item_id: the item id of the item to fetch 475 allowed_results_per_page: number of results per page 476 477 Returns: JSON array with all versions for the item 478 """ 479 resource_path = 'items/' + str(item_id) + '/versions' 480 versions = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 481 return versions 482 483 def get_item_version(self, item_id, version_num): 484 """ 485 Get the numbered version for the item with the specified ID 486 487 Args: 488 item_id: the item id of the item to fetch 489 version_num: the version number for the item 490 491 Returns: a dictionary object representing the numbered version 492 """ 493 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) 494 response = self.__core.get(resource_path) 495 JamaClient.__handle_response_status(response) 496 return response.json()['data'] 497 498 def get_versioned_item(self, item_id, version_num): 499 """ 500 Get the snapshot of the item at the specified version 501 502 Args: 503 item_id: the item id of the item to fetch 504 version_num: the version number for the item 505 506 Returns: a dictionary object representing the versioned item 507 """ 508 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 509 response = self.__core.get(resource_path) 510 JamaClient.__handle_response_status(response) 511 return response.json()['data'] 512 513 def get_pick_lists(self, allowed_results_per_page=__allowed_results_per_page): 514 """ 515 Returns a list of all the pick lists 516 517 Args: 518 allowed_results_per_page: number of results per page 519 520 Returns: an array of dictionary objects 521 522 """ 523 resource_path = 'picklists/' 524 pick_lists = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 525 return pick_lists 526 527 def get_pick_list(self, pick_list_id): 528 """ 529 Gets all a singular picklist 530 531 Args: 532 pick_list_id: The API id of the pick list to fetch 533 534 Returns: a dictionary object representing the picklist. 535 536 """ 537 resource_path = 'picklists/' + str(pick_list_id) 538 try: 539 response = self.__core.get(resource_path) 540 except CoreException as err: 541 py_jama_rest_client_logger.error(err) 542 raise APIException(str(err)) 543 JamaClient.__handle_response_status(response) 544 return response.json()['data'] 545 546 def get_pick_list_options(self, pick_list_id, allowed_results_per_page=__allowed_results_per_page): 547 """ 548 Gets all all the picklist options for a single picklist 549 Args: 550 pick_list_id: the api id of the picklist to fetch options for. 551 allowed_results_per_page: number of results per page 552 553 Returns: an array of dictionary objects that represent the picklist options. 554 555 """ 556 resource_path = 'picklists/' + str(pick_list_id) + '/options' 557 pick_list_options = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 558 return pick_list_options 559 560 def get_pick_list_option(self, pick_list_option_id): 561 """ 562 Fetches a single picklist option from the API 563 Args: 564 pick_list_option_id: The API ID of the picklist option to fetch 565 566 Returns: A dictonary object representing the picklist option. 567 568 """ 569 resource_path = 'picklistoptions/' + str(pick_list_option_id) 570 try: 571 response = self.__core.get(resource_path) 572 except CoreException as err: 573 py_jama_rest_client_logger.error(err) 574 raise APIException(str(err)) 575 JamaClient.__handle_response_status(response) 576 return response.json()['data'] 577 578 def get_relationships(self, project_id, allowed_results_per_page=__allowed_results_per_page): 579 """ 580 Returns a list of all relationships of a specified project 581 582 Args: 583 project_id: the api project id of a project 584 allowed_results_per_page: number of results per page 585 586 Returns: a list of dictionary objects that represents a relationships 587 588 """ 589 resource_path = 'relationships' 590 params = {'project': project_id} 591 relationship_data = self.__get_all(resource_path, params=params, 592 allowed_results_per_page=allowed_results_per_page) 593 return relationship_data 594 595 def get_relationship(self, relationship_id): 596 """ 597 Returns a specific relationship object of a specified relationship ID 598 599 Args: 600 relationship_id: the api project id of a relationship 601 602 Returns: a dictionary object that represents a relationship 603 604 """ 605 resource_path = 'relationships/' + str(relationship_id) 606 try: 607 response = self.__core.get(resource_path) 608 except CoreException as err: 609 py_jama_rest_client_logger.error(err) 610 raise APIException(str(err)) 611 JamaClient.__handle_response_status(response) 612 return response.json()['data'] 613 614 def get_abstract_items(self, 615 project=None, 616 item_type=None, 617 document_key=None, 618 release=None, 619 created_date=None, 620 modified_date=None, 621 last_activity_date=None, 622 contains=None, 623 sort_by=None): 624 """ 625 This method will return all items that match the query parameters entered. 626 627 Args: 628 project: Array[integer] 629 item_type: Array[integer] 630 document_key: Array[string] 631 release: Array[integer] 632 created_date: Array[string] 633 modified_date: Array[string] 634 last_activity_date: Array[string] 635 contains: Array[string] 636 sort_by: Array[string] 637 638 Returns: 639 A JSON Array of items. 640 641 """ 642 resource_path = 'abstractitems' 643 644 # Add each parameter that is not null to the request. 645 params = {} 646 647 if project is not None: 648 params['project'] = project 649 650 if item_type is not None: 651 params['itemType'] = item_type 652 653 if document_key is not None: 654 params['documentKey'] = document_key 655 656 if release is not None: 657 params['release'] = release 658 659 if created_date is not None: 660 params['createdDate'] = created_date 661 662 if modified_date is not None: 663 params['modifiedDate'] = modified_date 664 665 if last_activity_date is not None: 666 params['lastActivityDate'] = last_activity_date 667 668 if contains is not None: 669 params['contains'] = contains 670 671 if sort_by is not None: 672 params['sortBy'] = sort_by 673 674 abstract_items = self.__get_all(resource_path, params=params) 675 return abstract_items 676 677 def get_abstract_item(self, item_id): 678 """ 679 This method will return an item, test plan, test cycle, test run, or attachment with the specified ID 680 Args: 681 item_id: the item id of the item to fetch 682 683 Returns: a dictonary object representing the abstract item 684 685 """ 686 resource_path = 'abstractitems/' + str(item_id) 687 try: 688 response = self.__core.get(resource_path) 689 except CoreException as err: 690 py_jama_rest_client_logger.error(err) 691 raise APIException(str(err)) 692 JamaClient.__handle_response_status(response) 693 return response.json()['data'] 694 695 def get_abstract_item_versions(self, item_id): 696 """ 697 Get all versions for the item with the specified ID 698 699 Args: 700 item_id: the item id of the item to fetch 701 702 Returns: JSON array with all versions for the item 703 """ 704 resource_path = 'abstractitems/' + str(item_id) + '/versions' 705 versions = self.__get_all(resource_path) 706 return versions 707 708 def get_abtract_item_version(self, item_id, version_num): 709 """ 710 Get the numbered version for the item with the specified ID 711 712 Args: 713 item_id: the item id of the item to fetch 714 version_num: the version number for the item 715 716 Returns: a dictionary object representing the numbered version 717 """ 718 resource_path = 'abstractitems/' + str(item_id) + '/versions/' + str(version_num) 719 try: 720 response = self.__core.get(resource_path) 721 except CoreException as err: 722 py_jama_rest_client_logger.error(err) 723 raise APIException(str(err)) 724 JamaClient.__handle_response_status(response) 725 return response.json()['data'] 726 727 def get_abstract_versioned_item(self, item_id, version_num): 728 """ 729 Get the snapshot of the item at the specified version 730 731 Args: 732 item_id: the item id of the item to fetch 733 version_num: the version number for the item 734 735 Returns: a dictionary object representing the versioned item 736 """ 737 resource_path = 'abstractitems/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 738 try: 739 response = self.__core.get(resource_path) 740 except CoreException as err: 741 py_jama_rest_client_logger.error(err) 742 raise APIException(str(err)) 743 JamaClient.__handle_response_status(response) 744 return response.json()['data'] 745 746 747 def get_item_children(self, item_id, allowed_results_per_page=__allowed_results_per_page): 748 """ 749 This method will return list of the child items of the item passed to the function. 750 Args: 751 item_id: (int) The id of the item for which children items should be fetched 752 allowed_results_per_page: Number of results per page 753 754 Returns: a List of Objects that represent the children of the item passed in. 755 """ 756 resource_path = 'items/' + str(item_id) + '/children' 757 child_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 758 return child_items 759 760 def get_testruns(self, test_cycle_id, allowed_results_per_page=__allowed_results_per_page): 761 """This method will return all test runs associated with the specified test cycle. Test runs will be returned 762 as a list of json objects.""" 763 resource_path = 'testcycles/' + str(test_cycle_id) + '/testruns' 764 testrun_data = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 765 return testrun_data 766 767 def get_items_upstream_relationships(self, item_id, allowed_results_per_page=__allowed_results_per_page): 768 """ 769 Returns a list of all the upstream relationships for the item with the specified ID. 770 Args: 771 item_id: the api id of the item 772 allowed_results_per_page: number of results per page 773 774 Returns: an array of dictionary objects that represent the upstream relationships for the item. 775 776 """ 777 resource_path = 'items/' + str(item_id) + '/upstreamrelationships' 778 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 779 780 def get_items_downstream_related(self, item_id, allowed_results_per_page=__allowed_results_per_page): 781 """ 782 Returns a list of all the downstream related items for the item with the specified ID. 783 784 Args: 785 item_id: the api id of the item to fetch downstream items for 786 allowed_results_per_page: number of results per page 787 788 Returns: an array of dictionary objects that represent the downstream related items for the specified item. 789 790 """ 791 resource_path = 'items/' + str(item_id) + '/downstreamrelated' 792 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 793 794 def get_items_downstream_relationships(self, item_id, allowed_results_per_page=__allowed_results_per_page): 795 """ 796 Returns a list of all the downstream relationships for the item with the specified ID. 797 798 Args: 799 item_id: the api id of the item 800 801 Returns: an array of dictionary objects that represent the downstream relationships for the item. 802 803 """ 804 resource_path = 'items/' + str(item_id) + '/downstreamrelationships' 805 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 806 807 def get_items_upstream_related(self, item_id): 808 """ 809 Returns a list of all the upstream related items for the item with the specified ID. 810 811 Args: 812 item_id: the api id of the item to fetch upstream items for 813 814 Returns: an array of dictionary objects that represent the upstream related items for the specified item. 815 816 """ 817 resource_path = 'items/' + str(item_id) + '/upstreamrelated' 818 return self.__get_all(resource_path) 819 820 def get_item_workflow_transitions(self, item_id): 821 """ 822 Get all valid workflow transitions that can be made with the specified id 823 824 Args: 825 item_id: the api id of the item 826 allowed_results_per_page: number of results per page 827 828 Returns: an array of dictionary objects that represent the workflow transitions for the item. 829 830 """ 831 resource_path = 'items/' + str(item_id) + '/workflowtransitionoptions' 832 return self.__get_all(resource_path) 833 834 def get_tags(self, project, allowed_results_per_page=__allowed_results_per_page): 835 """ 836 Get all tags for the project with the specified id 837 Args: 838 project: The API ID of the project to fetch tags for. 839 allowed_results_per_page: Number of results per page 840 841 Returns: A Json Array that contains all the tag data for the specified project. 842 843 """ 844 resource_path = 'tags' 845 params = {'project': project} 846 tag_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 847 return tag_data 848 849 def get_tagged_items(self, tag_id, allowed_results_per_page=__allowed_results_per_page): 850 """ 851 Get all items tagged with the specified ID 852 853 Args: 854 tag_id: The ID of the tag to fetch the results for. 855 allowed_results_per_page: Number of results per page 856 857 Returns: 858 A List of items that match the tag. 859 860 """ 861 resource_path = 'tags/' + str(tag_id) + '/items' 862 params = None 863 tag_results = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 864 return tag_results 865 866 def get_users(self, allowed_results_per_page=__allowed_results_per_page): 867 """ 868 Gets a list of all active users visible to the current user 869 870 Args: 871 allowed_results_per_page: Number of results per page 872 873 Returns: JSON array 874 875 """ 876 resource_path = 'users/' 877 users = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 878 return users 879 880 def get_user(self, user_id): 881 """ 882 Gets a single speificed user 883 884 Args: 885 user_id: user api ID 886 887 Returns: JSON obect 888 889 """ 890 resource_path = 'users/' + str(user_id) 891 try: 892 response = self.__core.get(resource_path) 893 except CoreException as err: 894 py_jama_rest_client_logger.error(err) 895 raise APIException(str(err)) 896 return response.json()['data'] 897 898 def get_current_user(self): 899 """ 900 Gets a current user 901 902 Returns: JSON obect 903 904 """ 905 resource_path = 'users/current' 906 try: 907 response = self.__core.get(resource_path) 908 except CoreException as err: 909 py_jama_rest_client_logger.error(err) 910 raise APIException(str(err)) 911 return response.json()['data'] 912 913 def get_test_cycle(self, test_cycle_id): 914 """ 915 This method will return JSON data about the test cycle specified by the test cycle id. 916 917 Args: 918 test_cycle_id: the api id of the test cycle to fetch 919 920 Returns: a dictionary object that represents the test cycle 921 922 """ 923 resource_path = 'testcycles/' + str(test_cycle_id) 924 try: 925 response = self.__core.get(resource_path) 926 except CoreException as err: 927 py_jama_rest_client_logger.error(err) 928 raise APIException(str(err)) 929 JamaClient.__handle_response_status(response) 930 return response.json()['data'] 931 932 def delete_item(self, item_id): 933 """ 934 This method will delete an item in Jama Connect. 935 936 Args: 937 item_id: The jama connect API ID of the item to be deleted 938 939 Returns: The success status code. 940 """ 941 resource_path = 'items/' + str(item_id) 942 try: 943 response = self.__core.delete(resource_path) 944 except CoreException as err: 945 py_jama_rest_client_logger.error(err) 946 raise APIException(str(err)) 947 JamaClient.__handle_response_status(response) 948 return response.status_code 949 950 def delete_relationships(self, relationship_id): 951 """ 952 Deletes a relationship with the specified relationship ID 953 954 Args: 955 relationship_id: the api project id of a relationship 956 957 Returns: The success status code. 958 959 """ 960 resource_path = 'relationships/' + str(relationship_id) 961 try: 962 response = self.__core.delete(resource_path) 963 except CoreException as err: 964 py_jama_rest_client_logger.error(err) 965 raise APIException(str(err)) 966 JamaClient.__handle_response_status(response) 967 return response.status_code 968 969 def patch_item(self, item_id, patches): 970 """ 971 This method will patch an item. 972 Args: 973 item_id: the API ID of the item that is to be patched 974 patches: An array of dicts, that represent patch operations each dict should have the following entries 975 [ 976 { 977 "op": string, 978 "path": string, 979 "value": {} 980 } 981 ] 982 983 Returns: The response status code 984 985 """ 986 resource_path = 'items/' + str(item_id) 987 headers = {'Content-Type': 'application/json', 988 'Accept': 'application/json' 989 } 990 data = json.dumps(patches) 991 992 # Make the API Call 993 try: 994 response = self.__core.patch(resource_path, data=data, headers=headers) 995 except CoreException as err: 996 py_jama_rest_client_logger.error(err) 997 raise APIException(str(err)) 998 999 # validate response 1000 JamaClient.__handle_response_status(response) 1001 return response.json()['meta']['status'] 1002 1003 def post_user(self, username, password, first_name, last_name, email, license_type, phone=None, title=None, 1004 location=None): 1005 """ 1006 Creates a new user 1007 1008 Args: 1009 username: str 1010 password: str 1011 first_name: str 1012 last_name: str 1013 email: str 1014 phone: str - optional 1015 title: str - optional 1016 location: str - optional 1017 licenseType: enum [ NAMED, FLOATING, STAKEHOLDER, FLOATING_COLLABORATOR, RESERVED_COLLABORATOR, FLOATING_REVIEWER, RESERVED_REVIEWER, NAMED_REVIEWER, TEST_RUNNER, EXPIRING_TRIAL, INACTIVE ] 1018 1019 Returns: int of newly created user api ID 1020 1021 """ 1022 1023 body = { 1024 'username': username, 1025 'password': password, 1026 'firstName': first_name, 1027 'lastName': last_name, 1028 'email': email, 1029 'phone': phone, 1030 'title': title, 1031 'location': location, 1032 'licenseType': license_type 1033 } 1034 resource_path = 'users/' 1035 headers = {'content-type': 'application/json'} 1036 try: 1037 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1038 except CoreException as err: 1039 py_jama_rest_client_logger.error(err) 1040 raise APIException(str(err)) 1041 JamaClient.__handle_response_status(response) 1042 return response.json()['meta']['id'] 1043 1044 def post_tag(self, name: str, project: int): 1045 """ 1046 Create a new tag in the project with the specified ID 1047 Args: 1048 name: The display name for the tag 1049 project: The project to create the new tag in 1050 1051 Returns: The integer API ID fr the newly created Tag. 1052 """ 1053 resource_path = 'tags' 1054 body = { 1055 'name': name, 1056 'project': project 1057 } 1058 headers = {'content-type': 'application/json'} 1059 try: 1060 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1061 except CoreException as err: 1062 py_jama_rest_client_logger.error(err) 1063 raise APIException(str(err)) 1064 JamaClient.__handle_response_status(response) 1065 return response.json()['meta']['id'] 1066 1067 def post_testplans_testcycles(self, testplan_id, testcycle_name, start_date, end_date, testgroups_to_include=None, 1068 testrun_status_to_include=None): 1069 """ 1070 This method will create a new Test Cycle. 1071 1072 Args: 1073 testplan_id (int): The API_ID of the testplan to create the test cycle from. 1074 testcycle_name (str): The name you would like to set for the new Test Cycle 1075 start_date (str): Start date in 'yyyy-mm-dd' Format 1076 end_date (str): End date in 'yyyy-mm-dd' Format 1077 testgroups_to_include (int[]): This array of integers specify the test groups to be included. 1078 testrun_status_to_include (str[]): Only valid after generating the first Test Cycle, you may choose to only 1079 generate Test Runs that were a specified status in the previous cycle. Do not specify anything to 1080 include all statuses 1081 1082 Returns: 1083 (int): Returns the integer id for the newly created testcycle, or None if something went terribly wrong. 1084 """ 1085 resource_path = 'testplans/' + str(testplan_id) + '/testcycles' 1086 headers = {'content-type': 'application/json'} 1087 fields = { 1088 'name': testcycle_name, 1089 'startDate': start_date, 1090 'endDate': end_date 1091 } 1092 test_run_gen_config = {} 1093 if testgroups_to_include is not None: 1094 test_run_gen_config['testGroupsToInclude'] = testgroups_to_include 1095 if testrun_status_to_include is not None: 1096 test_run_gen_config['testRunStatusesToInclude'] = testrun_status_to_include 1097 body = { 1098 'fields': fields, 1099 'testRunGenerationConfig': test_run_gen_config 1100 } 1101 1102 # Make the API Call 1103 try: 1104 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1105 except CoreException as err: 1106 py_jama_rest_client_logger.error(err) 1107 raise APIException(str(err)) 1108 1109 # Validate response 1110 JamaClient.__handle_response_status(response) 1111 return response.json()['meta']['id'] 1112 1113 def post_item(self, project, item_type_id, child_item_type_id, location, fields, global_id=None): 1114 """ This method will post a new item to Jama Connect. 1115 :param global_id: optional param to post the item with a custom global id 1116 :param project integer representing the project to which this item is to be posted 1117 :param item_type_id integer ID of an Item Type. 1118 :param child_item_type_id integer ID of an Item Type. 1119 :param location dictionary with integer ID of the parent item or project. 1120 :param fields dictionary item field data. 1121 :return integer ID of the successfully posted item or None if there was an error.""" 1122 1123 body = { 1124 "project": project, 1125 "itemType": item_type_id, 1126 "childItemType": child_item_type_id, 1127 "location": { 1128 "parent": location 1129 }, 1130 "fields": fields 1131 } 1132 resource_path = 'items/' 1133 params = {} 1134 1135 # we setting a global ID? 1136 if global_id is not None: 1137 body['globalId'] = global_id 1138 params['setGlobalIdManually'] = True 1139 1140 headers = {'content-type': 'application/json'} 1141 try: 1142 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers, params=params) 1143 except CoreException as err: 1144 py_jama_rest_client_logger.error(err) 1145 raise APIException(str(err)) 1146 JamaClient.__handle_response_status(response) 1147 return response.json()['meta']['id'] 1148 1149 def post_item_tag(self, item_id, tag_id): 1150 """ 1151 Add an existing tag to the item with the specified ID 1152 Args: 1153 item_id: The API ID of the item to add a tag. 1154 tag_id: The API ID of the tag to add to the item. 1155 1156 Returns: 201 if successful 1157 1158 """ 1159 body = { 1160 "tag": tag_id 1161 } 1162 resource_path = 'items/' + str(item_id) + '/tags' 1163 headers = {'content-type': 'application/json'} 1164 try: 1165 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1166 except CoreException as err: 1167 py_jama_rest_client_logger.error(err) 1168 raise APIException(str(err)) 1169 JamaClient.__handle_response_status(response) 1170 return response.status_code 1171 1172 def post_item_sync(self, source_item: int, pool_item: int): 1173 """ 1174 add an item to an existing pool of global ids 1175 Args: 1176 source_item: integer API ID of the source item, this item will adopt the global id of the 1177 pool_item. 1178 pool_item: integer API ID of the item in the target global ID pool. 1179 1180 Returns: the integer ID of the modified source item. 1181 """ 1182 body = { 1183 'item': source_item 1184 } 1185 1186 resource_path = 'items/' + str(pool_item) + '/synceditems' 1187 headers = {'content-type': 'application/json'} 1188 try: 1189 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1190 except CoreException as err: 1191 py_jama_rest_client_logger.error(err) 1192 raise APIException(str(err)) 1193 JamaClient.__handle_response_status(response) 1194 return response.json()['meta']['id'] 1195 1196 def post_relationship(self, from_item: int, to_item: int, relationship_type=None): 1197 """ 1198 1199 Args: 1200 from_item: integer API id of the source item 1201 to_item: integer API id of the target item 1202 relationship_type: Optional integer API id of the relationship type to create 1203 1204 Returns: The integer ID of the newly created relationship. 1205 1206 """ 1207 body = { 1208 "fromItem": from_item, 1209 "toItem": to_item, 1210 } 1211 if relationship_type is not None: 1212 body['relationshipType'] = relationship_type 1213 resource_path = 'relationships/' 1214 headers = {'content-type': 'application/json'} 1215 try: 1216 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1217 except CoreException as err: 1218 py_jama_rest_client_logger.error(err) 1219 raise APIException(str(err)) 1220 JamaClient.__handle_response_status(response) 1221 return response.json()['meta']['id'] 1222 1223 def put_relationship(self, relationship_id: int, from_item: int, to_item: int, relationship_type: int = None): 1224 """ 1225 1226 Args: 1227 relationship_id: integer API id of the relationship 1228 from_item: integer API id of the source item 1229 to_item: integer API id of the target item 1230 relationship_type: Optional integer API id of the relationship type to create 1231 1232 """ 1233 body = { 1234 "fromItem": from_item, 1235 "toItem": to_item 1236 } 1237 if relationship_type is not None: 1238 body['relationshipType'] = relationship_type 1239 resource_path = 'relationships/{}'.format(relationship_id) 1240 headers = {'content-type': 'application/json'} 1241 try: 1242 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1243 except CoreException as err: 1244 py_jama_rest_client_logger.error(err) 1245 raise APIException(str(err)) 1246 JamaClient.__handle_response_status(response) 1247 1248 def post_item_attachment(self, item_id, attachment_id): 1249 """ 1250 Add an existing attachment to the item with the specified ID 1251 :param item_id: this is the ID of the item 1252 :param attachment_id: The ID of the attachment 1253 :return: 201 if successful / the response status of the post operation 1254 """ 1255 body = {"attachment": attachment_id} 1256 resource_path = 'items/' + str(item_id) + '/attachments' 1257 headers = {'content-type': 'application/json'} 1258 try: 1259 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1260 except CoreException as err: 1261 py_jama_rest_client_logger.error(err) 1262 raise APIException(str(err)) 1263 JamaClient.__handle_response_status(response) 1264 return response.status_code 1265 1266 def post_project_attachment(self, project_id, name, description): 1267 """ 1268 This Method will make a new attachment object in the specified project 1269 :param project_id: The integer project ID to create the attachment in. 1270 :param name: The name of the attachment 1271 :param description: The description of the attachment 1272 :return: Returns the ID of the newly created attachment object. 1273 """ 1274 body = { 1275 "fields": { 1276 "name": name, 1277 "description": description 1278 } 1279 } 1280 1281 resource_path = 'projects/' + str(project_id) + '/attachments' 1282 headers = {'content-type': 'application/json'} 1283 try: 1284 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1285 except CoreException as err: 1286 py_jama_rest_client_logger.error(err) 1287 raise APIException(str(err)) 1288 JamaClient.__handle_response_status(response) 1289 return response.json()['meta']['id'] 1290 1291 def put_item(self, project, item_id, item_type_id, child_item_type_id, location, fields): 1292 """ This method wil 1293 PUT a new item to Jama Connect. 1294 :param project integer representing the project to which this item is to be posted 1295 :param item_id integer representing the item which is to be updated 1296 :param item_type_id integer ID of an Item Type. 1297 :param child_item_type_id integer ID of an Item Type. 1298 :param location dictionary with a key of 'item' or 'project' and an value with the ID of the parent 1299 :param fields dictionary item field data. 1300 :return integer ID of the successfully posted item or None if there was an error.""" 1301 1302 body = { 1303 "project": project, 1304 "itemType": item_type_id, 1305 "childItemType": child_item_type_id, 1306 "location": { 1307 "parent": location 1308 }, 1309 "fields": fields 1310 } 1311 resource_path = 'items/' + str(item_id) 1312 headers = {'content-type': 'application/json'} 1313 try: 1314 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1315 except CoreException as err: 1316 py_jama_rest_client_logger.error(err) 1317 raise APIException(str(err)) 1318 return self.__handle_response_status(response) 1319 1320 def put_attachments_file(self, attachment_id, file_path): 1321 """ 1322 Upload a file to a jama attachment 1323 :param attachment_id: the integer ID of the attachment item to which we are uploading the file 1324 :param file_path: the file path of the file to be uploaded 1325 :return: returns the status code of the call 1326 """ 1327 resource_path = 'attachments/' + str(attachment_id) + '/file' 1328 with open(file_path, 'rb') as f: 1329 files = {'file': f} 1330 try: 1331 response = self.__core.put(resource_path, files=files) 1332 except CoreException as err: 1333 py_jama_rest_client_logger.error(err) 1334 raise APIException(str(err)) 1335 self.__handle_response_status(response) 1336 return response.status_code 1337 1338 def put_user(self, user_id, username, password, first_name, last_name, email, phone=None, title=None, 1339 location=None): 1340 """ 1341 updates an existing user 1342 1343 Args: 1344 username: str 1345 password: str 1346 first_name: str 1347 last_name: str 1348 email: str 1349 phone: str - optional 1350 title: str - optional 1351 location: str - optional 1352 1353 Returns: api status code 1354 1355 """ 1356 1357 body = { 1358 'username': username, 1359 'password': password, 1360 'firstName': first_name, 1361 'lastName': last_name, 1362 'email': email, 1363 'phone': phone, 1364 'title': title, 1365 'location': location 1366 } 1367 resource_path = 'users/' + str(user_id) 1368 headers = {'content-type': 'application/json'} 1369 try: 1370 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1371 except CoreException as err: 1372 py_jama_rest_client_logger.error(err) 1373 raise APIException(str(err)) 1374 raise APIException 1375 return self.__handle_response_status(response) 1376 1377 def put_user_active(self, user_id, is_active): 1378 """ 1379 updates an existing users active status 1380 1381 Args: 1382 is_active: boolean 1383 1384 Returns: api status code 1385 1386 """ 1387 body = { 1388 'active': is_active 1389 } 1390 resource_path = 'users/' + str(user_id) + '/active' 1391 headers = {'content-type': 'application/json'} 1392 try: 1393 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1394 except CoreException as err: 1395 py_jama_rest_client_logger.error(err) 1396 raise APIException(str(err)) 1397 return self.__handle_response_status(response) 1398 1399 def put_test_run(self, test_run_id, data=None): 1400 """ This method will post a test run to Jama through the API""" 1401 resource_path = 'testruns/' + str(test_run_id) 1402 headers = {'content-type': 'application/json'} 1403 try: 1404 response = self.__core.put(resource_path, data=data, headers=headers) 1405 except CoreException as err: 1406 py_jama_rest_client_logger.error(err) 1407 raise APIException(str(err)) 1408 return self.__handle_response_status(response) 1409 1410 def __get_all(self, resource, params=None, allowed_results_per_page=__allowed_results_per_page, **kwargs): 1411 """This method will get all of the resources specified by the resource parameter, if an id or some other 1412 parameter is required for the resource, include it in the params parameter. 1413 Returns a single JSON array with all of the retrieved items.""" 1414 1415 if allowed_results_per_page < 1 or allowed_results_per_page > 50: 1416 raise ValueError("Allowed results per page must be between 1 and 50") 1417 1418 start_index = 0 1419 allowed_results_per_page = 20 1420 total_results = float("inf") 1421 1422 data = [] 1423 1424 while len(data) < total_results: 1425 page_response = self.__get_page(resource, start_index, params=params, **kwargs) 1426 page_json = page_response.json() 1427 1428 page_info = page_json['meta']['pageInfo'] 1429 start_index = page_info['startIndex'] + allowed_results_per_page 1430 total_results = page_info.get('totalResults') 1431 page_data = page_json.get('data') 1432 data.extend(page_data) 1433 1434 return data 1435 1436 def __get_page(self, resource, start_at, params=None, allowed_results_per_page=__allowed_results_per_page, **kwargs): 1437 """This method will return one page of results from the specified resource type. 1438 Pass any needed parameters along 1439 The response object will be returned""" 1440 parameters = { 1441 'startAt': start_at, 1442 'maxResults': allowed_results_per_page 1443 } 1444 1445 if params is not None: 1446 for k, v in params.items(): 1447 parameters[k] = v 1448 1449 try: 1450 response = self.__core.get(resource, params=parameters, **kwargs) 1451 except CoreException as err: 1452 py_jama_rest_client_logger.error(err) 1453 raise APIException(str(err)) 1454 JamaClient.__handle_response_status(response) 1455 return response 1456 1457 @staticmethod 1458 def __handle_response_status(response): 1459 """ Utility method for checking http status codes. 1460 If the response code is not in the 200 range, An exception will be thrown.""" 1461 1462 status = response.status_code 1463 1464 if status in range(200, 300): 1465 return status 1466 1467 if status in range(400, 500): 1468 """These are client errors. It is likely that something is wrong with the request.""" 1469 1470 response_message = 'No Response' 1471 1472 try: 1473 response_json = json.loads(response.text) 1474 response_message = response_json.get('meta').get('message') 1475 1476 except json.JSONDecodeError: 1477 pass 1478 1479 # Log the error 1480 py_jama_rest_client_logger.error('API Client Error. Status: {} Message: {}'.format(status, 1481 response_message)) 1482 1483 if response_message is not None and "already exists" in response_message: 1484 raise AlreadyExistsException("Entity already exists.", 1485 status_code=status, 1486 reason=response_message) 1487 1488 if status == 401: 1489 raise UnauthorizedException("Unauthorized: check credentials and permissions. " 1490 "API response message {}".format(response_message), 1491 status_code=status, 1492 reason=response_message) 1493 1494 if status == 404: 1495 raise ResourceNotFoundException("Resource not found. check host url.", 1496 status_code=status, 1497 reason=response_message) 1498 1499 if status == 429: 1500 raise TooManyRequestsException("Too many requests. API throttling limit reached, or system under " 1501 "maintenance.", 1502 status_code=status, 1503 reason=response_message) 1504 1505 raise APIClientException("{} {} Client Error. Bad Request. " 1506 "API response message: {}".format(status, response.reason, response_message), 1507 status_code=status, 1508 reason=response_message) 1509 1510 if status in range(500, 600): 1511 """These are server errors and network errors.""" 1512 1513 # Log The Error 1514 py_jama_rest_client_logger.error('{} Server error. {}'.format(status, response.reason)) 1515 raise APIServerException("{} Server Error.".format(status), 1516 status_code=status, 1517 reason=response.reason) 1518 1519 # Catch anything unexpected 1520 py_jama_rest_client_logger.error('{} error. {}'.format(status, response.reason)) 1521 raise APIException("{} error".format(status), 1522 status_code=status, 1523 reason=response.reason) 1524 1525 def set_allowed_results_per_page(self, allowed_results_per_page): 1526 self.__allowed_results_per_page = allowed_results_per_page 1527 1528 def get_allowed_results_per_page(self): 1529 return self.__allowed_results_per_page
11class APIException(Exception): 12 """This is the base class for all exceptions raised by the JamaClient""" 13 14 def __init__(self, message, status_code=None, reason=None): 15 super(APIException, self).__init__(message) 16 self.status_code = status_code 17 self.reason = reason
This is the base class for all exceptions raised by the JamaClient
Inherited Members
- builtins.BaseException
- with_traceback
25class TooManyRequestsException(APIException): 26 """This exception is thrown whenever the api returns a 429 too many requests response.""" 27 pass
This exception is thrown whenever the api returns a 429 too many requests response.
Inherited Members
- builtins.BaseException
- with_traceback
30class ResourceNotFoundException(APIException): 31 """This exception is raised whenever the api returns a 404 not found response.""" 32 pass
This exception is raised whenever the api returns a 404 not found response.
Inherited Members
- builtins.BaseException
- with_traceback
35class AlreadyExistsException(APIException): 36 """This exception is thrown when the API returns a 400 response with a message that the resource already exists.""" 37 pass
This exception is thrown when the API returns a 400 response with a message that the resource already exists.
Inherited Members
- builtins.BaseException
- with_traceback
40class APIClientException(APIException): 41 """This exception is thrown whenever a unknown 400 error is encountered.""" 42 pass
This exception is thrown whenever a unknown 400 error is encountered.
Inherited Members
- builtins.BaseException
- with_traceback
45class APIServerException(APIException): 46 """This exception is thrown whenever an unknown 500 response is encountered.""" 47 pass
This exception is thrown whenever an unknown 500 response is encountered.
Inherited Members
- builtins.BaseException
- with_traceback
50class JamaClient: 51 """A class to abstract communication with the Jama Connect API""" 52 53 __allowed_results_per_page = 20 # Default is 20, Max is 50. if set to greater than 50, only 50 will items return. 54 55 def __init__(self, host_domain, 56 credentials=('username|clientID', 'password|clientSecret'), 57 api_version='/rest/v1/', 58 oauth=False, 59 verify=True, 60 allowed_results_per_page=20): 61 """Jama Client initializer 62 :rtype: JamaClient 63 :param host_domain: String The domain associated with the Jama Connect host 64 :param credentials: the user name and password as a tuple or client id and client secret if using Oauth. 65 :param api_version: valid args are '/rest/[v1|latest|labs]/' 66 :param verify: Defaults to True, Setting this to False will skip SSL Certificate verification""" 67 self.__credentials = credentials 68 self.__allowed_results_per_page = allowed_results_per_page 69 try: 70 self.__core = Core(host_domain, credentials, api_version=api_version, oauth=oauth, verify=verify) 71 except CoreException as err: 72 py_jama_rest_client_logger.error(err) 73 raise APIException(str(err)) 74 75 # Log client creation 76 py_jama_rest_client_logger.info('Created a new JamaClient instance. Domain: {} ' 77 'Connecting via Oauth: {}'.format(host_domain, oauth)) 78 79 def get_available_endpoints(self): 80 """ 81 Returns a list of all the available endpoints. 82 83 Returns: an array of available endpoints for this API 84 85 """ 86 try: 87 response = self.__core.get('') 88 except CoreException as err: 89 py_jama_rest_client_logger.error(err) 90 raise APIException(str(err)) 91 JamaClient.__handle_response_status(response) 92 return response.json()['data'] 93 94 def get_baselines(self, project_id, allowed_results_per_page=__allowed_results_per_page): 95 """ 96 Returns a list of Baseline objects 97 Args: 98 project_id: the Id of the project to fetch baselines for 99 allowed_results_per_page: number of results per page 100 101 Returns: a list of Baseline objects 102 """ 103 resource_path = 'baselines' 104 params = {'project': project_id} 105 baseline_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 106 return baseline_data 107 108 def get_baseline(self, baseline_id): 109 """ 110 This method will return a baseline 111 Args: 112 baseline_id: the id of the baseline to fetch 113 114 Returns: a dictionary object representing the baseline 115 116 """ 117 resource_path = 'baselines/' + str(baseline_id) 118 try: 119 response = self.__core.get(resource_path) 120 except CoreException as err: 121 py_jama_rest_client_logger.error(err) 122 raise APIException(str(err)) 123 JamaClient.__handle_response_status(response) 124 return response.json()['data'] 125 126 def get_baselines_versioneditems(self, baseline_id, allowed_results_per_page=__allowed_results_per_page): 127 """ 128 Get all baseline items in a baseline with the specified ID 129 Args: 130 baseline_id: The id of the baseline to fetch items for. 131 allowed_results_per_page: Number of results per page 132 Returns: A list of versioned items belonging to the baseline 133 """ 134 resource_path = 'baselines/' + str(baseline_id) + '/versioneditems' 135 baseline_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 136 return baseline_items 137 138 def get_projects(self, allowed_results_per_page=__allowed_results_per_page): 139 """This method will return all projects as JSON object 140 :return: JSON Array of Item Objects. 141 """ 142 resource_path = 'projects' 143 project_data = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 144 return project_data 145 146 def get_filter_results(self, filter_id, project_id=None, allowed_results_per_page=__allowed_results_per_page): 147 """ 148 Get all results items for the filter with the specified ID 149 150 Args: 151 filter_id: The ID of the filter to fetch the results for. 152 project_id: Use this only for filters that run on any project, where projectScope is CURRENT 153 allowed_results_per_page: Number of results per page 154 155 Returns: 156 A List of items that match the filter. 157 158 """ 159 resource_path = 'filters/' + str(filter_id) + '/results' 160 params = None 161 if project_id is not None: 162 params = {'project': str(project_id)} 163 filter_results = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 164 return filter_results 165 166 def get_items(self, project_id, allowed_results_per_page=__allowed_results_per_page): 167 """ 168 This method will return all items in the specified project. 169 Args: 170 project_id: the project ID 171 allowed_results_per_page: number of results per page 172 173 Returns: a Json array of item objects 174 175 """ 176 resource_path = 'items' 177 params = {'project': project_id} 178 item_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 179 return item_data 180 181 def get_item(self, item_id): 182 """ 183 This method will return a singular item of a specified item id 184 Args: 185 item_id: the item id of the item to fetch 186 187 Returns: a dictonary object representing the item 188 189 """ 190 resource_path = 'items/' + str(item_id) 191 try: 192 response = self.__core.get(resource_path) 193 except CoreException as err: 194 py_jama_rest_client_logger.error(err) 195 raise APIException(str(err)) 196 JamaClient.__handle_response_status(response) 197 return response.json()['data'] 198 199 def get_item_lock(self, item_id): 200 """ 201 Get the locked state, last locked date, and last locked by user for the item with the specified ID 202 Args: 203 item_id: The API ID of the item to get the lock info for. 204 205 Returns: 206 A JSON object with the lock information for the item with the specified ID. 207 208 """ 209 resource_path = 'items/' + str(item_id) + '/lock' 210 try: 211 response = self.__core.get(resource_path) 212 except CoreException as err: 213 py_jama_rest_client_logger.error(err) 214 raise APIException(str(err)) 215 JamaClient.__handle_response_status(response) 216 return response.json()['data'] 217 218 def put_item_lock(self, item_id, locked): 219 """ 220 Update the locked state of the item with the specified ID 221 Args: 222 item_id: the API id of the item to be updated 223 locked: boolean lock state to apply to this item 224 225 Returns: 226 response status 200 227 228 """ 229 body = { 230 "locked": locked, 231 } 232 resource_path = 'items/' + str(item_id) + '/lock' 233 headers = {'content-type': 'application/json'} 234 try: 235 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 236 except CoreException as err: 237 py_jama_rest_client_logger.error(err) 238 raise APIException(str(err)) 239 return self.__handle_response_status(response) 240 241 def get_item_tags(self, item_id, allowed_results_per_page=__allowed_results_per_page): 242 """ 243 Return all tags for the item with the specified ID 244 245 Args: 246 item_id: the item id of the item to fetch 247 allowed_results_per_page: number of results 248 249 Returns: a dictionary object representing the item's tags 250 251 """ 252 resource_path = 'items/' + str(item_id) + '/tags' 253 item_tags = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 254 return item_tags 255 256 def get_attachment(self, attachment_id): 257 """ 258 This method will return a singular attachment of a specified attachment id 259 Args: 260 attachment_id: the attachment id of the attachment to fetch 261 262 Returns: a dictonary object representing the attachment 263 264 """ 265 resource_path = 'attachments/' + str(attachment_id) 266 try: 267 response = self.__core.get(resource_path) 268 except CoreException as err: 269 py_jama_rest_client_logger.error(err) 270 raise APIException(str(err)) 271 JamaClient.__handle_response_status(response) 272 return response.json()['data'] 273 274 def get_abstract_items_from_doc_key(self, doc_key_list, allowed_results_per_page=__allowed_results_per_page): 275 """ DEPRECATED INSTEAD USE get_abstract_items below. 276 This method will take in a list of document keys and return an array of JSON Objects associated with the 277 document keys.""" 278 resource_path = 'abstractitems' 279 params = {'documentKey': doc_key_list} 280 abstract_items = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 281 return abstract_items 282 283 def get_relationship_rule_sets(self): 284 """ 285 This method will return all relationship rule sets across all projects of the Jama Connect instance. 286 287 Returns: An array of dictionary objects representing a rule set and its associated rules 288 289 """ 290 resource_path = 'relationshiprulesets/' 291 rule_sets = self.__get_all(resource_path) 292 return rule_sets 293 294 def get_relationship_rule_set(self, id): 295 """ 296 This method will return the relationship rule sets by id. 297 298 Returns: A dictionary object representing a rule set and its associated rules 299 300 """ 301 resource_path = 'relationshiprulesets/' + str(id) 302 response = self.__core.get(resource_path) 303 JamaClient.__handle_response_status(response) 304 return response.json()['data'] 305 306 def get_relationship_rule_set_projects(self, id): 307 """ 308 This method will return the projects that have a given relationship rule set defined. 309 310 Returns: An array of the dictionary objects representing the projects with a given rule set assigned 311 312 """ 313 resource_path = 'relationshiprulesets/' + str(id) + '/projects' 314 projects = self.__get_all(resource_path) 315 return projects 316 317 def get_relationship_types(self, allowed_results_per_page=__allowed_results_per_page): 318 """ 319 This method will return all relationship types of the across all projects of the Jama Connect instance. 320 321 Args: 322 allowed_results_per_page: Number of results per page 323 324 Returns: An array of dictionary objects 325 326 """ 327 resource_path = 'relationshiptypes/' 328 item_types = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 329 return item_types 330 331 def get_relationship_type(self, relationship_type_id): 332 """ 333 Gets relationship type information for a specific relationship type id. 334 335 Args: 336 relationship_type_id: The api id of the item type to fetch 337 338 Returns: JSON object 339 340 """ 341 resource_path = 'relationshiptypes/' + str(relationship_type_id) 342 try: 343 response = self.__core.get(resource_path) 344 except CoreException as err: 345 py_jama_rest_client_logger.error(err) 346 raise APIException(str(err)) 347 JamaClient.__handle_response_status(response) 348 return response.json()['data'] 349 350 def get_item_types(self, allowed_results_per_page=__allowed_results_per_page): 351 """ 352 This method will return all item types of the across all projects of the Jama Connect instance. 353 354 Args: 355 allowed_results_per_page: Number of results per page 356 357 Returns: An array of dictionary objects 358 359 """ 360 resource_path = 'itemtypes/' 361 item_types = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 362 return item_types 363 364 def get_item_type(self, item_type_id): 365 """ 366 Gets item type information for a specific item type id. 367 368 Args: 369 item_type_id: The api id of the item type to fetch 370 371 Returns: JSON object 372 373 """ 374 resource_path = 'itemtypes/' + str(item_type_id) 375 try: 376 response = self.__core.get(resource_path) 377 except CoreException as err: 378 py_jama_rest_client_logger.error(err) 379 raise APIException(str(err)) 380 JamaClient.__handle_response_status(response) 381 return response.json()['data'] 382 383 def get_items_synceditems(self, item_id, allowed_results_per_page=__allowed_results_per_page): 384 """ 385 Get all synchronized items for the item with the specified ID 386 387 Args: 388 item_id: The API id of the item being 389 allowed_results_per_page: Number of results per page 390 391 Returns: A list of JSON Objects representing the items that are in the same synchronization group as the 392 specified item. 393 394 """ 395 resource_path = 'items/' + str(item_id) + '/synceditems' 396 synced_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 397 return synced_items 398 399 def get_items_synceditems_status(self, item_id, synced_item_id): 400 """ 401 Get the sync status for the synced item with the specified ID 402 403 Args: 404 item_id: The id of the item to compare against 405 synced_item_id: the id of the item to check if it is in sync 406 407 Returns: The response JSON from the API which contains a single field 'inSync' with a boolean value. 408 409 """ 410 resource_path = 'items/' + str(item_id) + '/synceditems/' + str(synced_item_id) + '/syncstatus' 411 try: 412 response = self.__core.get(resource_path) 413 except CoreException as err: 414 py_jama_rest_client_logger.error(err) 415 raise APIException(str(err)) 416 JamaClient.__handle_response_status(response) 417 return response.json()['data'] 418 419 def get_item_versions(self, item_id): 420 """ 421 Get all versions for the item with the specified ID 422 423 Args: 424 item_id: the item id of the item to fetch 425 426 Returns: JSON array with all versions for the item 427 """ 428 resource_path = 'items/' + str(item_id) + '/versions' 429 versions = self.__get_all(resource_path) 430 return versions 431 432 def get_item_version(self, item_id, version_num): 433 """ 434 Get the numbered version for the item with the specified ID 435 436 Args: 437 item_id: the item id of the item to fetch 438 version_num: the version number for the item 439 440 Returns: a dictionary object representing the numbered version 441 """ 442 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) 443 try: 444 response = self.__core.get(resource_path) 445 except CoreException as err: 446 py_jama_rest_client_logger.error(err) 447 raise APIException(str(err)) 448 JamaClient.__handle_response_status(response) 449 return response.json()['data'] 450 451 def get_versioned_item(self, item_id, version_num): 452 """ 453 Get the snapshot of the item at the specified version 454 455 Args: 456 item_id: the item id of the item to fetch 457 version_num: the version number for the item 458 459 Returns: a dictionary object representing the versioned item 460 """ 461 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 462 try: 463 response = self.__core.get(resource_path) 464 except CoreException as err: 465 py_jama_rest_client_logger.error(err) 466 raise APIException(str(err)) 467 JamaClient.__handle_response_status(response) 468 return response.json()['data'] 469 470 def get_item_versions(self, item_id, allowed_results_per_page=__allowed_results_per_page): 471 """ 472 Get all versions for the item with the specified ID 473 474 Args: 475 item_id: the item id of the item to fetch 476 allowed_results_per_page: number of results per page 477 478 Returns: JSON array with all versions for the item 479 """ 480 resource_path = 'items/' + str(item_id) + '/versions' 481 versions = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 482 return versions 483 484 def get_item_version(self, item_id, version_num): 485 """ 486 Get the numbered version for the item with the specified ID 487 488 Args: 489 item_id: the item id of the item to fetch 490 version_num: the version number for the item 491 492 Returns: a dictionary object representing the numbered version 493 """ 494 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) 495 response = self.__core.get(resource_path) 496 JamaClient.__handle_response_status(response) 497 return response.json()['data'] 498 499 def get_versioned_item(self, item_id, version_num): 500 """ 501 Get the snapshot of the item at the specified version 502 503 Args: 504 item_id: the item id of the item to fetch 505 version_num: the version number for the item 506 507 Returns: a dictionary object representing the versioned item 508 """ 509 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 510 response = self.__core.get(resource_path) 511 JamaClient.__handle_response_status(response) 512 return response.json()['data'] 513 514 def get_pick_lists(self, allowed_results_per_page=__allowed_results_per_page): 515 """ 516 Returns a list of all the pick lists 517 518 Args: 519 allowed_results_per_page: number of results per page 520 521 Returns: an array of dictionary objects 522 523 """ 524 resource_path = 'picklists/' 525 pick_lists = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 526 return pick_lists 527 528 def get_pick_list(self, pick_list_id): 529 """ 530 Gets all a singular picklist 531 532 Args: 533 pick_list_id: The API id of the pick list to fetch 534 535 Returns: a dictionary object representing the picklist. 536 537 """ 538 resource_path = 'picklists/' + str(pick_list_id) 539 try: 540 response = self.__core.get(resource_path) 541 except CoreException as err: 542 py_jama_rest_client_logger.error(err) 543 raise APIException(str(err)) 544 JamaClient.__handle_response_status(response) 545 return response.json()['data'] 546 547 def get_pick_list_options(self, pick_list_id, allowed_results_per_page=__allowed_results_per_page): 548 """ 549 Gets all all the picklist options for a single picklist 550 Args: 551 pick_list_id: the api id of the picklist to fetch options for. 552 allowed_results_per_page: number of results per page 553 554 Returns: an array of dictionary objects that represent the picklist options. 555 556 """ 557 resource_path = 'picklists/' + str(pick_list_id) + '/options' 558 pick_list_options = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 559 return pick_list_options 560 561 def get_pick_list_option(self, pick_list_option_id): 562 """ 563 Fetches a single picklist option from the API 564 Args: 565 pick_list_option_id: The API ID of the picklist option to fetch 566 567 Returns: A dictonary object representing the picklist option. 568 569 """ 570 resource_path = 'picklistoptions/' + str(pick_list_option_id) 571 try: 572 response = self.__core.get(resource_path) 573 except CoreException as err: 574 py_jama_rest_client_logger.error(err) 575 raise APIException(str(err)) 576 JamaClient.__handle_response_status(response) 577 return response.json()['data'] 578 579 def get_relationships(self, project_id, allowed_results_per_page=__allowed_results_per_page): 580 """ 581 Returns a list of all relationships of a specified project 582 583 Args: 584 project_id: the api project id of a project 585 allowed_results_per_page: number of results per page 586 587 Returns: a list of dictionary objects that represents a relationships 588 589 """ 590 resource_path = 'relationships' 591 params = {'project': project_id} 592 relationship_data = self.__get_all(resource_path, params=params, 593 allowed_results_per_page=allowed_results_per_page) 594 return relationship_data 595 596 def get_relationship(self, relationship_id): 597 """ 598 Returns a specific relationship object of a specified relationship ID 599 600 Args: 601 relationship_id: the api project id of a relationship 602 603 Returns: a dictionary object that represents a relationship 604 605 """ 606 resource_path = 'relationships/' + str(relationship_id) 607 try: 608 response = self.__core.get(resource_path) 609 except CoreException as err: 610 py_jama_rest_client_logger.error(err) 611 raise APIException(str(err)) 612 JamaClient.__handle_response_status(response) 613 return response.json()['data'] 614 615 def get_abstract_items(self, 616 project=None, 617 item_type=None, 618 document_key=None, 619 release=None, 620 created_date=None, 621 modified_date=None, 622 last_activity_date=None, 623 contains=None, 624 sort_by=None): 625 """ 626 This method will return all items that match the query parameters entered. 627 628 Args: 629 project: Array[integer] 630 item_type: Array[integer] 631 document_key: Array[string] 632 release: Array[integer] 633 created_date: Array[string] 634 modified_date: Array[string] 635 last_activity_date: Array[string] 636 contains: Array[string] 637 sort_by: Array[string] 638 639 Returns: 640 A JSON Array of items. 641 642 """ 643 resource_path = 'abstractitems' 644 645 # Add each parameter that is not null to the request. 646 params = {} 647 648 if project is not None: 649 params['project'] = project 650 651 if item_type is not None: 652 params['itemType'] = item_type 653 654 if document_key is not None: 655 params['documentKey'] = document_key 656 657 if release is not None: 658 params['release'] = release 659 660 if created_date is not None: 661 params['createdDate'] = created_date 662 663 if modified_date is not None: 664 params['modifiedDate'] = modified_date 665 666 if last_activity_date is not None: 667 params['lastActivityDate'] = last_activity_date 668 669 if contains is not None: 670 params['contains'] = contains 671 672 if sort_by is not None: 673 params['sortBy'] = sort_by 674 675 abstract_items = self.__get_all(resource_path, params=params) 676 return abstract_items 677 678 def get_abstract_item(self, item_id): 679 """ 680 This method will return an item, test plan, test cycle, test run, or attachment with the specified ID 681 Args: 682 item_id: the item id of the item to fetch 683 684 Returns: a dictonary object representing the abstract item 685 686 """ 687 resource_path = 'abstractitems/' + str(item_id) 688 try: 689 response = self.__core.get(resource_path) 690 except CoreException as err: 691 py_jama_rest_client_logger.error(err) 692 raise APIException(str(err)) 693 JamaClient.__handle_response_status(response) 694 return response.json()['data'] 695 696 def get_abstract_item_versions(self, item_id): 697 """ 698 Get all versions for the item with the specified ID 699 700 Args: 701 item_id: the item id of the item to fetch 702 703 Returns: JSON array with all versions for the item 704 """ 705 resource_path = 'abstractitems/' + str(item_id) + '/versions' 706 versions = self.__get_all(resource_path) 707 return versions 708 709 def get_abtract_item_version(self, item_id, version_num): 710 """ 711 Get the numbered version for the item with the specified ID 712 713 Args: 714 item_id: the item id of the item to fetch 715 version_num: the version number for the item 716 717 Returns: a dictionary object representing the numbered version 718 """ 719 resource_path = 'abstractitems/' + str(item_id) + '/versions/' + str(version_num) 720 try: 721 response = self.__core.get(resource_path) 722 except CoreException as err: 723 py_jama_rest_client_logger.error(err) 724 raise APIException(str(err)) 725 JamaClient.__handle_response_status(response) 726 return response.json()['data'] 727 728 def get_abstract_versioned_item(self, item_id, version_num): 729 """ 730 Get the snapshot of the item at the specified version 731 732 Args: 733 item_id: the item id of the item to fetch 734 version_num: the version number for the item 735 736 Returns: a dictionary object representing the versioned item 737 """ 738 resource_path = 'abstractitems/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 739 try: 740 response = self.__core.get(resource_path) 741 except CoreException as err: 742 py_jama_rest_client_logger.error(err) 743 raise APIException(str(err)) 744 JamaClient.__handle_response_status(response) 745 return response.json()['data'] 746 747 748 def get_item_children(self, item_id, allowed_results_per_page=__allowed_results_per_page): 749 """ 750 This method will return list of the child items of the item passed to the function. 751 Args: 752 item_id: (int) The id of the item for which children items should be fetched 753 allowed_results_per_page: Number of results per page 754 755 Returns: a List of Objects that represent the children of the item passed in. 756 """ 757 resource_path = 'items/' + str(item_id) + '/children' 758 child_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 759 return child_items 760 761 def get_testruns(self, test_cycle_id, allowed_results_per_page=__allowed_results_per_page): 762 """This method will return all test runs associated with the specified test cycle. Test runs will be returned 763 as a list of json objects.""" 764 resource_path = 'testcycles/' + str(test_cycle_id) + '/testruns' 765 testrun_data = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 766 return testrun_data 767 768 def get_items_upstream_relationships(self, item_id, allowed_results_per_page=__allowed_results_per_page): 769 """ 770 Returns a list of all the upstream relationships for the item with the specified ID. 771 Args: 772 item_id: the api id of the item 773 allowed_results_per_page: number of results per page 774 775 Returns: an array of dictionary objects that represent the upstream relationships for the item. 776 777 """ 778 resource_path = 'items/' + str(item_id) + '/upstreamrelationships' 779 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 780 781 def get_items_downstream_related(self, item_id, allowed_results_per_page=__allowed_results_per_page): 782 """ 783 Returns a list of all the downstream related items for the item with the specified ID. 784 785 Args: 786 item_id: the api id of the item to fetch downstream items for 787 allowed_results_per_page: number of results per page 788 789 Returns: an array of dictionary objects that represent the downstream related items for the specified item. 790 791 """ 792 resource_path = 'items/' + str(item_id) + '/downstreamrelated' 793 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 794 795 def get_items_downstream_relationships(self, item_id, allowed_results_per_page=__allowed_results_per_page): 796 """ 797 Returns a list of all the downstream relationships for the item with the specified ID. 798 799 Args: 800 item_id: the api id of the item 801 802 Returns: an array of dictionary objects that represent the downstream relationships for the item. 803 804 """ 805 resource_path = 'items/' + str(item_id) + '/downstreamrelationships' 806 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 807 808 def get_items_upstream_related(self, item_id): 809 """ 810 Returns a list of all the upstream related items for the item with the specified ID. 811 812 Args: 813 item_id: the api id of the item to fetch upstream items for 814 815 Returns: an array of dictionary objects that represent the upstream related items for the specified item. 816 817 """ 818 resource_path = 'items/' + str(item_id) + '/upstreamrelated' 819 return self.__get_all(resource_path) 820 821 def get_item_workflow_transitions(self, item_id): 822 """ 823 Get all valid workflow transitions that can be made with the specified id 824 825 Args: 826 item_id: the api id of the item 827 allowed_results_per_page: number of results per page 828 829 Returns: an array of dictionary objects that represent the workflow transitions for the item. 830 831 """ 832 resource_path = 'items/' + str(item_id) + '/workflowtransitionoptions' 833 return self.__get_all(resource_path) 834 835 def get_tags(self, project, allowed_results_per_page=__allowed_results_per_page): 836 """ 837 Get all tags for the project with the specified id 838 Args: 839 project: The API ID of the project to fetch tags for. 840 allowed_results_per_page: Number of results per page 841 842 Returns: A Json Array that contains all the tag data for the specified project. 843 844 """ 845 resource_path = 'tags' 846 params = {'project': project} 847 tag_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 848 return tag_data 849 850 def get_tagged_items(self, tag_id, allowed_results_per_page=__allowed_results_per_page): 851 """ 852 Get all items tagged with the specified ID 853 854 Args: 855 tag_id: The ID of the tag to fetch the results for. 856 allowed_results_per_page: Number of results per page 857 858 Returns: 859 A List of items that match the tag. 860 861 """ 862 resource_path = 'tags/' + str(tag_id) + '/items' 863 params = None 864 tag_results = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 865 return tag_results 866 867 def get_users(self, allowed_results_per_page=__allowed_results_per_page): 868 """ 869 Gets a list of all active users visible to the current user 870 871 Args: 872 allowed_results_per_page: Number of results per page 873 874 Returns: JSON array 875 876 """ 877 resource_path = 'users/' 878 users = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 879 return users 880 881 def get_user(self, user_id): 882 """ 883 Gets a single speificed user 884 885 Args: 886 user_id: user api ID 887 888 Returns: JSON obect 889 890 """ 891 resource_path = 'users/' + str(user_id) 892 try: 893 response = self.__core.get(resource_path) 894 except CoreException as err: 895 py_jama_rest_client_logger.error(err) 896 raise APIException(str(err)) 897 return response.json()['data'] 898 899 def get_current_user(self): 900 """ 901 Gets a current user 902 903 Returns: JSON obect 904 905 """ 906 resource_path = 'users/current' 907 try: 908 response = self.__core.get(resource_path) 909 except CoreException as err: 910 py_jama_rest_client_logger.error(err) 911 raise APIException(str(err)) 912 return response.json()['data'] 913 914 def get_test_cycle(self, test_cycle_id): 915 """ 916 This method will return JSON data about the test cycle specified by the test cycle id. 917 918 Args: 919 test_cycle_id: the api id of the test cycle to fetch 920 921 Returns: a dictionary object that represents the test cycle 922 923 """ 924 resource_path = 'testcycles/' + str(test_cycle_id) 925 try: 926 response = self.__core.get(resource_path) 927 except CoreException as err: 928 py_jama_rest_client_logger.error(err) 929 raise APIException(str(err)) 930 JamaClient.__handle_response_status(response) 931 return response.json()['data'] 932 933 def delete_item(self, item_id): 934 """ 935 This method will delete an item in Jama Connect. 936 937 Args: 938 item_id: The jama connect API ID of the item to be deleted 939 940 Returns: The success status code. 941 """ 942 resource_path = 'items/' + str(item_id) 943 try: 944 response = self.__core.delete(resource_path) 945 except CoreException as err: 946 py_jama_rest_client_logger.error(err) 947 raise APIException(str(err)) 948 JamaClient.__handle_response_status(response) 949 return response.status_code 950 951 def delete_relationships(self, relationship_id): 952 """ 953 Deletes a relationship with the specified relationship ID 954 955 Args: 956 relationship_id: the api project id of a relationship 957 958 Returns: The success status code. 959 960 """ 961 resource_path = 'relationships/' + str(relationship_id) 962 try: 963 response = self.__core.delete(resource_path) 964 except CoreException as err: 965 py_jama_rest_client_logger.error(err) 966 raise APIException(str(err)) 967 JamaClient.__handle_response_status(response) 968 return response.status_code 969 970 def patch_item(self, item_id, patches): 971 """ 972 This method will patch an item. 973 Args: 974 item_id: the API ID of the item that is to be patched 975 patches: An array of dicts, that represent patch operations each dict should have the following entries 976 [ 977 { 978 "op": string, 979 "path": string, 980 "value": {} 981 } 982 ] 983 984 Returns: The response status code 985 986 """ 987 resource_path = 'items/' + str(item_id) 988 headers = {'Content-Type': 'application/json', 989 'Accept': 'application/json' 990 } 991 data = json.dumps(patches) 992 993 # Make the API Call 994 try: 995 response = self.__core.patch(resource_path, data=data, headers=headers) 996 except CoreException as err: 997 py_jama_rest_client_logger.error(err) 998 raise APIException(str(err)) 999 1000 # validate response 1001 JamaClient.__handle_response_status(response) 1002 return response.json()['meta']['status'] 1003 1004 def post_user(self, username, password, first_name, last_name, email, license_type, phone=None, title=None, 1005 location=None): 1006 """ 1007 Creates a new user 1008 1009 Args: 1010 username: str 1011 password: str 1012 first_name: str 1013 last_name: str 1014 email: str 1015 phone: str - optional 1016 title: str - optional 1017 location: str - optional 1018 licenseType: enum [ NAMED, FLOATING, STAKEHOLDER, FLOATING_COLLABORATOR, RESERVED_COLLABORATOR, FLOATING_REVIEWER, RESERVED_REVIEWER, NAMED_REVIEWER, TEST_RUNNER, EXPIRING_TRIAL, INACTIVE ] 1019 1020 Returns: int of newly created user api ID 1021 1022 """ 1023 1024 body = { 1025 'username': username, 1026 'password': password, 1027 'firstName': first_name, 1028 'lastName': last_name, 1029 'email': email, 1030 'phone': phone, 1031 'title': title, 1032 'location': location, 1033 'licenseType': license_type 1034 } 1035 resource_path = 'users/' 1036 headers = {'content-type': 'application/json'} 1037 try: 1038 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1039 except CoreException as err: 1040 py_jama_rest_client_logger.error(err) 1041 raise APIException(str(err)) 1042 JamaClient.__handle_response_status(response) 1043 return response.json()['meta']['id'] 1044 1045 def post_tag(self, name: str, project: int): 1046 """ 1047 Create a new tag in the project with the specified ID 1048 Args: 1049 name: The display name for the tag 1050 project: The project to create the new tag in 1051 1052 Returns: The integer API ID fr the newly created Tag. 1053 """ 1054 resource_path = 'tags' 1055 body = { 1056 'name': name, 1057 'project': project 1058 } 1059 headers = {'content-type': 'application/json'} 1060 try: 1061 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1062 except CoreException as err: 1063 py_jama_rest_client_logger.error(err) 1064 raise APIException(str(err)) 1065 JamaClient.__handle_response_status(response) 1066 return response.json()['meta']['id'] 1067 1068 def post_testplans_testcycles(self, testplan_id, testcycle_name, start_date, end_date, testgroups_to_include=None, 1069 testrun_status_to_include=None): 1070 """ 1071 This method will create a new Test Cycle. 1072 1073 Args: 1074 testplan_id (int): The API_ID of the testplan to create the test cycle from. 1075 testcycle_name (str): The name you would like to set for the new Test Cycle 1076 start_date (str): Start date in 'yyyy-mm-dd' Format 1077 end_date (str): End date in 'yyyy-mm-dd' Format 1078 testgroups_to_include (int[]): This array of integers specify the test groups to be included. 1079 testrun_status_to_include (str[]): Only valid after generating the first Test Cycle, you may choose to only 1080 generate Test Runs that were a specified status in the previous cycle. Do not specify anything to 1081 include all statuses 1082 1083 Returns: 1084 (int): Returns the integer id for the newly created testcycle, or None if something went terribly wrong. 1085 """ 1086 resource_path = 'testplans/' + str(testplan_id) + '/testcycles' 1087 headers = {'content-type': 'application/json'} 1088 fields = { 1089 'name': testcycle_name, 1090 'startDate': start_date, 1091 'endDate': end_date 1092 } 1093 test_run_gen_config = {} 1094 if testgroups_to_include is not None: 1095 test_run_gen_config['testGroupsToInclude'] = testgroups_to_include 1096 if testrun_status_to_include is not None: 1097 test_run_gen_config['testRunStatusesToInclude'] = testrun_status_to_include 1098 body = { 1099 'fields': fields, 1100 'testRunGenerationConfig': test_run_gen_config 1101 } 1102 1103 # Make the API Call 1104 try: 1105 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1106 except CoreException as err: 1107 py_jama_rest_client_logger.error(err) 1108 raise APIException(str(err)) 1109 1110 # Validate response 1111 JamaClient.__handle_response_status(response) 1112 return response.json()['meta']['id'] 1113 1114 def post_item(self, project, item_type_id, child_item_type_id, location, fields, global_id=None): 1115 """ This method will post a new item to Jama Connect. 1116 :param global_id: optional param to post the item with a custom global id 1117 :param project integer representing the project to which this item is to be posted 1118 :param item_type_id integer ID of an Item Type. 1119 :param child_item_type_id integer ID of an Item Type. 1120 :param location dictionary with integer ID of the parent item or project. 1121 :param fields dictionary item field data. 1122 :return integer ID of the successfully posted item or None if there was an error.""" 1123 1124 body = { 1125 "project": project, 1126 "itemType": item_type_id, 1127 "childItemType": child_item_type_id, 1128 "location": { 1129 "parent": location 1130 }, 1131 "fields": fields 1132 } 1133 resource_path = 'items/' 1134 params = {} 1135 1136 # we setting a global ID? 1137 if global_id is not None: 1138 body['globalId'] = global_id 1139 params['setGlobalIdManually'] = True 1140 1141 headers = {'content-type': 'application/json'} 1142 try: 1143 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers, params=params) 1144 except CoreException as err: 1145 py_jama_rest_client_logger.error(err) 1146 raise APIException(str(err)) 1147 JamaClient.__handle_response_status(response) 1148 return response.json()['meta']['id'] 1149 1150 def post_item_tag(self, item_id, tag_id): 1151 """ 1152 Add an existing tag to the item with the specified ID 1153 Args: 1154 item_id: The API ID of the item to add a tag. 1155 tag_id: The API ID of the tag to add to the item. 1156 1157 Returns: 201 if successful 1158 1159 """ 1160 body = { 1161 "tag": tag_id 1162 } 1163 resource_path = 'items/' + str(item_id) + '/tags' 1164 headers = {'content-type': 'application/json'} 1165 try: 1166 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1167 except CoreException as err: 1168 py_jama_rest_client_logger.error(err) 1169 raise APIException(str(err)) 1170 JamaClient.__handle_response_status(response) 1171 return response.status_code 1172 1173 def post_item_sync(self, source_item: int, pool_item: int): 1174 """ 1175 add an item to an existing pool of global ids 1176 Args: 1177 source_item: integer API ID of the source item, this item will adopt the global id of the 1178 pool_item. 1179 pool_item: integer API ID of the item in the target global ID pool. 1180 1181 Returns: the integer ID of the modified source item. 1182 """ 1183 body = { 1184 'item': source_item 1185 } 1186 1187 resource_path = 'items/' + str(pool_item) + '/synceditems' 1188 headers = {'content-type': 'application/json'} 1189 try: 1190 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1191 except CoreException as err: 1192 py_jama_rest_client_logger.error(err) 1193 raise APIException(str(err)) 1194 JamaClient.__handle_response_status(response) 1195 return response.json()['meta']['id'] 1196 1197 def post_relationship(self, from_item: int, to_item: int, relationship_type=None): 1198 """ 1199 1200 Args: 1201 from_item: integer API id of the source item 1202 to_item: integer API id of the target item 1203 relationship_type: Optional integer API id of the relationship type to create 1204 1205 Returns: The integer ID of the newly created relationship. 1206 1207 """ 1208 body = { 1209 "fromItem": from_item, 1210 "toItem": to_item, 1211 } 1212 if relationship_type is not None: 1213 body['relationshipType'] = relationship_type 1214 resource_path = 'relationships/' 1215 headers = {'content-type': 'application/json'} 1216 try: 1217 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1218 except CoreException as err: 1219 py_jama_rest_client_logger.error(err) 1220 raise APIException(str(err)) 1221 JamaClient.__handle_response_status(response) 1222 return response.json()['meta']['id'] 1223 1224 def put_relationship(self, relationship_id: int, from_item: int, to_item: int, relationship_type: int = None): 1225 """ 1226 1227 Args: 1228 relationship_id: integer API id of the relationship 1229 from_item: integer API id of the source item 1230 to_item: integer API id of the target item 1231 relationship_type: Optional integer API id of the relationship type to create 1232 1233 """ 1234 body = { 1235 "fromItem": from_item, 1236 "toItem": to_item 1237 } 1238 if relationship_type is not None: 1239 body['relationshipType'] = relationship_type 1240 resource_path = 'relationships/{}'.format(relationship_id) 1241 headers = {'content-type': 'application/json'} 1242 try: 1243 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1244 except CoreException as err: 1245 py_jama_rest_client_logger.error(err) 1246 raise APIException(str(err)) 1247 JamaClient.__handle_response_status(response) 1248 1249 def post_item_attachment(self, item_id, attachment_id): 1250 """ 1251 Add an existing attachment to the item with the specified ID 1252 :param item_id: this is the ID of the item 1253 :param attachment_id: The ID of the attachment 1254 :return: 201 if successful / the response status of the post operation 1255 """ 1256 body = {"attachment": attachment_id} 1257 resource_path = 'items/' + str(item_id) + '/attachments' 1258 headers = {'content-type': 'application/json'} 1259 try: 1260 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1261 except CoreException as err: 1262 py_jama_rest_client_logger.error(err) 1263 raise APIException(str(err)) 1264 JamaClient.__handle_response_status(response) 1265 return response.status_code 1266 1267 def post_project_attachment(self, project_id, name, description): 1268 """ 1269 This Method will make a new attachment object in the specified project 1270 :param project_id: The integer project ID to create the attachment in. 1271 :param name: The name of the attachment 1272 :param description: The description of the attachment 1273 :return: Returns the ID of the newly created attachment object. 1274 """ 1275 body = { 1276 "fields": { 1277 "name": name, 1278 "description": description 1279 } 1280 } 1281 1282 resource_path = 'projects/' + str(project_id) + '/attachments' 1283 headers = {'content-type': 'application/json'} 1284 try: 1285 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1286 except CoreException as err: 1287 py_jama_rest_client_logger.error(err) 1288 raise APIException(str(err)) 1289 JamaClient.__handle_response_status(response) 1290 return response.json()['meta']['id'] 1291 1292 def put_item(self, project, item_id, item_type_id, child_item_type_id, location, fields): 1293 """ This method wil 1294 PUT a new item to Jama Connect. 1295 :param project integer representing the project to which this item is to be posted 1296 :param item_id integer representing the item which is to be updated 1297 :param item_type_id integer ID of an Item Type. 1298 :param child_item_type_id integer ID of an Item Type. 1299 :param location dictionary with a key of 'item' or 'project' and an value with the ID of the parent 1300 :param fields dictionary item field data. 1301 :return integer ID of the successfully posted item or None if there was an error.""" 1302 1303 body = { 1304 "project": project, 1305 "itemType": item_type_id, 1306 "childItemType": child_item_type_id, 1307 "location": { 1308 "parent": location 1309 }, 1310 "fields": fields 1311 } 1312 resource_path = 'items/' + str(item_id) 1313 headers = {'content-type': 'application/json'} 1314 try: 1315 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1316 except CoreException as err: 1317 py_jama_rest_client_logger.error(err) 1318 raise APIException(str(err)) 1319 return self.__handle_response_status(response) 1320 1321 def put_attachments_file(self, attachment_id, file_path): 1322 """ 1323 Upload a file to a jama attachment 1324 :param attachment_id: the integer ID of the attachment item to which we are uploading the file 1325 :param file_path: the file path of the file to be uploaded 1326 :return: returns the status code of the call 1327 """ 1328 resource_path = 'attachments/' + str(attachment_id) + '/file' 1329 with open(file_path, 'rb') as f: 1330 files = {'file': f} 1331 try: 1332 response = self.__core.put(resource_path, files=files) 1333 except CoreException as err: 1334 py_jama_rest_client_logger.error(err) 1335 raise APIException(str(err)) 1336 self.__handle_response_status(response) 1337 return response.status_code 1338 1339 def put_user(self, user_id, username, password, first_name, last_name, email, phone=None, title=None, 1340 location=None): 1341 """ 1342 updates an existing user 1343 1344 Args: 1345 username: str 1346 password: str 1347 first_name: str 1348 last_name: str 1349 email: str 1350 phone: str - optional 1351 title: str - optional 1352 location: str - optional 1353 1354 Returns: api status code 1355 1356 """ 1357 1358 body = { 1359 'username': username, 1360 'password': password, 1361 'firstName': first_name, 1362 'lastName': last_name, 1363 'email': email, 1364 'phone': phone, 1365 'title': title, 1366 'location': location 1367 } 1368 resource_path = 'users/' + str(user_id) 1369 headers = {'content-type': 'application/json'} 1370 try: 1371 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1372 except CoreException as err: 1373 py_jama_rest_client_logger.error(err) 1374 raise APIException(str(err)) 1375 raise APIException 1376 return self.__handle_response_status(response) 1377 1378 def put_user_active(self, user_id, is_active): 1379 """ 1380 updates an existing users active status 1381 1382 Args: 1383 is_active: boolean 1384 1385 Returns: api status code 1386 1387 """ 1388 body = { 1389 'active': is_active 1390 } 1391 resource_path = 'users/' + str(user_id) + '/active' 1392 headers = {'content-type': 'application/json'} 1393 try: 1394 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1395 except CoreException as err: 1396 py_jama_rest_client_logger.error(err) 1397 raise APIException(str(err)) 1398 return self.__handle_response_status(response) 1399 1400 def put_test_run(self, test_run_id, data=None): 1401 """ This method will post a test run to Jama through the API""" 1402 resource_path = 'testruns/' + str(test_run_id) 1403 headers = {'content-type': 'application/json'} 1404 try: 1405 response = self.__core.put(resource_path, data=data, headers=headers) 1406 except CoreException as err: 1407 py_jama_rest_client_logger.error(err) 1408 raise APIException(str(err)) 1409 return self.__handle_response_status(response) 1410 1411 def __get_all(self, resource, params=None, allowed_results_per_page=__allowed_results_per_page, **kwargs): 1412 """This method will get all of the resources specified by the resource parameter, if an id or some other 1413 parameter is required for the resource, include it in the params parameter. 1414 Returns a single JSON array with all of the retrieved items.""" 1415 1416 if allowed_results_per_page < 1 or allowed_results_per_page > 50: 1417 raise ValueError("Allowed results per page must be between 1 and 50") 1418 1419 start_index = 0 1420 allowed_results_per_page = 20 1421 total_results = float("inf") 1422 1423 data = [] 1424 1425 while len(data) < total_results: 1426 page_response = self.__get_page(resource, start_index, params=params, **kwargs) 1427 page_json = page_response.json() 1428 1429 page_info = page_json['meta']['pageInfo'] 1430 start_index = page_info['startIndex'] + allowed_results_per_page 1431 total_results = page_info.get('totalResults') 1432 page_data = page_json.get('data') 1433 data.extend(page_data) 1434 1435 return data 1436 1437 def __get_page(self, resource, start_at, params=None, allowed_results_per_page=__allowed_results_per_page, **kwargs): 1438 """This method will return one page of results from the specified resource type. 1439 Pass any needed parameters along 1440 The response object will be returned""" 1441 parameters = { 1442 'startAt': start_at, 1443 'maxResults': allowed_results_per_page 1444 } 1445 1446 if params is not None: 1447 for k, v in params.items(): 1448 parameters[k] = v 1449 1450 try: 1451 response = self.__core.get(resource, params=parameters, **kwargs) 1452 except CoreException as err: 1453 py_jama_rest_client_logger.error(err) 1454 raise APIException(str(err)) 1455 JamaClient.__handle_response_status(response) 1456 return response 1457 1458 @staticmethod 1459 def __handle_response_status(response): 1460 """ Utility method for checking http status codes. 1461 If the response code is not in the 200 range, An exception will be thrown.""" 1462 1463 status = response.status_code 1464 1465 if status in range(200, 300): 1466 return status 1467 1468 if status in range(400, 500): 1469 """These are client errors. It is likely that something is wrong with the request.""" 1470 1471 response_message = 'No Response' 1472 1473 try: 1474 response_json = json.loads(response.text) 1475 response_message = response_json.get('meta').get('message') 1476 1477 except json.JSONDecodeError: 1478 pass 1479 1480 # Log the error 1481 py_jama_rest_client_logger.error('API Client Error. Status: {} Message: {}'.format(status, 1482 response_message)) 1483 1484 if response_message is not None and "already exists" in response_message: 1485 raise AlreadyExistsException("Entity already exists.", 1486 status_code=status, 1487 reason=response_message) 1488 1489 if status == 401: 1490 raise UnauthorizedException("Unauthorized: check credentials and permissions. " 1491 "API response message {}".format(response_message), 1492 status_code=status, 1493 reason=response_message) 1494 1495 if status == 404: 1496 raise ResourceNotFoundException("Resource not found. check host url.", 1497 status_code=status, 1498 reason=response_message) 1499 1500 if status == 429: 1501 raise TooManyRequestsException("Too many requests. API throttling limit reached, or system under " 1502 "maintenance.", 1503 status_code=status, 1504 reason=response_message) 1505 1506 raise APIClientException("{} {} Client Error. Bad Request. " 1507 "API response message: {}".format(status, response.reason, response_message), 1508 status_code=status, 1509 reason=response_message) 1510 1511 if status in range(500, 600): 1512 """These are server errors and network errors.""" 1513 1514 # Log The Error 1515 py_jama_rest_client_logger.error('{} Server error. {}'.format(status, response.reason)) 1516 raise APIServerException("{} Server Error.".format(status), 1517 status_code=status, 1518 reason=response.reason) 1519 1520 # Catch anything unexpected 1521 py_jama_rest_client_logger.error('{} error. {}'.format(status, response.reason)) 1522 raise APIException("{} error".format(status), 1523 status_code=status, 1524 reason=response.reason) 1525 1526 def set_allowed_results_per_page(self, allowed_results_per_page): 1527 self.__allowed_results_per_page = allowed_results_per_page 1528 1529 def get_allowed_results_per_page(self): 1530 return self.__allowed_results_per_page
A class to abstract communication with the Jama Connect API
55 def __init__(self, host_domain, 56 credentials=('username|clientID', 'password|clientSecret'), 57 api_version='/rest/v1/', 58 oauth=False, 59 verify=True, 60 allowed_results_per_page=20): 61 """Jama Client initializer 62 :rtype: JamaClient 63 :param host_domain: String The domain associated with the Jama Connect host 64 :param credentials: the user name and password as a tuple or client id and client secret if using Oauth. 65 :param api_version: valid args are '/rest/[v1|latest|labs]/' 66 :param verify: Defaults to True, Setting this to False will skip SSL Certificate verification""" 67 self.__credentials = credentials 68 self.__allowed_results_per_page = allowed_results_per_page 69 try: 70 self.__core = Core(host_domain, credentials, api_version=api_version, oauth=oauth, verify=verify) 71 except CoreException as err: 72 py_jama_rest_client_logger.error(err) 73 raise APIException(str(err)) 74 75 # Log client creation 76 py_jama_rest_client_logger.info('Created a new JamaClient instance. Domain: {} ' 77 'Connecting via Oauth: {}'.format(host_domain, oauth))
Jama Client initializer
Parameters
- host_domain: String The domain associated with the Jama Connect host
- credentials: the user name and password as a tuple or client id and client secret if using Oauth.
- api_version: valid args are '/rest/[v1|latest|labs]/'
- verify: Defaults to True, Setting this to False will skip SSL Certificate verification
79 def get_available_endpoints(self): 80 """ 81 Returns a list of all the available endpoints. 82 83 Returns: an array of available endpoints for this API 84 85 """ 86 try: 87 response = self.__core.get('') 88 except CoreException as err: 89 py_jama_rest_client_logger.error(err) 90 raise APIException(str(err)) 91 JamaClient.__handle_response_status(response) 92 return response.json()['data']
Returns a list of all the available endpoints.
Returns: an array of available endpoints for this API
94 def get_baselines(self, project_id, allowed_results_per_page=__allowed_results_per_page): 95 """ 96 Returns a list of Baseline objects 97 Args: 98 project_id: the Id of the project to fetch baselines for 99 allowed_results_per_page: number of results per page 100 101 Returns: a list of Baseline objects 102 """ 103 resource_path = 'baselines' 104 params = {'project': project_id} 105 baseline_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 106 return baseline_data
Returns a list of Baseline objects Args: project_id: the Id of the project to fetch baselines for allowed_results_per_page: number of results per page
Returns: a list of Baseline objects
108 def get_baseline(self, baseline_id): 109 """ 110 This method will return a baseline 111 Args: 112 baseline_id: the id of the baseline to fetch 113 114 Returns: a dictionary object representing the baseline 115 116 """ 117 resource_path = 'baselines/' + str(baseline_id) 118 try: 119 response = self.__core.get(resource_path) 120 except CoreException as err: 121 py_jama_rest_client_logger.error(err) 122 raise APIException(str(err)) 123 JamaClient.__handle_response_status(response) 124 return response.json()['data']
This method will return a baseline Args: baseline_id: the id of the baseline to fetch
Returns: a dictionary object representing the baseline
126 def get_baselines_versioneditems(self, baseline_id, allowed_results_per_page=__allowed_results_per_page): 127 """ 128 Get all baseline items in a baseline with the specified ID 129 Args: 130 baseline_id: The id of the baseline to fetch items for. 131 allowed_results_per_page: Number of results per page 132 Returns: A list of versioned items belonging to the baseline 133 """ 134 resource_path = 'baselines/' + str(baseline_id) + '/versioneditems' 135 baseline_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 136 return baseline_items
Get all baseline items in a baseline with the specified ID Args: baseline_id: The id of the baseline to fetch items for. allowed_results_per_page: Number of results per page Returns: A list of versioned items belonging to the baseline
138 def get_projects(self, allowed_results_per_page=__allowed_results_per_page): 139 """This method will return all projects as JSON object 140 :return: JSON Array of Item Objects. 141 """ 142 resource_path = 'projects' 143 project_data = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 144 return project_data
This method will return all projects as JSON object
Returns
JSON Array of Item Objects.
146 def get_filter_results(self, filter_id, project_id=None, allowed_results_per_page=__allowed_results_per_page): 147 """ 148 Get all results items for the filter with the specified ID 149 150 Args: 151 filter_id: The ID of the filter to fetch the results for. 152 project_id: Use this only for filters that run on any project, where projectScope is CURRENT 153 allowed_results_per_page: Number of results per page 154 155 Returns: 156 A List of items that match the filter. 157 158 """ 159 resource_path = 'filters/' + str(filter_id) + '/results' 160 params = None 161 if project_id is not None: 162 params = {'project': str(project_id)} 163 filter_results = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 164 return filter_results
Get all results items for the filter with the specified ID
Args: filter_id: The ID of the filter to fetch the results for. project_id: Use this only for filters that run on any project, where projectScope is CURRENT allowed_results_per_page: Number of results per page
Returns: A List of items that match the filter.
166 def get_items(self, project_id, allowed_results_per_page=__allowed_results_per_page): 167 """ 168 This method will return all items in the specified project. 169 Args: 170 project_id: the project ID 171 allowed_results_per_page: number of results per page 172 173 Returns: a Json array of item objects 174 175 """ 176 resource_path = 'items' 177 params = {'project': project_id} 178 item_data = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 179 return item_data
This method will return all items in the specified project. Args: project_id: the project ID allowed_results_per_page: number of results per page
Returns: a Json array of item objects
181 def get_item(self, item_id): 182 """ 183 This method will return a singular item of a specified item id 184 Args: 185 item_id: the item id of the item to fetch 186 187 Returns: a dictonary object representing the item 188 189 """ 190 resource_path = 'items/' + str(item_id) 191 try: 192 response = self.__core.get(resource_path) 193 except CoreException as err: 194 py_jama_rest_client_logger.error(err) 195 raise APIException(str(err)) 196 JamaClient.__handle_response_status(response) 197 return response.json()['data']
This method will return a singular item of a specified item id Args: item_id: the item id of the item to fetch
Returns: a dictonary object representing the item
199 def get_item_lock(self, item_id): 200 """ 201 Get the locked state, last locked date, and last locked by user for the item with the specified ID 202 Args: 203 item_id: The API ID of the item to get the lock info for. 204 205 Returns: 206 A JSON object with the lock information for the item with the specified ID. 207 208 """ 209 resource_path = 'items/' + str(item_id) + '/lock' 210 try: 211 response = self.__core.get(resource_path) 212 except CoreException as err: 213 py_jama_rest_client_logger.error(err) 214 raise APIException(str(err)) 215 JamaClient.__handle_response_status(response) 216 return response.json()['data']
Get the locked state, last locked date, and last locked by user for the item with the specified ID Args: item_id: The API ID of the item to get the lock info for.
Returns: A JSON object with the lock information for the item with the specified ID.
218 def put_item_lock(self, item_id, locked): 219 """ 220 Update the locked state of the item with the specified ID 221 Args: 222 item_id: the API id of the item to be updated 223 locked: boolean lock state to apply to this item 224 225 Returns: 226 response status 200 227 228 """ 229 body = { 230 "locked": locked, 231 } 232 resource_path = 'items/' + str(item_id) + '/lock' 233 headers = {'content-type': 'application/json'} 234 try: 235 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 236 except CoreException as err: 237 py_jama_rest_client_logger.error(err) 238 raise APIException(str(err)) 239 return self.__handle_response_status(response)
Update the locked state of the item with the specified ID Args: item_id: the API id of the item to be updated locked: boolean lock state to apply to this item
Returns: response status 200
256 def get_attachment(self, attachment_id): 257 """ 258 This method will return a singular attachment of a specified attachment id 259 Args: 260 attachment_id: the attachment id of the attachment to fetch 261 262 Returns: a dictonary object representing the attachment 263 264 """ 265 resource_path = 'attachments/' + str(attachment_id) 266 try: 267 response = self.__core.get(resource_path) 268 except CoreException as err: 269 py_jama_rest_client_logger.error(err) 270 raise APIException(str(err)) 271 JamaClient.__handle_response_status(response) 272 return response.json()['data']
This method will return a singular attachment of a specified attachment id Args: attachment_id: the attachment id of the attachment to fetch
Returns: a dictonary object representing the attachment
274 def get_abstract_items_from_doc_key(self, doc_key_list, allowed_results_per_page=__allowed_results_per_page): 275 """ DEPRECATED INSTEAD USE get_abstract_items below. 276 This method will take in a list of document keys and return an array of JSON Objects associated with the 277 document keys.""" 278 resource_path = 'abstractitems' 279 params = {'documentKey': doc_key_list} 280 abstract_items = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 281 return abstract_items
DEPRECATED INSTEAD USE get_abstract_items below. This method will take in a list of document keys and return an array of JSON Objects associated with the document keys.
283 def get_relationship_rule_sets(self): 284 """ 285 This method will return all relationship rule sets across all projects of the Jama Connect instance. 286 287 Returns: An array of dictionary objects representing a rule set and its associated rules 288 289 """ 290 resource_path = 'relationshiprulesets/' 291 rule_sets = self.__get_all(resource_path) 292 return rule_sets
This method will return all relationship rule sets across all projects of the Jama Connect instance.
Returns: An array of dictionary objects representing a rule set and its associated rules
294 def get_relationship_rule_set(self, id): 295 """ 296 This method will return the relationship rule sets by id. 297 298 Returns: A dictionary object representing a rule set and its associated rules 299 300 """ 301 resource_path = 'relationshiprulesets/' + str(id) 302 response = self.__core.get(resource_path) 303 JamaClient.__handle_response_status(response) 304 return response.json()['data']
This method will return the relationship rule sets by id.
Returns: A dictionary object representing a rule set and its associated rules
306 def get_relationship_rule_set_projects(self, id): 307 """ 308 This method will return the projects that have a given relationship rule set defined. 309 310 Returns: An array of the dictionary objects representing the projects with a given rule set assigned 311 312 """ 313 resource_path = 'relationshiprulesets/' + str(id) + '/projects' 314 projects = self.__get_all(resource_path) 315 return projects
This method will return the projects that have a given relationship rule set defined.
Returns: An array of the dictionary objects representing the projects with a given rule set assigned
317 def get_relationship_types(self, allowed_results_per_page=__allowed_results_per_page): 318 """ 319 This method will return all relationship types of the across all projects of the Jama Connect instance. 320 321 Args: 322 allowed_results_per_page: Number of results per page 323 324 Returns: An array of dictionary objects 325 326 """ 327 resource_path = 'relationshiptypes/' 328 item_types = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 329 return item_types
This method will return all relationship types of the across all projects of the Jama Connect instance.
Args: allowed_results_per_page: Number of results per page
Returns: An array of dictionary objects
331 def get_relationship_type(self, relationship_type_id): 332 """ 333 Gets relationship type information for a specific relationship type id. 334 335 Args: 336 relationship_type_id: The api id of the item type to fetch 337 338 Returns: JSON object 339 340 """ 341 resource_path = 'relationshiptypes/' + str(relationship_type_id) 342 try: 343 response = self.__core.get(resource_path) 344 except CoreException as err: 345 py_jama_rest_client_logger.error(err) 346 raise APIException(str(err)) 347 JamaClient.__handle_response_status(response) 348 return response.json()['data']
Gets relationship type information for a specific relationship type id.
Args: relationship_type_id: The api id of the item type to fetch
Returns: JSON object
350 def get_item_types(self, allowed_results_per_page=__allowed_results_per_page): 351 """ 352 This method will return all item types of the across all projects of the Jama Connect instance. 353 354 Args: 355 allowed_results_per_page: Number of results per page 356 357 Returns: An array of dictionary objects 358 359 """ 360 resource_path = 'itemtypes/' 361 item_types = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 362 return item_types
This method will return all item types of the across all projects of the Jama Connect instance.
Args: allowed_results_per_page: Number of results per page
Returns: An array of dictionary objects
364 def get_item_type(self, item_type_id): 365 """ 366 Gets item type information for a specific item type id. 367 368 Args: 369 item_type_id: The api id of the item type to fetch 370 371 Returns: JSON object 372 373 """ 374 resource_path = 'itemtypes/' + str(item_type_id) 375 try: 376 response = self.__core.get(resource_path) 377 except CoreException as err: 378 py_jama_rest_client_logger.error(err) 379 raise APIException(str(err)) 380 JamaClient.__handle_response_status(response) 381 return response.json()['data']
Gets item type information for a specific item type id.
Args: item_type_id: The api id of the item type to fetch
Returns: JSON object
383 def get_items_synceditems(self, item_id, allowed_results_per_page=__allowed_results_per_page): 384 """ 385 Get all synchronized items for the item with the specified ID 386 387 Args: 388 item_id: The API id of the item being 389 allowed_results_per_page: Number of results per page 390 391 Returns: A list of JSON Objects representing the items that are in the same synchronization group as the 392 specified item. 393 394 """ 395 resource_path = 'items/' + str(item_id) + '/synceditems' 396 synced_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 397 return synced_items
Get all synchronized items for the item with the specified ID
Args: item_id: The API id of the item being allowed_results_per_page: Number of results per page
Returns: A list of JSON Objects representing the items that are in the same synchronization group as the specified item.
399 def get_items_synceditems_status(self, item_id, synced_item_id): 400 """ 401 Get the sync status for the synced item with the specified ID 402 403 Args: 404 item_id: The id of the item to compare against 405 synced_item_id: the id of the item to check if it is in sync 406 407 Returns: The response JSON from the API which contains a single field 'inSync' with a boolean value. 408 409 """ 410 resource_path = 'items/' + str(item_id) + '/synceditems/' + str(synced_item_id) + '/syncstatus' 411 try: 412 response = self.__core.get(resource_path) 413 except CoreException as err: 414 py_jama_rest_client_logger.error(err) 415 raise APIException(str(err)) 416 JamaClient.__handle_response_status(response) 417 return response.json()['data']
Get the sync status for the synced item with the specified ID
Args: item_id: The id of the item to compare against synced_item_id: the id of the item to check if it is in sync
Returns: The response JSON from the API which contains a single field 'inSync' with a boolean value.
470 def get_item_versions(self, item_id, allowed_results_per_page=__allowed_results_per_page): 471 """ 472 Get all versions for the item with the specified ID 473 474 Args: 475 item_id: the item id of the item to fetch 476 allowed_results_per_page: number of results per page 477 478 Returns: JSON array with all versions for the item 479 """ 480 resource_path = 'items/' + str(item_id) + '/versions' 481 versions = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 482 return versions
Get all versions for the item with the specified ID
Args: item_id: the item id of the item to fetch allowed_results_per_page: number of results per page
Returns: JSON array with all versions for the item
484 def get_item_version(self, item_id, version_num): 485 """ 486 Get the numbered version for the item with the specified ID 487 488 Args: 489 item_id: the item id of the item to fetch 490 version_num: the version number for the item 491 492 Returns: a dictionary object representing the numbered version 493 """ 494 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) 495 response = self.__core.get(resource_path) 496 JamaClient.__handle_response_status(response) 497 return response.json()['data']
Get the numbered version for the item with the specified ID
Args: item_id: the item id of the item to fetch version_num: the version number for the item
Returns: a dictionary object representing the numbered version
499 def get_versioned_item(self, item_id, version_num): 500 """ 501 Get the snapshot of the item at the specified version 502 503 Args: 504 item_id: the item id of the item to fetch 505 version_num: the version number for the item 506 507 Returns: a dictionary object representing the versioned item 508 """ 509 resource_path = 'items/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 510 response = self.__core.get(resource_path) 511 JamaClient.__handle_response_status(response) 512 return response.json()['data']
Get the snapshot of the item at the specified version
Args: item_id: the item id of the item to fetch version_num: the version number for the item
Returns: a dictionary object representing the versioned item
514 def get_pick_lists(self, allowed_results_per_page=__allowed_results_per_page): 515 """ 516 Returns a list of all the pick lists 517 518 Args: 519 allowed_results_per_page: number of results per page 520 521 Returns: an array of dictionary objects 522 523 """ 524 resource_path = 'picklists/' 525 pick_lists = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 526 return pick_lists
Returns a list of all the pick lists
Args: allowed_results_per_page: number of results per page
Returns: an array of dictionary objects
528 def get_pick_list(self, pick_list_id): 529 """ 530 Gets all a singular picklist 531 532 Args: 533 pick_list_id: The API id of the pick list to fetch 534 535 Returns: a dictionary object representing the picklist. 536 537 """ 538 resource_path = 'picklists/' + str(pick_list_id) 539 try: 540 response = self.__core.get(resource_path) 541 except CoreException as err: 542 py_jama_rest_client_logger.error(err) 543 raise APIException(str(err)) 544 JamaClient.__handle_response_status(response) 545 return response.json()['data']
Gets all a singular picklist
Args: pick_list_id: The API id of the pick list to fetch
Returns: a dictionary object representing the picklist.
547 def get_pick_list_options(self, pick_list_id, allowed_results_per_page=__allowed_results_per_page): 548 """ 549 Gets all all the picklist options for a single picklist 550 Args: 551 pick_list_id: the api id of the picklist to fetch options for. 552 allowed_results_per_page: number of results per page 553 554 Returns: an array of dictionary objects that represent the picklist options. 555 556 """ 557 resource_path = 'picklists/' + str(pick_list_id) + '/options' 558 pick_list_options = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 559 return pick_list_options
Gets all all the picklist options for a single picklist Args: pick_list_id: the api id of the picklist to fetch options for. allowed_results_per_page: number of results per page
Returns: an array of dictionary objects that represent the picklist options.
561 def get_pick_list_option(self, pick_list_option_id): 562 """ 563 Fetches a single picklist option from the API 564 Args: 565 pick_list_option_id: The API ID of the picklist option to fetch 566 567 Returns: A dictonary object representing the picklist option. 568 569 """ 570 resource_path = 'picklistoptions/' + str(pick_list_option_id) 571 try: 572 response = self.__core.get(resource_path) 573 except CoreException as err: 574 py_jama_rest_client_logger.error(err) 575 raise APIException(str(err)) 576 JamaClient.__handle_response_status(response) 577 return response.json()['data']
Fetches a single picklist option from the API Args: pick_list_option_id: The API ID of the picklist option to fetch
Returns: A dictonary object representing the picklist option.
579 def get_relationships(self, project_id, allowed_results_per_page=__allowed_results_per_page): 580 """ 581 Returns a list of all relationships of a specified project 582 583 Args: 584 project_id: the api project id of a project 585 allowed_results_per_page: number of results per page 586 587 Returns: a list of dictionary objects that represents a relationships 588 589 """ 590 resource_path = 'relationships' 591 params = {'project': project_id} 592 relationship_data = self.__get_all(resource_path, params=params, 593 allowed_results_per_page=allowed_results_per_page) 594 return relationship_data
Returns a list of all relationships of a specified project
Args: project_id: the api project id of a project allowed_results_per_page: number of results per page
Returns: a list of dictionary objects that represents a relationships
596 def get_relationship(self, relationship_id): 597 """ 598 Returns a specific relationship object of a specified relationship ID 599 600 Args: 601 relationship_id: the api project id of a relationship 602 603 Returns: a dictionary object that represents a relationship 604 605 """ 606 resource_path = 'relationships/' + str(relationship_id) 607 try: 608 response = self.__core.get(resource_path) 609 except CoreException as err: 610 py_jama_rest_client_logger.error(err) 611 raise APIException(str(err)) 612 JamaClient.__handle_response_status(response) 613 return response.json()['data']
Returns a specific relationship object of a specified relationship ID
Args: relationship_id: the api project id of a relationship
Returns: a dictionary object that represents a relationship
615 def get_abstract_items(self, 616 project=None, 617 item_type=None, 618 document_key=None, 619 release=None, 620 created_date=None, 621 modified_date=None, 622 last_activity_date=None, 623 contains=None, 624 sort_by=None): 625 """ 626 This method will return all items that match the query parameters entered. 627 628 Args: 629 project: Array[integer] 630 item_type: Array[integer] 631 document_key: Array[string] 632 release: Array[integer] 633 created_date: Array[string] 634 modified_date: Array[string] 635 last_activity_date: Array[string] 636 contains: Array[string] 637 sort_by: Array[string] 638 639 Returns: 640 A JSON Array of items. 641 642 """ 643 resource_path = 'abstractitems' 644 645 # Add each parameter that is not null to the request. 646 params = {} 647 648 if project is not None: 649 params['project'] = project 650 651 if item_type is not None: 652 params['itemType'] = item_type 653 654 if document_key is not None: 655 params['documentKey'] = document_key 656 657 if release is not None: 658 params['release'] = release 659 660 if created_date is not None: 661 params['createdDate'] = created_date 662 663 if modified_date is not None: 664 params['modifiedDate'] = modified_date 665 666 if last_activity_date is not None: 667 params['lastActivityDate'] = last_activity_date 668 669 if contains is not None: 670 params['contains'] = contains 671 672 if sort_by is not None: 673 params['sortBy'] = sort_by 674 675 abstract_items = self.__get_all(resource_path, params=params) 676 return abstract_items
This method will return all items that match the query parameters entered.
Args: project: Array[integer] item_type: Array[integer] document_key: Array[string] release: Array[integer] created_date: Array[string] modified_date: Array[string] last_activity_date: Array[string] contains: Array[string] sort_by: Array[string]
Returns: A JSON Array of items.
678 def get_abstract_item(self, item_id): 679 """ 680 This method will return an item, test plan, test cycle, test run, or attachment with the specified ID 681 Args: 682 item_id: the item id of the item to fetch 683 684 Returns: a dictonary object representing the abstract item 685 686 """ 687 resource_path = 'abstractitems/' + str(item_id) 688 try: 689 response = self.__core.get(resource_path) 690 except CoreException as err: 691 py_jama_rest_client_logger.error(err) 692 raise APIException(str(err)) 693 JamaClient.__handle_response_status(response) 694 return response.json()['data']
This method will return an item, test plan, test cycle, test run, or attachment with the specified ID Args: item_id: the item id of the item to fetch
Returns: a dictonary object representing the abstract item
696 def get_abstract_item_versions(self, item_id): 697 """ 698 Get all versions for the item with the specified ID 699 700 Args: 701 item_id: the item id of the item to fetch 702 703 Returns: JSON array with all versions for the item 704 """ 705 resource_path = 'abstractitems/' + str(item_id) + '/versions' 706 versions = self.__get_all(resource_path) 707 return versions
Get all versions for the item with the specified ID
Args: item_id: the item id of the item to fetch
Returns: JSON array with all versions for the item
709 def get_abtract_item_version(self, item_id, version_num): 710 """ 711 Get the numbered version for the item with the specified ID 712 713 Args: 714 item_id: the item id of the item to fetch 715 version_num: the version number for the item 716 717 Returns: a dictionary object representing the numbered version 718 """ 719 resource_path = 'abstractitems/' + str(item_id) + '/versions/' + str(version_num) 720 try: 721 response = self.__core.get(resource_path) 722 except CoreException as err: 723 py_jama_rest_client_logger.error(err) 724 raise APIException(str(err)) 725 JamaClient.__handle_response_status(response) 726 return response.json()['data']
Get the numbered version for the item with the specified ID
Args: item_id: the item id of the item to fetch version_num: the version number for the item
Returns: a dictionary object representing the numbered version
728 def get_abstract_versioned_item(self, item_id, version_num): 729 """ 730 Get the snapshot of the item at the specified version 731 732 Args: 733 item_id: the item id of the item to fetch 734 version_num: the version number for the item 735 736 Returns: a dictionary object representing the versioned item 737 """ 738 resource_path = 'abstractitems/' + str(item_id) + '/versions/' + str(version_num) + '/versioneditem' 739 try: 740 response = self.__core.get(resource_path) 741 except CoreException as err: 742 py_jama_rest_client_logger.error(err) 743 raise APIException(str(err)) 744 JamaClient.__handle_response_status(response) 745 return response.json()['data']
Get the snapshot of the item at the specified version
Args: item_id: the item id of the item to fetch version_num: the version number for the item
Returns: a dictionary object representing the versioned item
748 def get_item_children(self, item_id, allowed_results_per_page=__allowed_results_per_page): 749 """ 750 This method will return list of the child items of the item passed to the function. 751 Args: 752 item_id: (int) The id of the item for which children items should be fetched 753 allowed_results_per_page: Number of results per page 754 755 Returns: a List of Objects that represent the children of the item passed in. 756 """ 757 resource_path = 'items/' + str(item_id) + '/children' 758 child_items = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 759 return child_items
This method will return list of the child items of the item passed to the function. Args: item_id: (int) The id of the item for which children items should be fetched allowed_results_per_page: Number of results per page
Returns: a List of Objects that represent the children of the item passed in.
761 def get_testruns(self, test_cycle_id, allowed_results_per_page=__allowed_results_per_page): 762 """This method will return all test runs associated with the specified test cycle. Test runs will be returned 763 as a list of json objects.""" 764 resource_path = 'testcycles/' + str(test_cycle_id) + '/testruns' 765 testrun_data = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 766 return testrun_data
This method will return all test runs associated with the specified test cycle. Test runs will be returned as a list of json objects.
768 def get_items_upstream_relationships(self, item_id, allowed_results_per_page=__allowed_results_per_page): 769 """ 770 Returns a list of all the upstream relationships for the item with the specified ID. 771 Args: 772 item_id: the api id of the item 773 allowed_results_per_page: number of results per page 774 775 Returns: an array of dictionary objects that represent the upstream relationships for the item. 776 777 """ 778 resource_path = 'items/' + str(item_id) + '/upstreamrelationships' 779 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page)
Returns a list of all the upstream relationships for the item with the specified ID. Args: item_id: the api id of the item allowed_results_per_page: number of results per page
Returns: an array of dictionary objects that represent the upstream relationships for the item.
795 def get_items_downstream_relationships(self, item_id, allowed_results_per_page=__allowed_results_per_page): 796 """ 797 Returns a list of all the downstream relationships for the item with the specified ID. 798 799 Args: 800 item_id: the api id of the item 801 802 Returns: an array of dictionary objects that represent the downstream relationships for the item. 803 804 """ 805 resource_path = 'items/' + str(item_id) + '/downstreamrelationships' 806 return self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page)
Returns a list of all the downstream relationships for the item with the specified ID.
Args: item_id: the api id of the item
Returns: an array of dictionary objects that represent the downstream relationships for the item.
821 def get_item_workflow_transitions(self, item_id): 822 """ 823 Get all valid workflow transitions that can be made with the specified id 824 825 Args: 826 item_id: the api id of the item 827 allowed_results_per_page: number of results per page 828 829 Returns: an array of dictionary objects that represent the workflow transitions for the item. 830 831 """ 832 resource_path = 'items/' + str(item_id) + '/workflowtransitionoptions' 833 return self.__get_all(resource_path)
Get all valid workflow transitions that can be made with the specified id
Args: item_id: the api id of the item allowed_results_per_page: number of results per page
Returns: an array of dictionary objects that represent the workflow transitions for the item.
850 def get_tagged_items(self, tag_id, allowed_results_per_page=__allowed_results_per_page): 851 """ 852 Get all items tagged with the specified ID 853 854 Args: 855 tag_id: The ID of the tag to fetch the results for. 856 allowed_results_per_page: Number of results per page 857 858 Returns: 859 A List of items that match the tag. 860 861 """ 862 resource_path = 'tags/' + str(tag_id) + '/items' 863 params = None 864 tag_results = self.__get_all(resource_path, params=params, allowed_results_per_page=allowed_results_per_page) 865 return tag_results
Get all items tagged with the specified ID
Args: tag_id: The ID of the tag to fetch the results for. allowed_results_per_page: Number of results per page
Returns: A List of items that match the tag.
867 def get_users(self, allowed_results_per_page=__allowed_results_per_page): 868 """ 869 Gets a list of all active users visible to the current user 870 871 Args: 872 allowed_results_per_page: Number of results per page 873 874 Returns: JSON array 875 876 """ 877 resource_path = 'users/' 878 users = self.__get_all(resource_path, allowed_results_per_page=allowed_results_per_page) 879 return users
Gets a list of all active users visible to the current user
Args: allowed_results_per_page: Number of results per page
Returns: JSON array
881 def get_user(self, user_id): 882 """ 883 Gets a single speificed user 884 885 Args: 886 user_id: user api ID 887 888 Returns: JSON obect 889 890 """ 891 resource_path = 'users/' + str(user_id) 892 try: 893 response = self.__core.get(resource_path) 894 except CoreException as err: 895 py_jama_rest_client_logger.error(err) 896 raise APIException(str(err)) 897 return response.json()['data']
Gets a single speificed user
Args: user_id: user api ID
Returns: JSON obect
899 def get_current_user(self): 900 """ 901 Gets a current user 902 903 Returns: JSON obect 904 905 """ 906 resource_path = 'users/current' 907 try: 908 response = self.__core.get(resource_path) 909 except CoreException as err: 910 py_jama_rest_client_logger.error(err) 911 raise APIException(str(err)) 912 return response.json()['data']
Gets a current user
Returns: JSON obect
914 def get_test_cycle(self, test_cycle_id): 915 """ 916 This method will return JSON data about the test cycle specified by the test cycle id. 917 918 Args: 919 test_cycle_id: the api id of the test cycle to fetch 920 921 Returns: a dictionary object that represents the test cycle 922 923 """ 924 resource_path = 'testcycles/' + str(test_cycle_id) 925 try: 926 response = self.__core.get(resource_path) 927 except CoreException as err: 928 py_jama_rest_client_logger.error(err) 929 raise APIException(str(err)) 930 JamaClient.__handle_response_status(response) 931 return response.json()['data']
This method will return JSON data about the test cycle specified by the test cycle id.
Args: test_cycle_id: the api id of the test cycle to fetch
Returns: a dictionary object that represents the test cycle
933 def delete_item(self, item_id): 934 """ 935 This method will delete an item in Jama Connect. 936 937 Args: 938 item_id: The jama connect API ID of the item to be deleted 939 940 Returns: The success status code. 941 """ 942 resource_path = 'items/' + str(item_id) 943 try: 944 response = self.__core.delete(resource_path) 945 except CoreException as err: 946 py_jama_rest_client_logger.error(err) 947 raise APIException(str(err)) 948 JamaClient.__handle_response_status(response) 949 return response.status_code
This method will delete an item in Jama Connect.
Args: item_id: The jama connect API ID of the item to be deleted
Returns: The success status code.
951 def delete_relationships(self, relationship_id): 952 """ 953 Deletes a relationship with the specified relationship ID 954 955 Args: 956 relationship_id: the api project id of a relationship 957 958 Returns: The success status code. 959 960 """ 961 resource_path = 'relationships/' + str(relationship_id) 962 try: 963 response = self.__core.delete(resource_path) 964 except CoreException as err: 965 py_jama_rest_client_logger.error(err) 966 raise APIException(str(err)) 967 JamaClient.__handle_response_status(response) 968 return response.status_code
Deletes a relationship with the specified relationship ID
Args: relationship_id: the api project id of a relationship
Returns: The success status code.
970 def patch_item(self, item_id, patches): 971 """ 972 This method will patch an item. 973 Args: 974 item_id: the API ID of the item that is to be patched 975 patches: An array of dicts, that represent patch operations each dict should have the following entries 976 [ 977 { 978 "op": string, 979 "path": string, 980 "value": {} 981 } 982 ] 983 984 Returns: The response status code 985 986 """ 987 resource_path = 'items/' + str(item_id) 988 headers = {'Content-Type': 'application/json', 989 'Accept': 'application/json' 990 } 991 data = json.dumps(patches) 992 993 # Make the API Call 994 try: 995 response = self.__core.patch(resource_path, data=data, headers=headers) 996 except CoreException as err: 997 py_jama_rest_client_logger.error(err) 998 raise APIException(str(err)) 999 1000 # validate response 1001 JamaClient.__handle_response_status(response) 1002 return response.json()['meta']['status']
This method will patch an item. Args: item_id: the API ID of the item that is to be patched patches: An array of dicts, that represent patch operations each dict should have the following entries [ { "op": string, "path": string, "value": {} } ]
Returns: The response status code
1004 def post_user(self, username, password, first_name, last_name, email, license_type, phone=None, title=None, 1005 location=None): 1006 """ 1007 Creates a new user 1008 1009 Args: 1010 username: str 1011 password: str 1012 first_name: str 1013 last_name: str 1014 email: str 1015 phone: str - optional 1016 title: str - optional 1017 location: str - optional 1018 licenseType: enum [ NAMED, FLOATING, STAKEHOLDER, FLOATING_COLLABORATOR, RESERVED_COLLABORATOR, FLOATING_REVIEWER, RESERVED_REVIEWER, NAMED_REVIEWER, TEST_RUNNER, EXPIRING_TRIAL, INACTIVE ] 1019 1020 Returns: int of newly created user api ID 1021 1022 """ 1023 1024 body = { 1025 'username': username, 1026 'password': password, 1027 'firstName': first_name, 1028 'lastName': last_name, 1029 'email': email, 1030 'phone': phone, 1031 'title': title, 1032 'location': location, 1033 'licenseType': license_type 1034 } 1035 resource_path = 'users/' 1036 headers = {'content-type': 'application/json'} 1037 try: 1038 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1039 except CoreException as err: 1040 py_jama_rest_client_logger.error(err) 1041 raise APIException(str(err)) 1042 JamaClient.__handle_response_status(response) 1043 return response.json()['meta']['id']
Creates a new user
Args: username: str password: str first_name: str last_name: str email: str phone: str - optional title: str - optional location: str - optional licenseType: enum [ NAMED, FLOATING, STAKEHOLDER, FLOATING_COLLABORATOR, RESERVED_COLLABORATOR, FLOATING_REVIEWER, RESERVED_REVIEWER, NAMED_REVIEWER, TEST_RUNNER, EXPIRING_TRIAL, INACTIVE ]
Returns: int of newly created user api ID
1045 def post_tag(self, name: str, project: int): 1046 """ 1047 Create a new tag in the project with the specified ID 1048 Args: 1049 name: The display name for the tag 1050 project: The project to create the new tag in 1051 1052 Returns: The integer API ID fr the newly created Tag. 1053 """ 1054 resource_path = 'tags' 1055 body = { 1056 'name': name, 1057 'project': project 1058 } 1059 headers = {'content-type': 'application/json'} 1060 try: 1061 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1062 except CoreException as err: 1063 py_jama_rest_client_logger.error(err) 1064 raise APIException(str(err)) 1065 JamaClient.__handle_response_status(response) 1066 return response.json()['meta']['id']
Create a new tag in the project with the specified ID Args: name: The display name for the tag project: The project to create the new tag in
Returns: The integer API ID fr the newly created Tag.
1068 def post_testplans_testcycles(self, testplan_id, testcycle_name, start_date, end_date, testgroups_to_include=None, 1069 testrun_status_to_include=None): 1070 """ 1071 This method will create a new Test Cycle. 1072 1073 Args: 1074 testplan_id (int): The API_ID of the testplan to create the test cycle from. 1075 testcycle_name (str): The name you would like to set for the new Test Cycle 1076 start_date (str): Start date in 'yyyy-mm-dd' Format 1077 end_date (str): End date in 'yyyy-mm-dd' Format 1078 testgroups_to_include (int[]): This array of integers specify the test groups to be included. 1079 testrun_status_to_include (str[]): Only valid after generating the first Test Cycle, you may choose to only 1080 generate Test Runs that were a specified status in the previous cycle. Do not specify anything to 1081 include all statuses 1082 1083 Returns: 1084 (int): Returns the integer id for the newly created testcycle, or None if something went terribly wrong. 1085 """ 1086 resource_path = 'testplans/' + str(testplan_id) + '/testcycles' 1087 headers = {'content-type': 'application/json'} 1088 fields = { 1089 'name': testcycle_name, 1090 'startDate': start_date, 1091 'endDate': end_date 1092 } 1093 test_run_gen_config = {} 1094 if testgroups_to_include is not None: 1095 test_run_gen_config['testGroupsToInclude'] = testgroups_to_include 1096 if testrun_status_to_include is not None: 1097 test_run_gen_config['testRunStatusesToInclude'] = testrun_status_to_include 1098 body = { 1099 'fields': fields, 1100 'testRunGenerationConfig': test_run_gen_config 1101 } 1102 1103 # Make the API Call 1104 try: 1105 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1106 except CoreException as err: 1107 py_jama_rest_client_logger.error(err) 1108 raise APIException(str(err)) 1109 1110 # Validate response 1111 JamaClient.__handle_response_status(response) 1112 return response.json()['meta']['id']
This method will create a new Test Cycle.
Args: testplan_id (int): The API_ID of the testplan to create the test cycle from. testcycle_name (str): The name you would like to set for the new Test Cycle start_date (str): Start date in 'yyyy-mm-dd' Format end_date (str): End date in 'yyyy-mm-dd' Format testgroups_to_include (int[]): This array of integers specify the test groups to be included. testrun_status_to_include (str[]): Only valid after generating the first Test Cycle, you may choose to only generate Test Runs that were a specified status in the previous cycle. Do not specify anything to include all statuses
Returns: (int): Returns the integer id for the newly created testcycle, or None if something went terribly wrong.
1114 def post_item(self, project, item_type_id, child_item_type_id, location, fields, global_id=None): 1115 """ This method will post a new item to Jama Connect. 1116 :param global_id: optional param to post the item with a custom global id 1117 :param project integer representing the project to which this item is to be posted 1118 :param item_type_id integer ID of an Item Type. 1119 :param child_item_type_id integer ID of an Item Type. 1120 :param location dictionary with integer ID of the parent item or project. 1121 :param fields dictionary item field data. 1122 :return integer ID of the successfully posted item or None if there was an error.""" 1123 1124 body = { 1125 "project": project, 1126 "itemType": item_type_id, 1127 "childItemType": child_item_type_id, 1128 "location": { 1129 "parent": location 1130 }, 1131 "fields": fields 1132 } 1133 resource_path = 'items/' 1134 params = {} 1135 1136 # we setting a global ID? 1137 if global_id is not None: 1138 body['globalId'] = global_id 1139 params['setGlobalIdManually'] = True 1140 1141 headers = {'content-type': 'application/json'} 1142 try: 1143 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers, params=params) 1144 except CoreException as err: 1145 py_jama_rest_client_logger.error(err) 1146 raise APIException(str(err)) 1147 JamaClient.__handle_response_status(response) 1148 return response.json()['meta']['id']
This method will post a new item to Jama Connect.
Parameters
- global_id: optional param to post the item with a custom global id :param project integer representing the project to which this item is to be posted :param item_type_id integer ID of an Item Type. :param child_item_type_id integer ID of an Item Type. :param location dictionary with integer ID of the parent item or project. :param fields dictionary item field data. :return integer ID of the successfully posted item or None if there was an error.
1150 def post_item_tag(self, item_id, tag_id): 1151 """ 1152 Add an existing tag to the item with the specified ID 1153 Args: 1154 item_id: The API ID of the item to add a tag. 1155 tag_id: The API ID of the tag to add to the item. 1156 1157 Returns: 201 if successful 1158 1159 """ 1160 body = { 1161 "tag": tag_id 1162 } 1163 resource_path = 'items/' + str(item_id) + '/tags' 1164 headers = {'content-type': 'application/json'} 1165 try: 1166 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1167 except CoreException as err: 1168 py_jama_rest_client_logger.error(err) 1169 raise APIException(str(err)) 1170 JamaClient.__handle_response_status(response) 1171 return response.status_code
Add an existing tag to the item with the specified ID Args: item_id: The API ID of the item to add a tag. tag_id: The API ID of the tag to add to the item.
Returns: 201 if successful
1173 def post_item_sync(self, source_item: int, pool_item: int): 1174 """ 1175 add an item to an existing pool of global ids 1176 Args: 1177 source_item: integer API ID of the source item, this item will adopt the global id of the 1178 pool_item. 1179 pool_item: integer API ID of the item in the target global ID pool. 1180 1181 Returns: the integer ID of the modified source item. 1182 """ 1183 body = { 1184 'item': source_item 1185 } 1186 1187 resource_path = 'items/' + str(pool_item) + '/synceditems' 1188 headers = {'content-type': 'application/json'} 1189 try: 1190 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1191 except CoreException as err: 1192 py_jama_rest_client_logger.error(err) 1193 raise APIException(str(err)) 1194 JamaClient.__handle_response_status(response) 1195 return response.json()['meta']['id']
add an item to an existing pool of global ids Args: source_item: integer API ID of the source item, this item will adopt the global id of the pool_item. pool_item: integer API ID of the item in the target global ID pool.
Returns: the integer ID of the modified source item.
1197 def post_relationship(self, from_item: int, to_item: int, relationship_type=None): 1198 """ 1199 1200 Args: 1201 from_item: integer API id of the source item 1202 to_item: integer API id of the target item 1203 relationship_type: Optional integer API id of the relationship type to create 1204 1205 Returns: The integer ID of the newly created relationship. 1206 1207 """ 1208 body = { 1209 "fromItem": from_item, 1210 "toItem": to_item, 1211 } 1212 if relationship_type is not None: 1213 body['relationshipType'] = relationship_type 1214 resource_path = 'relationships/' 1215 headers = {'content-type': 'application/json'} 1216 try: 1217 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1218 except CoreException as err: 1219 py_jama_rest_client_logger.error(err) 1220 raise APIException(str(err)) 1221 JamaClient.__handle_response_status(response) 1222 return response.json()['meta']['id']
Args: from_item: integer API id of the source item to_item: integer API id of the target item relationship_type: Optional integer API id of the relationship type to create
Returns: The integer ID of the newly created relationship.
1224 def put_relationship(self, relationship_id: int, from_item: int, to_item: int, relationship_type: int = None): 1225 """ 1226 1227 Args: 1228 relationship_id: integer API id of the relationship 1229 from_item: integer API id of the source item 1230 to_item: integer API id of the target item 1231 relationship_type: Optional integer API id of the relationship type to create 1232 1233 """ 1234 body = { 1235 "fromItem": from_item, 1236 "toItem": to_item 1237 } 1238 if relationship_type is not None: 1239 body['relationshipType'] = relationship_type 1240 resource_path = 'relationships/{}'.format(relationship_id) 1241 headers = {'content-type': 'application/json'} 1242 try: 1243 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1244 except CoreException as err: 1245 py_jama_rest_client_logger.error(err) 1246 raise APIException(str(err)) 1247 JamaClient.__handle_response_status(response)
Args: relationship_id: integer API id of the relationship from_item: integer API id of the source item to_item: integer API id of the target item relationship_type: Optional integer API id of the relationship type to create
1249 def post_item_attachment(self, item_id, attachment_id): 1250 """ 1251 Add an existing attachment to the item with the specified ID 1252 :param item_id: this is the ID of the item 1253 :param attachment_id: The ID of the attachment 1254 :return: 201 if successful / the response status of the post operation 1255 """ 1256 body = {"attachment": attachment_id} 1257 resource_path = 'items/' + str(item_id) + '/attachments' 1258 headers = {'content-type': 'application/json'} 1259 try: 1260 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1261 except CoreException as err: 1262 py_jama_rest_client_logger.error(err) 1263 raise APIException(str(err)) 1264 JamaClient.__handle_response_status(response) 1265 return response.status_code
Add an existing attachment to the item with the specified ID
Parameters
- item_id: this is the ID of the item
- attachment_id: The ID of the attachment
Returns
201 if successful / the response status of the post operation
1267 def post_project_attachment(self, project_id, name, description): 1268 """ 1269 This Method will make a new attachment object in the specified project 1270 :param project_id: The integer project ID to create the attachment in. 1271 :param name: The name of the attachment 1272 :param description: The description of the attachment 1273 :return: Returns the ID of the newly created attachment object. 1274 """ 1275 body = { 1276 "fields": { 1277 "name": name, 1278 "description": description 1279 } 1280 } 1281 1282 resource_path = 'projects/' + str(project_id) + '/attachments' 1283 headers = {'content-type': 'application/json'} 1284 try: 1285 response = self.__core.post(resource_path, data=json.dumps(body), headers=headers) 1286 except CoreException as err: 1287 py_jama_rest_client_logger.error(err) 1288 raise APIException(str(err)) 1289 JamaClient.__handle_response_status(response) 1290 return response.json()['meta']['id']
This Method will make a new attachment object in the specified project
Parameters
- project_id: The integer project ID to create the attachment in.
- name: The name of the attachment
- description: The description of the attachment
Returns
Returns the ID of the newly created attachment object.
1292 def put_item(self, project, item_id, item_type_id, child_item_type_id, location, fields): 1293 """ This method wil 1294 PUT a new item to Jama Connect. 1295 :param project integer representing the project to which this item is to be posted 1296 :param item_id integer representing the item which is to be updated 1297 :param item_type_id integer ID of an Item Type. 1298 :param child_item_type_id integer ID of an Item Type. 1299 :param location dictionary with a key of 'item' or 'project' and an value with the ID of the parent 1300 :param fields dictionary item field data. 1301 :return integer ID of the successfully posted item or None if there was an error.""" 1302 1303 body = { 1304 "project": project, 1305 "itemType": item_type_id, 1306 "childItemType": child_item_type_id, 1307 "location": { 1308 "parent": location 1309 }, 1310 "fields": fields 1311 } 1312 resource_path = 'items/' + str(item_id) 1313 headers = {'content-type': 'application/json'} 1314 try: 1315 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1316 except CoreException as err: 1317 py_jama_rest_client_logger.error(err) 1318 raise APIException(str(err)) 1319 return self.__handle_response_status(response)
This method wil PUT a new item to Jama Connect. :param project integer representing the project to which this item is to be posted :param item_id integer representing the item which is to be updated :param item_type_id integer ID of an Item Type. :param child_item_type_id integer ID of an Item Type. :param location dictionary with a key of 'item' or 'project' and an value with the ID of the parent :param fields dictionary item field data. :return integer ID of the successfully posted item or None if there was an error.
1321 def put_attachments_file(self, attachment_id, file_path): 1322 """ 1323 Upload a file to a jama attachment 1324 :param attachment_id: the integer ID of the attachment item to which we are uploading the file 1325 :param file_path: the file path of the file to be uploaded 1326 :return: returns the status code of the call 1327 """ 1328 resource_path = 'attachments/' + str(attachment_id) + '/file' 1329 with open(file_path, 'rb') as f: 1330 files = {'file': f} 1331 try: 1332 response = self.__core.put(resource_path, files=files) 1333 except CoreException as err: 1334 py_jama_rest_client_logger.error(err) 1335 raise APIException(str(err)) 1336 self.__handle_response_status(response) 1337 return response.status_code
Upload a file to a jama attachment
Parameters
- attachment_id: the integer ID of the attachment item to which we are uploading the file
- file_path: the file path of the file to be uploaded
Returns
returns the status code of the call
1339 def put_user(self, user_id, username, password, first_name, last_name, email, phone=None, title=None, 1340 location=None): 1341 """ 1342 updates an existing user 1343 1344 Args: 1345 username: str 1346 password: str 1347 first_name: str 1348 last_name: str 1349 email: str 1350 phone: str - optional 1351 title: str - optional 1352 location: str - optional 1353 1354 Returns: api status code 1355 1356 """ 1357 1358 body = { 1359 'username': username, 1360 'password': password, 1361 'firstName': first_name, 1362 'lastName': last_name, 1363 'email': email, 1364 'phone': phone, 1365 'title': title, 1366 'location': location 1367 } 1368 resource_path = 'users/' + str(user_id) 1369 headers = {'content-type': 'application/json'} 1370 try: 1371 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1372 except CoreException as err: 1373 py_jama_rest_client_logger.error(err) 1374 raise APIException(str(err)) 1375 raise APIException 1376 return self.__handle_response_status(response)
updates an existing user
Args: username: str password: str first_name: str last_name: str email: str phone: str - optional title: str - optional location: str - optional
Returns: api status code
1378 def put_user_active(self, user_id, is_active): 1379 """ 1380 updates an existing users active status 1381 1382 Args: 1383 is_active: boolean 1384 1385 Returns: api status code 1386 1387 """ 1388 body = { 1389 'active': is_active 1390 } 1391 resource_path = 'users/' + str(user_id) + '/active' 1392 headers = {'content-type': 'application/json'} 1393 try: 1394 response = self.__core.put(resource_path, data=json.dumps(body), headers=headers) 1395 except CoreException as err: 1396 py_jama_rest_client_logger.error(err) 1397 raise APIException(str(err)) 1398 return self.__handle_response_status(response)
updates an existing users active status
Args: is_active: boolean
Returns: api status code
1400 def put_test_run(self, test_run_id, data=None): 1401 """ This method will post a test run to Jama through the API""" 1402 resource_path = 'testruns/' + str(test_run_id) 1403 headers = {'content-type': 'application/json'} 1404 try: 1405 response = self.__core.put(resource_path, data=data, headers=headers) 1406 except CoreException as err: 1407 py_jama_rest_client_logger.error(err) 1408 raise APIException(str(err)) 1409 return self.__handle_response_status(response)
This method will post a test run to Jama through the API