Getting plain text instead of Python script execution - python

I'm trying to execute this little request with jquery on a page load:
$.ajax({
type: "GET",
url: "/static/query.py",
cache: false,
success: function (data) {
$(body).text(data);
}
});
On a server running nginx, python, in a virtualenv, working with Flask framework and the return is the query.py sourcecode, not the data retrieved from the DB.
query.py is marked as executable and the script has the shebang:
#!/home/gabriel/project/bin
which points to the bin in my virtualenv. I think got the basis covered but yet, the problem persists.
Tips?
More info:
Flask script:
from flask import Flask, render_template
application = Flask(__name__)
#application.route('/')
def init():
return render_template('index.html')
if __name__ == "__main__":
application.run(host='0.0.0.0', debug=True)
uwsgi.py to load the Flask script:
from myapp import application
if __name__ == "__main__":
application.run()
The query.py:
from db import * //Database model, SQLAlchemy.
def something():
data = Kingdom.query.all()
return data
something()

You should be running the actual code that's in query.py inside flask. Do something like:
#application.route("/query"):
def get_data():
.. whatever code you need; currently in query.py, you would probably use sqlalchemy/ flask-sqlalchemy
data = your data (dictionary? list?)
return jsonify(data=data) # flask will turn your data into a proper JSON string to send back as a response to the ajax call.
Don't forget to import jsonify from flask, consult docs here.
Also rename "/static/query.py" to "/query" in example above, or anything else you see fit. You can also send flask parameters via the AJAX call to process in your query; e.g., filtering parameters. Focus the question for further guidance.

Related

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.

Make a python script API

I have a script on python, which prints some data. The script is on Centos7, nginx.
How could I connect to the script via URL (GET query) to be able to parse the data?
You can use a framework like Django or flask to make an api out of it. I'll suggest flask since it's very light-weight, making it ideal for such small tasks.
E.g.
def your_function(input):
# do something
return output
from flask import Flask
from flask import request
app = Flask(__name__)
#app.route('/my_api')
def your_api_function():
input = request.args.get('my_query_string')
return your_function(input)
if __name__ == '__main__':
app.run(debug=True)
And then use the endpoint
/my_api?my_query_string=my_input
You can further play around with it to return JSON, take parameters from request body and so on and so forth.
Read more here http://flask.pocoo.org/

Running python files in javascript (possibly using REST API)

I would like to be able to run python code in my javascript. How do I do this?
This is my attempt, but it's not working and I don't know why
The two following files, I have in the same directory if that matters?
Please help, thanks
scripts.js:
function postPyScript(input){
var jqXHR = $.ajax({
type: "POST",
url: "/app.py",
data: { mydata: input }
});
return jqXHR.responseText;
}
$('#generateBtn').click(function(){
datatosend = 'this is my matrix';
result = postPyScript(datatosend);
alert('Got back ' + result);
});
app.py:
from flask import *
app = Flask(__name__)
#app.route("/app.py", methods=['GET', 'POST'])
def someFunction():
message = None
if(request.method=='POST'):
datafromjs = request.form['mydata']
result = "something to return"
resp = make_response('{"response": '+result+'}')
resp.headers['Content-Type'] = "application/json"
return respreturn
return render_template('index.html',message='')
if __name__ == '__main__':
app.run(debug=True)
Because you only have one route in flask, it seems that you are likely already using a server to serve your html and javascript - maybe you are using the apache instance that your computer came with? In addition to that, you need to be running your flask server. Your flask server will be running on a different port from your apache (or whatever) server.
So, two things:
run your flask server. you might do something like:
$ cd directory-of-this-project
$ export FLASK_APP=app.py
$ flask run
change the ajax url to include the port of the flask server (e.g. http://127.0.0.1:5000/app.py)

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

Running Flask application with twisted

My server.py is as follows,
from flask import Flask, jsonify, Response, redirect
import json
from UIAccess import UIAccess
app=Flask(__name__)
#app.route('/Hello/<username>')
def id_no(username):
id= obj.get_id(username)
return json.dumps(id)
if __name__ == '__main__':
obj=UIAccess()
app.run(threaded=True)
when I run the program and load the page using my browser I am able to view the output of 'id_no' but if I run the same program using twisted with the command,
twistd web --wsgi server.app
I get an internal server error, I am wondering whether this is the correct way to do this?
You only create obj if __name__ == '__main__', which it does not when you run with something besides python server.py. But the id_no view depends on obj being defined, so it fails. Move obj = UIAccess() out of the guard block.

Categories