django, wsgi_intercept and behave - python

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

Related

In Django, passenger_wsgi.py is calling itself creating infinite processes

We are using Angular JS for frontend and Django framework at backend. Whenever a request comes from the front-end, passenger_wsgi file receives the request. It processes the request and returns the expected response.
However, passenger_wsgi calls itself, which calls itself. This happens recursively, in an loop causing infinite processes and server to overload.
Appreciate your comments and a fix. Below is the current passenger_wsgi.
import os
import sys
import django.core.handlers.wsgi
from django.core.wsgi import get_wsgi_application
# Set up paths and environment variables
sys.path.append(os.getcwd())
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
# Set script name for the PATH_INFO fix below
SCRIPT_NAME = os.getcwd()
class PassengerPathInfoFix(object):
"""
Sets PATH_INFO from REQUEST_URI because Passenger doesn't provide it.
"""
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
from urllib.parse import unquote
environ['SCRIPT_NAME'] = SCRIPT_NAME
request_uri = unquote(environ['REQUEST_URI'])
script_name = unquote(environ.get('SCRIPT_NAME', ''))
offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
return self.app(environ, start_response)
# Set the application
application = get_wsgi_application()
application = PassengerPathInfoFix(application)
I have tried changing the last 2 lines. In this scenario, passenger_wsgi is not able to serve the request and frontend received 500 Server Error.

Opening Webbrowser after Running A Server with Bottle

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)

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

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.

Categories

Resources