path for including css, javascript in python flask application? - python

I am using code from this github project to create a python flask application with d3js charts. The templates/index.html file contains css and js code written in the HTML file. But, if I try to put that code in external files and reference that in my index.html, the file is untraceable. I tried different paths (templates folder and also the root folder) but none of them worked.
Please suggest on how I should use external css and js files.
This is my templates/index.html code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>flask+d3 Hello World</title>
<script src="http://d3js.org/d3.v2.js"></script>
<link rel="stylesheet" type="text/css" href="mystyle.css">
<link rel="stylesheet" type="text/css" href="templates/mystyle.css">
<link rel="stylesheet" type="text/css" href="../mystyle.css">
</head>
<body>
<h1>Hello World using d3.js & Flask</h1>
<div id="info">
<div id="point-info">
Click on a point.
</div>
</div>
<div id="plot">
</div>
<script>
// Set up the plot window.
var margin = 80;
var w = 700 - 2 * margin, h = 500 - 2 * margin;
var svg = d3.select("#plot").append("svg")
.attr("width", w + 2 * margin)
.attr("height", h + 2 * margin)
.append("svg:g")
.attr("transform", "translate(" + margin + ", " + margin + ")");
// The colorbar.
var color = d3.scale.quantize()
.range(["#156b87", "#876315", "#543510", "#872815"])
.domain([0, 1]);
// Axes scaling functions.
var xscale = d3.scale.linear().range([0, w]);
var yscale = d3.scale.linear().range([h, 0]);
// The axes objects themselves.
var xaxis = d3.svg.axis().scale(xscale).ticks(8);
var yaxis = d3.svg.axis().scale(yscale).ticks(8).orient("left");
svg.append("svg:g").attr("class", "x axis")
.attr("transform", "translate(0, " + h + ")");
svg.append("svg:g").attr("class", "y axis");
// Show the information about a particular point.
var show_info = function (d) {
d3.select("#point-info").text("This is point " + d._id + ". "
+ "It has the coordinates (" + d.x + ", " + d.y + ").");
};
// Load the data.
var callback = function (data) {
// Rescale the axes.
xscale.domain([d3.min(data, function (d) { return d.x; }) - 0.05,
d3.max(data, function (d) { return d.x; }) + 0.05]);
yscale.domain([d3.min(data, function (d) { return d.y; }) - 0.05,
d3.max(data, function (d) { return d.y; }) + 0.05]);
// Display the axes.
svg.select(".x.axis").call(xaxis);
svg.select(".y.axis").call(yaxis);
// Insert the data points.
svg.selectAll("circle").data(data).enter()
.append("circle")
.attr("id", function (d) { return d._id; })
.attr("cx", function (d) { return xscale(d.x); })
.attr("cy", function (d) { return yscale(d.y); })
.attr("r", function (d) { return 2 * Math.sqrt(d.area); })
.style("fill", function (d) { return color(d.color); })
.on("mousedown", show_info);
};
d3.json("/data", callback);
</script>
</body>
</html>
This is my mystyle.css code:
path.line {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
.domain {
stroke-width: 1px;
}
circle {
cursor: pointer;
}
.axis {
shape-rendering: crispEdges;
}
.axis line, .axis path {
stroke-width: 1px;
stroke: #000;
fill: none;
}
.tooltip {
display: none;
}
.tooltip.active {
display: block;
}
.tooltip rect {
fill: #ff0000;
}

Simple answer is: create a folder named 'static', place your static files in it and their url path in HTML is '/static/your_file_path/your_file_name.extension'.
Here is the documenation on static file where you can find the authentic answer.
If you would like to change the default 'static' folder and also change default static file url path, you can read these application startup configurations

Related

Google Fonts not loading on Bokeh Line Glyph until after interacting with the Glyph

I'm having an issue with the font incorrectly displaying on my graph until after the user interacts with the graph on my standalone HTML document.
Here's the python code that is used to generate the script and div to place in the HTML file (notice I am using Roboto as my font):
df1 = pd.DataFrame({"A":[1,2,3,4,5,6],
"B":[5,6,3,2,1,4]})
graph = ColumnDataSource(data= df1)
p = figure(plot_width=600, plot_height=400)
p.line(source = graph, x = 'A', y = 'B')
p.xaxis.axis_label = "Number"
p.xaxis.axis_label_text_font = 'Roboto'
p.xaxis.axis_label_text_font_size = '14pt'
p.xaxis.major_label_text_font_size = '10pt'
p.yaxis.axis_label = "Average"
p.yaxis.axis_label_text_font = 'Roboto'
p.yaxis.axis_label_text_font_size = '14pt'
p.yaxis.major_label_text_font_size = '10pt'
script, div = components(p)
And the following is the html after inserting both the script, div, and the necessary other scripts and links to the header (ie the cdn.bokeh.org and fonts.googleapis):
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bokeh Line Plot</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,500,700" />
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-1.4.0.min.js"></script>
<script type="text/javascript">
(function() {
var fn = function() {
Bokeh.safely(function() {
(function(root) {
function embed_document(root) {
var docs_json = '{"acd6be22-a352-429f-bbb6-e0e40d198ca6":{"roots":{"references":[{"attributes":{"callback":null},"id":"5824","type":"DataRange1d"},{"attributes":{"source":{"id":"5822","type":"ColumnDataSource"}},"id":"5859","type":"CDSView"},{"attributes":{},"id":"5847","type":"HelpTool"},{"attributes":{"dimension":1,"ticker":{"id":"5838","type":"BasicTicker"}},"id":"5841","type":"Grid"},{"attributes":{"below":[{"id":"5832","type":"LinearAxis"}],"center":[{"id":"5836","type":"Grid"},{"id":"5841","type":"Grid"}],"left":[{"id":"5837","type":"LinearAxis"}],"plot_height":400,"renderers":[{"id":"5858","type":"GlyphRenderer"}],"title":{"id":"5861","type":"Title"},"toolbar":{"id":"5848","type":"Toolbar"},"x_range":{"id":"5824","type":"DataRange1d"},"x_scale":{"id":"5828","type":"LinearScale"},"y_range":{"id":"5826","type":"DataRange1d"},"y_scale":{"id":"5830","type":"LinearScale"}},"id":"5823","subtype":"Figure","type":"Plot"},{"attributes":{"line_alpha":0.1,"line_color":"#1f77b4","x":{"field":"A"},"y":{"field":"B"}},"id":"5857","type":"Line"},{"attributes":{},"id":"5846","type":"ResetTool"},{"attributes":{},"id":"5833","type":"BasicTicker"},{"attributes":{"line_color":"#1f77b4","x":{"field":"A"},"y":{"field":"B"}},"id":"5856","type":"Line"},{"attributes":{"callback":null,"data":{"A":[1,2,3,4,5,6],"B":[5,6,3,2,1,4],"index":[0,1,2,3,4,5]},"selected":{"id":"5867","type":"Selection"},"selection_policy":{"id":"5868","type":"UnionRenderers"}},"id":"5822","type":"ColumnDataSource"},{"attributes":{"axis_label":"Average","axis_label_text_font":"Roboto","axis_label_text_font_size":{"value":"14pt"},"formatter":{"id":"5862","type":"BasicTickFormatter"},"major_label_text_font_size":{"value":"10pt"},"ticker":{"id":"5838","type":"BasicTicker"}},"id":"5837","type":"LinearAxis"},{"attributes":{"data_source":{"id":"5822","type":"ColumnDataSource"},"glyph":{"id":"5856","type":"Line"},"hover_glyph":null,"muted_glyph":null,"nonselection_glyph":{"id":"5857","type":"Line"},"selection_glyph":null,"view":{"id":"5859","type":"CDSView"}},"id":"5858","type":"GlyphRenderer"},{"attributes":{"bottom_units":"screen","fill_alpha":{"value":0.5},"fill_color":{"value":"lightgrey"},"left_units":"screen","level":"overlay","line_alpha":{"value":1.0},"line_color":{"value":"black"},"line_dash":[4,4],"line_width":{"value":2},"render_mode":"css","right_units":"screen","top_units":"screen"},"id":"5866","type":"BoxAnnotation"},{"attributes":{},"id":"5843","type":"WheelZoomTool"},{"attributes":{"overlay":{"id":"5866","type":"BoxAnnotation"}},"id":"5844","type":"BoxZoomTool"},{"attributes":{},"id":"5842","type":"PanTool"},{"attributes":{},"id":"5867","type":"Selection"},{"attributes":{},"id":"5862","type":"BasicTickFormatter"},{"attributes":{"callback":null},"id":"5826","type":"DataRange1d"},{"attributes":{},"id":"5864","type":"BasicTickFormatter"},{"attributes":{"text":""},"id":"5861","type":"Title"},{"attributes":{"ticker":{"id":"5833","type":"BasicTicker"}},"id":"5836","type":"Grid"},{"attributes":{"axis_label":"Number","axis_label_text_font":"Roboto","axis_label_text_font_size":{"value":"14pt"},"formatter":{"id":"5864","type":"BasicTickFormatter"},"major_label_text_font_size":{"value":"10pt"},"ticker":{"id":"5833","type":"BasicTicker"}},"id":"5832","type":"LinearAxis"},{"attributes":{},"id":"5828","type":"LinearScale"},{"attributes":{},"id":"5838","type":"BasicTicker"},{"attributes":{},"id":"5830","type":"LinearScale"},{"attributes":{},"id":"5868","type":"UnionRenderers"},{"attributes":{},"id":"5845","type":"SaveTool"},{"attributes":{"active_drag":"auto","active_inspect":"auto","active_multi":null,"active_scroll":"auto","active_tap":"auto","tools":[{"id":"5842","type":"PanTool"},{"id":"5843","type":"WheelZoomTool"},{"id":"5844","type":"BoxZoomTool"},{"id":"5845","type":"SaveTool"},{"id":"5846","type":"ResetTool"},{"id":"5847","type":"HelpTool"}]},"id":"5848","type":"Toolbar"}],"root_ids":["5823"]},"title":"Bokeh Application","version":"1.4.0"}}';
var render_items = [{"docid":"acd6be22-a352-429f-bbb6-e0e40d198ca6","roots":{"5823":"03d9974b-b67c-4395-9dec-d23214a6cb55"}}];
root.Bokeh.embed.embed_items(docs_json, render_items);
}
if (root.Bokeh !== undefined) {
embed_document(root);
} else {
var attempts = 0;
var timer = setInterval(function(root) {
if (root.Bokeh !== undefined) {
clearInterval(timer);
embed_document(root);
} else {
attempts++;
if (attempts > 100) {
clearInterval(timer);
console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
}
}
}, 10, root)
}
})(window);
});
};
if (document.readyState != "loading") fn();
else document.addEventListener("DOMContentLoaded", fn);
})();
</script>
</head>
<body>
<div class="bk-root" id="03d9974b-b67c-4395-9dec-d23214a6cb55" data-root-id="5823"></div>
</body>
</html>
Notice the font of the major axis labels, then drag the graph in any direction, you will notice the fonts for the major axis change to Roboto.
I've tried also to use autoload_static() method to generate the script, then insert the glyph into the HTML that way however, I end up with the exact same result. There are also no errors in the console on chrome.
Thanks for your help!
I had hoped things might fare better with the newer json_item API, but that does not work either. As of Bokeh 1.4 I am afraid I don't have any good answer or workaround to suggest. At this point I would characterize this as a bug that requires investigation, so I'd encourage you to submit a GitHub issue about it (including complete code to reproduce).

How to remove margins from PDF? (Generated using WeasyPrint)

I am trying to render a PDF document within my Flask application. For this, I am using the following HTML template:
<!DOCTYPE html>
<html>
<head>
<style>
#page {
margin:0
}
h1 {
color:white;
}
.header{
background: #0a0045;
height: 250px;
}
.center {
position: relative;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align:center;
}
</style>
</head>
<body>
<div class="header">
<div class="center">
<h1>Name</h1>
</div>
</div>
</body>
</html>
I keep getting white margins at the top and right/left of my header section:
Is there a way to remove them?
Edit:
Below is the code used to generate the PDF file using WeasyPrint in my Flask app:
def generate_pdf(id):
element = Element.query.filter_by(id=id).first()
attri_dict = get_element_attri_dict_for_tpl(element)
html = render_template('element.html', attri_dict=attri_dict)
pdf = HTML(string=html).write_pdf()
destin_loc = app.config['ELEMENTS_FOLDER']
timestamp = dt.datetime.now().strftime('%Y%m%d%H%M%S')
file_name = '_'.join(['new_element', timestamp])
path_to_new_file = destin_loc + '/%s.pdf' % file_name
f = open(path_to_new_file, 'wb')
f.write(pdf)
filename = return_latest_element_path()
return send_from_directory(directory=app.config['ELEMENTS_FOLDER'],
filename=filename,
as_attachment=True)
Maybe you forgot " ; " or/and " mm ",
it works:
#page {
size: A4; /* Change from the default size of A4 */
margin: 0mm; /* Set margin on each page */
}
The weasyprint uses 3 sources of css, one of them is default user agent stylesheet
(https://doc.courtbouillon.org/weasyprint/stable/api_reference.html#supported-features)
That defines:
body {
display: block;
margin: 8px;
}
make sure to override that margin on tag and you will loose the margin.

use textarea for python input() to Skulpt

i want to use a textarea whenever the Python input() function is run in Skulpt. The default is to use an alert box - i want to use a textarea instead.
i've tried to get this working, but nothing happens when i try this example:
https://github.com/skulpt/skulpt/issues/685
everything else works fine as i want it. please help! :D
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/jquery-3.2.1.min.js" type="text/javascript"></script>
<script src="js/debugger.js" type="text/javascript"></script>
<script src="js/skulpt.min.js" type="text/javascript"></script>
<script src="js/skulpt-stdlib.js" type="text/javascript"></script>
<title>i dont like the alert boxes</title>
<style type="text/css" media="screen">
#source{
position: relative;
width: 500px;
height: 300px;
}
#console{
position: relative;
width: 500px;
height: 100px;
overflow: scroll;
}
body{
background-color: whitesmoke;
}
#turtleCanvas{
position: relative;
border: 1px;
border-color: firebrick;
border-collapse: collapse;
border-style: solid;
width: 500px;
}
</style>
<script src="js/brython/brython.js" type="text/javascript"></script>
</head>
<body onload="brython()">
<script type="text/javascript">
function outf(text) {
var mypre = document.getElementById("console");
mypre.innerHTML = mypre.innerHTML + text;
}
function builtinRead(x) {
if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
throw "File not found: '" + x + "'";
return Sk.builtinFiles["files"][x];
}
function runit() {
var editor = ace.edit("source");
var code = editor.getValue();
document.getElementById("hiddenCode").innerHTML = code;
var prog = document.getElementById("hiddenCode").value;
var mypre = document.getElementById("console");
mypre.innerHTML = '';
Sk.pre = "console";
Sk.configure({output:outf, read:builtinRead});
(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'turtleCanvas';
var myPromise = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("<stdin>", false, prog, true);
});
myPromise.then(function(mod) {
console.log('success');
},
function(err) {
console.log(err.toString());
});
}
</script>
<textarea id="hiddenCode" style="display:none;"></textarea><br />
<div id="source">import turtle
myName = input("who r u?")
print(myName)
t = turtle.Turtle()
t.forward(100)</div>
<button type="button" onclick="runit()">Run</button>
<textarea id="programInputField">some input lines</textarea>
<pre id="console">output</pre>
<div id="turtleCanvas"></div>
<script src="js/ace/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var window1 = ace.edit("source");
var window2 = ace.edit("console");
window1.setTheme("ace/theme/textmate");
window2.setTheme("ace/theme/twilight");
window1.getSession().setMode("ace/mode/python");
</script>
</body>
Never mind!!!! This worked perfectly, just had to change the id of my text area, otherwise i just copied and pasted it and commented out my own sk.configure line..... brilliant, thankyou whoever you are!!!!!!! :D :D :D :D
Wait for an event to occur within a function in Javascript for Skulpt

HTML make markers clickable on google maps

I am plotting some markers using gmplot from Python. It produces an html file like this one:
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps - pygmaps </title>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=visualization&sensor=true_or_false"></script>
<script type="text/javascript">
function initialize() {
var centerlatlng = new google.maps.LatLng(4.670719, -74.099096);
var myOptions = {
zoom: 13,
center: centerlatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var latlng = new google.maps.LatLng(11.008578, -74.813284);
var img = new google.maps.MarkerImage('/home/vladimir/anaconda3/lib/python3.5/site-packages/gmplot/markers/FF0000.png');
var marker = new google.maps.Marker({
title: "http://www.google.com",
icon: img,
position: latlng
});
marker.setMap(map);
var latlng = new google.maps.LatLng(10.396109, -75.518069);
var img = new google.maps.MarkerImage('/home/vladimir/anaconda3/lib/python3.5/site-packages/gmplot/markers/FF0000.png');
var marker = new google.maps.Marker({
title: "http://www.google.com",
icon: img,
position: latlng
});
marker.setMap(map);
... (and so on)
}
</script>
</head>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width: 100%; height: 100%;"></div>
</body>
</html>
where /home/vladimir/anaconda3/lib/python3.5/site-packages/gmplot/markers/FF0000.png is the directory that saves the marker file. I have many points like those one, and for each point I have a URL. In this case I have put the URL as simply "http://www.google.com" in the marker's title. When I open the html file with a web browser and I hover over the markers the URL is shown to me. I would like to be able to click on the marker and make the browser open the URL. I do not have a lot of knowledge in HTML so I'm finding this rather difficult. I appreciate your help and good faith. Thanks.
ou could add a function for manage the listener on click event for marker
function initialize() {
var centerlatlng = new google.maps.LatLng(4.670719, -74.099096);
var myOptions = {
zoom: 13,
center: centerlatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// add a function for closure
var addListenersOnMarker = function(actMarker, aTarget,) {
google.maps.event.addListener(actMarker, 'click', function (event) {
window.open(aTarget, '_blank');
});
}
var latlng = new google.maps.LatLng(11.008578, -74.813284);
var img = new google.maps.MarkerImage('/home/vladimir/anaconda3/lib/python3.5/site-packages/gmplot/markers/FF0000.png');
var marker = new google.maps.Marker({
//title: "http://www.google.com",
icon: img,
position: latlng
});
marker.setMap(map);
// call the function for listener
addListenersOnMarker( marker, "http://www.google.com" ) ;
var latlng = new google.maps.LatLng(10.396109, -75.518069);
var img = new google.maps.MarkerImage('/home/vladimir/anaconda3/lib/python3.5/site-packages/gmplot/markers/FF0000.png');
var marker = new google.maps.Marker({
//title: "http://www.google.com",
icon: img,
position: latlng
});
marker.setMap(map);
// call the function for listener
addListenersOnMarker( marker, "http://www.google.com" ) ;
var
... (and so on)
}

my html file returns blank page. How to solve this?

my file temp.py read data from my sensor connected to my rasbperry . my views sends it to html file . I think my call in index.html is not correct . Because when I run my Django project it returns a blank page
views.py
from django.shortcuts import render
from temp import get_temp
import json
def index(request):
return render(request, 'aps/index.html', {'t' : get_temp()})
temp.py
def get_temp() :
tfile = open("/sys/bus/w1/devices/28-0000075292ed/w1_slave")
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000
return temperature
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title> Temperature Sensor</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<style type="text/css">
${demo.css}
</style>
<script type="text/javascript">
$(function () {
$(document).ready(function () {
Highcharts.setOptions({
global: {
useUTC: false
}
});
$('#container').highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = {{ t }} ;
series.addPoint([x, y], true, true);
}, 3000);
}
}
},
title: {
text: 'Live sensor temperature data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'sensor data',
data: (function () {
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: {{ t }}
});
}
return data;
}())
}]
});
});
});
</script>
</head>
<body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
</html>
Add your urls.py
What url are you using at the browser?
If possible add what give you back the browser when you press cntrl+u in your blank page.

Categories

Resources