my hyperlink generated in django doesn't work - python

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

Calling a function on HTML page, not found

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.

How to load static images in a django template from function not from view

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.

Unable to serve static file from flask server

I have a index.html file, which has the absolute path 'c:\project\web\frontend\index.html'
I am trying to return it using the following function
#webserver.route('/')
def home()
return webserver.send_static_file(path)
I have verified that the path is correct by accessing it directly in the browser.
I have tried to replace '\' with '/' without any luck.
It is running on a windows machine.
If you look at flask's documentation for send_static_file. You'll see that it says that it's used internally by flask framework to send a file to the browser. If you want to render an html, it's common to use render_template. You need to make sure that your index.html is in a folder called templates first.
So I would do the following:
#webserver.route('/')
def home()
return flask.render_template('index.html')
I had to define the path to be the static_folder, when creating the flask object. Once I defined the folder to be static, the html page was served.

How to run a Python script in a web page

I'm very new to Python. I just know what Python is.
I have created the below code (in Python IDLE):
print "Hi Welcome to Python test page\n";
print "Now it will show a calculation";
print "30+2=";
print 30+2;
Then I saved this page in my localhost as index.py
I run the script using
http://localhost/index.py
But it does not show the executed Python script. Instead, it showed the above code as HTML. Where is the problem? How can I run a Python file in a web page?
In order for your code to show, you need several things:
Firstly, there needs to be a server that handles HTTP requests. At the moment you are just opening a file with Firefox on your local hard drive. A server like Apache or something similar is required.
Secondly, presuming that you now have a server that serves the files, you will also need something that interprets the code as Python code for the server. For Python users the go to solution is nowadays mod_wsgi. But for simpler cases you could stick with CGI (more info here), but if you want to produce web pages easily, you should go with a existing Python web framework like Django.
Setting this up can be quite the hassle, so be prepared.
As others have pointed out, there are many web frameworks for Python.
But, seeing as you are just getting started with Python, a simple CGI script might be more appropriate:
Rename your script to index.cgi. You also need to execute chmod +x index.cgi to give it execution privileges.
Add these 2 lines in the beginning of the file:
#!/usr/bin/python
print('Content-type: text/html\r\n\r')
After this the Python code should run just like in terminal, except the output goes to the browser. When you get that working, you can use the cgi module to get data back from the browser.
Note: this assumes that your webserver is running Linux. For Windows, #!/Python26/python might work instead.
Using the Flask library in Python, you can achieve that.
Remember to store your HTML page to a folder named "templates" inside where you are running your Python script.
So your folder would look like
templates (folder which would contain your HTML file)
your Python script
This is a small example of your Python script. This simply checks for plagiarism.
from flask import Flask
from flask import request
from flask import render_template
import stringComparison
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template("my-form.html") # This should be the name of your HTML file
#app.route('/', methods=['POST'])
def my_form_post():
text1 = request.form['text1']
text2 = request.form['text2']
plagiarismPercent = stringComparison.extremelySimplePlagiarismChecker(text1,text2)
if plagiarismPercent > 50 :
return "<h1>Plagiarism Detected !</h1>"
else :
return "<h1>No Plagiarism Detected !</h1>"
if __name__ == '__main__':
app.run()
This a small template of HTML file that is used:
<!DOCTYPE html>
<html lang="en">
<body>
<h1>Enter the texts to be compared</h1>
<form action="." method="POST">
<input type="text" name="text1">
<input type="text" name="text2">
<input type="submit" name="my-form" value="Check !">
</form>
</body>
</html>
This is a small little way through which you can achieve a simple task of comparing two strings and which can be easily changed to suit your requirements.
If you are using your own computer, install a software called XAMPP (or WAMP either works). This is basically a website server that only runs on your computer. Then, once it is installed, go to the xampp folder and double click the htdocs folder. Now you
need to create an HTML file (I'm going to call it runpython.html). (Remember to move the Python file to htdocs as well.)
Add in this to your HTML body (and inputs as necessary).
<form action = "file_name.py" method = "POST">
<input type = "submit" value = "Run the Program!!!">
</form>
Now, in the Python file, we are basically going to be printing out HTML code.
# We will need a comment here depending on your server. It is basically telling the server where your python.exe is in order to interpret the language. The server is too lazy to do it itself.
import cgitb
import cgi
cgitb.enable() # This will show any errors on your webpage
inputs = cgi.FieldStorage() # REMEMBER: We do not have inputs, simply a button to run the program. In order to get inputs, give each one a name and call it by inputs['insert_name']
print "Content-type: text/html" # We are using HTML, so we need to tell the server
print # Just do it because it is in the tutorial :P
print "<title> MyPythonWebpage </title>"
print "Whatever you would like to print goes here, preferably in between tags to make it look nice"
Well, the OP didn't say server or client side, so I will just leave this here in case someone like me is looking for client side:
Skulpt is a implementation of Python to run at client side. Very interesting, no plugin required, just simple JavaScript code.
With your current requirement, this would work:
def start_html():
return '<html>'
def end_html():
return '</html>'
def print_html(text):
text = str(text)
text = text.replace('\n', '<br>')
return '<p>' + str(text) + '</p>'
if __name__ == '__main__':
webpage_data = start_html()
webpage_data += print_html("Hi Welcome to Python test page\n")
webpage_data += fd.write(print_html("Now it will show a calculation"))
webpage_data += print_html("30+2=")
webpage_data += print_html(30+2)
webpage_data += end_html()
with open('index.html', 'w') as fd: fd.write(webpage_data)
Open the index.html file, and you will see what you want.

Using an image URL for link_callback in the pisa html to pdf library

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).

Categories

Resources