Opening Webbrowser after Running A Server with Bottle - python

I am trying to create a program that will start a server with the Bottle module and then open the server url with the webbrowser module. I am having issues opening the webbrowser AFTER starting the bottle server. If i open webbrowser before starting the bottle server the webbrowser successfully opens. However, the webbrowser never opens if I start the bottle server before opening the webbrowser.
import webbrowser
from bottle import route, run, request
def step1():
url = 'http://localhost:8080'
chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s --incognito'
webbrowser.get(chrome_path).open_new(url)
run(host='', port=8080)
step1()
I expect the server to start and then for the webbrowser to open. However, the webbrowser just doesn't open and no errors are thrown.
In this example, opening the webbrowser before running the server works and the connection is successful. However, if I wanted to make a more complex webbrowser function that requires feedback from the server it wouldn't work.
Is there a way to open a webbrowser AFTER starting a bottle server?
Thanks!

Rus this script in console, open you Chrome and point it to http://localhost:8181/hello/Russell
import webbrowser
from bottle import route, run, template
#route('/hello/<name>')
def index(name):
url = 'http://localhost:8181/hello/Russell'
chrome_path = '"C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" %s --incognito'
webbrowser.get(chrome_path).open_new(url)
return template('<b>Hello, <font color=red size=+2>{{name}}</font></b>!', name=name)
run(host='localhost', port=8181)

Async is your friend here.
import gevent
from gevent import monkey, joinall, spawn, signal
monkey.patch_all()
from gevent.pywsgi import WSGIServer
import webbrowser
import bottle
from bottle import route, run, request, get
#get('/')
def home():
return 'Hello World'
def step1():
url = 'http://localhost:8080'
chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s --incognito'
webbrowser.get(chrome_path).open_new(url)
if __name__ == '__main__':
print('Started...')
botapp = bottle.app()
server = WSGIServer(("0.0.0.0", int(8080)), botapp )
def shutdown():
print('Shutting down ...')
server.stop(timeout=60)
exit(signal.SIGTERM)
gevent.signal(signal.SIGTERM, shutdown)
gevent.signal(signal.SIGINT, shutdown) #CTRL C
threads = []
threads.append(spawn(server.serve_forever))
threads.append(spawn(step1))
joinall(threads)

Related

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)

django, wsgi_intercept and behave

Hi I am trying to implement behave test framework in my django python app. However not sure what the problem is and I keep getting connection refused.
Following is the content of features/environment.py:
import os
import django
import urlparse
os.environ['DJANGO_SETTINGS_MODULE'] = 'tilesproj.settings'
django.setup()
def before_all(context):
from django.test.runner import DiscoverRunner
context.runner = DiscoverRunner()
import wsgi_intercept
from django.core.handlers.wsgi import WSGIHandler
host = context.host = 'localhost'
port = context.port = 8000
from django.core.wsgi import get_wsgi_application
from wsgiref.simple_server import make_server
application = get_wsgi_application()
wsgi_intercept.add_wsgi_intercept(host, port, lambda: application)
import mechanize
context.browser = mechanize.Browser()
def browser_url(url):
return urlparse.urljoin('http://%s:%d/' % (host, port), url)
context.browser_url = browser_url
from BeautifulSoup import BeautifulSoup
def parse_soup():
r = context.browser.response()
html = r.read()
r.seek(0)
return BeautifulSoup(html)
context.parse_soup = parse_soup
def before_scenario(context, scenario):
context.runner.setup_test_environment()
context.old_db_config = context.runner.setup_databases()
def after_scenario(context, scenario):
context.runner.teardown_databases(context.old_db_config)
context.runner.teardown_test_environment()
I am trying to figure out how to bootstrap my django app when behave script is run so can test my web app.
You should try the example Django Behave configuration from the website. Essentially you use a fake browser to perform requests which don't actually go through a real website. Your connections are refused because there is no real server to connect to.
So you should get the mechanize browser from wsgi_intercept instead of from mechanize directly:
### Set up the Mechanize browser.
from wsgi_intercept import mechanize_intercept
# MAGIC: All requests made by this monkeypatched browser to the magic
# host and port will be intercepted by wsgi_intercept via a
# fake socket and routed to Django's WSGI interface.
browser = context.browser = mechanize_intercept.Browser()

Trouble Sending iOS push notifications from Google App Engine

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.

Connection refused in Tornado test

I'm trying to create tests for a Tornado code base I'm picking up. I get the project to run fine but the first test I've written is getting a connection refused error.
Here's the code:
import unittest, os, os.path, sys, urllib
import tornado.options
from tornado.options import options
from tornado.testing import AsyncHTTPTestCase
APP_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(os.path.join(APP_ROOT, '..'))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))
from main import Application
app = Application()
def clear_db(app=None):
os.system("mysql -u user --password=pw --database=testdb < %s" % (os.path.join(APP_ROOT, 'db', 'schema.sql')))
class TestHandlerBase(AsyncHTTPTestCase):
def setUp(self):
clear_db()
super(TestHandlerBase, self).setUp()
def get_app(self):
return app
def get_http_port(self):
return 5000
class TestRootHandler(TestHandlerBase):
def test_redirect(self):
response = self.fetch(
'/',
method='GET',
follow_redirects=False)
print response
self.assertTrue(response.headers['Location'].endswith('/login'))
This is the response I get:
HTTPResponse(_body=None, buffer=None, code=599,
effective_url='http://localhost:5000/',
error=HTTPError('HTTP 599: [Errno 61] Connection refused',),
headers={}, reason='Unknown',
request=<tornado.httpclient.HTTPRequest object at 0x10c363510>,
request_time=0.01304006576538086, time_info={})
Any idea on what might be causing the error? Is there a step I'm missing to get everything running for the test? Thanks!!!
Don't override get_http_port. A new HTTP server with a new port is setup for each test, so it won't be 5000 every time, even if that's what you have in your settings.
I agree with the answer by Cole Maclean
If you need to configure custom URL, then override the below method of AsyncHTTPTestCase
def get_url(self, path):
url = 'http://localhost:8080' + path
return url
In this scenario, this will take the URL as http://localhost:8080 by default.

Simple flask/gevent request isn't running concurrently

I have this simple flask/gevent demo code.
#!/usr/bin/env python
import gevent
from gevent.pywsgi import WSGIServer
from gevent import monkey
monkey.patch_socket()
from flask import Flask, Response
app = Flask(__name__)
#app.route('/')
def stream():
def gen():
for i in range(10):
yield "data: %d\r\n" % i
gevent.sleep(1)
return Response(gen())
if __name__ == '__main__':
http = WSGIServer(('', 5000), app)
http.serve_forever()
When I run it and open multiple urls in the browser, all but one of them block. What am I doing wrong?
I have tried running it with monkey.patch_all(), and running it with gunicorn streaming:app -k gevent - it still blocks in the browser.
Multiple tabs in browsers will block. That doesn't mean gevent/gunicorn isn't running the requests concurrently. I tried it with concurrent curl requests and XmlHttpRequest - it works as expected. Also note that curl buffers output. "\r\n" is required to make it print line by line.
Sidenote: Thanks to mitsuhiko on #pocoo for resolving it. If you haven't tried flask, you should. Both mitushiko and flask are awesome.

Categories

Resources