Kubernetes Python 客户端 returns pod 的 JSON 来自代理动词的 HTTP 响应作为带有单引号而不是双引号的字符串

Kubernetes Python client returns pod's JSON HTTP response from proxy verb as string with single quotes instead of double quotes

我正在通过 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)

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

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

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

的任何建议

阅读 Kubernetes Python 客户端的一些代码后,现在很清楚 connect_get_namespaced_pod_proxy()connect_get_namespaced_pod_proxy_with_path() 强制响应主体从远程 API 调用到通过调用 self.api_client.call_api(..., response_type='str', ...) (core_v1_api.py) 转换为 str。所以,我们坚持使用 Kubernetes API 客户端,它只给我们 dict() 的字符串表示,表示原始 JSON 响应主体。

要将字符串转换回 dict()anwer to Convert a String representation of a Dictionary to a dictionary? suggests to use ast.literal_eval(). Wondering whether this is a sensible route to take, I've found the 表示这是明智之举。

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)

我 运行 在 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) 就可以了:)

正在查看 core_v1_api.py 的源代码。方法调用通常接受名为 _preload_content.

的 kwarg

将此参数设置为 False 指示方法 return urllib3.HTTPResponse 对象而不是已处理的 str。然后您可以直接使用与 json.loads().

协作的数据

示例:

corev1 = client.CoreV1Api()
res = corev1.connect_get_namespaced_pod_proxy_with_path(
    'mypod:5000', 'default', path='somepath', 
    path2='somepath', _preload_content=False)
json.loads(res.data)