web application using Python web.py - python

I have built a audio recorder and used Google Now services to do vocal recognition. They worked fine on my PC.
Now I am thinking about taking a step further and put it on web to allow user give vocal orders remotely.
I used Python's web library and saw hello world demo work on both my PC and android phone browser. I then tried to replace the GET method of the hello world with the previous codes that does the recognition. When the codes ran, my computer could still do the vocal recognition but my phone could not display the contents.
I wonder what I am missing here?(Maybe I am just being naive here..) Is it because I used too many libraries on my PC and phone is simply not compatible with them? Thanks.
Here's the codes.
import voice_recognition
import web
class SpeechRecognition(object):
def GET(self):
return voice_recognition.main_recognition()
#return "are you serious?"
app=web.application(('/','SpeechRecognition'),globals())
app.run()

I think you're correct in running your app as part of the GET method in class SpeechRecognition().
The next step is to run your application as CGI or WSGI. See the API web.application() on http://webpy.org/docs/0.3/api.
So update the class to something along the lines of:
class SpeechRecognition(object):
def GET(self):
wsgifunc(return voice_recognition.main_recognition())
Note: I'm trying to do a similar thing to you, but haven't cracked it just yet, but I know I'll need to run my app on www.mysite/myapp with WSGI to run the app.

Related

Why does my Flask App not work correctly on Google App Engine?

My portfolio site has been deployed using Google App Engine, and it mostly works correctly, but one of my pages on the website doesn't work like it works when I just type python main.py on my machine. The page features one of my projects that takes as input an Excel file and does some processing using Openpyxl in Python, and gives the file back to download in the new layout. The problem is when I deployed the app I cannot seem to upload the Excel file, because I get an error "Error 3: Please choose a file to process" which is an error I just made in HTML when someone didn't choose an Excel file, but this error happens even if I chose an Excel File. I made like a "Download Sample Input" which is a typical file you can use in the program, then you choose a method and in this case "Rentmeester" and then click process. Then it takes like a second then it is finished processing and then you can download the new file. The problem is none of the processing works and the project basically is broken when I deployed it on App Engine and I don't know why or how to fix it. I struggle to get appropriate error logs in App Engine as I'm new to it. Here is the link of the broken project: https://christo.appspot.com/automate.html and here is a video of how it is supposed to work: https://youtu.be/nmDz4SmaKXY also here is all the source code for my entire Portfolio site on Github: https://github.com/CGVanWyk/Portfolio-Website I would really appreciate any light into this problem I am experiencing.
I think it may be because not all of my libraries are working or isn't imported correctly, but I'm not certain where to see if all the libraries is imported right or pip install'd. I tried this tutorial online with no success: https://cloud.google.com/appengine/docs/standard/python/tools/using-libraries-python-27
https://github.com/CGVanWyk/Portfolio-Website
The code in question that isn't working is under /Templates/automate.html + failure.html + successful.html + inputFile.html + inputMethod.html for the HTML, /static/css/automate.css for the CSS, and most importantly main.py and helpers.py for the Python and Flask code and app.yaml just specifies the Python version. I don't know if I needed to include anything else there. I just followed this tutorial to deploy to Google App Engine https://cloud.google.com/appengine/docs/standard/python3/quickstart
Expected: successful.html when a file is inputted and the method was "Rentmeester" and the process button was clicked. Also there must be a new Excel file a user can download named "BEWERKTEFILE_RENT_SEPTEMBER2018.xlsx"
Actual: inputFile.html
I think that, maybe the problem could be that you're using App Engine Standard, and this way you can't write to disk as explained in this documentation[1], also I think the best practice is to use Cloud Storage to manage your App Engine files.
if this answer is helpful let me know.
[ 1 ] https://cloud.google.com/appengine/docs/the-appengine-environments

How to directly call python function from web through Apache

I'm from the PHP universe and completely new to Python. Python really is easy but trouble starts when trying to create some simple web pages. I read something about calling Python functions through the web browser should be possible. This is what I am talking about:
#!/usr/bin/python3
import cgi;
import cgitb;cgitb.enable()
import requests
print ("Content-Type: text/html\r\n")
print("<html><body>Test</body></html>")
def home():
print("<html><body>Another Test</body></html>")
Opening http://localhost/index.py returns "Test". Calling http://localhost/index.py/home returns the same, however, I want it to return "Another Test".
Any ideas how this could be accomplished? Running apache2 and mod_python. Do I need mod_rewrite for this?
PS.: I don't want to use any frameworks like Django, all I need is a simple web form to provide input for my scripts.

how can I make an outbound SIP call using Twilio?

I am using a Galaxy 8S android phone with the Samsung SIP settings. I have successfully registered a (Twilio) SIP account on the phone. I want to make an outbound call to an international PSTN Number NOT to another sip address.
My SIP doman, on Twilio, points to my heroku app.
The code is:
#application.route("/makesip", methods=['GET', 'POST'])
def makesip():
to_number=request.values.get('To', None),
client = Client(ACCOUNT_SID, AUTH_TOKEN)
call = client.calls.create(to=to_number, from_="+1415792xxxx", url="https://myapp.herokuapp.com/sipout", method="POST")
return call.sid
#return "OK"
#application.route("/sipout", methods=['GET', 'POST'])
def sipout():
response = VoiceResponse()
to_number = request.values.get('To', None)
dial = Dial(caller_id='+1415792xxxx')
dial.number(to_number)
response.append(dial)
return str(response)
When I make the call from my cell phone it hangs up almost immediately and says "Server Error try again later". The Twilio error log says:
We don't support dialing out to global twilio domains (domainname.sip.twilio.com). Only regional (domainname.sip.us1.twilio.com) ones are supported.
I think that I am making a very fundamental error here but I simply cannot identify it. Can anybody help please? Should I, for example, set the "from_" parameter as "sip:my_sip_address.domainname.sip.us1.twilio.com"?
I'm not a heroku expert, but your code looks similar enough to the php I have running which works fine for this.
In your phone settings is your SIP server set as user#domainname.sip.twilio.com or as user#domainname.sip.us1.twilio.com? It should be the latter. I seem to remember getting caught out by something like this when I was trying to get things working
EDIT
Just had another play with mine and I figured it out. You have to dial the number from your phone as phonenumber#yourdomain.sip.twilio.com, then twilio will return to as sip:phonenumber#yourdomain.sip.twilio.com
You need to change this line of your code to strip out just the number
to_number=request.values.get('To', None),
My php line is substr(strtok($to, '#'), 4); so whatever your equivalent of that is.
What I think is probably happening is that the "To" that is hitting your Heroku app is in the format "sip:+12312123123#yoursipdomain.sip.twilio.com;user=phone" and you're trying to inject that directly into the "dial" verb.
What you actually want is to strip it down to the bare number in E.194 format (with the leading +).
I'd suggest starting by testing using a quick TwiML Bin as per the Twilio SIP Registration docs, rather than your Heroku app.
TwiML Bins are basically static TwiML but with a tiny bit of intelligence in special tags. It's like the Twilio equivalent of Mail Merge, if you've ever used that in Microsoft Word.
(Twilio recently updated the SIP Registration docs. They're much better now.)
Use a TwiML Bin for initial testing otherwise you risk spending time fixing an otherwise working Heroku app because the problem is your phone/account.
Go to "Twilio Docs > API Reference > Twilio Voice API > SIP Registration".
Scroll down to "Using Enhanced TwiML Bin Templates to Call a mobile/landline on the Public Telephone Network" and follow that.
See if that works.
If it doesn't, my suspicion is your Samsung is actually spitting out something daft due to something dial plan related. (Dial plan is the conversion of +12345645642 into a SIP URI. You might find it's doing something like +012345645642 instead.)
If it does work, great. If you want to get your Heroku app working, compare the working response body to the one your Heroku app is spitting out. Post both, and we'll figure out what's going wrong.
Just to check, you are specifying a region in your Domain and Registration Server settings on the Samsung, yeah? The "yoursipdomain.sip.us1.twilio.com" that miknik talked about?

Recursive static content display with Flask

G'day,
I've written a piece of software in Python 3.x with PySide which dynamically displays images (as a slideshow) from a network directory. The software works as intended for local machines (i.e. the slideshow is displayed on the machine which is running the software).
I would like to run the software on a centralised server, which then serves each image of the slideshow temporarily on a local network web page. I've managed to serve static content in my code using the Flask library. Below is a snippet of my code:
def ServeImage(self, DisplayImage):
app = Flask(__name__)
#app.route("/")
def main():
return '''<img src='{}' />'''.format(url_for('static', filename=DisplayImage))
app.run(host='10.2.x.x', port=5000)
'DisplayImage' is the output image path from my current code. At present, the above will correctly display the image in the browser at the designated local address. However, I'm unsure how to return to the slideshow component of the software (where the DisplayImage is generated). It appears that once ServeImage() has been called, the code terminates. I believe it's due to the way this example Flask function was put together. What I'm hoping for is detailed in the pseudo-code below:
def ServeImage(self, DisplayImage):
app = Flask(__name__)
'''<img src='{}' />'''.format(url_for('static', filename=DisplayImage))
app.run(host='10.2.x.x', port=5000)
#Timer
self.ImageNumber += 1
self.SlideShow()
I don't know whether this is possible. As mentioned above, it appears that when app.run() is called, that particular address is served forever, so any code coming after app.run() will never be run. What I'd like is: once the image has been served (i.e. once app.run() has been called), the ImageNumber() variable is changed, and the main SlideShow() function is called, which in turn generates the next DisplayImage to be served on the web page.
Any clarification/suggestions here would be great!
Thanks!

How to accept a JSON POST?

First time here, it says to be specific... So here goes.
I'm doing a small project to connect Salesforce to my Raspberry Pi. The goal is to make a light (Think a beacon, siren-like light) flash when a high priority case comes in from a client in Salesforce. At the moment, clients usually send an email to a certain address, and this creates a case. It goes to the 'Unassigned Queue' and emails the team that this case is there waiting to be assigned.
Salesforce uses REST, so I need to be able to get the Pi to accept JSON so it can easily understand what Salesforce wants it to do.
Currently, I guess I have won half of the battle. I have a web server (Lighttpd) running on the Pi, which hosts an index page and a Python script. I am also using a Python wrapper, which allows me to easily run a command from a Telldus program I have installed. This program controls a USB RF Transmitter that I have connected, it is paired to a RF Socket, which is connected to the mains power supply with a light connected to it.
So the Python script is called power.py, and can be controlled with URL variables, so if I go to power.py?device=1&power=on&time=10&password=hunter2 that turns on device 1 for 10 seconds. I also created a POST form on the index page, which just POSTS to the python script, and runs it in the same way as using the URL variables. That all works great.
So all I need to do, is connect it to Salesforce. I would like to use REST and JSON, so that if I ever move away from Salesforce to another CRM program, it will easily be able to adapt and receive instructions from new places.
I have posted the Python script I am using here:
https://github.com/7ewis/RemotePiControl/blob/master/power.py
The Pi isn't currently allowed out of the local network, so I will need to somehow develop a way to send JSON commands, and the recieve and convert them to work using the correct variables etc. I'm not a programmer, I've just exposure to languages from hacking things and exploring. Hence why I need some guidance with this.
I have never used REST or JSON before, so what would I need to do to achieve this?
Seems like adding Flask http://flask.pocoo.org to your Raspberry Pi Webserver would be a good move. It allows server-side python to be run in response to JQuery ajax (and regular) requests. Check out a couple of examples here:
http://flask.pocoo.org/docs/patterns/jquery/
and this stack overflow question: how can I use data posted from ajax in flask?
Flask is pretty straightforward to get up and running, and is happy working with a number of servers, including Lighttpd. Writing RESTful flask is also a perfectly reasonable proposition, see: http://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask
Additionally, lots of people have used flask on the raspberry pi already-- so that could help get you up and running smoothly: http://mattrichardson.com/Raspberry-Pi-Flask/
Good luck!
Firstly don't use a Python script that prints out result directly to CGI. You will be forever debugging it.
Use a light weight framework like Flask. You can do something as simple as
from flask import Flask
application = Flask(__name__)
#application.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# use Flask's build in json decoder
the_data = request.get_json()
# then do something with the data
return "This was a POST request, how interesting..."
else:
# request was GET rather than POST, so do something with else
return "Hello World!"
See how to configure Flask to run with Lighttpd here http://flask.pocoo.org/docs/deploying/fastcgi/
If you want to test this you can either write another Python script to send JSON data to your server (I recommend looking at the Python Requests library for this http://www.python-requests.org/en/latest/), or you can do this manually using a HTTP request builder, such as HTTPRequester for Firefox (https://addons.mozilla.org/en-US/firefox/addon/httprequester/)

Categories

Resources