How to fetch the result of the cherrypy function? - javascript

I have the website hosted on local using XAMPP and the server written using cherrpy. I want to use cherrpy to return data and update the paragraph in the HTML page. Here's my code:
index.html
<p id="curtains_status" style="color: white;">a </p>
<script>
curtains_submit.onclick = function() {
response = await fetch("//127.0.0.1:8080/test");
alert(await response.text);
};
</script>
I created the paragraph to display its current state. I attached some code to it to (hopefully) fetch the data from the server.
server.py
import cherrypy
class Site(object):
#cherrypy.expose
def test(self):
return "test"
cherrypy.quickstart(Site())
Here I defined the test function to return the 'test' so that I can alert it in index.html The problem is I don't get the alert executed.
Does anybody know what's the issue?

Related

Display a picture saved in HTML into a Vue.js page

I am currently trying to display a local picture saved in HTML into my Vue.js page.
I have tried to load the content of the HTML file into a variable using the following lines:
computed: {
compiledHtml: function() {
return this.asset;
}
const path = 'http://localhost:5000/load_results'
axios
.get(path)
.then((res) => {
this.asset = res.data
})
Then I have tried to display it using v-html:
<div v-html="compiledHtml"></div>
It actually works with a simple HTML file which contains a few lines, for example:
<h1> test load HTML file </h1>
However, my picture size is 3.5Mb and is much more complex than the example I gave you and when I try to display it, it gives me a blank space.
Is there anyone who knows how to overcome this problem? Thanks.
Here is the GET method I have used:
#bp.route('/load_results', methods=['GET'])
def load():
f = codecs.open("./file.html", 'r', 'utf-8')
return f.read()
I have successfully overcome this problem by modifying my GET method to open the file inside my API like this :
import webbrowser
#bp.route('/load_html_picture_file', methods=['GET'])
def load():
webbrowser.open(path_to_file)
Therefore it open my image in a new tab in my webbrowser.
Thanks anyway.

How can I show a loading animation in Django while the server is processing a view?

So I'm currently working on a Django project that has a view that takes quite a bit of time to load and it can be rather user unfriendly to keep the user wondering what's wrong with the website until the page loads.
My website works in way such that the user would have a url such as:
http://www.example.com/Name/JohnRichards
Saved to their bookmarks. Upon visiting the above URL the server should display a loading message (probably with a GIF and AJAX or JS) of a loading screen until the server finishes loading data and then display it.
Note: Just in case it matters, when he user goes to the above mentioned link, they won't be redirected there, rather, this would be their entry point since it's a url that they have saved in their bookmarks
What I thought would work is returning some sort of a loading template of sorts as soon as somebody visits the page, and then after the data processing has finished, I would return the final response. But I can't have two returns in a function.
The following is my urls.py file:
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('', views.index, name='index'),
path('Name/'+'<str:Name>', views.NameInLink, name='NameInLink'),
]
And the following is my views.py file
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from .forms import NameForm
from . import DataProcessor
import time
def NameInLink(request, Name):
UserData = DataProcessor.process(Name)
return render(request, "UserData.html", {"UserData": UserData})
How could I add a loading screen of sorts between user using visiting the URL and the data processing finishing?
What I would suggest is putting the loading template (the GIF or whatever) in your default template for the page. And then, when the Ajax call has returend successfully, hide or remove the loading GIF using javascript.
I do not think it is necessary to send the loading template using Ajax, if I understand your scenario correctly.
EDIT
You cannot send two consecutive responses from one view. In your view the reponse cannot be send before the User data is processed.
So I think your flow should look like this:
Open the loading template without the user data
def NameInLink(request, Name):
return render(request, "UserData.html")
When loaded your page should send a AJAX request (receiving html data) to a second view, e.g.:
def process_data(request, name):
userData = DataProcessor.process(name)
context = {'data': userData}
result = render_to_string("some_results_template", context)
data = {'data': result}
return JsonReponse(data)
On successful return of the AJAX call remove the GIF and add the returned data using javaScript
Here is an example of a very stripped down possible template with the script, just to make the answer clearer
<head>
<!-- Don't forget to load jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h1>Default Page</h1>
<!-- The loading image -->
<div id="loading">
<p>Loading</p>
</div>
<!-- Container for result -->
<div id="success">
</div>
<script>
// Function for adding User data and removing loading animation
var replace_data = function(data){
$('#success').append(data.data);
$('#loading').remove();
}
// AJAX call when page has loaded
$(document).ready(function(){
$.ajax({
url: '/test2/',
data: {
'name': 'FOO'
},
data_type: 'html',
success: function(data){
replace_data(data);
}
});
});
</script>
</body>

Django AJAX returns undefined instead of the variables

So I have a simple Django script which I've found online for an AJAX function that runs a Python script and gets the output via stdout.
views.py
from django.shortcuts import render
def index(request):
return render(request,'homepage/page.html')
homepage/page.html
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function()
{
$('#clickme').click(function(){
alert('Im going to start processing');
$.ajax({
url: "static/homepage/js/external_func.py",
type: "POST",
datatype:"json",
data: {'key':'value','key2':'value2'},
success: function(response){
console.log(response.keys);
console.log(response.message);
}
});
});
});
</script>
</head>
<body>
<button id="clickme"> click me </button>
</body>
</html>
So you can see my url is linked to external_func.py which runs after the button is clicked. The script then returns a json.
external_func.py
import sys
import json
import cgi
fs = cgi.FieldStorage()
sys.stdout.write("Content-Type: application/json")
sys.stdout.write("\n")
sys.stdout.write("\n")
result = {}
result['success'] = True
result['message'] = "The command Completed Successfully"
result['keys'] = ",".join(fs.keys())
d = {}
for k in fs.keys():
d[k] = fs.getvalue(k)
result['data'] = d
sys.stdout.write(json.dumps(result, indent=1))
sys.stdout.write("\n")
sys.stdout.close()
However, when I run the server and clicked on the button, the console shows undefined for both values, meaning response.keys and response.message is undefined.
Now, when I instead switch the code to console.log(response) in homepage/page.html. The console prints out the entire external_func.py code in text.
I couldn't find a solution online. It seems like people rarely calls a Python script in an AJAX request, I see a lot of forum posts about AJAX calling for a php code instead.
EDIT1:
I have to clarify one thing. This is just a small section of my project which I want to run some test on. In my actual project, I will have a function in python that takes a long time to compute, hence I prefer to have a webpage partially rendered with a waiting icon while the function processes. The output from the function will then be displayed on a webpage.
You have a django app, and yet you are using CGI for this function? Why? Why not simply make the function another django view? Serving your response with django is much superior to CGI, unless that function significantly bloats or slows down your django. It is as easy as this:
from django.http import JsonResponse
def func(request):
result = ...
return JsonResponse(result)
If you really want to separate this into a CGI script, the most likely reason you are failing to get a response is your web server not being configured to process the CGI request. (Your Developer Tools Network tab is a great help for diagnosing exactly what kind of response you got.) For security reasons CGI is not enabled by default. You need to tell Apache (or whatever web server you are using) that CGI should be enabled for that directory, and that it should be associated with .py files.

Failing to pass data from client (JS) to server (Flask) with Ajax

First time ever using jQuery to pass a dictionary filled through a JS script to my server written in Python (Flask) when the user hits a submit button (I read somewhere that AJAX was the way to go).
Something must be broken since in the server function described below, request.get_data() or request.form are None. If any seasoned programmer could give recommendation on how to set up a jQuery request, it would be much appreciated.
In Python, I have the following:
#app.route('/submit',methods=['POST'])
def submit():
info = request.form['info']
action = request.form['action']
...
To handle the dictionary info. On my html file, I load AJAX through:
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
</head>
Define my "submit" button as followed:
<button class="btn" onclick="send(event,'s')" id="SUBMIT">Submit</button>
And handle the action through the script:
<script>
var dict = [];
function send(event,action) {
$.post('/submit', {
info: dict,
action: action
}).done(function() {
}).fail(function() {
});
}
...
</script>
Convert request.form to dictionary and print it you can able get the values
print(request.form.to_dict())

GAE python: success message or add HTML class after redirect

I've a website with a contact form running on a google App Engine. After submitting I'd like to redirect and show a message to the user to let him know the message was sent, this can eighter be a alert message or adding a class to a html tag. How can I do that?
my python file looks like this:
import webapp2
import jinja2
import os
from google.appengine.api import mail
jinja_environment = jinja2.Environment(autoescape=True,loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
class index(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('index.html')
self.response.write(template.render())
def post(self):
vorname=self.request.get("vorname")
...
message=mail.EmailMessage(sender="...",subject="...")
if not mail.is_email_valid(email):
self.response.out.write("Wrong email! Check again!")
message.to="..."
message.body=""" Neue Nachricht erhalten:
Vorname: %s
... %(vorname,...)
self.redirect('/#Kontakt')
app = webapp2.WSGIApplication([('/', index)], debug=True)
I already tried this in my html file:
<script>
function sentAlert() {
alert("Nachricht wurde gesendet");
}
</script>
<div class="submit">
<input type="submit" value="Senden" onsubmit="return sentAlert()"
id="button-blue"/>
</div>
but it does it before the redirect and therefore doesn't work.
Does someone have an idea how to do that?
After the redirect a request different than the POST one for which the email was sent will be served.
So you need to persist the information about the email being sent across requests, saving it in the POST request handler code and retrieving it in the subsequent GET request handler code (be it the redirected one or any other one for that matter).
To persist the info you can, for example, use the user's session (if you already have one, see Passing data between pages in a redirect() function in Google App Engine), or GAE's memcache/datastore/GCS.
Once the info is retrieved you can use it any way you wish.

Categories

Resources