Handle empty request body in post method via 400 status code - python

I am trying to create an error handler in my Flask API such that when an empty body is sent in a post request, the response should generate a jsonified 400 error message and give the status code as 400 Bad Request on Postman. But currently I am getting 400 error message in the response body and 500 status code on Postman
[1]: https://i.stack.imgur.com/DV1BX.png
import pyodbc
from pytz import timezone
from flask import Flask, jsonify, request, Response
from datetime import datetime, timedelta
from waitress import serve
from flask_api import status
app = Flask(__name__)
server = 'bla'
database = 'bla'
username = 'bla'
password = 'bla'
driver = '{ODBC Driver 18 for SQL Server}'
connection_string = 'DRIVER='+driver+';SERVER=tcp:'+server + \
';PORT=bla;DATABASE='+database+';UID='+username+';PWD=' + password
def hello(data):
try:
if data["url"] == "":
return jsonify({"message": "Error Code : 404 - Not found"}), status.HTTP_404_NOT_FOUND
Headers = {"Content-Type": "application/json",
"Authorization": "Bearer " + access_token}
resp = requests.post(
data["url"], json=bla, headers=Headers)
if resp.status_code == 200:
values = resp.json()["value"]
{perform some operation here}
return filtered_values, status.HTTP_200_OK
else:
return resp.json()["error"]["message"],resp.status_code
except Exception as e:
print("Error", e)
raise
#app.route("/")
def status():
return jsonify({"status": "OK"}), status.HTTP_200_OK
#app.errorhandler(404)
def not_found(e):
return jsonify({"message": str(e)}), status.HTTP_404_NOT_FOUND
#app.route("/somepath", methods=["GET", "POST"])
def details():
if request.method == "POST":
try:
operation_data = request.get_json()
data, code = hello(operation_data )
if code != 200:
return jsonify({"message": str(data)}), code
else:
if len(data) != 0 and data is not None:
conn = pyodbc.connect(connection_string)
cursor = conn.cursor()
for d in data:
cursor.execute(some query)
conn.commit()
cursor.close()
conn.close()
new_resp = jsonify({"message": "successful"})
return new_resp, status.HTTP_200_OK
else:
new_resp = jsonify({"message": "nothing to do"})
return new_resp, status.HTTP_200_OK
except Exception as exception:
print(exception)
return jsonify(str(exception)), status.HTTP_500_INTERNAL_SERVER_ERROR
else:
return jsonify({"status": str(request.method) + " - Method not allowed"}),status.HTTP_405_METHOD_NOT_ALLOWED
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8000, debug=True)
# serve(app, listen='*:8000')```

Related

How to display data in flask from post request on localhost? Error: local variable 'reqData' referenced before assignment

I want to display data that im sending in post request in the web browser on localhost:5000/event. In line print (reqData) data is displayed correctly in terminal when server is running, but server is rendering '/event' before i send a post and so reqData is not defined for that site.
post code
import requests
headers = {'content-type': 'application/json'}
payload = {'name': 'asd', 'sname': 'dsa'}
g = requests.post('http://localhost:5000/event', headers=headers, json=payload)
print(g.json)
flask code
#app.route('/event', methods=['GET', 'POST'])
def response():
if request.method=='POST':
reqData = request.get_json()
print(reqData)
return reqData
else:
if(reqData):
return reqData
else:
return 'No request.'
Simply change your post flask code by :
import requests
headers = {'content-type': 'application/json'}
payload = {'name': 'asd', 'sname': 'dsa'}
g = requests.post('http://localhost:5000/event', headers=headers, json=payload)
print(g.json()) # Line changed
Edit :
#app.route('/event', methods=['GET', 'POST'])
def response():
if request.method=='POST':
reqData = request.get_json()
print(reqData)
return reqData
else:
try: # Adding try except works
if(reqData):
return reqData
except:
return 'No request.'

404 Not Found when using Flask and Ngrok for http://127.0.0.1:5000

Complete beginner in flask, ngrok and twilio. I ran this piece of python code to create a flask app for twilio :
from flask import Flask, request, redirect
from twilio.twiml.messaging_response import MessagingResponse
app = Flask(__name__)
#app.route("/sms", methods=['GET', 'POST'])
def incoming_sms():
"""Send a dynamic reply to an incoming text message"""
# Get the message the user sent our Twilio number
body = request.values.get('Body', None)
# Start our TwiML response
resp = MessagingResponse()
# Determine the right reply for this message
if body == 'hello':
resp.message("Hi!")
elif body == 'bye':
resp.message("Goodbye")
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
It was hosted on http://127.0.0.1:5000
I then ran "ngrok http http://127.0.0.1:5000" which create an ngrok link, but when I used it I get 404 not found. What is causing this issue and how can I fix it ?
UPDATE: http://127.0.0.1:5000/sms does not work, shows blank page
1. Run ngrok 5000
2. Here is the flask code for generating, sending and validating OTP:
#app.route('/getOTP', methods=['GET', 'POST'])
def getOTP():
mobNum = request.get_json().get("mobNum")
length = len(mobNum)
val = 0
if length == 13 :
val = getOTPApi(mobNum)
elif length == '' or length < 12:
message = "Failure"
print(message)
return message
{'ContentType':'application/json'}
if val:
message = "Success"
print(message)
return message
else:
message = "NaN"
print(message)
return message
#app.route('/validateOTP', methods=['POST'])
def validateOTP():
otp = request.get_json().get("otp")
length = len(otp)
if 'response' in session:
s = session['response']
if s == otp:
message = "Success"
print(message)
return message
elif length == 0 or length < 6:
message = "NaN"
print(message)
return message
else:
message = "Failure"
print(message)
return message
session.pop('response', None)
def generateOTP():
return random.randrange(100000, 999999)
def getOTPApi(mobNum):
account_sid = 'XXXxxXXXXXX'
auth_token = 'XXXxxXXXXXX'
client = Client(account_sid, auth_token)
otp = generateOTP()
session['response'] = str(otp)
body = 'Your OTP is ' + str(otp)
message = client.messages.create(
from_='+1123456789',
body=body,
to=mobNum
)
if message.sid:
return True
else:
return False

file upload from Flask template to external APIs

I have divided my flask app with two-part API (Flask API) and web app (Flask template).
From the web app, I am trying to upload a file but on the API side, I am not able to send.
File upload is working from APIs side, I have tested from the postman.
Template (UI with port: 3010) and API (port: 3009)
Below is running on API side with port 3009
#app.route('/sources', methods=['POST', 'GET'])
def upload_file():
if request.method == 'POST':
try:
print(request.form.get('file')) # Not able to print file here
print(request.form.get('Language1')) # I am able to print it
if 'file' not in request.files:
resp = jsonify({'message' : 'No file part in the request'})
resp.status_code = 400
return resp
file = request.files['file']
if file.filename == '':
resp = jsonify({'message' : 'No file selected for uploading'})
resp.status_code = 400
return resp
if file and allowed_file(file.filename,'sources'):
sourceFileName = secure_filename(file.filename)
Lang1 = request.form.get('Language1')
Lang2 = request.form.get('Language2')
except Exception as e:
print(e)
resp = jsonify({'message' : 'Server Error'})
resp.status_code = 500
return resp
Below is running on UI side with port 3010
#app.route('/sources', methods=['POST'])
def upload_sources():
if request.method == "POST":
Language1 = request.form["Language1"]
Language2 = request.form["Language2"]
file = request.files["file"]
# File object is printing here like: [<FileStorage: 'source_text.docx' ('application/vnd.openxmlformats-officedocument.wordprocessingml.document')>]
print(file)
params = {
"Language1":Language1,
"Language2":Language2,
"file":file
}
headers = {'content-type': 'application/json'}
req = requests.post('http://localhost:3009/sources', headers=headers, data=params)
r = req.json()
print(r['message']) # I am getting response message : ['No file part in the request']
return redirect(url_for('fetch_sources'))
Below is working fine, just fetching uploaded file
#app.route('/sources', methods=['GET'])
def fetch_sources():
sources = requests.get('http://localhost:3009/sources')
source_data = sources.json()
if source_data:
return render_template('sources.html', sources=source_data['sources'])
I was sending a file object and the way which I was following that was incorrect...
I can not send file directly to API from webapp.
Here I have changed my code and it is working fine.
if request.method == 'POST':
file = request.files["file"]
sourceFileName = secure_filename(file.filename)
cwd = os.getcwd()+'/'
if 'temp' not in os.listdir(cwd):
os.mkdir(cwd + 'temp')
file.save(os.path.join(cwd + 'temp', sourceFileName))
with open(cwd + 'temp/'+ sourceFileName, 'rb') as f:
data_file = ImmutableMultiDict([("file", f)])
resp = requests.post(api_base_url + "/sources",
files=data_file)

github v3 api delete public key return error {'message': 'Not Found', 'documentation_url': 'https://developer.github.com/v3'}

I'm using python3 requests module to access Github v3 API (DELETE /user/keys/:key_id) of the deleting public ssh-key that it return the error
{'message': 'Not Found''documentation_url':'https://developer.github.com/v3'}.
I use python3 virtual environmemt and requests module to handle.
I checked the URL and method of the api and it has no problem. In addition, I added access_token='My token' after the URL parameter. but no effect. i try to use command
curl -H "Authorization: token 93ca7d685602dca9d32e8788ddffafc8e7385003" https://api.github.com/users/codertocat -I to find the scope of the token.
and I checked that the the key_id is correct also.
def __init__(self):
self.accessToken = '93ca7d685602dca9d32e8788ddffafc8e7385003'
self.rootUrl = 'https://api.github.com'
self.headers = {"Authorization": "token %s" % self.accessToken}
def baseGet(self, url, me='get', data=None):
try:
response = ''
if me == 'get':
response = requests.get(url)
if me == 'post':
response = requests.get(url, data)
if me == 'delete':
response = requests.delete(url)
else:
print('no support')
try:
data = response.json()
except:
data = response.content
return data
except Exception as e:
print('error by', e)
return False
def del_user_public_key(self, key_id):
# del_user_public_key
userkey = self.rootUrl + '/users/keys/%d?access_token=%s' % (key_id, self.accessToken)
print(userkey)
return self.baseGet(userkey, me='delete')
I expect the output of the result to be Status 204 No Content and the public deleted in github.

AttributeError: addinfourl instance has no attribute 'getCode'

from flask import Flask, session, render_template, request, redirect, url_for
from urllib2 import Request, urlopen, HTTPError
from json import dump
import json
def checkLogin():
data = {}
data['login'] = request.form['login']
data['password'] = request.form['password']
headers = {'Content-Type': 'application/json'}
jsonData = json.dumps(data)
myRequest = Request("http://edi.iem.pw.edu.pl....", data=jsonData,
headers=headers)
try:
myResponse = urlopen(myRequest)
myResponseDict = json.load(myResponse)
if myResponse.getCode() == 200 and myResponseDict['info'] == 'OK':
session['token'] = myResponseDict['token']
session['uid'] = myResponseDict['uid']
else:
myResponseDict['error']
except HTTPError as e:
print e.code
print e.reason
return e.read()
I get error: "AttributeError: addinfourl instance has no attribute 'getCode'"
I check if it work when I write method "getCode" without brackets but it doesn't work.
In similar topic I didn't got the answer so I have question what can I do in this case?
I have just change from upper "C" to lower "c" in getcode() although PyCharm prompted me to getCode() method.

Categories