Changing the favicon in Flask/Dash - flask

Trying to get the favicon to load I have followed suggestions from the internet:
server = Flask(__name__, static_folder='static')
app = dash.Dash(external_stylesheets=external_stylesheets, server=server)
app.css.config.serve_locally = False
app.scripts.config.serve_locally = True
#server.route('/favicon.ico')
def favicon():
print('Server root path', server.root_path)
return send_from_directory(os.path.join(server.root_path, 'static'),
'dice.ico', mimetype='image/vnd.microsoft.icon')
...
app.run_server(debug=True)
If I browse to the favicon, I see it:
http://www.example.com/favicon.ico
However, when I browse to
http://www.example.com
I see the dash default icon with it's own description. How do I ensure my ownfavicon loads correctly?

To simply change the favicon all you need to do is to create a folder called assets next to your app.py and place your favicon.ico inside of that folder and it will work perfectly.
app.py:
import flask
import dash
import dash_html_components as html
server = flask.Flask(__name__)
#server.route('/')
def index():
return 'Hello Flask app'
app = dash.Dash(
__name__,
server=server,
routes_pathname_prefix='/dash/'
)
app.layout = html.Div("My Dash app")
if __name__ == '__main__':
app.run_server(debug=True)
Here is the docs link for more information: Dash docs

An alternative used in Dash is:
app = dash.Dash()
app._favicon = ("path_to_folder/(your_icon).co")

You can just put title="My Title" as an argument when establishing the Dash app instance. i.e.
app = dash.Dash(
__name__,
title="My Title",
server=server,
routes_pathname_prefix='/dash/'
)

Adding for the sake of completeness. Nowadays, it's recommended to use a bundle of icons with different resolutions to please different browsers and ensure the best picture quality. You can produce such a bundle with the help of, say, realfavicongenerator.net Or you simply might want to use a non-standard .png or .svg icon.
For that, you can subclass Dash and add your much desired link rel and meta tags to its interpolate_index method:
import dash
class CustomDash(dash.Dash):
def interpolate_index(self, **kwargs):
return '''
<!DOCTYPE html>
<html>
<head>
{metas}
<title>{title}</title>
<link rel="apple-touch-icon" sizes="180x180" href="assets/favicons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicons/favicon-16x16.png">
<link rel="manifest" href="assets/favicons/site.webmanifest">
<link rel="mask-icon" href="assets/favicons/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
{css}
</head>
<body>
{app_entry}
<footer>
{config}
{scripts}
{renderer}
</footer>
</body>
</html>
'''.format(**kwargs)
app = CustomDash()
Do not forget to place the unzipped bundle into your assets/favicons subfolder!

You should create an "assets" folden and then update the "__favicon" property in your Dash app:
app._favicon = "favico.ico"

Even if OP's accepted answer doesn't work, refer to official document which says:
It is recommended to add name to the dash init to ensure the resources in the assets folder are loaded, eg: app = dash.Dash(name, meta_tags=[...]). When you run your application through some other command line (like the flask command or gunicorn/waitress), the main module will no longer be located where app.py is. By explicitly setting name, Dash will be able to locate the relative assets folder correctly.
Include __name__ in Dash object:
app = Dash(__name__)

Related

Recommended way to import web components in Django templates?

Google's Polymer relies on HTML imports like this:
<link rel="import" href="../components/core-header-panel/core-header-panel.html">
Right now I'm keeping all the custom web components in the static folder and loading them like this:
template.html
<link rel="import" href="{% static 'polymer/my-custom-element.html' %}">
In the web component I import things using paths relative to the file:
my-custom-element.html
<link rel="import" href="../bower_components/polymer/polymer.html">
Is this the recommended way to import web components when using Django or is there a better way?
Better to use absolute path where possible.
Also I advice you use django-bower. It can handle bower statics in best way.
Use django-bower (https://github.com/nvbn/django-bower), importing its also bit tricky cause 'static' in django template will add all import url pattern, for example yours import url it must be
<link rel="import" href="../polymer.html">

Flask.url_for() error: Attempted to generate a URL without the application context being pushed

I have a trivial app where I'm trying to redirect the favicon per:
http://flask.pocoo.org/docs/0.10/patterns/favicon/
app = flask.Flask(__name__)
app.add_url_rule('/favicon.ico', redirect_to=flask.url_for('static', filename='favicon.ico'))
But this fails with:
RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available.
So, guessing, I try this:
app = flask.Flask(__name__)
with app.app_context():
flask.current_app.add_url_rule('/favicon.ico', redirect_to=flask.url_for('static', filename='favicon.ico'))
But get a different error:
RuntimeError: Application was not able to create a URL adapter for request independent URL generation. You might be able to fix this by setting the SERVER_NAME config variable.
What is going on?
According to the doc:
Setting a SERVER_NAME also by default enables URL generation without a request context but with an application context.
since you're using app_context, you may set the SERVER_NAME Configuration Value.
By the way, as the doc:Adding a favicon says:
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
the above line should be enough for most browsers, we don't have to do any other things.
Late answer, I've just run into the same problem. I don't see a big downside in handling the redirect like this instead:
#app.route('/favicon.ico')
def favicon():
return redirect(url_for('static', filename='favicon.ico'))
This prevents url_for from being called before the application is ready.
To give a counterpoint to using a link in the HTML only, it's a good practice for every site to have a favicon.ico and robots.txt at the root level - even if they're empty. It avoids problems like this and other unnecessary errors that adds noise to logs.
Don't put this in the app but in the html file
<html lang="en">
<head>
<title>{{ title }}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width/2, initial-scale=1">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>

how to embed standalone bokeh graphs into django templates

I want to display graphs offered by the bokeh library in my web application via django framework but I don't want to use the bokeh-server executable because it's not the good way. so is that possible? if yes how to do that?
Using the Embedding Bokeh Plots documentation example as suggested by Fabio Pliger, one can do this in Django:
in the views.py file, we put:
from django.shortcuts import render
from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import components
def simple_chart(request):
plot = figure()
plot.circle([1,2], [3,4])
script, div = components(plot, CDN)
return render(request, "simple_chart.html", {"the_script": script, "the_div": div})
in the urls.py file we can put :
from myapp.views import simple_chart
...
...
...
url(r'^simple_chart/$', simple_chart, name="simple_chart"),
...
...
in the template file simple_chart.html we'll have :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Experiment with Bokeh</title>
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-0.8.1.min.js"></script>
<link rel="stylesheet" href="http://cdn.bokeh.org/bokeh/release/bokeh-0.8.1.min.css">
</head>
<body>
{{ the_div|safe }}
{{ the_script|safe }}
</body>
</html>
And it works.
You don't need to use bokeh-server to embed bokeh plots. It just means you'll not be using (and probably don't need) the extra features it provides.
In fact you can embed bokeh plots in many ways like generating standalone html, by generating bokeh standalone components that you can then embed in you django app when rendering templates or with the method we call "autoloading" which makes bokeh return a tag that will replace itself with a Bokeh plot. You'll find better details looking at the documentation.
Another good source of inspiration is the embed examples you can find in the repository.
It is also possible to have it work with AJAX requests. Let's say we have a page loaded and would like to show a plot on button click without reloading the whole page. From Django view we return Bokeh script and div in JSON:
from django.http import JsonResponse
from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import components
def simple_chart(request):
plot = figure()
plot.circle([1,2], [3,4])
script, div = components(plot, CDN)
return JsonResponse({"script": script, "div": div})
When we get AJAX response in JS (in this example Jquery is used) the div is first appended to the existing page and then the script is appended:
$("button").click(function(){
$.ajax({
url: "/simple_chart",
success: function(result){
var bokeh_data = JSON.parse(result);
$('#bokeh_graph').html(bokeh_data.div);
$("head").append(bokeh_data.script);
}});
});
It must put {{the_script|safe}} inside the head tag
Here's a flask app that uses jquery to interract with a bokeh plot. Check out the templates/ for javascript you can reuse. Also search for bokeh-demos on github.

Dygraph is not defined, using Flask

I am using flask and trying to get the dygraph sample to work. Here is the sample code (2nd example from the tutorial page: http://dygraphs.com/tutorial.html):
<html>
<head>
<script type="text/javascript"
src="dygraph-combined.js"></script>
</head>
<body>
<div id="graphdiv2"
style="width:500px; height:300px;"></div>
<script type="text/javascript">
g2 = new Dygraph(
document.getElementById("graphdiv2"),
"temperatures.csv", // path to CSV file
{} // options
);
</script>
</body>
</html>
Here is my Flask code (I'm trying to use render_template()):
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def render_plot():
return render_template('sample.html')
if __name__ == '__main__':
app.run()
When I run this through python firebug gives me the error "Dygraph is not defined." from the line g2 = new Dygraph(
Sample.html works in my folder, but it does not work when I try to access it from my url after running my flask code from python. My folders look like this:
FlaskStuff/main.py
FlaskStuff/templates/sample.html
FlaskStuff/templates/dygraph-combined.js (To load sample.html in my folder).
FlaskStuff/js/dygraph-combined.js
I am new to Flask. Similar answers did not help me to solve this problem.
Where is dygraph-combined.js located? It needs to be somewhere it can be served. You will most likely what to place it inside your static folder. It's a fairly common practice to group like files inside static (e.g., css, js).
Using this structure
static/
js/
dygraph-combined.js
you'll want to update sample.html as follows
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
This will allow the Flask development server to serve the file. You'll also want to add a rule to your HTTP server to serve content from /static directly.
You will also have to do a similar thing for the temperature.csv file. (I've placed it in the static folder)
"{{ url_for('static', filename='temperatures.csv') }}", // path to CSV file

How can I change the Django Admin Static Files url?

I'm hosting my Django project on my own server, and exactly as the docs say, the Django admin media stop showing up.
The solution is simply to host it yourself, which I'm doing. The problem I'm having is that the url the Django admin is using to try to find them is incorrect. Specifically, Django is looking at
<link rel="stylesheet" type="text/css" href="/ceasarb-cfa/admin/css/base.css">
when I want it to look at
<link rel="stylesheet" type="text/css" href="/ceasarb-cfa/static/admin/css/base.css">
My question is, how can I change that path?
Intuitively, I've tried adjust the ADMIN_MEDIA_PREFIX file in settings.py (currently set to /ceasarb-cfa/static/admin) but fiddling with that value didn't seem to change anything.
My guess is that your settomgs.py you have:
STATIC_URL = "/ceasarb-cfa/"
but it should be
STATIC_URL = "/ceasarb-cfa/static/".
Here's more documentation on that setting:
https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-STATIC_URL