google app engine redirection pages in website - python

i want to go from one page to another in my website using a button.
my code for this is like the following:
self.response.out.write('''<form
action="/sign" method=post> <br><input type=submit value="go to lesson 2 ">
</form>
''') % self.redirect("/lesson1")
now i am in lesson one page and i want using this button to go to lesson1 page but i keep getting this error:
PyDev breakpoint
inconsistent dedent at line 53, column 2
Bad Indentation (7 spaces)
does any one know how to fix this?
thanks
Amal

Aside from bad indentation and an errant attempt at using %, self.redirect(...) is done for effect, not to get a string you can use to embed elsewhere. What you've got it more properly divided into a get handler (to emit the form) and a post handler to do the redirect.
An alternative is to do the redirect in the browser, using JavaScript.

I got the correct answer using html.
I have two pages inside my website in google app engine and they are:
lesson1.py
lesson2.py
to go from lesson one to lesson using a button i put this code inside lesson1.py:
self.response.out.write('''<form action="/lesson2" method="get">
<input type="submit" value="go to lesson2" />
</form> ''')
application = webapp.WSGIApplication([('/', MainHandler)], debug=True)
application = webapp.WSGIApplication([('/lesson1', MainHandler)],debug = True)
then in lesson2.py where i want to go i put this code:
application = webapp.WSGIApplication([('/', MainHandler)], debug=True)
application = webapp.WSGIApplication([('/lesson2', MainHandler)],debug = True)
an important issue is the app.yaml file mine looks like this:
application: Sign-language version: 1
runtime: python
api_version: 1
handlers:
- url: /lesson2
script: lesson2.py
- url: /.*
script: lesson1.py

Use Preferences->Pydev->Editor and uncheck replace tabs with spaces. Tabs can be 4 spaces despite popular opinion that it should be changed to 8 spaces.

Related

Connecting python script with html button and flask

I am trying to create a webapp and am fairly new to it. I have a python script(file.py) that transforms data selected by a user. It handles all the inputs and outputs.
I am using flask(main.py) for the server part of it and html. I want to place a button in my html code so it will start the execution of the file.py. Can anyone assist me with an example setup for the connections between the 3?
I've looked at other examples but I'm unable to recreate it as they're doing different things. Also, file.py is fairly large so I want to avoid putting it into a function.
Edit: not looking for a flask tutorial. I've tried 3things:
A shell pops up for half a second but the disappears. Then I'm redirected to a page which just has the text in my return statement
in my html file
<form action="/pic" method="POST">
<input type="submit" value="GET THE SCRIPT">
</form>
in my main.py flask file
#app.route('/pic', methods=['GET', 'POST'])
def pic():
os.system("python file.py") #file.py is the script I'm trying to start
return "done"
Doesn't do anything at all.
in html file:
<input type="button" id='script' name="scriptbutton" value=" Run Script " onclick="goPython()">
<script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script>
function goPython(){
$.ajax({
url: "/scripts/file.py",
context: document.body
}).done(function() {
alert('finished python script');;
});
}
</script>
I get a GET "/scripts/file.py HTTP/1.1" 404 message. I have my scripts folder in the same directory as my templates folder. Also tried placing the scripts folder inside the templates folder.
in html
<form action="/run" method = "POST">
<input type="button" id='script' name="submit" value="Run Scripttttttt">
</form>
in flask main.py
#app.route('/run',methods=['GET', 'POST'])
def index():
def inner():
proc = subprocess.Popen(
['python file.py'],
shell=True,
stdout=subprocess.PIPE
)
for line in iter(proc.stdout.readline,''):
time.sleep(1)
yield line.rstrip() + '<br/>\n'
return Flask.Response(inner(), mimetype='text/html')
Using an HTML Anchor tag (i.e ) is the easiest way. Here is an example:
This is a link
But since you've chosen button, JavaScript will come in handy. Here's an example(inline):
<button onclick="window.location.href='your_flask_route';">
This is a link
</button>
and then in your flask main.py file you should have this:
#app.route('/your_flask_route')
def your_flask_route():
'''some lines of code'''
You can set up a Flask endpoint that your button can send a request to. Then let the endpoint's function call your python script.
Have a look at this discussion about Flask - Calling python function on button OnClick event and this discussion about How can I make one python file run another? to get you started.

Hide Python Verbose

I am new to Python development.
I am trying to integrate ChatterBot in a webpage on my local host.
So to do this my first challenge is to establish a talk between a web page and Python script and I have achieved this.
The issue I am facing is - when I train ChatterBot using a list it shows verbose but I don't want those verbose on the webpage since they are of no use for the end user, so for this I tried logging.basicConfig with diifferent-2 logging levels but I am not able to hide logs.
Here is my webpage (index.html) :
<!DOCTYPE html>
<html>
<body>
<h2>Text Input</h2>
<form action = "chatbot.py" method = "POST" >
First name:<br>
<input type="text" name="firstname">
<br>
Last name:<br>
<input type="text" name="lastname">
<button type = "submit" >Submit</button>
</form>
<p>Note that the form itself is not visible.</p>
<p>Also note that the default width of a text input field is 20 characters.</p>
</body>
</html>
Here is chatbot.py
#!C:\Users\Shishupal\AppData\Local\Programs\Python\Python36-32\python.exe
# This program prints Hello, world!
from chatterbot import ChatBot
import logging
print("Content-Type: text/html")
print()
import cgi
print('Hello, world!')
logging.basicConfig(logging.INFO)
# Create a new chat bot named Charlie
chatbot = ChatBot(
'Charlie',
trainer='chatterbot.trainers.ListTrainer'
)
chatbot.train([
"Hi, can I help you?",
"Sure, I'd like to book a flight to Iceland.",
"Your flight has been booked."
])
# Get a response to the input text 'How are you?'
response = chatbot.get_response('I would like to book a flight.')
print(response)
Verbose that comes when I don't put or when I put logging.basicConfig(logging.INFO) in chatbot.py, so I want to hide these logs since they are of no use for end user.
Is there any Python expert over the Globe who can help me in sorting this out :)
You can hide the verbose output by changing the logging level.
Take a look at this line in your code:
logging.basicConfig(logging.INFO)
Right now, the logging level is INFO which prints everything.
You can choose a less verbose logging level such as WARNING, ERROR, or CRITICAL.
You can also remove the logging configuration line entirely to disable the verbose logging.

how to send response to html using cgi python script

I am trying to design and implement a basic calculator in HTML and Python(using CGI). Below given is a static HTML web page and it is being redirected to a python script (calci.py) where, I am able to calculate the sum but unable to append the resultant to the 'output' textbox.
calculator.html
<html>
<head>
<title>Calculator</title>
</head>
<body>
<form action="python_scripts/calci.py" method="post">
Input 1 : <input type="text" name="input1"/><br>
Input 2 : <input type="text" name="input2"/><br>
<input type="submit" value="+" title="add" /><br>
output : <input type="text" name="output"/><br>
</form>
</body>
</html>
calci.py
import cgi
form = cgi.FieldStorage()
input1 = form.getvalue('input1')
input2 = form.getvalue('input2')
output = str(int(input1)+int(input2))
#how to return the response to the html
#and append it to the textbox
Thanks
This is not the way Web applications work - not hat simply, at least.
If you want to rely only on the browser, and plain HTML for your application, each request has to send the whole html page as a string. You have to use Python's string formatting capabilities to put the resulting number in the correct place in the HTML form.
This way of working is typical of "Web 1.0" applications (as opposed to the "Web 2.0" term used about ten years ago).
Modern web applications use logic that runs on the client side, in Javascript code, to make an HTTP request to retrieve only the needed data - and them, this client-side logic would place your result in the proper place in the page, without reloading the page. This is what isgenerally known as "ajax". It is not that complex, but the html + javascript side of the application become much more complex.
I think one should really understand the "Web 1.0" way before doing it the "Ajax way". in your case, let's suppose your HTML containing the calculator form is in a file called "calc.html". Inside it, where the result should lie, put a markup that can be understood by Python's built-in native string formatting methods, like {result} -
<html>
<body>
...
calculator body
...
Answer: <input type="text" readonly="true" value={result} />
</body>
</html>
And rewrite your code like:
import cgi
form = cgi.FieldStorage()
input1 = form.getvalue('input1')
input2 = form.getvalue('input2')
result = int(input1)+int(input2)
html = open("calc.html".read())
header = "Content-Type: text/html; charset=UTF-8\n\n"
output = header + html.format(result=result)
print (output)
The CGI way is outdated, but is nice for learning: it relies on your whole program being run, and whatever it prints to the standard output to be redirected to the HTTP request as a response. That includes the HTTP Headers, which are included, in a minimal form, above.
(I will leave the complete implementation of a way for the raw '{result}' string not to show up in the inital calculator form as an exercise from where you are 0- the path is to get the initial calculator html template through a CGI script as well, instead of statically, (maybe the same) as well - and just populate "result" with "0" or an empty string)
you can transfer response with the help of java script.
use under print("window.location=url")

How do I display a website with html-forms locally using python and collect the user input?

I am a behavorial scientist and usually collect data by letting participants do some tasks on a computer and record their responses (I write the programs using the pyglet wrapper PsychoPy). That is, the program runs locally and the data is stored locally.
Now I would like to know if there is a way to use Python to display a (local) website with html-forms to the user and collect the input (locally). The reason for this idea is that currently whenever I want to display checkboxes, radiobuttons, or input fields I use wxPython. This works quite well, but programming and layouting in wxPython is kind of cumbersome and I would prefer html with forms.
A requirement would be that it would need to rum without any borders, adress field, menu bar, ... The reason is that I need it in kind of fullscreen mode (I currently open a non-fullscreen pygflet window in the size of the screen to hide the desktop) so that participants can do nothing but work on the forms.
So I am looking for a way to (a) display html websites including html form above a pyglet window with no menu bar or whatsoever, (b) collect the input when clicking on the Ok button (i.e., the form is send), (c) control what is presented prior and after viewing this website, and (d) everything of this should happen locally!
My idea would be that the data is collected when participants hit the "Send away" button in the following example pic and the next page is displayed.
Update: I use windows (XP or 7).
This is a solution using Qt Webkit for rendering HTML. The default navigation request handler is wrapped by a function that checks for submitted form requests. The form uses the "get" method, so the data is included in the url of the request and can be retrieved that way. The original request is declined and you can change the content of the displayed web page as you wish.
from PyQt4 import QtGui, QtWebKit
app = QtGui.QApplication([])
view = QtWebKit.QWebView()
# intercept form submits
class MyWebPage(QtWebKit.QWebPage):
def acceptNavigationRequest(self, frame, req, nav_type):
if nav_type == QtWebKit.QWebPage.NavigationTypeFormSubmitted:
text = "<br/>\n".join(["%s: %s" % pair for pair in req.url().queryItems()])
view.setHtml(text)
return False
else:
return super(MyWebPage, self).acceptNavigationRequest(frame, req, nav_type)
view.setPage(MyWebPage())
# setup the html form
html = """
<form action="" method="get">
Like it?
<input type="radio" name="like" value="yes"/> Yes
<input type="radio" name="like" value="no" /> No
<br/><input type="text" name="text" value="Hello" />
<input type="submit" name="submit" value="Send"/>
</form>
"""
view.setHtml(html)
# run the application
view.show()
app.exec_()
As AdamKG mentioned, using a webframework would be a good choice. Since Django and similar might be an overkill here, using a micro webframework like 'flask' or 'bottle' would be a great choice.
This link demonstrates via step by step instruction how to make a simple form via a To-DO application. It assumes zero previous knowledge.
You can run it only locally also.
your want a simple solution, so just write a http server and run your simple page.
using python.BaseHTTPServer, coding a 15 line web server:
import BaseHTTPServer
class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/foo':
self.send_response(200)
self.do_something()
else:
self.send_error(404)
def do_something(self):
print 'hello world'
server = BaseHTTPServer.HTTPServer(('',80), WebRequestHandler)
server.serve_forever()
easy enough,but i suggest using some web frameworks. They are easy too.
for example, web.py. here is what u want in 50 line codes:
install web.py
make a dir with 2 files:
./
|-- app.py
`-- templates
`-- index.html
index.html
$def with (form, ret)
<html>
<head>
<title> another site </title>
</head>
<body>
<h1> hello, this is a web.py page </h1>
<form action="" method="post">
$:form.render()
</form>
<h2>$:ret</h2>
</body>
</html>
app.py logic file:
import web
### Url mappings
urls = (
'/', 'Index', )
### Templates
render = web.template.render('templates')
class Index:
form = web.form.Form(
web.form.Textbox('fav_name', web.form.notnull, description="Favorite Name:"),
web.form.Textbox('cur_name', web.form.notnull, description="Current Name:"),
web.form.Button('Send Away'),
)
def GET(self):
""" Show page """
form = self.form()
return render.index(form, "")
def POST(self):
""" handle button clicked """
form = self.form()
if not form.validates():
return render.index(form, "INPUT ERROR")
# save data by ur method, or do some task
#pyglet.save_data(form.d.fav_name, form.d.cur_name)
#pyglet.draw(some_pic)
#os.system(some_cmd)
form = self.form()
return render.index(form, "YOUR DATA SAVED")
app = web.application(urls, globals())
if __name__ == '__main__':
app.run()
run this server in your windows:
python app.py 9999
open browser: http://127.0.0.1:9999/
by the way, if ur data is only strings, u can save them in web.by by sqlite.
My suggestion would be:
Use some python server as, for example SimpleHTTPServer. It is needed because the submit button on forms sends the information to a server. There you should manage the received info some way;
Have your browser configured with one of those Kiosk extensions, which disallow even the use of Alt+F4. An example would be Open Kiosk extension for Firefox
Optionally, if you have affinity with scripts in general, you could create a script which, when executed, would at the same time run the python server AND open your html file in the browser. That would ease a lot your setup work for every subject in your group.
EDIT: I've read you need the pyglet over the browser window. That could be included in the script of step 3, using "always on top" option and absolute positioning of the pyglet (I can tell this would probably be simpler on Linux, which could be run from persistent LiveUSB - just a thought!)
EDIT (regarding the posted comment):
I think the most reliable option for output would be to disk (file or database) instead or RAM (running python object), then you read the info from file afterwards. Then, in case of a surprise (system hang, power failure), the already-entered data would be there.
The only (and most important) part I don't know HOW to do is to handle the content of the form's "submit" on the server-side. Probably some server-side script file (php, python) shoud be created and left on the server root, so the server would receive an http request containing the info, and send the info to the script, which then handles the processing and file/database storage activities.
This might be of your interest:
"The POST request method is used when the client needs to send data to the server as part of the request, such as when uploading a file or submitting a completed form." (from wikipedia on "POST(HTTP)" ENTRY)
In another link, some thoughts on using SimpleHTTPServer itself for handling POST requests:
http://islascruz.org/html/index.php/blog/show/Python%3A-Simple-HTTP-Server-on-python..html
Hope this helps.
The reason for this idea is that currently whenever I want to display
checkboxes, radiobuttons, or input fields I use wxPython. This works
quite well, but programming and layouting in wxPython is kind of
cumbersome and I would prefer html with forms.
You can combine the ease of HTML and still create native Windows applications using Flex with a Python backend.
If you are averse to Flex, a bit more - involved - but still native windows application generator is Camelot
Edit
Instead of typing it out again - I would suggest the django + flex + pyamf article on Adobe that explains it all with screenshots as well. You can replace django with flask or bottle as they are more lightweight, however the PyAMF library provides native support for django which is why it was used in the example.
PyAMF provides Action Message Format (a binary protocol to exchange object with the flash runtime) support for Python.

Issue with links Embedding the app engine's shell app within my own app, for help coding

In my own App Engine App, at the browser, I wanted to mess around with new code by simulating having access to the python interpretor's >> within a browser window by embedding this app --> http://shell.appspot.com/ .
One can get shell_20091112.tar.gz at http://code.google.com/p/google-app-engine-samples/downloads/detail?name=shell_20091112.tar.gz&can=2&q=
So I moved the key files and folder from the shell app into my own app directory.
When I launch my app from the SDK I can see in the browser the shell app at
http://dwms.appspot.com/shell
in my app but after I hit 'enter' after writing something say >>a=1...
then nothing happens , so assume my handler link from the form to my app is wrong? (sorry if I am getting the jargon incorrect).
The form I am supposed to be receiving information from is within shell.html as looks like below:
<form id="form" action="shell.do" method="get">
<nobr>
<textarea class="prompt" id="caret" readonly="readonly" rows="4"
onfocus="document.getElementById('statement').focus()"
>>>></textarea>
<textarea class="prompt" name="statement" id="statement" rows="4"
onkeypress="return shell.onPromptKeyPress(event);"></textarea>
</nobr>
<input type="hidden" name="session" value="{{ session }}" />
<input type="submit" style="display: none" />
</form>
so I am thinking the problem is that my app is no responding when the server gets 'shell.do' from the client because of changes I made or didnt make or made incorrectly....
on the old shell.py that I copied off the web into my app's directory I commented out all the lines from the main() function:
#def main():
#application = webapp.WSGIApplication(
#[('/shell', FrontPageHandler),
#('/shell/shell.do', StatementHandler)], debug=_DEBUG)
#wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
#main()
and replaced the linking or plumbing information by adding those similar links to my own main.py as follows:
application = webapp.WSGIApplication(
[('/', MainPage),
('/shell',shell.FrontPageHandler),
('shell.do', shell.StatementHandler),
('/sign', Guestbook),
('/zxy/.*', PNGserver) ],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
again -- so right now the issue is that I see a shell app when I go to
http://dwms.appspot.com/shell
and type
>> a=10
but nothing happens after I enter statements into the form after >>a=10
In case it is relevant...Below you will notice that I also commented out some lines I copied from the the old shell's app handlers app.yaml into the app.yaml of my app..NOTE: After experimenting by uncommenting the below lines it made no difference in how the shell doesn't work in my app...The reason for the comments below is that I thought this might be needed for the shell to know what's is going on with all global variables in the entire app not just where the shell is running? (I might be confused about this?)
My app.yaml is below:
application: dwms
version: 1
runtime: python
api_version: 1
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /.*
script: main.py
- url: /static
static_dir: static
expiration: 1d
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
# if you're adding the shell to your own app, change this regex url to the URL
# endpoint where you want the shell to run, e.g. /shell . You'll also probably
# want to add login: admin to restrict to admins only.
#
#- url: /shell
# script: shell.py
The answer to my own question is to install the following shell console, very easy, and looks very helpful:
http://con.appspot.com/console/help/about

Categories