在 python3 dict 中包含 unicode 字符

问题描述

我正在尝试将带有标签的 dict 发送到 check_mk web-api - 但是 web-api 使用 python2 - 并且开发人员坚持要验证标签是 Unicode。

我在 p3 中的示例字典:

"": [
    {
        "condition": {
            "service_description": [
                {
                    "$regex": "Callcentre Queue: OTU"
                }
            ]
        },"value": {
            u"max_check_attempts": u"3"
        },"options": {
            "description": "Label - max_check_attempts\nService - Callcentre Queue: OTU"
        }
    }]

但是在发送时,我收到了 label max_check_attempts must be unicode type 错误

Traceback (most recent call last):
  File "./cmk_import.py",line 415,in <module>
    process_service_rulelist()
  File "./cmk_import.py",line 309,in process_service_rulelist
    api().set_ruleset('service_label_rules',total_lbl_ruleset)
  File "/usr/local/lib/python3.6/dist-packages/check_mk_web_api/__init__.py",line 724,in set_ruleset
    return self.make_request('set_ruleset',data=data,query_params={'request_format': 'python'})
  File "/usr/local/lib/python3.6/dist-packages/check_mk_web_api/__init__.py",line 164,in make_request
    raise CheckMkWebApiException(result)
check_mk_web_api.exception.CheckMkWebApiException: Check_MK exception: ERROR: The label ID 'max_check_attempts' is of type <type 'str'>,but should be unicode. Affected Rule {'value': {'max_check_attempts': '3'},'condition': {'service_description': [{'$regex': 'Callcentre Queue: OTU'}]},'options': {'description': 'Label - max_check_attempts\nService - Callcentre Queue: OTU'}}

错误来自 check_mk web-api 发出的 checkMK 本身。由于侦听代理是 Python2 - 它试图将 type() 验证为 unicode

我知道 P3 已将 unicode 合并到 str 中 - 但想知道是否有一种方法可以覆盖和保留 dict unicode 字符,而无需重写 python2 中受影响的部分。>

Web 请求由这个库处理 - https://github.com/brennerm/check-mk-web-api

request = urllib.request(self._build_request_path(query_params),WebApi._build_request_data(data,request_format))

其中的内容是: 参数 1:

http://localhost/preprod/check_mk/webapi.py?effective_attributes=0&action=get_all_hosts&_username=automation&_secret=foobar

和片段:

{%27condition%27: {%27service_description%27: [
{%27%24regex%27: %27VPN: Premier Ping - 1.1.1.1%27}

]},%27value%27:
{%27check_interval%27: %275%27,%27max_check_attempts%27: %273%27,%27retry_interval%27: %271%27,%27check_period%27: %2724x7%27,%27notification_period%27: %2724x7%27,%27notification_interval%27: %27120%27,%27notifications_enabled%27: %271%27,%27active_checks_enabled%27: %271%27,%27check_freshness%27: %270%27,%27event_handler_enabled%27: %271%27,%27flap_detection_enabled%27: %271%27,%27is_volatile%27: %270%27,%27obsess_over_service%27: %271%27,%27passive_checks_enabled%27: %271%27,%27process_perf_data%27: %271%27,%27retain_nonstatus_information%27: %271%27,%27retain_status_information%27: %271%27},%27options%27: {%27description%27: %27Labels for Service - VPN: Premier Ping - 1.1.1.1%27}}

解决方法

API 客户端以它所谓的“python”格式发送数据,该格式基本上是一个已调用 str() 的字典。目的是服务器将在此字典字符串上调用 ast.literal_eval()。客户端对响应的正文执行相同的操作。将其转换回 Python dict。

在整个 API 中有一些地方确实支持 JSON 进行请求/响应处理,并且可以在某些功能的查询参数中设置。不幸的是,对于此处失败的特定请求 (set_ruleset) JSON 不是一个选项。

服务器无法处理此请求的原因并不明显。我尝试在 Python 2 中取消引用消息正文并通过 literal_eval() 运行它,它似乎有效。

我注意到的一件事是请求字典 "Label - max_check_attempts\nService - Callcentre Queue: OTU" 中嵌入的换行符。这可能是服务器在提到“标签 ID 'max_check_attempts'”时所抱怨的。

进一步的问题跟踪需要查看服务器日志和可能的代码,以了解那里发生了什么。