So I am hosting some user-uploaded images on my site. I want to have an html page that displays the image inline, and some data about it on the side, etc. I've set up my app with two handlers, one that displays the image on the page that uses a url_for to get the url for the raw image(e.g. i.mysite.com/image.jpg). It displays on the page fine, but takes forever to load. When I remove this function and just generate a URL for the image alone without the page, it loads instantly. Is this just a flask thing that will be remedied in a production environment with a real webserver, or is there another way I should be doing this? The images are not in the /static folder, they are in their own folder. I get the url for the raw image link in the handler for the function that displays the page with the image on it, and pass that as a path to the template.
#app.route('/<filename>', subdomain='i')
def uploaded_image(filename):
return send_from_directory(app.config['IMAGE_FOLDER'], filename)
#app.route('/<tag>/', subdomain='i', methods=['GET'])
def display_image(tag):
file = Storedfile.query.filter_by(routing_id=tag).first()
filename = file.name
return render_template("image-page.html", source=url_for('uploaded_image', filename=filename))
Like I said it displays the image fine, but takes forever to load, and when I inspect the image on the page with FF's dev tools, instead of seeing an actual URL, I see something like
<img src="/pyhE4eJ.jpg"></img>
For the other links, I get actual URLS that are made from functions, like
Shouldn't the source for the image be looking like this too?
Related
I am writing a tool to record and monitor downtime on a range of equipment.
I have my file structure as below:
File Structure
Sites is just a subfolder containing individual HTMLS for where the equipment is located.
Currently, flask runs webapp.py which contains:
>from . import app
>#app = (__init__.app)
>from . import views
>from . import ReportingTool
views.py has all of my #app.route's in it, up until the [site].html files. From there, on the [site].html file I ask for input from the user. I haven't started writing code to record the user input in any meaningful way, just want to get the data to a python script and commit them to variables. To this end, in the html file I have
<body>
<div class="menu">
<form method="post" enctype="multipart\form-data" action="{{ url_for('downTime') }}">
<fieldset class="datafieldset">
This then requests different data from the user in the form of multiple field sets as seen here: fieldsets
as you see in the code snippet above I set the action to be url_for('downTime'), downTime is a function in my python file ReportingTool.py. this throws out an error, "werkzeug.routing.exceptions.BuildError: Could not build url for endpoint 'downTime'. Did you mean 'supportguide' instead?" traceback
Is there something I need to add or specify on the html document to enable this page (and the other [site].html pages to call functions from the ReportingTool.py file? the #app.route that calls the [site].html file is this and that is called with a redirected from here I've only got it setup like that becuase I wanted the name for the site to appear in the address bar.
Thanks in advance.
I am not sure on steps to fix as I am kind of throwing myself in the deep end to learn basic coding by creating an application for my workplace to replace an excel spreadsheet I created.
You are not reaching the downTime function in the ReportingTool.py file. I suggest trying add_url_rule in your views.py by adding the /reported endpoint referencing the downTime function in ReportingTool.py. Something like this;
app.add_url_rule('/reported', 'ReportingTool.downTime', view_func=ReportingTool.downTime, methods=METHODS)
This answer is based on the responds for this question. You are trying to reach a function in a different file from your main view file. Assuming you are calling the page with the form from a function in the views.py file.
Solved with info from Kakedis' input, and the links they provided.
I added:
app.add_url_rule('/reported', 'ReportingTool.downTime', view_func=ReportingTool.downTime, methods=METHODS)
to webbapp.py, then:
#app.route('/reported')
def downTime():
try:
DTref = request.form['refDT']
except:
DTref = "No Reference"
print(DTref)
print("reported")
return(render_template("/UserRip.html"))
to ReportingTool.py
This now prints the above to console to confirm it's pulling the correct func and brings the user back to the starting page.
I am using a django template to generate pdf via feeding it a context object from the function but not the view, it works fine in case of view, but I am not able to load the local static images on the template from the function. but this is possible in view because there I can tell which base path to use. But I not able to do the same in the function.
As you can see I can how I am getting the base url from the view. Here I can get because I have requests object but in function I do not have any requests object. So images are not loading.
html = HTML(string=html_string, base_url=request.build_absolute_uri('/'))
This is how I am trying to do in the function:
html_string = render_to_string('experiences/voucher.html', data)
html = HTML(string=html_string, base_url=settings.STATIC_ROOT)
result = html.write_pdf("file_new.pdf", stylesheets=[css],optimize_images=True)
I would like to know how can I tell, where are my images so that images can be rendered on the pdf.
It was not working because base_url had not way to know where the images are located especially on the running server, so I had to explicitly define the path to the local resources so I did something like this:
first I added an envoirnment variable in my .env file:
like HOST=http://localhost:8000 and then I get this url in my actuall code like this:
path = os.environ["HOST"]+"/static/"
and at the end i pass this path to base_url parameter in HTML()
html = HTML(string=html_string, base_url=path)
and after all this it worked like a charm.
Currently I am using flask and heroku to deploy my website but i need my webpage show random photo from img directory currently my code look like this
import os
import random
imgs = os.listdir('static/img')
imgs = ['img/' + file for file in imgs]
imgrand = random.sample(imgs,k=5)
#app.route('/')
def index():
return render_template('index.html', imgrand=imgrand)
And my HTML code look like this
{% for img in imgrand %}
<img src="static/{{img}}" alt="{{imgL}}" style="width:100%">
{% endfor %}
So long it work fine in my local machine ,but it only random picture only once when start flask run command in terminal. My goal is to make my web page random picture everytime when refresh webpage without going to end terminal session and start flask run command all over again.
In this case imggrand variable only takes one sample at the beggining of the program, for repeating the process everytime you refresh the webpage you need to put imggrand inside the endpoint.
I recommend you to learn about endpoints and designing the workflow starting with this: https://flask.palletsprojects.com/en/1.1.x/quickstart/#rendering-templates
So I have the following environment; django 1.8. apache on ubuntu 14 with mod_wsgi and mod x-sendfile enabled.
I have a very simple view to server the files as follows:
def foo(request, filename):
response = HttpResponse()
response['Content-Disposition'] = 'attachment; filename={0}'.format(filename)
response['X-Sendfile'] = "/home/amir/DjV/Files/{0}".format(filename)
return response
and here's my urlconf regarding the view:
url(r'^foo/(.+)/$', foo)
I've written a snippet that generate absolute path to files to be presented in a download list. The generated paths work fine if I enter them in the browser; but if I use them as hyperlinks, when clicked it goes to blank page. For examlple here is one the urls that is generated by the snippet I mentioned:
http://192.168.43.6:8000/foo/uuid.txt
it works fine and I get to download the uuid.txt, but when I put it into django template as follows, it doesn't work:
192.168.43.6:8000/foo/uuid.txt
My question being: why my link works fine when entered manually but not when used as a hyperlink? Could it be because of being a local address? How can I fix it?
You need to specify a protocol inside your template when doing such things:
192.168.43.6:8000/foo/uuid.txt
However, you should not hard code urls in this way in special not if they are handled inside your Django application. Check {% url %} templating whether it could be a benefit for you
Related to: django - pisa : adding images to PDF output
I've got a site that uses the Google Chart API to display a bunch of reports to the user, and I'm trying to implement a PDF version. I'm using the link_callback parameter in pisa.pisaDocument which works great for local media (css/images), but I'm wondering if it would work with remote images (using a google charts URL).
From the documentation on the pisa website, they imply this is possible, but they don't show how:
Normaly pisa expects these files to be found on the local drive. They may also be referenced relative to the original document. But the programmer might want to load form different kind of sources like the Internet via HTTP requests or from a database or anything else.
This is in a Django project, but that's pretty irrelevant. Here's what I'm using for rendering:
html = render_to_string('reporting/pdf.html', keys,
context_instance=RequestContext(request))
result = StringIO.StringIO()
pdf = pisa.pisaDocument(
StringIO.StringIO(html.encode('ascii', 'xmlcharrefreplace')),
result, link_callback=link_callback)
return HttpResponse(result.getvalue(), mimetype='application/pdf')
I tried having the link_callback return a urllib request object, but it does not seem to work:
def link_callback(uri, rel):
if uri.find('chxt') != -1:
url = "%s?%s" % (settings.GOOGLE_CHART_URL, uri)
return urllib2.urlopen(url)
return os.path.join(settings.MEDIA_ROOT, uri.replace(settings.MEDIA_URL, ""))
The PDF it generates comes out perfectly except that the google charts images are not there.
Well this was a whole lot easier than I expected. In your link_callback method, if the uri is a remote image, simply return that value.
def link_callback(uri, rel):
if uri.find('chart.apis.google.com') != -1:
return uri
return os.path.join(settings.MEDIA_ROOT, uri.replace(settings.MEDIA_URL, ""))
The browser is a lot less picky about the image URL, so make sure the uri is properly quoted for pisa. I had space characters in mine which is why it was failing at first (replacing w/ '+' fixed it).