0
votes

I'm using Python to query the REST API of our org's Azure Devops server. I've been able to query just about every type of object for many months (projects, workitems, teams, iterations, members, etc.) but when I try to query builds or build definitions I get a 401. I'm using my person access token which has Read permission to everything. This token hasn't expired as I can prove by still getting successful 200 responses from all my other API calls. What's strange is that I'm able to get a 200 result from Postman using the same token and basic auth.

Here's the URL I'm trying to hit:

https://{MYCOMPANY}.com:{PORT}/{COLLEGTION}/{PROJECT}/_apis/build/definitions

Any ideas why this API URL might behave differently?

1
Hi friend, is there any update for this issue? What's the result if you create a Full Access PAT with admin account and use it in my second code sample below? Can if work?(To test the code) - LoLance

1 Answers

0
votes

If the url works well via Postman in same machine, then it should also work for your python script.

You could check several points:

1.API version. For TFS2018U2 it's 4.1 and for Azure Devops Server 2019 it's 5.0.

2.The Url, normally the url looks like:

http://{tfsServerName}:8080/tfs/{CollectionName}/{ProjectName}/_apis/build/definitions?api-version=4.1

You shouldn't use https unless SSL is enabled on server. Also, make sure the basic auth is enabled. Check this similar one.

3.Check the python code, we have two ways for authentication in windows OS:

Windows auth and basic auth with PAT.

For windows auth you can use code like this (Hint from Roopendra):

import logging
import getpass
import requests
from requests_ntlm import HttpNtlmAuth

username = 'DomainName\\Administrator'
password = 'xxx'
tfsApi = 'http://xxx:8080/tfs/xxx/xxx/_apis/build/definitions?api-version=x.x'

tfsResponse = requests.get(tfsApi,auth=HttpNtlmAuth(username,password))
if(tfsResponse.ok):
    tfsResponse = tfsResponse.json()
    print(tfsResponse)
else:
    tfsResponse.raise_for_status()

For basic auth with pat you can use code (Hint from Jack Jia):

import requests
import base64

pat = 'acxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiq'
authorization = str(base64.b64encode(bytes(':'+pat, 'ascii')), 'ascii')

headers = {
    'Accept': 'application/json',
    'Authorization': 'Basic '+authorization
}

response = requests.get(
    url="http://MyServerName:8080/tfs/xxx/xxx/_apis/build/definitions?api-version=x.x", headers=headers)
print(response.text)

Also you can try creating a new PAT will full access for the test purpose...