如何使用 Python 请求模块和 TeamCity API 触发构建?

How to use Python requests module and TeamCity API to trigger a build?

TeamCity 9.x DocumentationTriggering a Build 部分有一个 cURL 示例:

curl -v -u user:password http://teamcity.server.url:8111/app/rest/buildQueue --request POST --header "Content-Type:application/xml" --data-binary @build.xml

我想知道如何将它转换成等效的 Python 脚本(使用来自 requests 模块的 POST 请求)?


顺便说一句,我尝试了以下 Python 脚本但得到了这样的响应代码 400 (Bad Request):

url = "http://myteamcity.com:8111/httpAuth/app/rest/buildQueue/"
headers = {'Content-Type': 'application/json'}
data = json.dumps({'buildTypeId': 'MyTestBuild'})
r = requests.post(url, headers=headers, data=data, auth=("username", "password"), timeout=10)
print "r = ", r

>> r =  <Response [400]>

如果将headers中的Content-Type改成Accept,得到另一个响应码415 (Unsupported Media Type)

headers = {'Accept': 'application/json'}

>> r =  <Response [415]>

触发构建的文档显示您需要发送 XML,而不是 JSON:

<build>
    <buildType id="buildConfID"/>
</build>

TeamCity REST API 有点鱼龙混杂;有些方法同时接受 XML 和 JSON,有些只接受 XML。这是后一种方法。他们会根据您将 Accept header 设置为 XML 或 JSON 来响应。

将以上内容与您所需的构建 ID 一起发送;对于 XML 文档,您可以简单地使用模板:

from xml.sax.saxutils import quoteattr

template = '<build><buildType id={id}/></build>'

url = "http://myteamcity.com:8111/httpAuth/app/rest/buildQueue/"
headers = {'Content-Type': 'application/xml'}
build_id = 'MyTestBuild'
data = template.format(id=quoteattr(build_id))

r = requests.post(url, headers=headers, data=data, auth=("username", "password"), timeout=10)

请注意,我使用 xml.sax.saxutils.quotattr() function 来确保 build_id 的值被正确引用以包含在 XML 属性中。

这将产生 XML;如果要处理 JSON 响应,请将 'Accept': 'application/json' 添加到 headers 字典。

仅供参考 json 请求在 TeamCity 10 中有效。

自从编写并回答了这个问题后,现在就存在一个当代的 OSS 替代方案:pyteamcity

要安装的 pip 命令(或将 pyteamcity 添加到 requirements.txt 等)

pip install pyteamcity

代码:

from pyteamcity import TeamCity
tc = TeamCity('username', 'password', 'server', 'port')
result = tc.trigger_build('build_id')
print(f'Build triggered. Web URL: {result['webUrl']}')