I'm trying to display an image on a simple website, which I am using Flask for. I already tried to do this using a js script on the website itself, but it didn't work.
However, I do not know how to periodically update/refresh the image.
I'm using html and javascript for the first time right now and I'm too confused to get it to work.
This is the main .py file:
from flask import Flask, render_template
import os
#sorry for the bad code :/
app = Flask(__name__)
#app.route("/")
def running():
return "<p>Website running!</p>"
app.config['UPLOAD_FOLDER'] = os.path.join('static','images')
#app.route("/chart")
def show_img():
full_filename = os.path.join(app.config['UPLOAD_FOLDER'], 'chart.png')
return render_template("chart.html", user_image = full_filename)
if __name__ == "__main__":
app.run(port=3000)
This is chart.html:
<!DOCTYPE html>
<html>
<body>
<img src={{ url_for("static", filename="images/"+"chart.png" ) }}/>
</body>
</html>
What is the easiest way to update/reload the image every 5 seconds?
The filename stays the same, but the image itself changes
Some notes:
When working inside a request, it is better to use current_app
from Flask import current_app
#app.route("/chart")
def show_img():
# current_app.config
full_filename = os.path.join('images', 'chart.png')
return render_template("chart.html", user_image=full_filename)
We removed static as we'll be using static in the template itself.
Since you already have the user_image variable, you can add it to the file directly
<!DOCTYPE html>
<html>
<body>
<img src={{ url_for("static", filename=user_image ) }}/>
</body>
</html>
This will display the image.
Dealing with uploads
If you want to implement uploads etc, use flask-reuploaded, a maintained fork of Flask-uploads.
On the front-end, you need a file upload form. Then you need a route to accept the uploaded file. Then you need to make sure that the uploaded filename is always the same, maybe by deleting existing files beforehand.
A complete demo
Following the official docs, here is a demo.
Folder structure
.
├── app.py
├── static
│ └── images
├── templates
└── chart.html
chart.html
<!DOCTYPE html>
<html>
<body>
<form method="post" enctype=multipart/form-data action="/upload">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
<br>
<img src={{ url_for("static", filename=user_image ) }}/>
</body>
</html>
app.py
import os
from flask import Flask, flash, request, redirect, url_for, render_template
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
current_file = ''
#app.route("/")
def running():
return "<p>Website running!</p>"
app.config['UPLOAD_FOLDER'] = os.path.join('static','images')
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/upload', methods=['GET', 'POST'])
def upload_file():
global current_file
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
current_file = filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('show_img', name=filename))
#app.route("/chart")
def show_img():
filename = os.path.join('images', current_file)
return render_template("chart.html", user_image=filename)
if __name__ == "__main__":
app.run(port=3000)
Related
I am building a web API with FLASK and I want to read some images in data folder
venv/data/cartes/carte1.png
carte2.png
carte3.png
carte4.png
in order to show them in an html file index.html and loop over them whit javascript:
#app.route('/')
def index():
return render_template('index.html')
I tried to use this but it gaves error GET LINK... not found:
app.config["CLIENT_IMAGES"] = "/data/cartes"
#app.route("/get-image/<image_name>",methods=['GET', 'POST'])
def get_image(image_name):
try:
return send_from_directory(app.config["CLIENT_IMAGES"], filename=image_name, as_attachment=True)
except FileNotFoundError:
print("failure")
abort(404)
According to the docs:
(https://flask.palletsprojects.com/en/1.0.x/api/#flask.send_from_directory)
#app.route('/get-image/<path:image_name>')
def get_image(image_name):
return send_from_directory('/data/cartes', image_name, as_attachment=True)
You can find more examples here:
https://www.programcreek.com/python/example/65747/flask.send_from_directory
You should use the static directory for that:
https://flask.palletsprojects.com/en/2.0.x/tutorial/static/
With url_for you can generate the relative path to any file in that directory.
The static directory exists, so that there is a clear distinction between public files and server side code files.
If you want to include images in a html file you can use them inside a template as
<img src="{{ url_for('static', filename='smthn.png')}}"></img>
I have the following code for an flask server:
from flask import render_template
import connexion
# Create the application instance
app = connexion.App(__name__, specification_dir="./")
# read the swagger.yml file to configure the endpoints
app.add_api("swagger.yml")
# Create a URL route in our application for "/"
#app.route("/")
def home():
"""
This function just responds to the browser URL
localhost:5000/
:return: the rendered template "home.html"
"""
return render_template("home.html")
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5100)
Which works fine, but I need to add CORS support, so I intalled the library:
pip3 install -U flask-cors
And the lines:
from flask_cors import CORS
CORS(app)
The rest remains the same:
from flask import render_template
from flask_cors import CORS
import connexion
# Create the application instance
app = connexion.App(__name__, specification_dir="./")
# read the swagger.yml file to configure the endpoints
app.add_api("swagger.yml")
CORS(app)
# Create a URL route in our application for "/"
#app.route("/")
def home():
"""
This function just responds to the browser URL
localhost:5000/
:return: the rendered template "home.html"
"""
return render_template("home.html")
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5100)
But now, when I try to run it I get, this error:
Traceback (most recent call last):
File "server.py", line 15, in <module>
CORS(app)
File "/home/luis/.local/lib/python3.6/site-packages/flask_cors/extension.py", line 129, in __init__
self.init_app(app, **kwargs)
File "/home/luis/.local/lib/python3.6/site-packages/flask_cors/extension.py", line 154, in init_app
app.after_request(cors_after_request)
AttributeError: 'FlaskApp' object has no attribute 'after_request'
It works below.
I think it's solved...
https://github.com/zalando/connexion/issues/438
from flask import render_template
from flask_cors import CORS
import connexion
# Create the application instance
app = connexion.App(__name__, specification_dir="./")
# read the swagger.yml file to configure the endpoints
app.add_api("swagger.yml")
CORS(app.app) # this
# Create a URL route in our application for "/"
#app.route("/")
def home():
"""
This function just responds to the browser URL
localhost:5000/
:return: the rendered template "home.html"
"""
return render_template("home.html")
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5100)
My issue was adding the CORS line before the adding the yml files, also passing *.app to the CORS method instead.
flask_server = connexion.App(__name__) # pylint: disable=invalid-name
flask_server.add_api("api.yaml", strict_validation=True)
CORS(flask_server.app)
This question already has answers here:
How to serve static files in Flask
(24 answers)
Link to Flask static files with url_for
(2 answers)
Closed 5 years ago.
I'm currently creating a project involving flask and webpack. Currently the flask server is able to find the revelant template, but is not able to find the relevant JavaScript.
I have a webpack config for creating the HTML file using the webpack html plugin like so:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {app: './src/index.js', print: './src/print.js'},
output: {filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist')},
plugins: [new HtmlWebpackPlugin({template:"./src/index.html"}), new CleanWebpackPlugin(['dist'])],
};
This uses a template called index.html in the src directory which contains the following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hellow World</title>
</head>
<body>
<h1>It Works</h1>
</body>
</html>
Which should be bundled by webpack with the following javascript,
index.js:
import _ from 'lodash';
import printMe from './print.js';
function component() {
let element = document.createElement('div');
let btn = document.createElement('button');
// lodash now imported
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
// new button
btn.innerHTML = 'Click me and check the console!';
btn.onclick = printMe;
element.appendChild(btn);
return element;
}
document.body.appendChild(component());
and print.js:
export default function printMe() {
console.log('I get called from print.js!');
}
The app.py looks like the following:
from flask import Flask, render_template
app = Flask(__name__, template_folder="dist/", static_folder="dist/")
#app.route("/")
def index():
"""
renders basic index page
:return: template
"""
return render_template("index.html")
# app entry point
if __name__ == "__main__":
app.run(debug=True)
After running a build, a template is produced in the dist folder with the following content in index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hellow World</title>
</head>
<body>
<h1>It Works</h1>
<script type="text/javascript" src="app.bundle.js"></script><script type="text/javascript" src="print.bundle.js"></script></body>
</html>
I can't workout how it is able to find the template but not able to find the relevant JavaScript.
The correct URL for app.bundle.js as per your configuration is /dist/app.bundle.js
If you want to serve static files from a different folder, you have to set the static_url_path parameter, in this case to "":
app = Flask(__name__, template_folder="dist", static_folder="dist", static_url_path="")
Reference: https://vilimpoc.org/blog/2012/11/21/serving-static-files-from-root-and-not-static-using-flask/
I am following this simple tutorial for creating a pinterest clone.
http://blog.jetbrains.com/pycharm/2013/12/video-pycharm-web-magic-building-a-pinterest-clone/
I'm having trouble getting Angular to work.
html code:
<!DOCTYPE html>
<html>
<head>
<title>Pin Clone</title>
</head>
<body ng-app1="app1" ng-controller="AppCtrl as app1">
{{ app1.message }}
<script src="bower_components/angular/angular.js"></script>
<script src="js/app1.js"></script>
</body>
</html>
app1.js code:
var app1 = angular.module("app1", []);
app1.controller("AppCtrl", function () {
var app1 = this;
app1.message = "not working"
})
When I reload the page I simply get to see the text:
{{ app1.message }}
This is in the browser.
Console states this on reload:
127.0.0.1 - - [07/Jun/2014 12:59:50] "GET / HTTP/1.1" 304 -
127.0.0.1 - - [07/Jun/2014 12:59:50] "GET /bower_components/angular/angular.js HTTP/1.1" 304 -
127.0.0.1 - - [07/Jun/2014 12:59:50] "GET /js/app1.js HTTP/1.1" 304 -
This is on Ubuntu 14.04. I'm using Bower to install Angular into the project.
AngularJS version 1.2.17
Bower 1.3.4
node version v0.10.28
npm version 1.4.9
Project Folders:
Edit 1, Flask Code in Home_Site.py:
from flask import Flask
from flask.ext.restless.manager import APIManager
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, Text
# instantiating Flask
app = Flask(__name__, static_url_path='')
# setting the SQLALCHEMY_DATABASE_URI to the pin database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///pin.db'
# setting an instance of SQLAlchemy
db = SQLAlchemy(app)
# creates a database model with an id, title, image
class Pin(db.Model):
id = Column(Integer, primary_key=True)
title = Column(Text, unique=False)
image = Column(Text, unique=False)
db.create_all()
# automatically creates an api for the pins in the db
# api stands for application programming interface
api_manager = APIManager(app, flask_sqlalchemy_db=db)
api_manager.create_api(Pin, methods=['GET', 'POST', 'DELETE', 'PUT'])
# type route and hit tab to create this
# this allows you to route to the main html file in the static folder
#app.route('/')
def index1():
return app.send_static_file('index1.html')
# reloads the server on its own
app.debug = True
if __name__ == '__main__':
app.run()
You have a typo in your ngApp declaration:
<body ng-app1="app1" ng-controller="AppCtrl as app1">
should be:
<body ng-app="app1" ng-controller="AppCtrl as app1">
(Note the lack of 1 in the ng-app declaration.)
You need to load your static resources through the /static route:
<script src="/static/bower_components/angular/angular.js"></script>
<script src="/static/js/app1.js"></script>
This also means you need to move your js folder into the static folder of your project.
I was trying to call a function from a .js file in the Google App Engine enviroment.
the code of the html print goes like this:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class jumpPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('');
self.response.out.write('');
self.response.out.write('<head>');
self.response.out.write('<script type="text/javascript" src="/js/pxc11.js" >');
self.response.out.write('</script>');
self.response.out.write('</head>');
self.response.out.write('<body">');
self.response.out.write('<form name="f1">');
self.response.out.write(' <input type="hidden" name="theStartValue" value="1"><p>');
self.response.out.write(' <input type="button" value="-15" onClick="dummy()">');
self.response.out.write(' <input type="button" value="+15" onClick="dummy()" ><p>');
self.response.out.write('</form>');
self.response.out.write('</body>');
self.response.out.write('');
self.response.out.write('</html>');
application = webapp.WSGIApplication(
[('/tonteria', jumpPage)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
and then the .js is just this:
<script language="javascript" type="text⁄javascript">
function dummy()
{
alert("POPOPOPOPOPO");
}
<⁄script>
The app.yaml includes a static folder that has the .js file.
handlers:
- url: /js
static_dir: js
- url: /tonteria
script: tonteria.py
.js files contain Javascript, not HTML tags.
Your life might be easier by making the file into an html template and then rendering it with your variables. Google has a great tutorial