For a bokeh folder application that will only run locally I am trying to display a PDF within an Iframe. The following code is indeed showing an Iframe but unfortunately it is always only filled with the following information: "404: Not Found"
from bokeh.models.widgets import Div
from bokeh.layouts import row
from bokeh.io import curdoc
div = Div(text="""<iframe src="path/to/pdf.pdf"></iframe>""",
width=300, height=300)
curdoc().add_root(row(div))
Any other solution than displaying the pdf in an Iframe would be welcomed as well.
Did you try a folder app with custom templates?
in my_app/
you have :
my_app/main.py
my_app/templates/index.html
in index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{{ bokeh_css }}
{{ bokeh_js }}
</head>
<body>
<iframe src="path/to/pdf.pdf"></iframe>
{{ plot_div|indent(8) }}
{{ plot_script|indent(8) }}
</body>
</html>
Related
I am trying to increase the font-size of the title of a slider in bokeh (0.12.4). For any other object there seems to be a "something_font_size" attribute, but as far as I can tell this doesn't seem to be the case for a slider title as it's saved as a string. Is there a way of doing this using bokeh or do I need to find a way to fix it using JavaScript?
Not certain if you can fix this using bokeh.
Try see what attributes and methods can be applied to the slider object.
If that fails, you could change it through investigating the elements on chrome/firefox then adding these to a styles.css file or similar.
.bk-slider-parent
{
font-size:20px
}
That seemed to increase both the name and value font sizes, you can also change just the values font size/color etc...
Let me just add that I am running with
bokeh serve --show Appdirectory
and Appdirectory contains main.py, Templates/index.html , Templates/styles.css - so you can include the snippet in either file (styles.css is included in index.html)
Updated: See below for bare minimum index.html should look like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Title</title>
{{ bokeh_css }}
{{ bokeh_js }}
</head>
<body>
<div class="content">
<h1>Title</h1>
{{ plot_div|indent(8) }}
{{ plot_script|indent(8) }}
</div>
</body>
</html>
My flask driven app works as expected with the high level Bar plot from Bokeh.
I now want to change the plot to a horizontal bar plot and found this SO answer.
My code minus the formatting for brevity:
from flask import Flask, render_template
from bokeh.embed import components
from bokeh.util.string import encode_utf8
from bokeh.plotting import figure
import pandas as pd
app = Flask(__name__)
#app.route('/')
def test():
kws = ["one", "two", "cat", "dog"]
count = [23, 45, 11, 87]
df = pd.DataFrame({"kw": kws,
"count": count
})
df.sort("count", inplace=True)
df.set_index("kw", inplace=True)
series = df['count']
p = figure(width=1000, height=1000, y_range=series.index.tolist())
j = 1
for k, v in series.iteritems():
w = v / 2 * 2
p.rect(x=v/2,
y=j,
width=w,
height=0.4,
color=(76, 114, 176),
width_units="screen",
height_units="screen"
)
j += 1
#### get components ####
script, div = components(p)
page = render_template('test.html', div=div, script=script)
return encode_utf8(page)
if __name__ == "__main__":
app.run(debug=True,
threaded=False
)
Located in templates/test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="http://cdn.bokeh.org/bokeh/release/bokeh-0.9.0.min.css" rel="stylesheet" type="text/css">
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-0.9.0.min.js"></script>
</head>
<body>
{{ div | safe }}
{{ script | safe }}
</body>
</html>
This answer works in testing with show(p). However the actual application takes the p object and gets the components div and script and embeds those in html.
When I run the app with debug=True I do not get an error just a hanging page.
EDIT: "Hang" is not accurate. I get a blank page.
Following Bigreddot's advice, I checked my version of Bokeh and adjusted the BokehJS version to match.
conda list bokeh yielded:
bokeh 0.10.0 py27_0
I then changed my html and the minimal example works as expected.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="http://cdn.bokeh.org/bokeh/release/bokeh-0.10.0.min.css" rel="stylesheet" type="text/css">
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-0.10.0.min.js"></script>
</head>
<body>
{{ div | safe }}
{{ script | safe }}
</body>
</html>
In case anyone comes across this from now on please note that bokeh.util.string import encode_utf8 has been removed since bokeh==2.0.0
In my case, with a flask app (using flask==1.1.2 and bokeh==2.0.2), I was simply able to delete this line from the code and in the html render template, just return html rather than return encode_utf8(html).
I'm new to Flask and
I'm trying to create a Stumbleupon like website but I'm having problems while loading the content into an iFrame. I just cant figure it out how to iterate through each url and load them into the iFrame while clicking in the <a> tag.
Here is what I've done:
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def index():
urls = [
'http://www.w3schools.com',
'http://techcrunch.com/',
'https://www.fayerwayer.com/',
]
return render_template('index.html', urls=urls)
if __name__ == "__main__":
app.run(debug=True)
templates/layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="/static/css/normalize.css"/>
<link rel="stylesheet" type="text/css" href="/static/css/foundation.css"/>
</head>
<body>
<nav class="top-bar">
<h3 align="center">Stumble</h3>
</nav>
{% block content %}
{% endblock content %}
</body>
</html>
templates/index.html
{% extends 'layout.html' %}
{% block content %}
<iframe frameborder='0' noresize='noresize' style='position: absolute; background: transparent; width: 100%; height:100%;' src="????????" frameborder="0"></iframe>
{% endblock content %}
After adding import random at the top of your app.py file you could structure your code like this:
def index():
urls = [
'http://www.w3schools.com',
'http://techcrunch.com/',
'https://www.fayerwayer.com/',
]
iframe = random.choice(urls)
return render_template('index.html', iframe=iframe)
Then access the value in your template:
<iframe frameborder='0' noresize='noresize' style='position: absolute; background: transparent; width: 100%; height:100%;' src="{{ iframe }}" frameborder="0"></iframe>
And simply set the Stumble button to refresh the page.
<h3 align="center">Stumble</h3>
This will be pretty basic, but it will have the behaviour you're describing.
An improvement will be to use the session object to make sure that two subsequent requests do not display the same page inside the iframe.
I am able to execute the python file through shell like so:
$ python jinja.py
[code]
from jinja2 import Environment, FileSystemLoader
DIR = '/Users/username/Sites'
env = Environment(loader=FileSystemLoader(DIR))
templateVars = {
"title" : "Test Example",
"description" : "Description"
}
template = env.get_template('index.html')
print template.render(templateVars)
[/code]
Here is the ouput via the shell:
[code]
<html>
<head>
<title>Test Example</title>
<meta name="description" content="Description">
</head>
<body>
test dictionary
</body>
</html>
[/code]
However, when I pull up index.html on the browser it doesn't render the variable, I am not sure the file jinja.py is even being executed.
Here is the sourcecode directly from my the browser window:
[code]
<html>
<head>
<title>{{ title }}</title>
<meta name="description" content="{{ description }}">
</head>
<body>
test dictionary
</body>
</html>
[/code]
Fyi, I am not using jinja2 in conjunction with any frameworks or other package dependencies.
Anyone able to help out.
Thanks
Mark
Your http://www.example.com/index.html should GET a script, which uses jinja to render the HTML.
You need a framework like webapp2 in Google App Engine to handle the GET.
I found this tutorial: https://www.youtube.com/watch?v=XyGW0ExGHDQ
Or use: https://developers.google.com/appengine/docs/python/gettingstartedpython27/introduction
I have a HTML template that I'm rendering using Django. I'm passing in all the necessary context variables — my_heading is the heading, my_html is the mark-safed html. I'd like to display my_html in the iframe.
<html>
<head>
<title>Iframe Example</title>
</head>
<body>
<p>{% my_heading %}</p>
<iframe name="iframe1" width="600" height="400" src="http://www.yahoo.com" frameborder="yes" scrolling="yes"></iframe>
</body>
</html>
Would you know how to do this? All the examples I've found show the iframe pointing to a URL. I'm god-horrible at HTML and JS. :|
Thanks
Michael Klocker does not answer your question, but the answer he has given is a better solution. You should rather do that.
But to answer you question: You can only pass a url to a IFrame, so if really want to use a IFrame, you need to set up second url+view in django to return my_html as the response. I.e. 2 http requests will happen. 1 for the page containing the IFrame, and 1 request for then contents of the IFrame.
If I understand you correctly, you just want to show the HTML content that you prepared dynamically with Python within the Django template, correct? If that is the case, you do not need an Iframe. Iframes are only necessary if you would like to integrate parts of a different URI (webpage) as a frame (section on your webpage) on your page. Here a sample:
<html>
<head>
<title>Iframe Example</title>
</head>
<body>
<p>{% my_heading %}</p>
<div id="content">{% my_html %}</div>
</body>
</html>
Addition to the above code, base on comment below. Sounds like you want to show an entire page with an Iframe and that this second page comes form another view/url on your box. Then use:
<html>
<head>
<title>Iframe Example</title>
</head>
<body>
<p>{% my_heading %}</p>
<iframe src="URL_TO_MY_2ND_VIEW_IN_DJANGO" width="100%" height="300"></iframe>
</body>
</html>
Iframe explanation on W3Schools
Iframe description on W3C Site
I used this hack to do it. The div is hidden and contains the HTML. The IFrame doesn't point to a location because I don't want any CORS issues. I then inject my HTML into it.
<html>
<head>
<title>Iframe Example</title>
</head>
<body>
<p>{% my_heading %}</p>
<iframe name="iframe2" id="iframe2" width="0" height="0" src="" style="border:0px; overflow-x:hidden;"></iframe>
<div id="page" style="display:none" >{{ my_html }}</div>
<script type="text/javascript">
function getWindow(iframe) {
return (iframe.contentWindow) ? iframe.contentWindow : (iframe.contentDocument.document) ? iframe.contentDocument.document : iframe.contentDocument;
}
getWindow(document.getElementById('iframe2')).document.open();
getWindow(document.getElementById('iframe2')).document.write(document.getElementById('page').innerHTML);
getWindow(document.getElementById('iframe2')).document.close();
document.getElementById('iframe2').style.height = (getWindow(document.getElementById('iframe2')).document.body.scrollHeight + 20) +"px";
document.getElementById('iframe2').style.width = (document.getElementById('iframe2').parentNode.offsetWidth) +"px";
</script>
</body>
</html>