How to execute python code on client side using flask? - python

I have my server.py file, where i have:
from flask import Flask,render_template,url_for
app=Flask(__name__)
#app.route("/")
#app.route("/home")
def home():
return render_template("home.html",posts=posts,title="arroz")
if __name__=="__main__":
app.run(debug=False)
My home.html file has:
{%extends "layout.html"%}
{%block content%}
<!--here-->
{%endblock content%}
I want to execute some python code in a python file on the client side in the comment here on the home.html file. I can't just call regular python code from flask, because that would run on the server side. How can I run it on the client side?
My project's structure is the following:
|-server.py
|-pythonToExecuteOnClientSide.py
|-templates
|-home.html

This won't work since Python is not a web-app language supported by browsers. Everything that is client-side needs to be able to run on the client computer and for Python code you need to have Python installed on your computer.
The only option you have is to code your feature in JavaScript to let it run on the client side.
Why exactly do you want it to run on the client side? Maybe there is a different solution for your problem. Like a server-client program.

You are already executing python code on the client side.
{% pyton code %} <html> {% python %}.
to give you an example.
when you render your page you can pass a python variable named 'posts' to your page with the value "i did it"; along with a python variable named 'title' with the value "arroz".
return render_template("home.html", posts=posts, title=title)
you can display the value of those python variables like this:
{%extends "layout.html"%}
{%block content%}
{{ posts }} {{ title }}
{%endblock content%}
you can format the value displayed just like any other html content:
<p> {{ posts }} </p> <h1> {{ title }} </h1>
your final code should be
server.py
from flask import Flask,render_template,url_for
app=Flask(__name__)
#app.route("/")
#app.route("/home")
def home():
posts = None
title = "arroz"
return render_template("home.html",posts=posts,title=title)
if __name__=="__main__":
app.run(debug=False)
home.html
{%extends "layout.html"%}
{%block content%}
<p> {{ posts }} </p> <h1> {{ title }} </h1>
{%endblock content%}

Related

Accessing flask methods in Jinaj2.Template.render()

Say we have a flask template as such:
{% extends "layout.html" %}
{% block body %}
<div class="container page-container">
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</div>
{% endblock %}
We can render this template using the flask.render_template() function, and thus display a flash message using code like this:
from flask import flash, render_template
#timesheet_billing.route('/timesheet-billing')
def timesheet_billing_select_job():
jobs = get_open_jobs()
flash('A job was not selected!')
return render_template('timesheet_billing/index.html', jobs = jobs)
However if we render it using Jinja2's template class function jinja2.Template.render() with code like this:
from flask import flash
import jinja2
env = jinja2.Environment(loader=jinja2.PackageLoader('templates'))
index_temp = env.get_template('index.html')
#timesheet_billing.route('/timesheet-billing')
def timesheet_billing_select_job():
jobs = get_open_jobs()
flash('A job was not selected!')
return index_temp.render(jobs = jobs)
We get the following error when trying to load the page:
jinja2.exceptions.UndefinedError: 'get_flashed_messages' is undefined
What is the difference here? The answer in this question suggests that they should be the same. However it seems in one we do not have access to flask methods.
I believe the difference here is how flask.get_flashed_messages works.
This webpage https://flask.palletsprojects.com/en/1.1.x/templating/ explains the scope of jinja2 context variables:
The Jinja Context Behavior:
These variables are added to the context of variables, they are not global variables. The difference is that by default these will not show up in the context of imported templates.
This is partially caused by performance considerations, partially to
keep things explicit.
Here is where flask's render_template makes a difference, when comparing it to jinja2.render (from the question link you referred to):
def render_template(template_name_or_list, **context):
ctx = _app_ctx_stack.top
ctx.app.update_template_context(context)
return _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list),
context, ctx.app)
def _render(template, context, app):
before_render_template.send(app, template=template, context=context)
rv = template.render(context)
template_rendered.send(app, template=template, context=context)
return rv
by calling render directly, you're missing the application context update call, which will inject all the information a template context processor will need to make functions (like get_flashed_messages, in this case) available to templates.

How to render new line from python string to HTML template using FLASK?

message=""
#app.route("/", methods=["GET", "POST"])
def upload_file():
global message
if request.method == "POST":
if request.files:
data=request.files["file"]
if data.filename == "":
message="File doesn't have a name! <br>"
elif allowed_file(data.filename):
message+="File Allowed <br>"
data.save(os.path.join(app.config["FILE_UPLOAD"], data.filename))
message+="File Saved"
if(validate()):
message+="File validated! <br>"
else: message+="Failed validation <br>"
else:
message+="File extension not allowed! <br>"
return render_template("ui.html",message=message)
I'm trying to validate the file uploaded on my ui.html template using flask and I want to send a "message" string back to ui.html about the status of verification and to show it nicely I'm trying to add new line whenever a new string gets added to "message" string so that when I render it in my ui.html, new line is added where I wanted it to be.
This is how I'm rendering the "message" string in ui.html:
{% if message %}
<p>{{ message }}</p>
{% endif %}
But ui.html is not rendering <br> and it is printing it as a string on ui.html template. How can I resolve this? I have tried <br /> as well.
Also mentioned in render html strings in flask templates
flask's template engine (jinja2) assumes that input inside of {{ }} is unsafe and will not allow js or html to be rendered inside of it. The easiest way is to use safe filter in order to do such thing.
{{ message | safe }}
According to flask's documentation https://flask.palletsprojects.com/en/1.1.x/templating/ there are two other ways to control autoescaping behaviour which is either wrap the HTML string in a Markup object or disabling autoescaping altogether like this:
{% autoescape false %}
<p>autoescaping is disabled here
<p>{{ will_not_be_escaped }}
{% endautoescape %}
I tackled it with flash function provided by flask. It prints each message separately so I can add <p> in my HTML File only.
The changes made in ui.html file for rendering are:
{% for message in get_flashed_messages() %}
<p>{{ message }}</p>
{% endfor %}

Flask Run Function on button click

I am looking to make a web page to enable triggering few processes on network. I have decided to use flask as the research i did online overwhelming suggest flask being better for beginners.
I have written the following code as a sample and to test my knowledge. I want to trigger a process on button click. However it doesn't seem to render the next page on click. Any help would be appreciated.
from flask import Flask, render_template
import testt
app = Flask(__name__)
#app.route('/',methods=['GET', 'POST'])
def hello_world():
return render_template('index.html')
#app.route('/my-link/',methods=['GET','POST'])
def my_link():
testt.trial()
work = 'working'
return render_template('process-complete.html',work= work)
if __name__ == '__main__':
app.run()
process-complete.html
{% extends 'base.html' %}
{% block head %}
<title>Task Master</title>
{% endblock %}
{% block body %}
<div class="content" method= "post">
<h1 style="text-align: center">Flask Trial</h1>
<div class="form">
<p> Process Completed {{work}}.<p>
</div>
</div>
{% endblock %}
The code below helped me execute the action i wanted to perform.
<p>Click Below to Start the Process<p>
<a class="button" href="{{ url_for('my_link') }}">Flask Trial</a>

How to handle a variable in HTML?

I have the following flask application that displays a dashboard with various buttons. Each button executes a python function. After the execution of such a function I want the application to return to the dashboard. In order to give the user a simple log I want to output some string on the html page. For that thought about a tag above the buttons on the dashboard that get filled with the respective value. How can I do that?
Flask:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def main():
return render_template('index.html')
#app.route('/something')
def do_something():
print("Hello")
return render_template('index.html', user="Successfully executed!")
if __name__ == "__main__":
app.run()
HTML:
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="UTF-8">
</head>
<title>MP Reporting</title>
</head>
<body>
<div value=user></div>
Your button
</body>
</html>
For flask template use "{{kwarg}}" i.e. in your example
<div>{{user}}</div>
will render as
<div>Successfully executed!</div>
In addition to other answers, I suggest using Flask's built-in message flashing which is simpler, and neater instead of passing variables to render_template manually. It's simple as that:
(template)
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div>{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
(flask view)
from flask import flash
flash("Successfully executed!")
You can get more information from here.
You can print variables using Jinja2.
To print out the variable user in your example add
{{ user }} in the html template.
If you send a list of items to the html you can output them by using a simple for:
{% for item in items %}
{{ item }}
{% endfor %}

How to display flashing message without reloading the page in Flask?

I'm working on a web application using Flask in Python.
I have small function in my application that calculates some values in the background and displays the result on the web page via a flashing message.
Everything is displaying and working fine but it requires page reloading to get the flashing message.
I want to display messages without reloading page.
I heard that I can do that with js, but I'm not familiar with js.
If you have any ideas or suggestion I would appreciate.
There is my code that could build a better picture of what I'm doing.
This is the renderer between my app and the main html file
{% macro render_field(field) %}
<dt> {{ field.label }}
<dd> {{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endmacro %}
This is the html file were I want to display flashing messages:
<div class="container-fluid" style="min-height:100%">
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
{{message}}
</div>
{% endfor %}
{% endif %}
{% endwith %}
</div>
Here's what Flask Web Development: Developing Web Applications with Python (pp. 46-48) has to say of Message Flashing:
Sometimes it is useful to give the user a status update after a request is completed. This
could be a confirmation message, a warning, or an error. A typical example is when you
submit a login form to a website with a mistake and the server responds by rendering
the login form again with a message above it that informs you that your username or
password is invalid.
Flask includes this functionality as a core feature. Example 4-6 shows how the flash()
function can be used for this purpose.
Example 4-6. hello.py: Flashed messages
#app.route('/', methods=['GET', 'POST'])
def index():
form = Nameform()
if form.validate_on_submit():
old_name = session.get('name')
if old_name is not None and old_name != form.name.data:
flash('Looks like you have changed your name!')
session['name'] = form.name.data
form.name.data = ''
return redirect(url_for('index'))
return render_template('index.html', form=form, name=session.get('name'))
form = form, name = session.get('name'))
In this example, each time a name is submitted it is compared against the name stored
in the user session, which would have been put there during a previous submission of
the same form. If the two names are different, the flash() function is invoked with a
message to be displayed on the next response sent back to the client.
Calling flash() is not enough to get messages displayed; the templates used by the
application need to render these messages. The best place to render flashed messages is
the base template, because that will enable these messages in all pages. Flask makes a
get_flashed_messages() function available to templates to retrieve the messages and
render them, as shown in Example 4-7.
Example 4-7. templates/base.html: Flash message rendering
{% block content %}
<div class="container">
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ message }}
</div>
{% endfor %}
{% block page_content %}{% endblock %}
</div>
{% endblock %}
In this example, messages are rendered using Bootstrap’s alert CSS styles for warning
messages (one is shown in Figure 4-4).
Figure 4-4. Flashed message
A loop is used because there could be multiple messages queued for display, one for
each time flash() was called in the previous request cycle. Messages that are retrieved from get_flashed_messages() will not be returned the next time this function is called,
so flashed messages appear only once and are then discarded.
This is not possible via Python without reloading the page. You must do this in javascript. I suggest CSS styling with display: none and display: block. Here is an example.
1) Python Code, this should go in your app.py or flask.py file.
app.route('/flash/<message>')
def flash(message):
return render_template('flash.html', msg=message)
This will render the HTML page named flash.html. The URL passed in will also have another argument, <message> this is the message that will flash. A URL like this, localhost:80/flash/Hello%20World! will flash the message "Hello World!" on your screen.
There is also another way to pass a message in, this is will arguments. The code for that is like so.
app.route('/flash')
def flash():
message = request.args.get("msg")
return render_template("flash.html", ,msg=message)
This uses the flask's request arguments. So a URL like this, localhost:80/flash?msg=Hello%20World! will give a flashing message saying "Hello World!". If you want to use this method be sure to have the import statement, from flask import request in your import statements.
2) Html Code, this is a separate file named, flash.html in your templates folder.
<body>
<h1 id="header">{{ message }}</h1>
<script>
var heading = $("#header");
setInterval(function() {
if (heading.style.display == "block") { heading.style.display = "none"; }
else if (heading.style.display == "none") { heading.style.display = "block"; }
}, 1000);
</script>
</body>
The 1000 in the setInterval is milliseconds. So the heading will blink every 2 seconds.
You may want to consider using Toastr instead. I ran into the same roadblock with Flask's Flash feature, and Toastr is pure JS. You can use it just like a console log line in your code
toastr.info("Here's a message to briefly show to your user");

Categories