Calling Python file in an Ajax Call - python

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

Related

How to trigger a function in a Python REST API

I have a local Flask REST API that runs some queries and return JSON responses. My idea is to send a POST request to the API and trigger a function capable of updating my database.
The inspiration behind this idea is the way we create resources in a public Cloud. Example: let's say we create a Virtual Cloud Network on any public cloud. The cloud architecture has several APIs for each module and the creation of a VCN trigger the creation of NAT Gateways, Route Tables, Security Lists, Subnets and so on through a GET or POST request to each resource type.
So inspired by this architecture, I want to do this in a simplified and local manner. My first guess is to use the multiprocessing library to spawn processes as soon as a request hits the endpoint, but I don't know if this the best way or a good practice. Can anyone give me an idea on how to do this or if I am in the right path.
i dont really understand... but i can try to help you,
the following code is a code that is the same API but you can get different responses, i dont know what are you going to do with so i added my own examples.
from flask import *
app = Flask(__name__)
#app.route('/api/route/1', methods=['POST'])
def api_1():
if request.method == 'POST':
# Some code here
#Eg:
# data = request.get_json()
# print(data)
#return data.thing
#OR
return "Hello from route 1"
#app.route('/api/route/2', methods=['POST'])
def api_2():
if request.method == 'POST':
# Some code here
#Eg:
# data = request.get_json()
# print(data)
#return data.thing
#OR
return "Hello from route 2"
#app.route('/api/route/3', methods=['POST'])
def api_3():
if request.method == 'POST':
# Some code here
#Eg:
# data = request.get_json()
# print(data)
#return data.thing
#OR
return "Hello from route 3"
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8000, debug=True)

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/

Cloud9: Running a python server

In my Cloud9 IDE, which is running on Ubuntu I have encountered a problem in trying to reach my Python server externally. It's because their projects use a non-standard naming structure:
https://preview.c9users.io/{user}/{project}/
Changing the address to something like this, which is the default server address, doesn't help:
https://preview.c9users.io:8080/{user}/{project}/
I'm looking for a solution so I can run the following script or for a way to be able to combine HTML+JS+Python on Cloud9. The purpose of the server should be to respond to AJAX calls.
The Cloud9 server is Ubuntu-based, so there may be other ways to address this problem than just my script below.
import web
def make_text(string):
return string
urls = ('/', 'tutorial')
render = web.template.render('templates/')
app = web.application(urls, globals())
my_form = web.form.Form(
web.form.Textbox('', class_='textfield', id='textfield'),
)
class tutorial:
def GET(self):
form = my_form()
return render.tutorial(form, "Your text goes here.")
def POST(self):
form = my_form()
form.validates()
s = form.value['textfield']
return make_text(s)
if __name__ == '__main__':
app.run()
The server above actually runs and is available through URL in special format. It has been changed since earlier version, so I couldn't find it at first:
http://{workspacename}-{username}.c9users.io
Now I prefer to run it as a service (daemon) in the console window to execute additional scripts in the backend and test frontend functionality.

Getting plain text instead of Python script execution

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.

Changing URLs after deploying Flask app

So, I have a flask application that works well when it's not deployed. Imagine it has pages for /index/ and /home/ and /home/field/. Now that I have deployed the app using Apache and mod_wsgi, it needs to have a prefix for every URL.
Now, it should look like /newapp/index/ and /newapp/home/ and /newapp/home/field/.
So, I changed all of the URLs to include the new /newapp/ prefix, but the only URL that works with it is the original /index/ URL. All of the others return a
Not Found The requested URL was not found on the server.
in the browser when I click for that URL. I definitely handle that route in my main.py, so I don't know why it would not be found.
Anyone know what is going on?
EDIT: adding some code
Basically I changed all my code in main.py from:
Original:
#app.route('/')
#app.route('/index/', methods=['GET', 'POST'])
def index():
#Stuff
#app.route('/home/')
def farms():
#More stuff
#app.route('/home/<selector>')
def fields(selector):
#Further stuff
To....
New Code
#app.route('/newapp/')
#app.route('/newapp/index/', methods=['GET', 'POST'])
def index():
#Stuff
#app.route('/newapp/home/')
def farms():
#More stuff
#app.route('/newapp/home/<selector>')
def fields(selector):
#Further stuff
I did this because the domain I am using already has another Flask app, so I had to differentiate between the two. Also, I expect there to be more flask apps in the future, so this newapp will end up being an identifier for any given flask app.
I changed main.py as well has all of my hrefs in my templates. So, the hrefs went from
href=/index/
to
href=/newapp/index/
And, I get the error that I posted above whenever I try to click on a link
Further info:
So, checking out the apache error logs one error says, File does not exist: /var/www/flask_util.js, because in my main.py I call from flask_util_js import FlaskUtilJs. I'm not sure if this has anything to do with the URL routing, but it might
You don't need to add the prefix in your code.
Say you have code like
#app.route('/hi', methods = ['GET','POST'])
def myIndex():
return "Hello World!", 200
And you set your alias like to deploy it to www.myserver.com/app/
WSGIScriptAlias /app /var/www/myDir/myApp/app.wsgi
the server should automatically map www.myserver.com/app/hi to /hi in your application.
However if you set the mapping to
#app.route('/newapp/hi', methods = ['GET','POST'])
def myIndex():
return "Hello World!", 200
You WSGI app would only receive the call for /hi (server strips away the prefix) so it would find no matching Path and return not found.

Categories