如何使用Python请求库发布帖子请求?

时间:2017-07-19 21:49:18

标签: python json django python-3.x cassandra

我在Postman中使用以下过滤器在Web API中发出POST请求,但我无法在Python中使用请求库发出简单的POST请求。

首先,我发送一个POST请求到这个URL(http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets),Postman中的以下过滤器应用于Body,带有raw和JSON(application / json)选项选择。

Filters in Postman

{
  "filter": {
    "filters": [
      {
        "field": "RCA_Assigned_Date",
        "operator": "gte",
        "value": "2017-05-31 00:00:00"
      },
      {
        "field": "RCA_Assigned_Date",
        "operator": "lte",
        "value": "2017-06-04 00:00:00"
      },
      {
        "field": "T_Subcategory",
        "operator": "neq",
        "value": "Temporary Degradation"
      },
      {
        "field": "Issue_Status",
        "operator": "neq",
        "value": "Queued"
      }],
     "logic": "and"
    }
}

存储数据的数据库是Cassandra,并根据以下链接Cassandra not equal operatorCassandra OR operator,  Cassandra Between order by operators,Cassandra不支持 NOT EQUAL TO OR BETWEEN 运算符,所以我无法过滤使用这些运算符的网址除 AND 外。

第二次,我使用以下代码将简单过滤器应用于请求库。

import requests
payload = {'field':'T_Subcategory','operator':'neq','value':'Temporary Degradation'}
url = requests.post("http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets",data=payload)

但我得到的是门票的完整数据,而不仅仅是那些不是暂时退化的门票。

第三次,系统实际上正在运行但我们正在经历2-3分钟的延迟才能看到数据。逻辑如下:我们有8个用户,我们希望看到每个用户的所有票证都不会暂时降级,然后我们

def get_json():
    if user_name == "user 001":
        with urllib.request.urlopen(
    "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets?user_name=user&001",timeout=15) as url:
            complete_data = json.loads(url.read().decode())

    elif user_name == "user 002":
        with urllib.request.urlopen(             
    "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets?user_name=user&002",timeout=15) as url:
            complete_data = json.loads(url.read().decode())
    return complete_data

def get_tickets_not_temp_degradation(start_date,end_date,complete_):
    return Counter([k['user_name'] for k in complete_data if start_date < dateutil.parser.parse(k.get('DateTime')) < end_date and k['T_subcategory'] != 'Temporary Degradation'])

基本上,我们从当前和去年获得整套票,然后我们让Python过滤用户的完整集,到目前为止只有10个用户,这意味着这个过程重复10次,让我毫不奇怪地发现为什么我们得到延迟...

我的问题是如何解决请求库的这个问题?我使用以下链接Requests library documentation作为教程使其工作,但似乎我的有效负载没有被读取。

5 个答案:

答案 0 :(得分:9)

您的邮递员请求是JSON正文。只需在Python中重现相同的主体即可。您的Python代码不发送JSON,也不发送与Postman示例相同的数据。

对于初学者,通过application/x-www-form-urlencoded参数发送字典会将该字典编码为import requests filters = {"filter": { "filters": [{ "field": "RCA_Assigned_Date", "operator": "gte", "value": "2017-05-31 00:00:00" }, { "field": "RCA_Assigned_Date", "operator": "lte", "value": "2017-06-04 00:00:00" }, { "field": "T_Subcategory", "operator": "neq", "value": "Temporary Degradation" }, { "field": "Issue_Status", "operator": "neq", "value": "Queued" }], "logic": "and" }} url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets" response = requests.post(url, json=filters) 表单,而不是JSON。其次,您似乎正在发送一个过滤器。

以下代码完全复制了您的邮递员帖子:

filters

请注意,json Python 数据结构,并将其传递给Content-Type关键字参数。使用后者有两件事:

  • 将Python数据结构编码为JSON(生成与原始Postman体值完全相同的JSON值)。
  • application/json标题设置为JSON(正如您在Postman配置中所做的那样,选择正文raw后,在下拉菜单中选择requests选项。

urllib.request.urlopen否则只是一个HTTP API ,它不能使Cassandra做任何其他HTTP库。 GET代码发送requests个请求,并通过以下内容轻松转换为def get_json(): url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets" response = requests.get(url, params={'user_name': user}, timeout=15) return response.json()

if

我删除了params分支,并使用user_name参数替换了该参数,该参数将键值对字典转换为正确编码的URL查询(将用户名作为{{传递) 1}}键)。

请注意json()对回复的调用;这将负责解码从服务器返回的JSON数据。这仍然需要很长时间,你不会在这里过滤Cassandra数据。

答案 1 :(得分:4)

我建议使用json属性而不是数据。它为你处理倾销。

import requests

data = {'user_name':'user&001'}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets/"
r = requests.post(url, headers=headers, json=data)

更新,回答问题3.你有没有理由使用urllib?我也会对此请求使用python请求。

import requests

def get_json():
    r = requests.get("http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets”, params={"user_name": user_name.replace(" ", "&")})

    return r.json

# not sure what you’re doing here, more context/code example would help
def get_tickets_not_temp_degradation(start_date, end_date, complete_):
    return Counter([k['user_name'] for k in complete_data if start_date < dateutil.parser.parse(k.get('DateTime')) < end_date and k['T_subcategory'] != 'Temporary Degradation'])

此外,用户名真的应该是user+001而不是user&001user 001吗?

答案 2 :(得分:0)

我认为,您可以按如下方式使用请求库:

import requests
import json

payload = {'field':'T_Subcategory','operator':'neq','value':'Temporary Degradation'}
url = requests.post("http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets",data=json.dumps(payload))

答案 3 :(得分:0)

您正在使用网址发送用户,通过帖子使用它,但它取决于端点的实现方式。您可以尝试以下代码:

import requests
from json import dumps

data = {'user_name':'user&001'}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets/"
r = requests.post(url, headers=headers, data=dumps(data))

答案 4 :(得分:0)

我的经验如下:我已经尝试过urllib并在python中请求很多来处理API。这是非常有问题的。通常GET请求是直接的,但POST请求是非常有问题的。有时不起作用(如在你的有效载荷情况下),或者更糟糕的是,它工作得很糟糕。我最近有这个脚本通过了我的测试,但它对生产的某些情况不起作用,直到我发现有特殊字符的请求(如葡萄牙语中的ã)不起作用。 :(
在某些时候,我说'对这个黑盒依赖性来说是地狱'。事实上,可以在没有python或任何其他脚本语言的情况下进行任何API调用(至少你需要使用bash)。作为UNIX用户,可以将CURL用于一切。这是解放!没有更多的例子不起作用,没有更多的语言版本没有更多的http库。我只是从终端发送一个卷曲请求,看看我想要的是什么。 你的情况是:

curl -H "Content-Type: application/json" -d '{"field":"T_Subcategory","operator":"neq","value":"Temporary Degradation"}' "http://10.61.202.98:8081/T/a/api/rows/cat/ect/tickets"

接下来,我为GET构建以下python脚本:

import subprocess
import json

header1 = "Content-Type: application/json"   
header2 = "app_token: your_token"
header3 = "access_token: your_token2"

url = "https://your_api"
command = ["curl","-s","-H",header1,"-H",header2,"-H",header3, url ]
raw_response = subprocess.check_output(command)
string_response = raw_response.decode('utf8')
data = json.loads(string_response)

对于POST:

import subprocess
import json

header1 = "Content-Type: application/json"   
header2 = "app_token: your_token"
header3 = "access_token: your_token2"

data = {"my":"phyton_dictionary"}
data = json.dumps(data) #this is a json string now

url = "https://your_api"
command = ["curl","-s","-H",header1,"-H",header2,"-H",header3, -d, data, url ]
raw_response = subprocess.check_output(command)
string_response = raw_response.decode('utf8')
data = json.loads(string_response)

很容易在python函数中转换这两个原型,并在需要其他调用时创建一个“库”。如果您正在处理需要的API,您可以手动构建URL参数。

因此,这个答案并不能解决您的特定问题。它只是告诉你我有很多这些问题,通过试验和错误黑客风格解决了一些问题,并最终通过改变我构建API脚本的方式,通过删除所有依赖项来解决问题,直到我达到非常干净的脚本。如果文档有我需要访问的URL和我需要发送的标题,那么再也没有问题。

希望它有所帮助。

相关问题