call python function from html code - javascript

I'm now working to develop google app engine using flask framework i have create a template with different control i need no to call function in python from my html where i catch the button trigger by ajax script the html code as follow
<html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" ></script>
<br>
<form action="" method="post" >
<div id ="par_input" ><table> <tr> <td><textarea id ="equation" rows="2" cols="60"></textarea> <input id ="insert" type="button" onclick="insert_fun()" value="Insert" > <!-- -->
</form>
</div>
<script type="text/javascript">
function insert_fun(){
//window.alert("Tariq work !");
$.ajax({
type: 'POST',
url: window.location.href + '/insert'
});
document.getElementById("equation").value = "{{ TARIQ_ID }}";
}
</script>
</html>
and my python code is
from flask import Flask #import the Flask class.
from flask import make_response
from flask import render_template
from flask import request
from flask import session
from flask.kvsession import KVSessionExtension
from flask import abort
from flask import jsonify
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
APPLICATION_NAME='application test '
app = Flask(__name__)
#app.route('/', methods=['GET'])
def index():
"""Initialize a session for the current user, and render index.html."""
TARIQ_ID = 'inside index function'
# serving it.
response = make_response(
render_template('tariq.html',
APPLICATION_NAME=APPLICATION_NAME,
TARIQ_ID=TARIQ_ID))
response.headers['Content-Type'] = 'text/html'
return response
#app.route('/', methods=['POST'])
def insert(self = webapp.RequestHandler):
TARIQ_ID = 'In Python Code Function__INSIDE RESPONSE___===='
response = make_response(
render_template('tariq.html',
APPLICATION_NAME=APPLICATION_NAME,
TARIQ_ID=TARIQ_ID))
response.headers['Content-Type'] = 'text/html'
return response
class MyHandler(webapp.RequestHandler):
def get(self):
TARIQ_ID = 'In Python Code Function__INSIDE get===='
self.response.out.write(unicode(
template.render('tariq.html',
TARIQ_ID)))
def post(self):
TARIQ_ID = 'In Python Code Function__INSIDE post===='
self.response.out.write(unicode(
template.render('tariq.html',
TARIQ_ID)))
def main():
#app.debug = True
#app.run(host='0.0.0.0', port=4567) #we use the run() function to run the local server with our application
app = webapp.WSGIApplication([
(r'.*',MyHandler)], debug=True)
wsgiref.handlers.CGIHandler().run(app)
if __name__ == '__main__':
main()
but the python function dose not return the updated value of TARIQ_ID also it dose not make any response please your help

I don't know Flask so this is just a guess, but do you need to change this:
#app.route('/', methods=['POST'])
def insert(self = webapp.RequestHandler):
to this:
#app.route('/insert', methods=['POST'])
def insert(self = webapp.RequestHandler):

A callback function is needed in the Javascript function insert_fun() in the $.ajax() call.
The examples in https://api.jquery.com/jQuery.ajax/ show '.done(some_callback_function)' after the $.ajax() call.

Related

how to send ckeditor5 content to python flask on change in the editor content

I am writing a code to get data as user is typing (or copy paste to the editor ) in ckeditor for my spellchecking project, I need to get the data in editor everytime it changes , so i created a variable editorData which will be holding the changed value. But as I am new to web programming I am not able to send this data to server using python flask, here is how my code looks like:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CKEditor 5 – Classic editor</title>
<script src="https://cdn.ckeditor.com/ckeditor5/25.0.0/classic/ckeditor.js"></script>
</head>
<body>
<h1>Classic editor</h1>
<div id="editor" method ="POST" ></div>
<script>
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then( editor => {
editor.model.document.on( 'change:data', () => {
editorData = editor.getData();
console.log( 'The data has changed!' )
} );
} )
.catch( error => {
console.error( error );
} );
</script>
</body>
</html>
Python flask code
from flask import Flask, render_template, request
from flask_ckeditor import CKEditor
app = Flask(__name__)
#app.route('/', methods=['GET'])
def new_post():
print('hello')
if request.method == ' POST':
data = editorData
print(data)
return render_template('test-page.html')
if __name__ == "__main__":
app.run(debug=True)
Please help me how can i send the created javascript variables to flask server every time there is change in the editor.
You have to put the editor into a POST request so you can send the content to the backend
HTML:
...
<form method=post enctype="multipart/form-data">
<div id="editor" name="content">Content</div>
<p><input type=submit value="Save">
</form>
...
Then fetch it with your api.
Backend:
#app.route('/', methods=['GET'])
def new_post():
if request.method == ' POST':
data = request.form.get("content")
print(data)
return render_template('test-page.html')

Return render template and another value to Ajax call [duplicate]

I have a function that analyzes a CSV file with Pandas and produces a dict with summary information. I want to return the results as a response from a Flask view. How do I return a JSON response?
#app.route("/summary")
def summary():
d = make_summary()
# send it back as json
A view can directly return a Python dict or list and Flask will call jsonify automatically.
#app.route("/summary")
def summary():
d = make_summary()
return d
For older Flask versions, or to return a different JSON-serializable object, import and use jsonify.
from flask import jsonify
#app.route("/summary")
def summary():
d = make_summary()
return jsonify(d)
jsonify serializes the data you pass it to JSON. If you want to serialize the data yourself, do what jsonify does by building a response with status=200 and mimetype='application/json'.
from flask import json
#app.route('/summary')
def summary():
data = make_summary()
response = app.response_class(
response=json.dumps(data),
status=200,
mimetype='application/json'
)
return response
Pass keyword arguments to flask.jsonify and they will be output as a JSON object.
#app.route('/_get_current_user')
def get_current_user():
return jsonify(
username=g.user.username,
email=g.user.email,
id=g.user.id
)
{
"username": "admin",
"email": "admin#localhost",
"id": 42
}
If you already have a dict, you can pass it directly as jsonify(d).
If you don't want to use jsonify for some reason, you can do what it does manually. Call flask.json.dumps to create JSON data, then return a response with the application/json content type.
from flask import json
#app.route('/summary')
def summary():
data = make_summary()
response = app.response_class(
response=json.dumps(data),
mimetype='application/json'
)
return response
flask.json is distinct from the built-in json module. It will use the faster simplejson module if available, and enables various integrations with your Flask app.
To return a JSON response and set a status code you can use make_response:
from flask import jsonify, make_response
#app.route('/summary')
def summary():
d = make_summary()
return make_response(jsonify(d), 200)
Inspiration taken from this comment in the Flask issue tracker.
As of version 1.1.0 Flask, if a view returns a dict it will be turned into a JSON response.
#app.route("/users", methods=['GET'])
def get_user():
return {
"user": "John Doe",
}
If you want to analyze a file uploaded by the user, the Flask quickstart shows how to get files from users and access them. Get the file from request.files and pass it to the summary function.
from flask import request, jsonify
from werkzeug import secure_filename
#app.route('/summary', methods=['GET', 'POST'])
def summary():
if request.method == 'POST':
csv = request.files['data']
return jsonify(
summary=make_summary(csv),
csv_name=secure_filename(csv.filename)
)
return render_template('submit_data.html')
Replace the 'data' key for request.files with the name of the file input in your HTML form.
Flask 1.1.x supports returning a JSON dict without calling jsonify. If you want to return something besides a dict, you still need to call jsonify.
#app.route("/")
def index():
return {
"api_stuff": "values",
}
is equivalent to
#app.route("/")
def index():
return jsonify({
"api_stuff": "values",
})
See the pull request that added this: https://github.com/pallets/flask/pull/3111
I use a decorator to return the result of jsonfiy. I think it is more readable when a view has multiple returns. This does not support returning a tuple like content, status, but I handle returning error statuses with app.errorhandler instead.
import functools
from flask import jsonify
def return_json(f):
#functools.wraps(f)
def inner(**kwargs):
return jsonify(f(**kwargs))
return inner
#app.route('/test/<arg>')
#return_json
def test(arg):
if arg == 'list':
return [1, 2, 3]
elif arg == 'dict':
return {'a': 1, 'b': 2}
elif arg == 'bool':
return True
return 'none of them'
Prior to Flask 0.11, jsonfiy would not allow returning an array directly. Instead, pass the list as a keyword argument.
#app.route('/get_records')
def get_records():
results = [
{
"rec_create_date": "12 Jun 2016",
"rec_dietary_info": "nothing",
"rec_dob": "01 Apr 1988",
"rec_first_name": "New",
"rec_last_name": "Guy",
},
{
"rec_create_date": "1 Apr 2016",
"rec_dietary_info": "Nut allergy",
"rec_dob": "01 Feb 1988",
"rec_first_name": "Old",
"rec_last_name": "Guy",
},
]
return jsonify(results=list)
In Flask 1.1, if you return a dictionary and it will automatically be converted into JSON. So if make_summary() returns a dictionary, you can
from flask import Flask
app = Flask(__name__)
#app.route('/summary')
def summary():
d = make_summary()
return d
The SO that asks about including the status code was closed as a duplicate to this one. So to also answer that question, you can include the status code by returning a tuple of the form (dict, int). The dict is converted to JSON and the int will be the HTTP Status Code. Without any input, the Status is the default 200. So in the above example the code would be 200. In the example below it is changed to 201.
from flask import Flask
app = Flask(__name__)
#app.route('/summary')
def summary():
d = make_summary()
return d, 201 # 200 is the default
You can check the status code using
curl --request GET "http://127.0.0.1:5000/summary" -w "\ncode: %{http_code}\n\n"
The answer is the same when using Flask's class-based views.
from flask import Flask, request, jsonify
from flask.views import MethodView
app = Flask(__name__)
class Summary(MethodView):
def get(self):
d = make_summary()
return jsonify(d)
app.add_url_rule('/summary/', view_func=Summary.as_view('summary'))
if its a dict, flask can return it directly (Version 1.0.2)
def summary():
d = make_summary()
return d, 200
To serialize an object, use jsonify from flask module to jsonify the object, a dictionary gets serialized by default. Also, if you're dealing with files you can always use make_response.
I like this way:
#app.route("/summary")
def summary():
responseBody = { "message": "bla bla bla", "summary": make_summary() }
return make_response(jsonify(responseBody), 200)

Flask + Celery + socketio RuntimeError: Working outside of request context

I am currently trying to design a flask app that allows real time charts through the use of sockets and celery. I want to be able to get data asynchronously and then send that via a socket to the client. I am however getting the error: RuntimeError: Working outside of request context. I get this when the socket first connects.
stack trace
Traceback (most recent call last):
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/celery/app/trace.py", line 374, in trace_task
R = retval = fun(*args, **kwargs)
File "/Users/bev/PycharmProjects/flask_project/celery_config.py", line 15, in __call__
return TaskBase.__call__(self, *args, **kwargs)
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/celery/app/trace.py", line 629, in __protected_call__
return self.run(*args, **kwargs)
File "/Users/bev/PycharmProjects/flask_project/main.py", line 20, in async_data
send(jsonify({"result": sample(range(101), 6)}))
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/flask/json.py", line 251, in jsonify
if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] and not request.is_xhr:
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/werkzeug/local.py", line 306, in _get_current_object
return self.__local()
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/flask/globals.py", line 37, in _lookup_req_object
raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.
main.py
from flask import Flask, render_template, jsonify
from flask_socketio import SocketIO, send
from random import sample
from celery_config import make_celery
app = Flask(__name__)
app.config["SECRET_KEY"] = "thisisasecret"
socketio = SocketIO(app)
app.config.update(
CELERY_BROKER_URL="amqp://localhost//",
CELERY_RESULT_BACKEND="rpc://"
)
celery = make_celery(app)
#celery.task(name="main.async_data")
def async_data():
# for now this is very small as an example
# preferably batched to be done every 15 minutes.
send(jsonify({"result": sample(range(101), 6)}))
return True
#app.route("/")
def index():
return render_template("chart.html")
#socketio.on("connect")
def handle_connection():
async_data.delay()
print("You are connected and we are getting your data")
if __name__ == "__main__":
socketio.run(app, debug=True)
celery_config.py
from celery import Celery
def make_celery(app):
celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'],
broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery
chart javascript
let chartConfig = {
type: "line",
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
datasets: [{
label: "GOOG",
data: [],
borderColor: "rgba(22, 172, 65, 1)",
borderWidth: 1,
fill:false
}]
}
};
let socket = io.connect("http://" + document.domain + ':' + location.port);
socket.on("connect", function() {
socket.send("Connected Socket off to get data");
});
socket.on("message", function (data) {
chartConfig.data.datasets[0].data = data.result;
let ctx = document.getElementById("myChart").getContext("2d");
let myLineChart = new Chart(ctx, chartConfig)
});
The reason is only in the Flask. Let's made a little test(main.py):
from random import sample
from flask import Flask, jsonify
from celery_config import make_celery
app = Flask(__name__)
app.config["SECRET_KEY"] = "thisisasecret"
app.config.update(
CELERY_BROKER_URL="redis://localhost:6379/0", # or your broker
CELERY_RESULT_BACKEND="redis://localhost:6379/0" # or your broker
)
celery = make_celery(app)
#celery.task(name="main.async_data")
def async_data():
jsonify({"result": sample(range(101), 6)})
return True
#app.route("/")
def index():
async_data.delay()
return 'test'
if __name__ == "__main__":
app.run(debug=True)
Run Celery and Flask apps, open '/' route. You will see the next error:
RuntimeError: Working outside of request context
How it works. You using jsonify method. As you can see in the docs, it turns the JSON output into a Response object with the application/json mimetype. But Celery task doesn't know anything about current/active response of Flask. This is just asynchronous code/processing. If you need to work with json in celery you can use any lib(json, ujson, simplejson etc).
Now let's change jsonify to json.dumps({"result": sample(range(101), 6)}). You will see that everything works fine.
Hope this helps.

How to display json value in django template?

This is my View.py code...
import requests
from django.http import HttpResponse
from django.shortcuts import render import json
def book(request):
if request.method == 'POST':
r = requests.post('http://api.railwayapi.com/cancelled/date/01-09-2016/apikey/mezxa1595/', params=request.POST)
book=r.json()
else:
r = requests.get('http://api.railwayapi.com/cancelled/date/01-09-2016/apikey/mezxa1595/', params=request.GET)
book=r.json()
js=json.dumps(book)
if r.status_code == 200:
return render(request,'book.html', {'js':js})
return HttpResponse('Could not save data')
and question is that how to display return render(request,'book.html', {'js':js}) in Html?
That "js" should be a python dict not json object. You may need to:
return render(request,'book.html', {'js': json.loads(js)})
Then you can use the variables in book.html template.

How to call a function in view by clicking a button in django?

I am trying to call the function ssl_verify from my html template . But it gives 404 error. Can anyone help me with this? Where i am wrong ?
#views.py
def ssl_verify( request , dns, port ):
if request.is_ajax():
result = dns + port
return result
#urls.py
url(r'ssl_verify/(\d+)/(\d+)/$', views.ssl_verify,name='ssl_verify'),
#script in html
function verify()
{
dns = document.getElementById("dns1").value;
port = document.getElementById("port1").value;
$.post('ssl_verify/'+dns+'/'+port+'/', function (data) {
alert (data) ;
});
}
Your urls.py must contain (replace the regexp line)
url(r'^ssl_verify/(?P<dns>[^/]+)/(?P<port>[^/]+)/$','views.check_ssl'),
or if you import:
from views import check_ssl
....
url(r'^ssl_verify/(?P<dns>[^/]+)/(?P<port>[^/]+)/$','check_ssl'),
and your views:
from django.http import HttpResponse
def check_ssl( request , dns, port ):
if request.is_ajax():
message = str(dns)+str(port)
return HttpResponse(message)
else:
return HttpResponse('/faulthandler') # declare in urls if needed

Categories

Resources