【问题标题】:Kubernetes Python client returns pod's JSON HTTP response from proxy verb as string with single quotes instead of double quotesKubernetes Python 客户端从代理动词返回 pod 的 JSON HTTP 响应,作为带有单引号而不是双引号的字符串
【发布时间】:2019-04-25 13:09:57
【问题描述】:

我正在通过 Kubernetes API 代理动词从 pod 的 Web 服务器请求一些 JSON 数据。那就是:

corev1 = kubernetes.client.CoreV1Api()
res = corev1.connect_get_namespaced_pod_proxy_with_path(
    'mypod:5000', 'default', path='somepath', path2='somepath')
print(type(res))
print(res)

调用成功并返回一个str,其中包含来自我的 pod 的 Web 服务的序列化 JSON 数据。不幸的是,res 现在看起来像这样......这根本不是有效的 JSON,所以json.loads(res) 拒绝解析它:

{'x': [{'xx': 'xxx', ...

如您所见,字符串化响应看起来像 Python 字典,而不是有效的 JSON。关于如何将它安全地转换回正确的 JSON 或正确的 Python dict,有什么建议吗?

【问题讨论】:

  • res.replace("'",""")?))
  • 不是一个好主意,因为当名称或字符串中有转义的“'”时,这会中断。另外,eval() 也不是一个好主意,因为那样可能有人会攻击我的 Kubernetes 客户端。

标签: json kubernetes proxy kubernetes-python-client


【解决方案1】:

在阅读了 Kubernetes Python 客户端的一些代码后,现在很清楚 connect_get_namespaced_pod_proxy()connect_get_namespaced_pod_proxy_with_path() 通过调用 self.api_client.call_api(..., response_type='str', ...) (@987654321) 强制将远程 API 调用的响应体转换为 str @)。所以,我们被 Kubernetes API 客户端卡住了,它只给我们提供了 dict() 的字符串表示形式,代表原始 JSON 响应正文。

要将字符串转换回dict()anwer to Convert a String representation of a Dictionary to a dictionary? 建议使用ast.literal_eval()。想知道这是否是明智的选择,我发现answer to Is it a best practice to use python ast library for operations like converting string to dict 说这是明智的做法。

import ast
corev1 = kubernetes.client.CoreV1Api()
res = corev1.connect_get_namespaced_pod_proxy_with_path(
    'mypod:5000', 'default', path='somepath', path2='somepath')
json_res = ast.literal_eval(res)

【讨论】:

    【解决方案2】:

    我在 pod 上执行时遇到了类似的问题并找到了解决方案。 我想它也对你有用。

    1. 将参数 _preload_content=False 添加到流调用中 -> 您会收到一个 WSClient 对象
    2. 调用 run_forever(timeout=10) 就可以了
    3. 然后使用 .read_stdout() 得到正确且未格式化的字符串

    例如:

    wsclient_obj = stream(v1.connect_get_namespaced_pod_exec, m
                        y_name,
                        'default',
                        command=['/bin/sh', '-c', 'echo $MY_VAR'],
                        stderr=True,
                        stdin=False,
                        stdout=True,
                        tty=False,
                        _preload_content=False
                    )
    wsclient_obj.run_forever(timeout=10)
    response_str = wsclient_obj.read_stdout()
    

    之后json.loads(response_str) 将起作用:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      相关资源
      最近更新 更多