RallyDev: 无法创建缺陷。服务器提示“无法解析输入...”

3 投票
1 回答
1267 浏览
提问于 2025-04-17 23:23

原帖: 我正在尝试通过编程的方式创建缺陷(bug)。但是我遇到了一些错误,进展得很困难。基本上,我的代码是这样的:

import requests, json

rally_auth = ('my_user', 'my_pw')
rally_auth_url = 'https://rally1.rallydev.com/slm/webservice/v2.0/security/authorize'
rally_defect = 'https://rally1.rallydev.com/slm/webservice/v2.0/defect/defect'
workspace_ref = 'https://rally1.rallydev.com/slm/webservice/v2.0/workspace/12345'
fe_project_ref = 'https://rally1.rallydev.com/slm/webservice/v2.0/project/7890'                                                                                                                      
current_fe_release_ref = "https://rally1.rallydev.com/slm/webservice/v2.0/release/45678"

r = requests.get(rally_auth_url, auth=rally_auth)
token = r.json()['OperationResult']['SecurityToken']
url = rally_defect + '/create?key=' + token

payload = {
  'Name': 'My defect',
  'State': 'Open',                                                                                                                       
  'Project': fe_project_ref,                                                                                                        
  'Rank': 120,                                                                                                                           
  'Release': current_fe_release_ref,                                                                                                
  'key': token
}
headers = {'content-type': 'application/json'}
r = requests.post(url, data=json.dumps(payload), auth=rally_auth, headers=headers)

你会注意到我把令牌(token)放在了POST请求的URL和数据里。API文档说我应该在URL中包含这个密钥,但如果我不把密钥放在POST数据里,我就会收到:

{"CreateResult": {"_rallyAPIMajor": "2", "_rallyAPIMinor": "0", "Errors": ["Not authorized to perform action: Invalid key"], "Warnings": []}}

如果我把密钥放进去,API请求就会以不同的方式失败。它会在第一个逗号那里出错。

{"CreateResult": {"_rallyAPIMajor": "2", "_rallyAPIMinor": "0", "Errors": ["Cannot parse input stream due to I/O error as JSON document: Parse error: expected '}' but saw ',' [ chars read = >>>{\"Name\": \"My defect\",<<< ]"], "Warnings": []}}

我感到很困惑。


修复后的代码 感谢@nickm

import requests, json

rally_auth = ('my_user', 'my_pw')
rally_auth_url = 'https://rally1.rallydev.com/slm/webservice/v2.0/security/authorize'
rally_defect = 'https://rally1.rallydev.com/slm/webservice/v2.0/defect/defect'
workspace_ref = 'https://rally1.rallydev.com/slm/webservice/v2.0/workspace/12345'
fe_project_ref = 'https://rally1.rallydev.com/slm/webservice/v2.0/project/7890'                                                                                                                      
current_fe_release_ref = "https://rally1.rallydev.com/slm/webservice/v2.0/release/45678"

s = requests.Session()
r = s.get(rally_auth_url, auth=rally_auth)
token = r.json()['OperationResult']['SecurityToken']
url = rally_defect + '/create?key=' + token

payload = {
  'Name': 'My defect',
  'State': 'Open',                                                                                                                       
  'Project': fe_project_ref,
  'Rank': 120,
  'Release': current_fe_release_ref,
}
headers = {'content-type': 'application/json'}
r = s.post(url, data=json.dumps(payload), headers=headers)

1 个回答

1

如果你在使用WS API的2.0版本,那么在更新和创建请求时是需要一个令牌的,所以你在请求的URL中加上它是对的。

如果请求中没有附加令牌,或者令牌在特定会话中无效,就会出现无效密钥的错误。当我们直接访问接口时,必须保持一个带有cookie的HTTP会话,否则请求会在一个新的会话中进行,这个会话和我们获取令牌时的会话是不同的。

请查看这篇帖子。虽然它不是专门针对Python的,但概念上是一样的。

我注意到你在请求中提到了Rank。你有自定义的Rank字段吗?在Rally的2.0版本中并没有这样的内置字段。有一个叫DragAndDropRank的字段,但它不是数字类型,给它设置一个值为120是行不通的。另外,你在请求中试过用双引号而不是单引号吗?

有一个叫pyral的Rally Python工具包,它提供了一些方便的方法,这样你就不需要直接访问接口了。目前它支持WS API的1.43版本。这个工具包并没有官方支持,但我预计在2014年6月之前,它会更新以支持WS API的2.0版本,因为到时候1.43版本将不再被支持(根据这个时间表)。

安全令牌是在2.0版本中引入的。这个额外的身份验证层在WS API的1.43版本中是不存在的,如果使用pyral,你就不需要处理令牌。

撰写回答