Turbogears abort function automatically escapes HTML code - python

I would like to use some HTML messages in the turbogears abort function.
Although the name does not match exactly (I use the 'tg.abort' function), this is the abort definition I found :
abort
The code used currently :
from tg import abort
message="The following {} occured, this is due to {}, please visit this url : {}".format(error, reason, url)
abort(status_code=502, detail=message)
I would like to have something like this :
from tg import abort
message="""The following error occured : {}</br>
The most probable reason would be {} </br>
Your solution might be found here
""".format(error, reason, url)
abort(status_code=502, detail=message)
I think the content is automatically escaped.
The Html page generated from the abort function, endering something like this :
<html>
<head>
<title>502 Bad Gateway</title>
</head>
<body>
<h1>502 Bad Gateway</h1>
Bad gateway.<br /><br />
The following error occured : hungry<br/>
The most probable reason would be : maybe you should eat </br>
<a href="http://dummyurl">Your solution might be found here</a>
</body>
</html>
If you have any idea of how to insert html code without escaping, I would be very interested.
Also I really am focused on the abort method here, I am aware that I could use some dedicated page that would use a templating framework (like the rest of the website).
Thank you very much.
Regards

The error message is actually exposed by the controllers/error.py code in your application. So if you want to expose the message from abort details you should fetch it and return it in the ErrorController.
This is now done by default on newly quickstarted projects ( see https://github.com/TurboGears/tg2devtools/blob/master/devtools/templates/turbogears/%2Bpackage%2B/controllers/error.py_tmpl#L27 ) but it was not done on old versions.

Related

Textarea event handling with Python3

I wonder if someone can help me. I'm trying to do something like the following to get input events from a HTML text box and send them to a python function.
textarea = cgi.FieldStorage()
chars = textarea.getvalue('1')
def MyPythonFunction():
'Do something with chars'
print(<textarea oninput=MyPythonFunction() </textarea>)
I've tried all kinds of things but can't get it to work.
Thanks in advance
First, the oninput keyword of the textarea HTML tag expects JavaScript code and would interpret mypythonfunction to be a JavaScript function. You need to output an HTML form that contains a SUBMIT tag such that when the form is submitted it invokes your server-side script: the form might look like:
<form name="f" action="my_script.py" method="post">
<textarea name="chars"></textarea>
<br>
<input type="submit" name="submit" value="Submit">
</form>
Your server side script, my_script.py, which must be executable, might look like:
#!/usr/bin/env python
import cgi
import cgitb
cgitb.enable()
form = cgi.FieldStorage()
chars = form.getvalue('chars')
If you really wanted to process input a character at a time, then you would remove the SUBMIT HTML tag, put back the oninput keyword. But then you would have to specify a JavaScript function that would get invoked whenever the contents of the textarea changed. This function would have to use a technique called AJAX to invoke your server-side Python script passing the contents of the TEXTAREA as an argument. This is a rather advanced topic, but you can investigate this.

Apache2 "Response header name '<!--' contains invalid characters, aborting request"

Edit
The problem had nothing to do with the http header. It was a variable that was called in the cgi/python script before it was defined. Just in case others also try to work with an error message like that but can't find the reason for it.
I have inherited a website based on apache2/python/cgi scripts that I'm trying to maintain, but sometimes I'm struggling with really unhelpful errors. In this case, I get The server encountered an internal error or misconfiguration and was unable to complete your request. when clicking on an element on a page. The error log gives me the following information:
[Fri Jul 28 14:11:15.150877 2017] [http:error] [pid 1727] [client 193.174.111.250:53426] AH02429: Response header name '<!--' contains invalid characters, aborting request
Based on a similar question, I'm assuming the error is quite new, but I can't find the problem. Especially since the link / the script name stays the same. It works when first opening the site, but then stops working when I click something which does not refer me to a different site/script. How can that be the header's fault?
Just in case, here is the code that generates the beginning of the web page:
Code = "Content-Type: text/html\n\n"
Code += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN'>\n<html>\n"
Code += "<head>\n <title>BACTOME: RELATIVE EXPRESSIONS</title>\n"
...
As far as I understand now, the first line constitutes the only HTTP header I have. There is no '<!--' as stated in the error log. Does the header need anything else to be functional?
PS: Alternatively, if there's any easy way to turn these generic errors into more verbose ones, I'd also be very interested in that.
The answers from #eorochena and #dogacan are special cases. In general:
You get this error if an exception is raised in a Python CGI script.
A good way of figuring out what went wrong is to invoke Python's CGI module debug helper function at the beginning of your CGI script like this:
cgitb.enable(display=0, logdir=OUTDIR)
where OUTDIR is a directory name. If your CGI scripts raises some exception, then Apache puts an HTML file into that directory. The file has some garbage name such as tmpw4olz3xr.html, and at its end it contains the Python stack trace enclosed within HTML comments (<!-- ... -->). This is the information that will help you fix the problem.
Notes:
The display=0 parameter means that the error details are not shown
in the browser to your users.
You should probably comment out
cgitb.enable(...) when you are sure your script works OK.
Purpose
I think the purpose using cgitb is to get the whole information from web browser to help debugging.So we sholud correct the problem, not avoid the problem.
Do some research
Let us have a look at the information:
AH02429: Response header name '<!--' contains invalid characters, aborting request
It indicates the header name contains invalid characters, so i do some research on cgitb.py code as follow:
def reset():
"""Return a string that resets the CGI and browser to a known state."""
return '''<!--: spam
Content-Type: text/html
<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> -->
<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> -->
</font> </font> </font> </script> </object> </blockquote> </pre>
</table> </table> </table> </table> </table> </font> </font> </font>'''
This function returns the characters <!--. But apache httpd treat it as response header name which should not contain <!--.
There is also a open issue8704 in the Issue Tracker of python.
Maybe not a good solution
I do not know the should we delete the code in cgitb.py or adjust the configration of apache httpd. My solution is deleting some code as follows:
return '''
<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> -->
<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> -->
</font> </font> </font> </script> </object> </blockquote> </pre>
</table> </table> </table> </table> </table> </font> </font> </font>'''
Then it works very well, and it has good view.Anyone know what is the situation in ngix?
In my case the problem was the way the aligment of the output from the print statement
Before:
try:
if <some-condition>
message = "%s" % filename
else:
message = "file not found"
print """\n
Content-Type: text/html\n
<html><body>
<p>%s</p>
</body></html>
""" % (message,)
except Exception as e:
print e
After:
try:
if <some-condition>:
message = "%s" % filename
else:
message = "file not found"
print """\
Content-Type: text/html\n
<html><body>
<p>%s</p>
</body></html>
""" % (message,)
except Exception as e:
print e
For the same error, in a similar printing case, it was due to database collation; changing it to a UTF-8 helped me.

How can I run a Python script in HTML?

Currently I have some Python files which connect to an SQLite database for user inputs and then perform some calculations which set the output of the program. I'm new to Python web programming and I want to know: What is the best method to use Python on the web?
Example: I want to run my Python files when the user clicks a button on the web page. Is it possible?
I started with Django. But it needs some time for the learning. And I also saw something called CGI scripts. Which option should I use?
You are able to run a Python file using HTML using PHP.
Add a PHP file as index.php:
<html>
<head>
<title>Run my Python files</title>
<?PHP
echo shell_exec("python test.py 'parameter1'");
?>
</head>
Passing the parameter to Python
Create a Python file as test.py:
import sys
input=sys.argv[1]
print(input)
Print the parameter passed by PHP.
It probably would depend on what you want to do. I personally use CGI and it might be simpler if your inputs from the web page are simple, and it takes less time to learn. Here are some resources for it:
cgi — Common Gateway Interface support
Python - CGI Programming
However, you may still have to do some configuring to allow it to run the program instead of displaying it.
Here's a tutorial on that: Apache Tutorial: Dynamic Content with CGI
If your web server is Apache you can use the
mod_python module in order to run your Python CGI scripts.
For nginx, you can use mod_wsgi.
Thanks to WebAssembly and the Pyodide project, it is now possible to run Python in the browser. Check out my tutorial on it.
const output = document.getElementById("output")
const code = document.getElementById("code")
function addToOutput(s) {
output.value += `>>>${code.value}\n${s}\n`
output.scrollTop = output.scrollHeight
code.value = ''
}
output.value = 'Initializing...\n'
// Init pyodide
languagePluginLoader.then(() => { output.value += 'Ready!\n' })
function evaluatePython() {
pyodide.runPythonAsync(code.value)
.then(output => addToOutput(output))
.catch((err) => { addToOutput(err) })
}
<!DOCTYPE html>
<head>
<script type="text/javascript">
// Default Pyodide files URL ('packages.json', 'pyodide.asm.data', etc.)
window.languagePluginUrl = 'https://pyodide-cdn2.iodide.io/v0.15.0/full/';
</script>
<script src="https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js"></script>
</head>
<body>
Output:
</div>
<textarea id='output' style='width: 100%;' rows='10' disabled></textarea>
<textarea id='code' rows='3'>
import numpy as np
np.ones((10,))
</textarea>
<button id='run' onclick='evaluatePython()'>Run</button>
<p>You can execute any Python code. Just enter something
in the box above and click the button.
<strong>It can take some time</strong>.</p>
</body>
</html>
There's a new tool, PyScript, which might be helpful for that.
Official website
GitHub repository
You can't run Python code directly
You may use Python Inside HTML.
Or for inside PHP this:
http://www.skulpt.org/
You should try the Flask or Django frameworks. They are used to integrate Python and HTML.
There is a way to do it with Flask!
Installation
First you have to type pip install flask.
Setup
You said when a user clicks on a link you want it to execute a Python script
from flask import *
# Importing all the methods, classes, functions from Flask
app = Flask(__name__)
# This is the first page that comes when you
# type localhost:5000... it will have a tag
# that redirects to a page
#app.route("/")
def HomePage():
return "<a href='/runscript'>EXECUTE SCRIPT </a>"
# Once it redirects here (to localhost:5000/runscript),
# it will run the code before the return statement
#app.route("/runscript")
def ScriptPage():
# Type what you want to do when the user clicks on the link.
#
# Once it is done with doing that code... it will
# redirect back to the homepage
return redirect(url_for("HomePage"))
# Running it only if we are running it directly
# from the file... not by importing
if __name__ == "__main__":
app.run(debug=True)
You should use Py Code because it could run Any python script In html Like this:
<py-script>print("Python in Html!")<py-script>
Im not sure if it could run modules like Ursina engine ect But what i know is
That It allows you to type Python in Html. You can check out its offical Site for more info.
We can use Python code in HTML files. We have to use Python’s libraries within our browsers.
As we use Pyscript, we don’t need to worry about deployments. Everything happens in a web browser. We can share our HTML files with anyone containing fancy dashboards or any chars data. They can directly run it in a web browser without any complex setup.
Pyscript allows us to write python code with the help of 3 main components:
Py-env: It defines the python packages list which needs to run your
code.
Py-script: In this tag, the user will write their python code.
Py-repl: It will Create a REPL component. The REPL component
executes the code user enters and displays the result of the code in
the browser.
Let's start:
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
Our Hello world program will look something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<title>Python HTML app Hello World</title>
</head>
<body>
<py-script>
print("Hello World!")
</py-script>
</body>
</html>
This project is still in the alpha stage, so maybe we can see many more new things in the upcoming days. Let know more about how to use python in HTML file.

Django and AngularJS: how to display Angular $http errors that come from Django debug error messages

I have a Django view that is called from Angular with a $http.post
//LOADFILE ===================
this.loadfile = function (clickedItem) {
$http.post('/display/' , { "filename": clickedItem.fileName} )
.success(function(data) {
$scope.fileView.text = data;
$scope.fileView.title = clickedItem.title
}).error(function(data) {$scope.displayError=data});
};
If Django throws an error, data will be a full Django error page (full html page).
How do I display that error page (a complete html page) under Angular? (Some discussion of modals here : AngularJS, show popups - The most elegant way?, but nothing about a complete html page...)
I thought I could do this with a frame element and dom:
$window.frames['myErrorFrame'].document.innerHTML = $scope.displayError;
But that doesn't look very Angularish... And this almost does it, but I still have the problem of writing directly to the dom since the src is a string: insert an iframe into page dynamically in AngularJS
Is there a better way to display a full html page string in Angular?
Here is a possible solution. It works, but there are degrees of working, and this is a bit hacky -- the degree zero of working.
The error function (from Write elements into a child iframe using Javascript or jQuery):
update_error = function (message) {
var ifrm = document.getElementById('errorIFrame');
ifrm = (ifrm.contentWindow) ? ifrm.contentWindow : (ifrm.contentDocument.document) ? ifrm.contentDocument.document : ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write(message);
ifrm.document.close();
};
And the html:
<div ng-show="errorMessage != ''">
<button class="btn btn-info btn-xs" ng-click="errorMessage=''">Close</button><br />
<iframe width="100%" id="errorIFrame"> </iframe>
</div>
The error callback:
.error(function(data) {
update_error(data);
$scope.errorMessage="error"}
Note the switching of the errorMessage flag, which I seem to have to do because update_error is outside the controller (there must be a simple fix for that, but I have other fish to fry). This works, but I imagine it isn't orthodox. There is probably a better way with $sce (will fry that one later).

how do i print outputs to html page using python?

I want user to enter a sentence then I break up that sentence into a list. I got the html page down but i have trouble passing that sentence to python.
How do I properly send the user input to be processed by python and output it to a new page?
There are many Python web frameworks. For example, to break up a sentence using bottle:
break-sentence.py:
#!/usr/bin/env python
from bottle import request, route, run, view
#route('/', method=['GET', 'POST'])
#view('form_template')
def index():
return dict(parts=request.forms.sentence.split(), # split on whitespace
show_form=request.method=='GET') # show form for get requests
run(host='localhost', port=8080)
And the template file form_template.tpl that is used both to show the form and the sentence parts after processing in Python (see index() function above):
<!DOCTYPE html>
<title>Break up sentence</title>
%if show_form:
<form action="/" method="post">
<label for="sentence">Input a sentence to break up</label>
<input type="text" name="sentence" />
</form>
%else:
Sentence parts:<ol>
%for part in parts:
<li> {{ part }}
%end
</ol>
%end
request.forms.sentence is used in Python to access user input from <input name="sentence"/> field.
To try it you could just download bottle.py and run:
$ python break-sentence.py
Bottle server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.
Now you can visit http://localhost:8080/.
Have you tried Google? This page sums up the possibilities, and is one of the first results when googling 'python html'.
As far as I know, the two easiest options for your problem are the following.
1) CGI scripting. You write a python script and configure it as a CGI-script (in case of most HTTP-servers by putting it in the cgi-bin/ folder). Next, you point to this file as the action-attribute of the form-tag in your HTML-file. The python-script will have access to all post-variables (and more), thus being able to process the input and write it as a HTML-file. Have a look at this page for a more extensive description. Googling for tutorials will give you easier step-by-step guides, such as this one.
2) Use Django. This is rather suited for larger projects, but giving it a try on this level may provide you certain insights, and wetting your appetite for future work ;)

Categories

Resources