【问题标题】:Python cURL command via os.system() fails with JSON parse error通过 os.system() 的 Python cURL 命令因 JSON 解析错误而失败
【发布时间】:2017-11-09 12:37:17
【问题描述】:

您好,我正在尝试通过 Python 脚本向 Orion 上下文代理发送 cURL 命令。 我在 OpenWRT 上运行脚本,所以我无法安装 requestsurllib2 库,因为内存问题,另外像 subprocess 这样的库无法编译。所以我使用os.system() 来执行cURL 命令。这是脚本的代码:

import sys
import os
from urllib import urlencode
sys.path.insert(0, '/usr/lib/python2.7/bridge')
from bridgeclient import BridgeClient as bridgeclient

value = bridgeclient()


header="(curl 10.130.1.228:1026/v1/updateContext -s -S --header 'Content-Type: application/json' \
--header 'Accept: application/json'     -d @- | python -mjson.tool) <<EOF"

json_string="""
{
    "contextElements": [
        {
            "type": "Room",
            "isPattern": "false",
            "id": "R1",
            "attributes": [
                {
                    "name": "temperature",
                    "type": "float",
                    "value": "firstValue"
                },
                {
                    "name": "pressure",
                    "type": "float",
                    "value": "secondValue"
                }
            ]    
        }
    ],
    "updateAction": "UPDATE"
}
EOF""" 


while(True):

    all=value.getall()
    sentValue1=""
    sentValue2=""
    if all['Tmp'] is None:
        sentValue1=all['Tmp']
    else:
        sentValue1="NoValue"
    if all['Prs'] is None:
        sentValue2=all['Prs']
    else:
        sentValue2="NoValue"
    json_string=json_string.replace("firstValue",sentValue1)
    json_string=json_string.replace("secondValue",sentValue2)   
    os.system(header+json_string)

如果我复制并粘贴我给os.system() 的命令,就像它在终端窗口中一样,一切都会顺利进行,我的 Orion 实例也会更新。但是,如果我通过上述脚本运行相同的命令,我会从服务器得到这个响应:

{
    "errorCode": {
        "code": "400",
        "details": "JSON Parse Error",
        "reasonPhrase": "Bad Request"
    }
}

我认为是一些格式问题,我已尽一切努力使其工作,但没有运气。

更新:

我在 contextBroker 日志中发现了这条消息:

from=10.130.1.1 | srv=pending | subsrv=<defalut> | comp=Orion | 
op=AlarmMenager.cpp[405]:badInput | msg=Releasing alarm BadInput 
10.130.1.1: JSON Parse Error: unspecified file(1):expected end of input

还有这个:

from=10.130.1.1 | srv=pending | subsrv=<defalut> | comp=Orion | 
op=AlarmMenager.cpp[405]:badInput | msg=Releasing alarm BadInput 
10.130.1.1: JSON Parse Error: unspecified file(1):expected object

对我提出的每个 cURL 请求都重复。

更新 2:

我设法让subprocess.call() 工作,但它给出了完全相同的响应。

【问题讨论】:

  • 如果您在 header 变量中指定 /usr/bin/python 是否值得?
  • @Shan-Desai 我试过了,但没用。同样正如我所说,在终端中复制和粘贴的字符串 header+json_string 没有问题。
  • 如果可以,请尝试使用pycurl。不过要解决这个问题。使用import json,然后不要编写字符串,而是将json_string 创建为python 字典并使用json.dumps(json_string)
  • @Shan-Desai 非常感谢您的帮助。但是如果我需要一个嵌套的 json,我该如何制作一个 python 字典呢?

标签: python json curl fiware-orion


【解决方案1】:

感谢@Shan-Desai 我解决了这个问题。

我使用 json.dump 构建了 json 字符串并使用了 pycurl。

这是工作代码:

import sys
import os
import subprocess
import json
from urllib import urlencode
from collections import OrderedDict
import StringIO
import pycurl

sys.path.insert(0, '/usr/lib/python2.7/bridge')
from bridgeclient import BridgeClient as bridgeclient


fout = StringIO.StringIO()
value = bridgeclient()
apiurl = '10.130.1.228:1026/v1/updateContext'
headers=['Content-Type: application/json','Accept: application/json']

firstValue = 'firstValue'

secondValue = 'secondValue'

d_attributes = [{'name': 'temperature', 'type': 'float', 'value': firstValue},
            {'name': 'pressure', 'type': 'float', 'value': secondValue}]

d_context = [{'type': 'Room', 'isPattern': 'false', 'id': 'R1', 'attributes': d_attributes}]

d_json = {'contextElements': d_context, 'updateAction': 'UPDATE'}

c = pycurl.Curl()

while (True):

        all = value.getall()

        if all['Tmp'] is not None:
            firstValue = all['Tmp']
        else:
            firstValue = "NoValue"
        if all['Prs'] is not None:
            secondValue = all['Prs']
        else:
            secondValue = "NoValue"
        d_json["contextElements"][0]["attributes"][0]["value"]=firstValue
        d_json['contextElements'][0]['attributes'][1]['value']=secondValue
        c.setopt(pycurl.WRITEFUNCTION, fout.write)
        c.setopt(pycurl.URL, apiurl)
        c.setopt(pycurl.HTTPHEADER, headers)
        c.setopt(pycurl.POST, 1)
    s_json=json.dumps(d_json)
        c.setopt(pycurl.POSTFIELDS,s_json)
        c.perform()
        c.getinfo(pycurl.RESPONSE_CODE)
        print(json.dumps(OrderedDict(d_json)))
        print(fout.getvalue())

【讨论】:

    猜你喜欢
    • 2020-10-07
    • 1970-01-01
    • 2017-03-08
    • 2020-06-18
    • 2019-07-06
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 2014-01-31
    相关资源
    最近更新 更多