Trouble Sending iOS push notifications from Google App Engine - python

I'm working on my first iOS app that uses push notifications. I have a python script that lets me to send push notifications from my machine but I'm unable to get this working with the Google App Engine Launcher.
When I run this on GAE I get nothing - no errors and no push notifications. What am I doing wrong? I know the code for sending the actual notification is working properly but I'm not able to duplicate this on Google's servers.
Here is the script I'm trying to run with GAE Launcher:
import os
import cgi
import webapp2
from google.appengine.ext.webapp.util import run_wsgi_app
import ssl
import json
import socket
import struct
import binascii
TOKEN = 'my_app_token'
PAYLOAD = {'aps': {'alert':'Push!','sound':'default'}}
class APNStest(webapp2.RequestHandler):
def send_push(token, payload):
# Your certificate file
cert = 'ck.pem'
# APNS development server
apns_address = ('gateway.sandbox.push.apple.com', 2195)
# Use a socket to connect to APNS over SSL
s = socket.socket()
sock = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, certfile=cert)
sock.connect(apns_address)
# Generate a notification packet
token = binascii.unhexlify(token)
fmt = '!cH32sH{0:d}s'.format(len(payload))
cmd = '\x00'
message = struct.pack(fmt, cmd, len(token), token, len(payload), payload)
sock.write(message)
sock.close()
send_push(TOKEN, json.dumps(PAYLOAD))
application = webapp2.WSGIApplication([
('/apns', APNStest)
], debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()

So the solution was very simple as I expected. I had enabled billing for the project on cloud.google.com but needed to have billing enabled at appengine.google.com as well. Stupid mistake that set me back 2 days.

Related

WebSocket from Dart/Flutter to Python/Flask

I am trying to set up bidirectional communication between my Flutter android project and a server written in Python/Flask.
The code on the python side is basically the same as can be found at https://flask-sock.readthedocs.io/en/latest/quickstart.html. ie.
from flask import Flask, render_template
from flask_sock import Sock
app = Flask(__name__)
sock = Sock(app)
#sock.route('/echo')
def echo(ws):
while True:
data = ws.receive()
ws.send(data)
On the Dart side, I have:
final channel = WebSocketChannel.connect(
Uri.parse('wss://10.0.2.2:5000/echo'),
);
And the dependency in the pubspec.yaml file is:
web_socket_channel: ^2.1.0
Running it I get the bizarre error message:
127.0.0.1 - - [23/Jul/2022 17:49:09] code 400, message Bad request version ('\x18±-8ÛF\x18Ã\x9b(ôP')
There is nothing wrong with the flask side of things, my app processes the standard html requests fine. But setting up the websockets causes these runtime complaints.
I tried flask.socketio and got the similar errors.

Not printing to the console upon establishing connection to the server

I'm currently following a Udemy course that's having me use flask and socketio to use a neural network model to drive a simulated car. However, as he's explaining the basics of how flask and socketio work, he had us write this code:
import socketio
import eventlet
from flask import Flask
sio = socketio.Server()
app = Flask(__name__)
#sio.on('connect')
def connect(sid, environ):
print('Connected')
if __name__ == "__main__":
app = socketio.Middleware(sio, app)
eventlet.wsgi.server(eventlet.listen(('', 4567)), app)
Which is supposed to print "Connected!" to the console when we connect to the server. Now, I get this message when I run it, so I'm pretty sure I'm connected.
(7532) accepted ('127.0.0.1', 49374)
But it's refusing to print "Connected!" when I connect like it's supposed to, no matter what I try.
EDIT:
So, I'm still not sure what the root cause of this is, but I found out how to fix it.
conda install python-engineio==3.13.2
conda install python-socketio==4.6.1
You might need to run anaconda as an administrator. If so, search for "Anaconda Powershell Prompt" then run it as an admin.
socketio uses special protocol so you need special client to use it.
At least
import socketio
sio = socketio.Client()
con = sio.connect('http://0.0.0.0:4567')
sio.wait()
I will not work with web browser. With web browser you can see only accepted.
Browser have to load web page which uses special JavaScript module to use socketio.
You can find more details in socketio documentation: Client
EDIT:
And here server which you can test with web browser.
When you open http://0.0.0.0:4567 in browser then index() sends to browser HTML with JavaScript code which loads special library and uses socketio to send own event. And you should see Connected, my event. When you close page or browser then you should see Disconnected
It is based on example from documentation for flask-socketio
import socketio
import eventlet
from flask import Flask
sio = socketio.Server()
app = Flask(__name__)
#app.route('/')
def index():
return """
Hello World!
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('connect', function() {
socket.emit('my event', {data: 'Im connected!'});
});
</script>
"""
#sio.on('connect')
def connect(sid, environ):
print('Connected')
#sio.on('disconnect')
def disconnect(sid): # without `environ`
print('Disconnected')
#sio.on('my event')
def my_event(sid, environ):
print('my event')
if __name__ == "__main__":
app = socketio.Middleware(sio, app)
eventlet.wsgi.server(eventlet.listen(('', 4567)), app)

Non-blocking tornado instance on Openshift?

I am trying to create tornado webserver and quick start made me standard project of tornado, but according to documentation this configuration is blocking.
I am new to non-blocking python.
I have this wsgi file that lies in root folder in my PAAS server
#!/usr/bin/env python
import os
import imp
import sys
#
# Below for testing only
#
if __name__ == '__main__':
ip = 'localhost'
port = 8051
zapp = imp.load_source('application', 'wsgi/application')
from wsgiref.simple_server import make_server
httpd = make_server(ip, port, zapp.application)
httpd.serve_forever()
This is main handler file
#!/usr/bin/env python
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
And Application folder contains this
# Put here yours handlers.
import tornado.wsgi
from . import handlers
handlers = [(r'/',MainHandler),]
application = tornado.wsgi.WSGIApplication(handlers, **settings)
In WSGI mode asynchronous methods are not supported
uses WSGI to deploy the python applications
Is it possible to configure python application on openshift to be fully non-blocking
Though i have seen project that seemed to work
If you are talking about OpenShift V2 (not V3 which uses Kubernetes/Docker), then you need to use the app.py file as described in:
http://blog.dscpl.com.au/2015/08/running-async-web-applications-under.html

Emitting event from socketIo python

I'm stuck in development of socket.io with Python. I'm using this lib
I got a chat app running by using this android part and with the lib sample. I want to trigger an event from the server side from a separate file. Here's my code.
import socketio
import eventlet
from flask import Flask, render_template
sio = socketio.Server(logger=True, async_handlers= True)
app = Flask(__name__)
eventlet.monkey_patch()
#sio.on('connect', namespace='/d')
def connect(sid, environ):
print('connect ', sid)
pass
#sio.on('messaget', namespace='/d')
def messaget(sid, data):
print('message ', data)
# sio.emit('messaget', data, namespace='/d')
# sendmsg("YO YO")
#sio.on('disconnect', namespace='/d')
def disconnect(sid):
print('disconnect ', sid)
def start_socket(app):
# wrap Flask application with socketio's middleware
app = socketio.Middleware(sio, app)
eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
def sendmsg(data):
my_data= { 'text': data };
sio.emit('messaget', my_data, namespace='/d')
start_socket(app)
I'm calling sendmsg("dipen") from my another python file. I'm getting a log emitting event "messaget" to all [/d] but android app is not getting any messages. And it work's if event is emitting from the Android app. I tried with the NodeJs code and it worked for the NodeJs code so I'm pretty sure that something is wrong in my Python code. Hope that someone could save me from this.
Send a message from Android client. Does your Python code get it? If not, check if you have connected to the same namespace.

How to deploy CherryPy on pythonanywhere.com

I have a python app developed on Flask. Everything works fine offline, I tried deploying on CherryPy successfully too. Now, I'm trying to deploy the same on www.pythonanywhere.com.
Here's the deploy.py I use for deploying the Flask app on CherryPy
from cherrypy import wsgiserver
from appname import app
def initiate():
app_list = wsgiserver.WSGIPathInfoDispatcher({'/appname': app})
server = wsgiserver.CherryPyWSGIServer( ('http://username.pythonanywhere.com/'), app_list)
try:
server.start()
except KeyboardInterrupt:
server.stop()
print "Server initiated..."
initiate()
print "Ended"
I created a "manual configuration" app on pythonanywhere.com.
Here's the configuration file (username_pythonanywhere_com_wsgi.py):
import sys
path = '/home/username/appname'
if path not in sys.path:
sys.path.append(path)
import deploy
deploy.initiate()
Now I'm pretty sure that it "almost worked", because in the server logs I could see my "Server initiated..." message.
2013-09-27 09:57:16 +0000 username.pythonanywhere.com - *** Operational MODE: single process ***
Server initiated...
Now the problem, when I try to view my app username.pyhtonanywhere.com/about, it times out.
This I believe is caused due to incorrect port given while starting the CherryPy server (in deploy.py).
Could anyone please tell how I can properly initiate the CherryPy server?
Joe Doherty is right. You want something more like this in you wsgi file:
import sys
sys.path = [ <path to your web app> ] + sys.path
from cherrypy._cpwsgi import CPWSGIApp
from cherrypy._cptree import Application
from <your_web_app> import <your web app class>
config_path = '<path to your cherrypy config>'
application = CPWSGIApp(
Application(<your web app class>(), '', config = config_path)
I stuck everything that should be based on your particular app in <>s.

Categories

Resources