Azure Devops:进行 API 调用后,CFD 小部件在 Web 界面中出现错误

问题描述 投票:0回答:1

我一直在编写一些 Python 代码来以编程方式更新 CFD 小部件设置,以显示过去 14、15、16 天等的数据。 但是,当我测试 API 端点 来更新小部件时,Web 界面向我抛出一个错误:

TypeError: e.split is not a function

但是,我发出的API请求得到了成功的返回。 这是代码:

import fazer_requisicoes
import json
import base64
import os
from dotenv import load_dotenv
from pprint import pp

load_dotenv()

token_do_azure = os.environ['AZURE_DEVOPS_PAT']

pat_encoded = base64.b64encode((":" + token_do_azure).encode()).decode()
headers = {
    'Content-Type': 'application/json',
    'Authorization': f'Basic {pat_encoded}'
}

settings_dict = {
    "chartDataSettings": {
        "timePeriod": {
            "settings": 16
        }
    }
}

def atualizar_cfd():
    organization = r'ACR-AcompanhamentoCliente'
    project = r'S565 - Acompanhamento de Clientes'
    team = r'S565 - Acompanhamento de Clientes Team'
    dashboard_id = r'c80b8254-5432-442e-a0af-c761af863f1e'
    widget_id = r'591ecd56-87ed-4dcf-ae65-4c7619a1c79d'
    url = f'https://dev.azure.com/{organization}/{project}/{team}/_apis/dashboard/dashboards/{dashboard_id}/widgets/{widget_id}?api-version=7.2-preview.2'
    get_req = fazer_requisicoes.fazer_requisicoes("GET", url, headers)
    get_req_text = json.loads(get_req.text)
    # Assuming the ETag is in the body, otherwise look for it in the headers
    current_etag_widget = get_req_text['eTag']
    current_etag_dashboard = get_req_text['dashboard']['eTag']
    pp(current_etag_widget)
    pp(current_etag_dashboard)
    url = f'https://dev.azure.com/{organization}/{project}/{team}/_apis/dashboard/dashboards/{dashboard_id}/widgets/{widget_id}?api-version=7.2-preview.2'
    req_body = {
        "id": widget_id,
        "name": "Cumulative Flow Diagram (CFD)",
        "eTag": f'{current_etag_widget}',
        'position': {'row': 4, 'column': 5},
        "size": {
            "rowSpan": 2, "columnSpan": 3
        },
        'settings': settings_dict,
        "settingsVersion":
        {
            "major": 1,
            "minor": 0,
            "patch": 0
        },
        "contributionId": "ms.vss-dashboards-web.Microsoft.VisualStudioOnline.Dashboards.CumulativeFlowDiagramWidget",
        'dashboard': {'position': -1,
                      'eTag': f'{current_etag_dashboard}',
                      'modifiedDate': '0001-01-01T00:00:00',
                      'lastAccessedDate': '0001-01-01T00:00:00'},
    }
    req = fazer_requisicoes.fazer_requisicoes("PATCH", url, headers, req_body)
    req_text = json.loads(req.text)
    req_response = json.dumps(req_text)
    pp(req_response)


def main():
    atualizar_cfd()


main()

这是 'fazer_requisicoes 函数:

import requests
import time
import urllib3
from requests.exceptions import JSONDecodeError
from pprint import pprint

urllib3.disable_warnings()

session = requests.Session()

contador_timeout = 0
contador_SSL = 0

def fazer_requisicoes(metodo, url, headers, request_body=None):
    global contador_timeout
    global contador_SSL

    while True:
        try:
            if metodo in ['GET', 'DELETE']:
                req = session.request(metodo, url, headers=headers, verify=False)
            else:
                req = session.request(metodo, url, headers=headers, json=request_body, verify=False)
                try:
                    req.json()
                except JSONDecodeError:
                    print(f'{req.status_code}\n')
                    pprint(req.text)
                    print(f"Resposta inválida recebida. Tentando novamente...")
                    time.sleep(10)
                    continue 
            return req
        except requests.exceptions.ConnectTimeout as e:
            contador_timeout += 1
            print(f"Erro de timeout número {contador_timeout}. Tentando novamente...")
            time.sleep(10)
        except requests.exceptions.SSLError as e:
            contador_SSL += 1
            print(f"Erro de SSL número {contador_SSL}. Tentando novamente...")
            time.sleep(10)

我可以修复它吗?如果是的话,怎么办?

我尝试在设置中使用多行,但它在 Web 界面中引发了另一个错误,即 SyntaxError。

python azure azure-devops azure-devops-rest-api
1个回答
0
投票

您的问题可能与以下几件事有关:

  1. settings
    ”对象的值是一个json字符串,其中所有双引号(
    "
    )都通过斜杠(
    \
    )转义。当传递给
    PATCH
    API 调用时,还应该使用转义的 json 字符串。

  2. 更新“

    settings
    ”对象的值时,似乎需要将整个转义的json字符串与更新的部分一起传递给
    PATCH
    API调用。

下面是我尝试的一个 Python 示例。它可以很好地更新CFD Widget的设置,不会出现任何错误。您可以参考它来更新您的 Python 脚本。

# coding=utf-8

import os
import json
import base64
import requests

organization = '{organization}'
project = '{project}'
team = '{team}'
dashboardId = '{dashboardId}'
widgetId = '{widgetId}'

ado_pat = os.environ['AZURE_DEVOPS_PAT']
b64token = base64.b64encode((":" + ado_pat).encode()).decode()

url = f'https://dev.azure.com/{organization}/{project}/{team}/_apis/dashboard/dashboards/{dashboardId}/widgets/{widgetId}?api-version=7.2-preview.2'

headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': f'Basic {b64token}'
}

session = requests.Session()

print("-------------------- CFD Widget befor updating --------------------")
response_get = session.request('GET', url, headers=headers, json=None)
json_object_get = json.loads(response_get.content)
json_format_get = json.dumps(json_object_get, indent=2)
print(json_format_get)

print("-------------------- Updating CFD Widget --------------------")
body_patch = json_object_get

print("The settings before updating is:")
settings = body_patch["settings"]
json_object_settings = json.loads(settings)
json_format_settings = json.dumps(json_object_settings, indent=2)
print(json_format_settings)

print("Update the settings to:")
json_object_settings["chartDataSettings"]["timePeriod"]["settings"] = 20
json_format_settings_updated = json.dumps(json_object_settings, indent=2)
print(json_format_settings_updated)

print("-------------------- CFD Widget after updating --------------------")
body_patch["settings"] = json.dumps(json_object_settings).replace('"', '\"')
response_patch = session.request('PATCH', url, headers=headers, json=body_patch)
json_object_patch = json.loads(response_patch.content)
json_format_patch = json.dumps(json_object_patch, indent=2)
print(json_format_patch)
© www.soinside.com 2019 - 2024. All rights reserved.