Read data from local folder in FLASK - javascript

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>

Related

Update image on python flask app using javascript

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)

Python Flask blueprint without static folder for css and javascript

I have searched similar answer to this and found to no avail.
Using CGI Handler Apache server with an index.cgi
I have to adhere the strict policy on the directory list; they're adamantly refused to have a static folder in the directory for Flask.
I kinda wish Flask add static_js and static_css that would make our life easier.
How do I override the static folder?
It works with a single path for either css or javascript:
# in app.py
app.register_blueprint(index_bp)
app.add_url_rule('/css/<path:filename>', endpoint='css', view_func=app.send_static_file)
app.add_url_rule('/js/<path:filename>', endpoint='js', view_func=app.send_static_file)
# css_dir = /parent_folder/css and read from json load
from config import css_dir
index = Blueprint('index', __name__, template_folder=html_dir, static_folder=css_dir)
# in html file
<link rel='stylesheet' href="{{ url_for('css', filename='bootstrap.min.css') }}">
# note: javascript won't load at all
or
# js_dir = /parent_folder/js and read from json load
from config import js_dir
index = Blueprint('index', __name__, template_folder=html_dir, static_folder=css_dir)
# in the html file
<script type ="text/javascript" src="{{ url_for('js', filename='lib/bootstrap.min.js') }}"></script>
# note: css won't load at all
but does not work:
# multi_dir = /parent_folder and read from json load
from config import multi_dir
index = Blueprint('index', __name__, template_folder=html_dir, static_folder=multi_dir)
# in html file
<link rel='stylesheet' href="{{ url_for('css', filename='bootstrap.min.css') }}">
<script type ="text/javascript" src="{{ url_for('js', filename='lib/bootstrap.min.js') }}"></script>
# note: both won't load at all
I want to include javascript and css folders without a static folder
parent_folder
cgi-bin
python/perl stuff
templates
html stuff
css
css stuff
js
lib
javascript stuff
How do I achieve this?
I figured it out, it can be achieved by create a two python files and register them in the app.py blueprint.
Since Stack Overflow won't let me post code in here due to error which is in correct format.

Pyramid can not access static asset (neither an .jpg image nor a .js file)

I have a bigger testcase which uses Pyramid and Mako and also Javascript. It works fine unless I put the Javascript code into a separate file. Then it fails.
I have reduced the test case to the following (3 files) replacing the JS file with a simple picture I wanted to load but that fails too with the same error message:
NotImplementedError: Can't perform this operation for unregistered loader type
127.0.0.1 - - [15/Oct/2021 10:46:44] "GET /static/system6.jpg HTTP/1.1" 500 59
127.0.0.1 - - [15/Oct/2021 10:46:44] "GET /favicon.ico HTTP/1.1" 404 164
post_trypyramid.py:
from pyramid.config import Configurator
if __name__ == '__main__':
with Configurator() as config:
config.include("pyramid_mako")
config.add_route('home', '/')
config.add_route('system', '/system')
config.add_static_view(name='static', path='static')
config.scan('post_trypyramid_views')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
post_pyramid_views.py:
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
from pyramid.response import Response
from pyramid.view import view_config
#view_config(route_name='home')
def home_view(request):
return Response('<p>Welcome</p>')
#view_config(route_name='system', renderer='post_trypyramid_template.mako')
def form_view(request):
return {"Nothing": "nothing"}
post_trypyramid_template.mako:
<head>
<title>My SANDBOX</title>
<meta charset="utf-8"/>
</head>
<body>
<h1>Settings:</h1>
<img src="static/system6.jpg" alt="Here you should see an image">
<img src="{{ request.static_url('__main__:static/system6.jpg') }}" alt="Here you should see an image" >
</body>
</html>
I start the application in "C:/Users/myAccount/Projects/TryPyramid" but no image is shown on the webpage, only the heading.
If I replace the "add_static_view()" call above with the absolute path like
"config.add_static_view(name='static', path='C:/Users/myAccount/Projects/TryPyramid/static')"
then at least the first "<img ...>" leads to an image in the browser.
So what is wrong with my relative path setting?? Or what else do I miss?
I have tried all sorts of modifications, like trailing or leading slashes. Nothing helped
Any hint welcome. Thanks.
You are using Jinja2 syntax in a Mako template. As an aside, you should use the project name, not __main__. Try this:
<img src="${ request.static_url('myproject:static/system6.jpg') }" alt="Here you should see an image" >
If you use pyramid-cookiecutter-starter to create a starter project using Mako as the templating engine, then you can see other examples of how to build a project and proper syntax. See the documentation for a tutorial.

Load a Javascript in another Javascript in Play-scala Framework

How can we load another javascript in js file in Playframe work
This is my conf file
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / controllers.Application.index
POST /upload controllers.Application.uploadFile
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
I tried a to load js file:
(function(window){
var RECORDER_WORKER_PATH = '/javascripts/recordWorker.js")';
var ENCODER_WORKER_PATH = '/javascripts/mp3Worker.js")';
but i ended up with this in the webconsole:
Error:ScriptFile not found at 'javascripts/recordWorker.js
Error:ScriptFile not found at 'javascripts/mp3Worker.js
Static assets are served under /assets/* per your definition in the routes file.
You should therefore prepend /assets/ to your URIs.
(function(window){
var RECORDER_WORKER_PATH = '/assets/javascripts/recordWorker.js")';
var ENCODER_WORKER_PATH = '/assets/javascripts/mp3Worker.js")';
See Play Asset controller docs for more details.

Django's support for translations in Javascript files

I read and followed the instructions in here, but can't seem to see the string in the javascript in the po file.
structure of my project is:
cb/
cb_app
cb
static_files
templates
First I copied these into my url.py:
js_info_dict = {
'packages': ('cb_app',),
}
urlpatterns = patterns('',
(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
)
Then I added this script to my html:
<script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>
The actual script where I would like to get the translation, is as simple as that:
$(document).ready(function () {
$('#id_sales_item').chosen({no_results_text: gettext('No results match')});
});
...and is utilized in the same html.
So is there anything more I need to do?
All I did then was to run the line below both from cb/cb and from cb/cb_app.
django-admin.py makemessages -l en_GB
But still no sign of 'No results match' in either cb/cb/locale nor in cb/cb_app/locale
Any tips?
I have finally found the problem.
The documentation suggests creating the messages once from the Django project and once from Django app. That way you end up with two locale directory. And in neither of those would the javascript translations be picked up anyway. This is quite a mess.
The cleanest solution I have found is to go to settings.py and insert this line (see also my project hierarchy above):
LOCALE_PATHS = ( '/home/kave/projects/cb/locale',)
Then create a directory called locale in the project-root-directory (see the path above)
Don't forget applying the entries into url.py and html as well (see above).
Finally now that the local's are unified into one place, go to project-root-directory: /home/kave/projects/cb and run these two commands:
django-admin.py makemessages -l en_GB
django-admin.py makemessages -d djangojs -l en_GB
The first command get the translation texts from both project and app subfolders.
The second gets the javascript translation into a second po file.
Thats it.

Categories