【问题标题】:Unable to post to flask restful endpoint with Python无法使用 Python 发布到烧瓶 restful 端点
【发布时间】:2021-01-14 06:00:13
【问题描述】:

我有一个接受 JSON 的端点

api.add_resource(EventsList, '/events')

Flask Restful / SQL Alchemy 是:

class EventsList (Resource):
    #RETURNS ALL EVENTS
    def get(self):
        schema = EventSchema()
        result = db.session.query(EventModel).all()
        return schema.dump(result, many=True), 200

    #POSTS A SINGLE EVENT
    def post(self):

        title = request.json['title']
        date = request.json['date']

        event = EventModel(title=title,date=date)

        db.session.add(event)
        db.session.commit()

        data = ({'title': event.title,
                 'date': event.date})

        response = jsonify(data)
        response.status_code = 200
        return response

当通过命令行使用 curl 时,这绝对可以正常工作:

卷曲请求

curl http://localhost:5002/events -H "Content-Type: application/json" -d '{"title": "TEst Event 3", "date":"2020-02-23"}'

卷曲响应

响应包含预期的数据:

{"date":"Sun, 23 Feb 2020 00:00:00 GMT","title":"TEst Event 3"}

这一切都很好。但是,当我尝试从 Python 执行此操作时,我收到了服务器错误。

Python

import importlib
import subprocess
import csv
import sys
import requests

targetWikiPage = input("Target Wiki Page: ")
eventTitle = input("Event Title: ")
eventDate = input("Event Date: ")

    
#POST AN EVENT
data = '{"title": "'+eventTitle+'","date":"'+eventDate+'"}'
print("SENDING EVENT DATA:")
print(requests.body)
print(requests.headers)

response = requests.post("http://localhost:5002/events", json=data)

服务器控制台输出

[2020-09-28 16:38:14,182] ERROR in app: Exception on /events [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.8/site-packages/flask_restful/__init__.py", line 468, in wrapper
    resp = resource(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/flask/views.py", line 89, in view
    return self.dispatch_request(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/flask_restful/__init__.py", line 583, in dispatch_request
    resp = meth(*args, **kwargs)
  File "api.py", line 155, in post
    title = request.json['title']
TypeError: string indices must be integers
127.0.0.1 - - [28/Sep/2020 16:38:14] "POST /events HTTP/1.1" 500 -

感谢任何帮助。

【问题讨论】:

    标签: python sqlalchemy python-requests flask-restful


    【解决方案1】:

    您在字符串对象中有 JSON 数据。尝试通过其键从字符串中提取值将产生您描述的错误

    >>> response = '{"date":"Sun, 23 Feb 2020 00:00:00 GMT","title":"TEst Event 3"}'
    >>> response_date = response["date"]
    Traceback (most recent call last):
      File "<pyshell#1>", line 1, in <module>
        response_date = response["date"]
    TypeError: string indices must be integers
    

    您需要先将字符串转换为dict,然后提取值

    >>> import json
    >>> response_as_json = json.loads(response)
    >>> response_date = response_as_json["date"]
    >>> response_date
    'Sun, 23 Feb 2020 00:00:00 GMT'
    

    【讨论】:

    • 问题似乎出在端点收到的请求并在资源中解析,而不是您建议的客户端收到的响应。
    • 代码是在api.py中写的吗?堆栈跟踪显示错误发生在该文件的第 155 行。
    • 是的,第 155 行是:title = request.json['title'] 在上面的 POST 中。
    • 所以你需要在尝试提取['title']之前运行request.json字符串到json.loads
    【解决方案2】:

    解决了这个问题。

    问题在于我如何将数据发送到服务器。这就是我所拥有的:

    targetWikiPage = input("Target Wiki Page: ")
    eventTitle = input("Event Title: ")
    eventDate = input("Event Date: ")
    
        
    #POST AN EVENT
    data = '{"title": "'+eventTitle+'","date":"'+eventDate+'"}'
    print("SENDING EVENT DATA:")
    print(requests.body)
    print(requests.headers)
    
    response = requests.post("http://localhost:5002/events", json=data)
    

    请注意,我的 requests.post 传递了两个值。网址和数据。

    问题如下:

    1. 数据格式不正确。这应该是:

    data = json.dumps({"title": eventTitle, "date": eventDate})

    1. 我需要添加标题:

    headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}

    1. 我需要将data 值传递给服务器,而不是json

    requests.post("http://localhost:5002/events", headers=headers, data=data)

    这将我的文件更改为:

    targetWikiPage = input("Target Wiki Page: ")
    eventTitle = input("Event Title: ")
    eventDate = input("Event Date: ")
    
    #POST AN EVENT
    data = json.dumps({"title": eventTitle, "date": eventDate})
    headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
    print(data)
    print(headers)
    print("SENDING EVENT DATA:")
    
    response = requests.post("http://localhost:5002/events", headers=headers, data=data)
    json=json.loads(response.content)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多