Flask failing with apostrophes - python

If a ' is used within the newName header value everything works okay, however, if ’ is used, for example, the server fails to handle the request.
I'm debugging some larger code, but have created a minimalist version that is subject to the same problem.
from flask import Flask, request
app = Flask(__name__)
#app.route('/dave', methods=['POST'])
def hello():
newName=request.headers['newName']
return newName
if __name__ == '__main__':
app.run(host= '0.0.0.0', debug=True)
app.debug = True
I am using Postman to debug. If I send " David's " everything works as intended, however, if I send "David’s" it fails, and nothing seems to show up in the error log (although I may be missing a trick).

As pointed out in the comments I've neglected to realise that headers should not contain ’. Data should therefore be sent within the POST body, rather than the header.
Example: How to get data received in Flask request
Single quotes can be an issue with Python and JSON, apparently. This appears to solve that problem https://stackoverflow.com/a/36599122/5152133

Related

Setting status callback URL using Python - Flask

I am trying to use Python - Flask to test the StatusCallback in Twilio, however, I am not getting any results, not sure what I am missing. I am using ngrok as well.
This is the code:
from flask import Flask, request, abort
import logging
logging.basicConfig(level=logging.INFO)
app = Flask(__name__)
#app.route('/webhook', methods =['POST', 'GET'])
def webhook():
status=request.values.get(['CallSid', 'From', 'To', 'Direction'])
logging.info('Status: {}'.format(status))
return ('', 204)
if __name__ == '__main__':
app.run(debug=True)
When I make a call, from the image I attached, you will notice I am not getting any results. Could you please advise what I may be missing? Thanks.
Twilio developer evangelist here.
When you create a tunnel with ngrok, a URL is set up that looks like https://RANDOMSUBDOMAIN.ngrok.io, make sure you are using the entire URL, including the subdomain.
When ngrok is running there is also a dashboard you can check to ensure that requests are being made to your ngrok URLs. You can reach this dashboard at http://localhost:4040. You can also use this to check the request parameters that are being sent.
Finally, you might have trouble with request.values.get and passing an array of keys. The get method of request.values only takes a single key, not an array.
As you pointed out in the comments, you can use request.form.to_dict(flat=False) to get a dictionary of the parameters instead. If you want to destructure that further into separate variables in a single line, you can use itemgetter from the operator module, like this:
from operator import itemgetter
#app.route('/webhook', methods =['POST', 'GET'])
def webhook():
parameters=request.form.to_dict(flat=False)
CallSid, From, To, Direction = itemgetter('CallSid', 'From', 'To', 'Direction')(parameters)
logging.info('CallSid: {}'.format(CallSid))
return ('', 204)

flask, Jsonify not pretty prints on Heroku

I am building a simple flask app, jsonify() works fine on my localhost, it will return the information with new lines and the proper indent in a json format, however when running the exact same code on heroku, it omits the new lines and the indentation
This is how it looks on my localhost and this is on heroku
This is mentioned on the docs for jsonify()
This function's response will be pretty printed if the JSONIFY_PRETTYPRINT_REGULAR config parameter is set to True or the Flask app is running in debug mode
I have both set
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True
app.run(debug=True)
I tried manually setting the content type to application/json, but that did not help, I even tried using json.dumps() and got the same result
return jsonify(data), 200, {'Content-Type': 'application/json; charset=utf-8'}
Any input on what could be causing heroku not pretty printing?
Edit:
from flask import request, jsonify, Flask
app = Flask(__name__)
#app.route('/test', methods = ['GET'])
def test():
test_dict = {"Key1": "Value1", "Key2": ["Value2","Value2","Value2",]}
print(jsonify(test_dict).headers)
return jsonify(test_dict)
if __name__ == '__main__':
app.run(debug=True)
This simple flask app would pretty print on my localhost like the photos linked above, however on heroku it wont. Looks like it is returning plain text. It can be seen here https://jojoapi.herokuapp.com/test.
I am using gunicorn, not sure if that has any impacts on the output
Edit 2
So, I set manually debug to True as suggested in the comments app.config["DEBUG"] = True and it works properly on heroku now
Some servers (not only Heroku) may not run directly your script and not execute app(debug=True) but they may import app to own code and run it with own arguments app(...own args...) - and this can makes problem.
You can set debug mode in code in different method.
app.config["DEBUG"] = True
Eventually you can try to set environment variable in Linux
export FLASK_DEBUG=1
or
export FLASK_ENV=development
See doc: Debug Mode
Flask doc: Standalone WSGI Containers - it shows servers which import app (as myproject:app) and they may runs with own arguments.

Flask - 404 not found

I am a newbie in the flask development this is my first program in the flask but it shows me this error:
The requested URL was not found on the server. If you entered the URL
manually please check your spelling and try again.
& this is my code
from flask import Flask
app = Flask(__name__)
#app.route('/index')
def index():
return 'Hello World'
if __name__ == '__main__':
app.run(debug=True)
I think you should just go to http://localhost:5000/index or http://127.0.0.1:5000/index but if you want to make that page your code should be like that
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return 'Hello World'
if __name__ == '__main__':
app.run(debug=True)
change #app.route('/index') to #app.route('/') also you should check this http://flask.pocoo.org/docs/0.12/quickstart/#routing
You have to specify the route for index page as
#app.route('/')
If you give any other name to the template, you need to have to specify the name to the route.
For eg, if the template name is "home", then you have to give it as:
#app.route('/home')
I came across this question while having an almost similar problem. But in my case, the app.py would be executed, for the first time, then if i try to reload my localhost, maybe numerous times after making changes on my app.py the above cited error would be generated.
To solve this, i got a solution from this link: https://stackoverflow.com/a/44950213
Basically the last execution of python would continue running even after i updated my files and my console indicated a restart. So lets say you have made 3 changes while saving each change, then in the background you will have 3 instances of python.exe running. Depending on your OS, you will need to end these processes and re-execute your app.py.
So even if you use http://127.0.0.1:5000/index yet there are still instances of previous python.exe running, it may not execute
Note: this doesnt have to be the case all the time.
if you make the correct changes and it still doesn't work, I found out the hard way that the answer is to just save your file, and then run the program again.
I had the same problem. I created the home page which ran just fine:
#app.route('/')
def hello_world():
return 'Hello, World!'
But then when I tried making another page the next day:
#app.route('/bye/')
def bye():
return 'Bye!'
It gave me a 404 error.
So this is what I did to solve it:
Go to terminal ---> set FLASK_APP=youPythonfilename.py ------> flask run
After doing this the problem was solved. To avoid reloading everytime you need to set your debugger to ON.
if __name__ == '__name__':
app.run(debug=True)
After you have turned debugger ON by the above code, all you need to do is save the file everytime you make changes (windows - ctrl+s).

Bottle mysql connect

I am trying connect to mysql in bottle framework but with no success. Error tells me to give second argument to route but I do not want additional argument in url.
import bottle
import bottle_mysql
from bottle import route, run, template, app
app = bottle.Bottle()
plugin = bottle_mysql.Plugin(dbuser='root', dbpass='toor', dbname='database')
app.install(plugin)
#route('/show/<a>')
def show(a, db):
db.execute('SELECT * FROM table WHERE a > "%d"', (a,))
return template('Hello {{name}}, how are you?', name=a)
run(host='192.168.1.19', port=8080, debug=True)
Error:
TypeError('show() takes exactly 2 arguments (1 given)',)
You may want to create db as a global variable and remove it as a parameter for the function show() or possibly make it an optional variable
The author of bottle-mysql says :
to automatically detect routes that need a database connection,
the plugin searches for route callbacks that require a db keyword
argument (configurable) and skips routes that do not.
Each route needs to be configured as belonging to the app or the app's plugin can't send data via that route.
So you do need the "app." in #app.route('/show/<a>')
And your run statement on the last line needs to specify the app too otherwise it won't recognise the routes belonging to the app.
run(app, host='192.168.1.19', port=8080, debug=True)
As others have responded, you need to change:
#route('/show/<a>')
to:
#app.route('/show/<a>')
But this is not the only change you need to make to solve the issue, you also need to change:
run(host='192.168.1.19', port=8080, debug=True)
to:
app.run(host='192.168.1.19', port=8080, debug=True)
Unfortunately this last part is not clear in the documentation and took a bit of guess work to figure out, but it's actually pretty obvious actually because if you just call run without the app. prefix, you're basically running a new bottle instance, which will result in 404 errors tying to access your routes.

Calling Python file in an Ajax Call

So I have established a pretty decent understanding of the simple architecture of an angularjs app, calling $http and posting to a php page, and receiving data back.
What I'm wondering, is how to do the same type of function with python. Is it possible to have python act the same, with self contained script files that accept post data and echo json back?
$username = $_POST['username'];
type variable assignment at the beginning of the script, and:
echo json_encode(response);
type response.
I'm wanting to use Python for some Internal Tools for my company, as it offers better libraries for remotely running powershell scripts (as the tools are all linux hosted) and overall just has libraries that fit my needs. I'm just having a difficult time finding a concise answer to how this could be set up.
---EDIT------
So I set up a quick example using the information below.
the angular:
var app = angular.module("api");
app.controller("MainController", ["$scope","$http",MainController]);
function MainController($scope,$http){
$http.post('/api',{test: "hello"})
.then(function(response){
console.log(response.data);
})
}
The flask:
from flask import Flask, request
import json
app = Flask(__name__)
#app.route('/api', methods=['POST', 'GET'])
def api():
if request.method == 'POST':
request.data
return 'You made it' # Just so I originally could see that the flask page
if __name__ == "__main__":
app.run()
I'm getting a 404 for that URL. If I change the angular to look at 'localhost:5000/api' (where my flask app is running),it gives me the error of "Unsupported URL Type".
I am seeing when I do the first case, it tries to look at http://localhost/api , which is correct! except for the port. Which is why I tried to specify the port.
Any suggestions for a next step?
Use flask.
You could host your app on a flask "server" and return the content you'd like too with a python processing.
http://flask.pocoo.org/
Use the documentation to setup a route where you'll POST your data using jquery or whatever, then on the route you can do your python stuff and return a JSON to your angular app if you need to.
from flask import request
#app.route('/test', methods=['POST', 'GET'])
def test():
if request.method == 'POST':
print request.data['your_field']
return your_json_data

Categories