项目作者: rcoenmans

项目描述 :
A client library for Microsoft Azure DevOps (VSTS) and TFS written in Python
高级语言: Python
项目地址: git://github.com/rcoenmans/vsts-client.git
创建时间: 2018-01-31T09:48:35Z
项目社区:https://github.com/rcoenmans/vsts-client

开源协议:MIT License

下载


Azure DevOps (VSTS) & TFS Client

A client library for working with Azure DevOps (formerly VSTS) and TFS projects, areas/iterations, sprints, work items and tasks written in Python.

Please feel free to send me a pull request if you’ve fixed a bug or added a feature.

Installation

  1. pip install vsts-client

Connecting to Azure DevOps

In order to connect to Azure DevOps, you need to obtain a personal access token.

  1. # Import the VstsClient module
  2. from vstsclient.vstsclient import VstsClient
  3. # Initialize the VSTS client using the Azure DevOps url and personal access token
  4. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')

Or you can still use visualstudio.com.

  1. client = VstsClient('<account>.visualstudio.com', '<personalaccesstoken>')

What about TFS?

To connect to an on-premises TFS environment you supply the server name and port number (default is 8080).

  1. client = VstsClient('tfs.contoso.com:8080', '<personalaccesstoken>')

The VSTS client will pick the DefaultCollection by default. You can specify a different collection using the optional collection parameter.

  1. client = VstsClient('tfs.contoso.com:8080', '<personalaccesstoken>', '<your collection>')

Connecting from behind a proxy

  1. client.set_proxy('proxy.contoso.com', 8080, '<username>', '<password>')

Team Projects

Get a list of team projects

Get all team projects in the project collection that the authenticated user has access to.

  1. from vstsclient.vstsclient import VstsClient
  2. from vstsclient.constants import StateFilter
  3. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  4. # StateFilter options are WellFormed (default), New, Deleting, CreatePending and All
  5. projects = client.get_projects(StateFilter.WELL_FORMED)

Get a team project

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. project = client.get_project('Contoso')

Create a team project

Create a team project in a Azure DevOps account using the given SourceControlType and ProcessTemplate.

  1. from vstsclient.vstsclient import VstsClient
  2. from vstsclient.constants import (
  3. ProcessTemplate,
  4. SourceControlType
  5. )
  6. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  7. project = client.create_project(
  8. 'Contoso', # Project name
  9. 'A project description', # Project description
  10. SourceControlType.GIT, # Source control type: Git or Tfvc
  11. ProcessTemplate.AGILE) # Process template: Agile, Scrum or CMMI

Areas and Iterations

All work items have an area and an iteration field. The values that these fields can have are defined in the classification hierarchies.

Get a list of areas and iterations

Get the root area tree

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. areas = client.get_areas('Contoso')

Get the area tree with 2 levels of children

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. areas = client.get_areas('Contoso', 2)
  4. for area in areas.children:
  5. print(area.name)

Get the root iteration tree

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. iterations = client.get_iterations('Contoso')

Get the iteration tree with 2 levels of children

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. iterations = client.get_iterations(
  4. 'Contoso', # Team project name
  5. 2) # Hierarchy depth
  6. for iteration in iterations.children:
  7. print(iteration.name)

Get an area and iteration

Get an area

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. area = client.get_area('Contoso', 'Area 1')

Get an iteration

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. iteration = client.get_iteration('Contoso', 'Sprint 1')

Create an area and iteration

Create an area

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. area = client.create_area(
  4. 'Contoso', # Team project name
  5. 'Area 1') # Area name

Create an iteration

  1. from vstsclient.vstsclient import VstsClient
  2. start_date = datetime.datetime.utcnow() # Sprint starts today
  3. finish_date = start_date + datetime.timedelta(days=21) # Ends in 3 weeks
  4. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  5. iteration = client.create_iteration(
  6. 'Contoso', # Team project name
  7. 'Sprint 1', # Iteration name
  8. start_date, # Start date
  9. finish_date) # End date

Work items

By IDs

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. workitems = client.get_workitems_by_id('1,2,3,5,8,13,21,34')

Get a work item

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. workitem = client.get_workitem(13)

Create a work item

When you create a work item, you can provide values for any of the work item fields.

  1. from vstsclient.vstsclient import VstsClient
  2. from vstsclient.models import JsonPatchDocument, JsonPatchOperation
  3. from vstsclient.constants import SystemFields, MicrosoftFields
  4. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  5. # Create a JsonPatchDocument and provide the values for the work item fields
  6. doc = JsonPatchDocument()
  7. doc.add(JsonPatchOperation('add', SystemFields.TITLE, 'Work item 1'))
  8. doc.add(JsonPatchOperation('add', SystemFields.DESCRIPTION, 'Work item description.'))
  9. doc.add(JsonPatchOperation('add', SystemFields.TAGS, 'tag1; tag2'))
  10. # Create a new work item by specifying the project and work item type
  11. workitem = client.create_workitem(
  12. 'Contoso', # Team project name
  13. 'User Story', # Work item type (e.g. Epic, Feature, User Story etc.)
  14. doc) # JsonPatchDocument with operations

Update work items

  1. from vstsclient.vstsclient import VstsClient
  2. from vstsclient.models import JsonPatchDocument, JsonPatchOperation
  3. from vstsclient.constants import SystemFields
  4. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  5. # Create a JsonPatchDocument and provide the values for the fields to update
  6. doc = JsonPatchDocument()
  7. doc.add(JsonPatchOperation('replace', SystemFields.TITLE, 'Work item 2'))
  8. # Update work item id 13
  9. workitem = client.update_workitem(13, doc)

Change work item type

Only supported on Azure DevOps (not on TFS).

  1. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  2. client.change_workitem_type(13, 'Task')

Move a work item

Only supported on Azure DevOps (not on TFS).
```python
client = VstsClient(‘dev.azure.com/‘, ‘‘)

To move a work item, provide the Team Project, Area path and Iteration path to move to

client.move_workitem(13, ‘Contoso’, ‘Contoso’, ‘Sprint 1’)

  1. #### Add a tag
  2. ```python
  3. tags = ['Tag1', 'Tag2']
  4. client.add_tags(13, tags)
  1. from vstsclient.constants import LinkTypes
  2. feature = client.get_workitem(1) # Get a feature
  3. userstory = client.get_workitem(2) # Get a user story
  4. # Create a parent/child link between the feature and the userstory
  5. client.add_link(userstory.id, feature.id, LinkTypes.PARENT, 'Adding this user story to feature x')
  6. # Note that you can create the same link the other way around
  7. client.add_link(feature.id, userstory.id, LinkTypes.CHILD, 'Adding user story x to this feature')

Add an attachment

To attach a file to a work item, upload the attachment to the attachment store using upload_attachment, then attach it to the work item.

  1. workitem = client.get_workitem(1)
  2. attachment = None
  3. # Upload the attachment to the attachment store
  4. with open('./example.png', 'rb') as f:
  5. attachment = client.upload_attachment('example.png', f)
  6. # Link the attachment to the work item
  7. client.add_attachment(workitem.id, attachment.url, 'Linking example.png to a work item')

Update work items bypassing rules

Bypassing the rules engine allows you to modify work item fields without any restrictions, for example you can assign a work item to a user no longer in the organization.

To modify the System.CreatedBy, System.CreatedDate, System.ChangedBy, or System.ChangedDate fields, you must be a member of the Project Collection Service Acccounts group.
```python
doc = JsonPatchDocument()
doc.add(JsonPatchOperation(‘add’, SystemFields.CHANGED_BY, ‘Woody woody@contoso.com‘))
doc.add(JsonPatchOperation(‘add’, SystemFields.CHANGED_DATE, ‘01-01-2018’))

Set the bypass_rules parameter to True

client.update_workitem(13, doc, bypass_rules=True)

  1. > `System.CreatedBy` and `System.CreatedDate` can only be modified using bypass rules on work item creation, i.e. the first revision of a work item.
  2. ```python
  3. # Set the Created By and Created Date fields
  4. doc = JsonPatchDocument()
  5. doc.add(JsonPatchOperation('add', SystemFields.TITLE, 'Work item 1'))
  6. doc.add(JsonPatchOperation('add', SystemFields.DESCRIPTION, 'Work item description.'))
  7. doc.add(JsonPatchOperation('add', SystemFields.CREATED_BY, 'Woody <woody@contoso.com>'))
  8. doc.add(JsonPatchOperation('add', SystemFields.CREATED_DATE, '01-01-2018'))
  9. # Set the bypass_rules parameter to True
  10. client.create_workitem('Contoso', 'User Story', doc, bypass_rules=True)

Delete a work item

  1. client.delete_workitem(1)

Access team and team members in a project

Get all teams in a project in a project

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. for team in client.get_teams('project name')['value']:
  4. print(str(team))

Get members of all teams in a project

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. project_name = 'project name'
  4. for team in client.get_teams(project_name)['value']:
  5. for dev in client.get_team_members(project_name, team['id'])['value']:
  6. print(dev['identity']['displayName']] + ': ' + dev['identity']['uniqueName'])

Managing comments of work items

Get all comments of a work item

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. comments = client.get_comments_from_workitem('project', 73)

Get specific comment of a work item

Comments inside a work item are indexed by comment id.

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. workitem_id = 73
  4. comment_id = 8307896
  5. comment = client.get_comment_from_workitem('project', workitem_id, comment_id)

Add a comment of a work item

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. comment = client.create_comment('project', 73, 'This is a test comment!')

Removing a comment of a work item

  1. from vstsclient.vstsclient import VstsClient
  2. workitem_id = 73
  3. comment_id = 8307896
  4. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  5. client.delete_comment('project', workitem_id, comment_id)

Fields

Create a field

Create a new field.

  1. from vstsclient.vstsclient import VstsClient
  2. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  3. name = 'New work item field'
  4. ref_name = 'new.work.item.field'
  5. field = client.create_field(
  6. name, # Name
  7. ref_name, # Reference name
  8. 'Contoso', # Project name
  9. 'Field description', # Field description
  10. 'string', # Field type: boolean, string, dateTime, integer, double, guid, html, identity, plainText, etc.
  11. 'workItem', # Field usage: none, tree, workItem, workItemLink or workItemTypeExtension
  12. [{ # Supported operations
  13. 'referenceName': 'SupportedOperations.Equals',
  14. 'name': '='
  15. }])

Get a field

  1. ref_name = 'new.workitem.field' # Name or reference name
  2. prj_name = 'Contoso' # Project name
  3. field = client.get_field(ref_name, prj_name)

Delete a field

  1. ref_name = 'new.workitem.field' # Name or reference name
  2. prj_name = 'Contoso' # Project name
  3. client.delete_field(ref_name, prj_name)

Work item query language (WIQL)

Run a query

  1. # Specifying the team project is optional
  2. query = "Select [System.Id], [System.Title], [System.State] From WorkItems Where [System.Title] = 'User Story A'"
  3. result = client.query(query, 'Contoso')
  4. for row in result.rows:
  5. workitem_id = row['id']
  6. workitem = client.get_workitem(id)

Note that the query returns a list of work item ids

Supported API version in Azure DevOps and TFS

You can obtain information about supported API versions of your server for each topic (git, wit, etc). Please see this Github issue from MicrosoftDocs/vsts-docs for detailed explanation about this version API.

  1. client = VstsClient('dev.azure.com/<account>', '<personalaccesstoken>')
  2. client.get_api_info('wit')

The call get_api_info() returns an array of supported API versions. For example with work item comments accessed by revision (this API has):

  1. {
  2. 'area': 'wit',
  3. 'id': '19335ae7-22f7-4308-93d8-261f9384b7cf',
  4. 'maxVersion': '5.0',
  5. 'minVersion': '3.0',
  6. 'releasedVersion': '0.0',
  7. 'resourceName': 'comments',
  8. 'resourceVersion': 2,
  9. 'routeTemplate': '{project}/_apis/{area}/workItems/{id}/comments/{revision}'
  10. }