How to control my webapp with Alexa - python

I built an alexa skill using Python with Flask_ask, which goes to my DB and retrieves information that I need and spells it out.
I am now trying to create a web UI which would have an option of asking the required question by typing it in or speaking directly to alexa. The web UI works easily as it redirects to the page I want as below :
#app.route('/getdog')
def getdog():
return render_template('mypage.html')
Ideally I would configure an intent which would trigger the change in webpage e.g.
#ask.intent('myintent')
def changepage():
getdog()
Any ideas how to handle this?

You can use use a simple HTML form with a text input box:<form method="POST" action="/changepage/">
Enter Your Query: <input type="text" name="intent_string" />
<input type="submit" value="Ask Alexa"/>
</form>
Your changepage url should call a method which handles calling other intents based on whatever string has been passes in the POST request.
If you not able to exactly match the required intent to call you can add a full text search and match with that

Related

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.

Obtain 'post' form URL using .cgi file

File name: http://localhost/PostForm.html
<form method ="post" action="Information.cgi">
<table>
<tr><td>New date: </td><td> <input type ="date" name="DateNew" /></td></tr><br>
<tr><td>Old date: </td><td> <input type ="date" name="OldDate" /></td></tr><br>
</table>
<input type="submit" name = "submitname" value="Add Entry" />
</form>
Is there any way in which I can obtain the file name, which the post form is located on, from the .cgi python file?
I want to obtain the file name http://localhost/PostForm.html in the Information.cgi Python file.
Any help is greatly appreciated.
Yes, you can get that information, but not in a completely secure way. Browsers insert a header, Referer: which names the previous page.
Reference:
http://en.wikipedia.org/wiki/HTTP_referer
One way would be to grab the referrer info within Information.cgi using an Environmental Variable:
$ReferringPage = $ENV{HTTP_REFERER};
However, that's unreliable. Some users change browser settings to prevent sending referrer info amongst other possible situations where it might not pass.
You could also hard-code something in the referring page's form HTML that lets you know which page sent the referral:
<input type="hidden" name="wherefrom" value="Somepage.html">
Then, in your Information.cgi script, just grab that value and do whatever with it:
use CGI;
$in = new CGI;
$WhichPage = $in->{'wherefrom'};
This could be bypassed by the user or it might not work depending on your setup, but could work in some situations.

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

Uploading file to Google App Engine using new dev_appserver

Google App Engine documentation makes it appear very simple to get the contents of an uploaded file (self.request.get('user_file')), but while I can do this with old_dev_appserver.py, I cannot get it with the current dev_appserver.py (v1.9.2).
Here's a simple example that generates the incoming data:
<form name="myform" action="http://localhost:8080/sync?cmd=tester" enctype="multipart/form-data" method="post">
Username: <input type="file" name="user_file" />
<input type="submit" value="Submit" />
</form>
In old_dev_appserver.py, one could get the file in GAE via self.request.get('user_file'), but not with the latest (1.9.2) dev_appserver.py
WebApp2 says "Uploaded files are available as cgi.FieldStorage (see the cgi module) instances directly in request.POST." But, request.POST is empty, and cgi.FieldStorage() does not contain 'user_file' either.
Strangely, if I print out self.request.params, I do see an element in the UnicodeMultiDict that is (u'user_file', FieldStorage(u'user_file', u'myfile.ico')). But when I try to get that element, either via named access or just iterating over params, I cannot get it. Even if I do a Len(self.request.params) I get one less than what I see, and the 'user_file' element is missing. If I do this with old_dev_appserver, the Len(self.request.params) is correct.
How do I get user_file?
Figured it out (finally!). I had been logging elements of the request (params, body, etc.) as I sorted through other issues. But you can only instantiate a cgi.FieldStorage element once, so by the time I got to the actual self.request.get('user_file'), it was already gone.
Classic case in which removing the debugging actually makes it work.

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.

Categories