Reputation: 1273
I've an endpoint which accepts JSON
api.add_resource(EventsList, '/events')
The Flask Restful / SQL Alchemy is:
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
When using curl via the command line this works absolutely fine:
curl http://localhost:5002/events -H "Content-Type: application/json" -d '{"title": "TEst Event 3", "date":"2020-02-23"}'
The response contains the data as expected:
{"date":"Sun, 23 Feb 2020 00:00:00 GMT","title":"TEst Event 3"}
This all works fine. However, when I attempt to do this from Python I receive a server error.
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 -
Any help is appreciated.
Upvotes: 0
Views: 828
Reputation: 1273
Fixed this.
The problem lay with how I was sending the data to the server. This is what I had:
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)
Note that my requests.post
had two values being passed. The url and the data.
The problems were as below:
data = json.dumps({"title": eventTitle, "date": eventDate})
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
data
value to the server, not json
requests.post("http://localhost:5002/events", headers=headers, data=data)
That changed my file to this:
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)
Upvotes: 2
Reputation: 123549
You have JSON data in a string object. Trying to extract a value from the string via its key will produce the error you described
>>> 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
You need to convert the string to a dict
first, then extract the value
>>> import json
>>> response_as_json = json.loads(response)
>>> response_date = response_as_json["date"]
>>> response_date
'Sun, 23 Feb 2020 00:00:00 GMT'
Upvotes: 1