Flask : how to "fix" the static directory - python

I have this issue with Flask when i try running this code with Flask :
#app.route('/viz')
def root():
return render_template('page.html')
The file 'page.html' is in the templates folder, and contains some lines like this :
<link rel="stylesheet" href="static/main.css">
But when I execute my program, the file doen't look for main.css in the static directory, but in the viz/static direcory ( /viz is the route of the view).
How can I solve this issue ?
Thanks and sorry for my english.

You need a leading slash to tell the browser to use an absolute path.
<link rel="stylesheet" href="/static/main.css">

You need to place the static folder within the package or next to your module. See the Flask Quickstart documentation for more details. Without knowing more about your structure, my guess is your tree should look something like this:
- top level directory (e.g. your package "root")
| app.py
| static/
| viz/

Related

Flask app is fetching the assets (css, js) from a strange path [duplicate]

This question already has answers here:
Link to Flask static files with url_for
(2 answers)
Closed 2 years ago.
I have a simple flask app that has a strange behaviour.
It seems that passing a route name is making the browser fetch the assets from another folder.
My html
<link href="./static/assets/main.css" rel="stylesheet">
Reserva já
My Flask route
#app.route('/work/<int:store_id>')
def stores(store_id):
mycursor.execute("SELECT * FROM stores WHERE store_id = %s" % store_id)
result = mycursor.fetchone()
return render_template("work.html")
The console says the browser now is looking for the css file here:
http://localhost:5000/work/static/assets/main.css
I dont understand why it puts the "work" in the path here. Im new to flask, maybe Im not understanding exactly how the routing works. I pass "work/22" because I want to pass two pieces of information, it this bad practice?
Thanks
This here is a relative path:
<link href="./static/assets/main.css" rel="stylesheet">
It is relative to the current location, which is /work/store_id. This works the same way as in a file system, so /work would be the current directory and the relative path therefore resolves to /work/static/assets/main.css.
If you want the path to be /static/assets/main.css, remove the leading dot:
<link href="/static/assets/main.css" rel="stylesheet">

jQuery doesn't work when delivered with flask but works otherwise [duplicate]

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 4 years ago.
I'm pretty new to python, even less experienced with flask, and I cannot figure out this issue. I have the following simple web page with jQuery functionality that works great when I double click the file and open it in a browser:
<!DOCTYPE html>
<html>
<head>
<script src="jquery-3.3.1.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
$("#updateBtn").on("click", function() {
text = "<h2>The div has been updated!</h2>";
$("#jQuery_div").html(text);
});
});
</script>
<div>
<h1>This is a non-jQuery div</h1>
</div>
<div id="jQuery_div">
<h2>This div should update with jQuery</h2>
</div>
<button id="updateBtn">update</button>
</body>
</html>
However, when flask delivers the web page on localhost:5000, the jQuery functionality is no longer present. My python is as follows:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def render():
return render_template("jquery_test.html")
if __name__ == "__main__":
app.run(port=5000, debug=True)
My app's file tree is:
/AJAX_practice
ajax_practice.py
/templates
jquery-3.3.1.js
jquery_test.html
I was trying to follow this tutorial when I couldn't get the "echo" button to work. In my efforts to debug, I have slowly chipped away and drastically simplified the program to the above code to see why I cannot get my jQuery to work through flask. I am still at a loss. I am running the flask app by pressing F5 in IDLE, with no errors in Python 2.7.13 Shell, and the Terminal (from which I started IDLE with $ sudo idle) showing:
my ip - - [date and time] "GET / HTTP/1.1" 200 -
my ip - - [date and time] "GET /jquery-3.3.1.js HTTP/1.1" 404 -
From this, my best guess is that flask cannot find the jquery.3.3.1.js file, though I have tried putting it everywhere in the file tree with no luck. I cannot use the script src to https for jQuery dependencies, as my server will eventually be on a non-internet connected LAN. Am I on the right track? If so, how does flask find and/or navigate jQuery dependencies? Can anyone point me towards some documentation that might help my fundamental understanding of this issue?
Any help on this matter would be greatly appreciated.
You are trying to serve JavaScript file from templates folder. Add a static folder and use that to serve static content.
in your case create a directory structure like "static/js/jquery.min.js"
and then add script reference like this
<script src="{{url_for('static', filename='js/jquery.min.js')}}"></script>
See this :
http://exploreflask.com/en/latest/static.html
If you don't want to keep it in "static" folder and use another local directory you can use send_from_directory as shown in this example :
https://stackoverflow.com/a/20648053/2118215
This has always worked for me with Flask in the past:
<script src="{{ url_for('static', filename='jquery-3.3.1.js') }}"></script>
'static' is the name of the folder it's in (and the 'static' folder is in the root of my project). You can edit this to suit your preferred structure and naming, so change 'static' to 'templates' if that's where you'd rather keep your jquery file, although I would recommend keeping it in a separate folder from your HTML templates, purely in the interests of keeping your project well organised.
I believe the path to jquery should be /templates/jquery-3.3.1.js
On me flask server when i serve jquery it has the full path from the home directory: /static/js/jquery.min.js

Web.py not serving static files

Running on the devel server, I can render 0.0.0.0:8080/index.html without CSS fine, but no static files load. 0.0.0.0:8080/static results in "Not found" and 0.0.0.0:8080/static/style.css gets a 404.
All I've googled quotes or links to http://webpy.org/cookbook/staticfiles, which I feel like I've followed to point.
filetree
code.py
/web
...
/static
style.css
/images
...
/pages
index.html
code.py
import web
render = web.template.render('/home/keith/code/webpy/skeleton/pages/')
urls = (
'/', 'index',)
class index:
def GET(self):
return render.index()
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
/pages/index.html
...
<link rel="stylesheet" type="text/css" href="static/style.css" />
...
Would appreciate any help!
I tried running python code.py from a terminal window and the static files served fine! Before, I was using the terminal emulator in my IDE (Geany 1.24.1). So that was the problem, for whatever reason.

Bottle serve file from a different directory

I have simple Bottle application which serves a page for /Startpage location. The index.html page is located under /banana folder and the banana folder is located under the same folder where my views.py exist.
When I try this, its unable to find the page and throws internal server error
#app.wrap_app.route('/StartPage',method='GET')
def doStartPage():
return template('banana/index.html')
How can I refer my /banana folder in my template?
The bottle FAQ specifies the following
Bottle searches in ./ and ./views/ for templates. In a mod_python or mod_wsgi environment, the working directory (./) depends on your Apache settings. You should add an absolute path to the template search path so bottle searches the right paths.
You will need to add the bananas folder to the TEMPLATE_PATH
base_path = os.path.abspath(os.path.dirname(__file__))
bananas_path = os.path.join(base_path, 'bananas')
bottle.TEMPLATE_PATH.insert(0, bananas_path)
EDIT: Improved the answer with Graham's suggestion to use paths relative to where the code is located.
You can do something like this :
Create a rooting rule for your folder :
#route('/banana/<filepath:path>')
def file_stac(filepath):
return static_file(filepath, root="./banana")
And then, you only need to refer to this folder like this :
#route('/foo')
def bar():
return template('banana/foo.tpl')
You can do the same for as many folder as you want, and this is usefull for serving css/js files inside a template (on your template, you can then do :
<link href="banana/css/bootstrap.min.css" rel="stylesheet">
Hope it helped !
Almost 8 years late, but I did as follow for my issue, but replacing my folder with yours:
#route(/banana/<filename>)
def banana(filename):
return static_file(filename, root='./views/banana/')

Difficulty accessing json file with d3 and flask

I am using Flask as a web framework, and I am trying to implement the first example from the book Getting Started with D3, by Mike Dewar. I have a Python script named run.py and two directories, templates/ and static/, containing index.html and service_status.json, respectively. Unfortunately, my code is not rendering the data at all, nor is it producing any glaring errors.
This is what I have in run.py:
#!/usr/bin/env python
from flask import Flask, render_template, url_for
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
if __name__=="__main__":
port = 5000
app.debug = True
app.run( port=port )
This is what I have in templates/index.html:
<!DOCTYPE HTML>
<HTML>
<HEAD>
<META CHARSET="utf-8">
<SCRIPT SRC="http://d3js.org/d3.v3.min.js"></SCRIPT>
<SCRIPT>
function draw(data) {
"use strict";
d3.select("body")
.append("ul")
.selectAll("li")
.data(data)
.enter()
.append("li")
.text( function(d){
return d.name + ": " + d.status;
}
);
}
</SCRIPT>
<TITLE>MTA Data</TITLE>
</HEAD>
<BODY>
<H1>MTA Availability Data</H1>
<SCRIPT>
d3.json("{{ url_for( 'static', filename='service_status.json') }}",draw); // <---- BIG PROBLEM
</SCRIPT>
</BODY>
</HTML>
I am using Windows 7, Google Chrome, and Python 2.7.
If the JSON file is not going to change, then you should put it in the static directory and use
from flask import url_for
url_for('static', filename='service_status.json')
For this to work, also change the path in the JavaScript to '/static/service_status.json'
Static files like your json document, are by default served from a different directory from the templates - by default 'static'
You dont need to use the url_for call in your view, you can use it in your template:
d3.json("{{ url_for('static', filename='service_status.json') }}",draw);
So to summarise: 1) Move your json document in to the static folder (a folder called static along side your templates folder, by default), and 2) use the url_for call in your template to get the correct URI for your json document.
If you want to use a folder other than static, you can change that by passing static_folder to the Flask object contructor
You seem to be getting a 304 status code as you mentioned in earlier comments. I see that your JSON has the following date/time:
"Date": [
"12/15/2011"
],
"Time": [
" 7:35AM"
],
I am not 100% sure but this might help:
http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#if-modified-since
Basically, it says that
"This request header is used with GET method to make it conditional: if the requested document has not changed since the time specified in this field the document will not be sent, but instead a Not Modified 304 reply.
Format of this field is the same as for Date:"
So, may be you can check the timestamp on the JSON and probably just do a fresh save ?

Categories