httpie POST请求转Python requests库调用方法
httpie POST 请求迁移为 Python requests 的实现方法
报错核心原因
你遇到的GraphQL server error (client error): expected value at line 1 column 1报错,本质是两次请求的实际传输结构完全不等价,具体存在两类问题:
- 字符串冗余引号错误:你写的Python代码中,GraphQL查询字符串首尾多包裹了Shell层面的单引号,实际传给服务端的查询内容第一个字符就是单引号,不符合GraphQL要求的
{作为查询起始标识的规则。这些单引号原本只是Shell命令行里用来包裹带空格字符串的本地语法,根本不会被httpie发送到服务端。之前你尝试用字典形式作为data参数传值仍然报错,基本也是字典内的query值同样残留了这类多余的单引号。 - 请求体结构不匹配:httpie 在写
query='xxx'形式的键值对POST参数时,默认会将参数编码为application/x-www-form-urlencoded格式的表单结构,组装成query=<编码后的查询内容>的请求体;而你之前直接把裸查询字符串作为data参数传入requests时,请求体没有query=的键名标识,服务端无法识别到合法的参数字段,自然无法正常解析。
可直接运行的正确实现
1:1 复刻原httpie请求的写法
完全对齐你当前能正常运行的httpie请求的传输结构:
import requests url = "https://api.thegraph.com/subgraphs/name/graphprotocol/graph-network-mainnet" # 移除所有多余的包裹引号,保留纯GraphQL查询内容 graphql_query = """{ indexers { id } }""" # 以表单字典形式传参,requests会自动完成URL编码、设置对应请求头 resp = requests.post(url, data={"query": graphql_query}) print(resp.text)
更通用的GraphQL标准写法
所有遵循GraphQL规范的服务端都兼容JSON格式传参,实际使用的稳定性高于表单传参:
import requests url = "https://api.thegraph.com/subgraphs/name/graphprotocol/graph-network-mainnet" graphql_query = """{ indexers { id } }""" # 使用json参数传参,requests会自动设置Content-Type为application/json resp = requests.post(url, json={"query": graphql_query}) print(resp.text)
通用转换避坑规则
- 命令行工具(httpie、curl)的Shell语法引号仅用于本地包裹带空格的参数内容,转换为Python代码时必须移除,不能作为参数内容的一部分发送给服务端
- httpie的参数格式和requests传参的对应关系:
- 写
key=value形式的POST参数,默认对应requests的data={"key": "value"}(表单编码) - 写
json:key=value形式的POST参数,对应requests的json={"key": "value"}(JSON格式请求体)
- 写
- 排查参数等价性的最快方式:给httpie命令加
--print=HB参数,直接查看实际发送的请求头、请求体内容,1:1复刻结构即可避免结构不匹配的问题
内容的提问来源于stack exchange,提问作者Jonathan Lindgren
相关产品推荐
相关产品推荐

