Reputation: 1
I'm new to Flask and trying to build a Flask app to receive POST requests coming from an API, then insert data into a database. The POST requests come as-is from a 3rd party program, I cannot modify how they are sent. Below is an example from one such request:
POST / HTTP/1.1
Host: example.com
Accept: */*
Content-Length: 264
Content-Type: application/x-www-form-urlencoded
User-Agent: Arma Reforger/1.1.0.42 (Headless; Windows)
{"token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","events":[{"name":"serveradmintools_conflict_base_captured","title":"Base André's Beacon captured by Soviet Army","data":{"faction":"Soviet Army","base":"André's Beacon"},"timestamp":1716526768}]}
I am using Postman to simulate these requests using the same HTTP headers, since I'm testing locally. I have tried parsing these requests a number of different ways and cannot get the results I want. The two closest solutions I have found are the following:
1.) First attempt using request.get_data() and unquote:
from flask import Flask, request
from urllib.parse import unquote
app = Flask(__name__)
@app.route('/', methods=['POST'])
def events():
requestData = request.get_data()
eventData = unquote(requestData) # works but replaces first colon with equals sign?
return eventData
if __name__ == '__main__':
app.run(debug=True)
And the results I see in Postman look like this (notice how the first colon in the JSON string is replaced with an equals sign. I can't figure out why this is happening for the life of me):
{"token"="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","events":[{"name":"serveradmintools_conflict_base_captured","title":"Base André's Beacon captured by Soviet Army","data":{"faction":"Soviet Army","base":"André's Beacon"},"timestamp":1716526768}]}
2.) Second attempt using request.form:
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['POST'])
def events():
eventData = request.form
return eventData
if __name__ == '__main__':
app.run(debug=True)
But the results in Postman look like this (notice the extra, escaped double-quotes, and some of the characters didn't display properly). I've been able to fix the character display issue, and I could using regex or string replace to remove the extra, escaped double-quotes, but why are they there in the first place and is there a better way to do this?):
{
"{\"token\"": "\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\"events\":[{\"name\":\"serveradmintools_conflict_base_captured\",\"title\":\"Base Andr\u00e9's Beacon captured by Soviet Army\",\"data\":{\"faction\":\"Soviet Army\",\"base\":\"Andr\u00e9's Beacon\"},\"timestamp\":1716526768}]}"
}
I just want to parse the submitted POST data as JSON so I can then insert it into a database. How should I do this properly? I have tried things like request.get_json(force=True)
and json.loads()
but it fails with errors about invalid JSON (even though running the JSON string through a validator says its valid).
Here are screenshots of the request headers and body in Postman: POST Request Body in Postman HTTP Request Headers in Postman
Any and all help is greatly appreciated! :)
Update: I can't figure out why the json isn't parsed correctly, but I've just added some extra code to check and replace the random equals sign with a colon, which fixes the string to be valid JSON. Below is the code for my solution. I still don't feel like this is the best way, but until I find a better solution...
from flask import Flask, request
from urllib.parse import unquote
app = Flask(__name__)
@app.route('/', methods=['POST'])
def events():
requestData = unquote(request.get_data())
eventData = requestData
# check for equals sign in first 10 chars, replace it with colon:
firstChars = eventData[:10]
if '=' in firstChars:
eventDataJson = eventData.replace('=',':')
return eventDataJson
if __name__ == '__main__':
app.run(debug=True)
Upvotes: 0
Views: 173