postman可以请求成功,但是postman生成的python代码不行

云开发产品技术讨论,包括IoT Core和其他云服务API、数据分析产品等话题


Post Reply
luentong
Posts: 2

我自己模拟postman的pre-req javascript逻辑写了一套python代码,最后的请求参数都是一摸一样的,同样也是不行。都是报sign invalid. 请问是为什么,今天弄了一个晚上,有点崩溃。。


Tags:
luentong
Posts: 2

Re: postman可以请求成功,但是postman生成的python代码不行

import requests
import json

url = "https://openapi.tuyacn.com/v1.0/devices ... value=true"

payload = json.dumps({
"commands": [
{
"code": "switch_1",
"value": True
}
]
})
headers = {
'client_id': 'ed8gtgj49j8ydsdtrjr9',
'access_token': ********************************',
'sign': '
***********************',
't': '1736613094839',
'sign_method': 'HMAC-SHA256',
'Content-Type': 'application/json',
'nonce': '',
'stringToSign': ''
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)
这种设备指令下发的代码,打星号的都是和postman中console看到的一摸一样,还是会报错

qiufeng.yu
Posts: 17

Re: postman可以请求成功,但是postman生成的python代码不行

你好,云开发平台针对 python 开发者也提供了相应的 SDK,你可以在这里找到:https://developer.tuya.com/cn/docs/iot/ ... 09frvx48db

使用起来也很简单,比如查询设备信息:

Code: Select all

def main():
    from tuya_connector import (
        TuyaOpenAPI,
    )

ACCESS_ID = "你的云项目 ClientId"
ACCESS_KEY = "你的云项目 SecretKey"
API_ENDPOINT = "https://openapi.tuyacn.com"

# Init openapi and connect
openapi = TuyaOpenAPI(API_ENDPOINT, ACCESS_ID, ACCESS_KEY)
openapi.connect()

# Call any API from Tuya
response = openapi.get("/v1.1/iot-03/devices/{你的设备 ID}")
# 打印 response
print(response)


if __name__ == "__main__":
    main()

当然你也可以参考这个 SDK 里的签名逻辑,代码在 openapi.py 文件里:

Code: Select all

    def _calculate_sign(
        self,
        method: str,
        path: str,
        params: Optional[Dict[str, Any]] = None,
        body: Optional[Dict[str, Any]] = None,
    ) -> Tuple[str, int]:

    # HTTPMethod
    str_to_sign = method
    str_to_sign += "\n"

    # Content-SHA256
    content_to_sha256 = (
        "" if body is None or len(body.keys()) == 0 else json.dumps(body)
    )

    str_to_sign += (
        hashlib.sha256(content_to_sha256.encode(
            "utf8")).hexdigest().lower()
    )
    str_to_sign += "\n"

    # Header
    str_to_sign += "\n"

    # URL
    str_to_sign += path

    if params is not None and len(params.keys()) > 0:
        str_to_sign += "?"

        query_builder = ""
        params_keys = sorted(params.keys())

        for key in params_keys:
            query_builder += f"{key}={params[key]}&"
        str_to_sign += query_builder[:-1]

    # Sign
    t = int(time.time() * 1000)

    message = self.access_id
    if self.token_info is not None:
        message += self.token_info.access_token
    message += str(t) + str_to_sign
    sign = (
        hmac.new(
            self.access_secret.encode("utf8"),
            msg=message.encode("utf8"),
            digestmod=hashlib.sha256,
        )
        .hexdigest()
        .upper()
    )
    return sign, t
Post Reply