python Flask SocketIO throwing SSL error with eventlet - python

I am running this python code where I am trying to run a socketio flask application and passing ssl certificate files:
from flask import Flask, render_template, request, session, Markup, current_app, jsonify
from flask_socketio import emit, SocketIO
import eventlet
from flask_babel import gettext
app = Flask(__name__)
app.config['SECRET_KEY'] = '123'
app.config['FILEDIR'] = 'static/_files/'
socketio = SocketIO(app)
if __name__ == '__main__':
try:
app_host = os.environ.get('APP_HOST')
app_port = os.environ.get('APP_PORT')
eventlet.wsgi.server(eventlet.wrap_ssl(eventlet.listen((app_host, int(app_port))),certfile ='selfsigned.crt', keyfile = 'selfsigned.key',server_side = True),app)
except Exception as e:
logger.error(e)
When I run this code it throws following SSL error:
(21755) wsgi starting up on https://12.34.56.78:5000
(21755) accepted ('12.34.56.79', 50021)
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 458, in fire_timers
timer()
File "/usr/local/lib/python3.6/site-packages/eventlet/hubs/timer.py", line 58, in __call__
cb(*args, **kw)
File "/usr/local/lib/python3.6/site-packages/eventlet/greenthread.py", line 218, in main
result = function(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 781, in process_request
proto.__init__(conn_state, self)
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 335, in __init__
self.handle()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 368, in handle
self.handle_one_request()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 397, in handle_one_request
self.raw_requestline = self._read_request_line()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 380, in _read_request_line
return self.rfile.readline(self.server.url_length_limit)
File "/usr/local/lib/python3.6/socket.py", line 586, in readinto
return self._sock.recv_into(b)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 204, in recv_into
return self._base_recv(nbytes, flags, into=True, buffer_=buffer)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 225, in _base_recv
read = self.read(nbytes, buffer_)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 139, in read
super(GreenSSLSocket, self).read, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 113, in _call_trampolining
return func(*a, **kw)
File "/usr/local/lib/python3.6/ssl.py", line 871, in read
return self._sslobj.read(len, buffer)
File "/usr/local/lib/python3.6/ssl.py", line 631, in read
v = self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: HTTP_REQUEST] http request (_ssl.c:2217)
What I want is that this app should run over https connection but this error is preventing it from running. Below are my python and package version details:
python 3.6.3
eventlet==0.22.1
Flask==0.12.2
Flask-SocketIO==2.9.3

It seems that the request that has been made to the server is using http instead of https. You have to make sure that the client is also making a request using the same https protocol as the server. For example in you client code, you have to make a request to https://<server-ip> instead of http://<server-ip>

Related

Maximum recursion depth exceeded on SSLContext (eventlet, flask, flask-socketio, tweepy)

I'm building a flask app that displays real-time data visualizations of tweets based on a user input. Right now, the client is still hosted locally and I'm just trying to get to the point where a json of a single tweet gets emitted from the server to the client. This is also my first time building a flask app on my own, so I've been learning HTML/CSS/node.js/JS along the way (be gentle with me).
My problem is with the backend/server. Here is the relevant flask code:
from flask import Flask, request, render_template, session
from flask_socketio import SocketIO, emit
from time import sleep
import threading
from threading import Thread, Event, Lock
import eventlet
import json
import TweePoll_API_nostream
eventlet.monkey_patch(socket=True)
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket = SocketIO(app, async_mode=None, logger=True, engineio_logger=True)
streamer2 = TweePoll_API_nostream.getTweet()
thread = None
thread_lock = Lock()
def background_thread():
count = 0
while True:
socket.sleep(10)
x = streamer2.main(v)
count += 1
socket.emit('my_response',
{'data': x, 'count': count},
namespace='/output')
#app.route('/', methods = ['GET','POST'])
def index():
return(render_template("index.html", async_mode = socket.async_mode))
#socket.on('my_event', namespace='/output')
def test_message(message):
global v
v = message['data']
print(v)
global thread
with thread_lock:
if thread is None:
thread = socket.start_background_task(background_thread)
emit('my_response', {'data': v, 'count': 0})
if __name__ == '__main__':
socket.run(app, port = 5000, debug = True)
The error occurs on x = streamer2.main(v) in the background_thread() function. Here is the relevant code for the tweepy streamer:
import tweepy
import config
import TweePoll_NLP_single
import json
MLObj = TweePoll_NLP_single.ReadyForSQL()
class getTweet(object):
def __init__(self):
self.auth = tweepy.auth.OAuthHandler(config.ckey, config.csecret)
self.auth.set_access_token(config.atoken, config.asecret)
self.api = tweepy.API(self.auth)
def main(self, keywrd):
tweet = str()
user = str()
time = str()
status = self.api.search(q = [keywrd + " #realDonaldTrump", keywrd + " #JoeBiden"], count = 1, result_type = "recent", lang = 'en')[0]
if hasattr(status, "retweeted_status"): # Check if Retweet
try:
tweet = status.retweeted_status.extended_tweet["full_text"]
except AttributeError:
tweet = status.retweeted_status.text
else:
try:
tweet = status.extended_tweet["full_text"]
except AttributeError:
tweet = status.text
user = status.author.screen_name
time = str(status.created_at)
prez = MLObj.whichPrez(tweet)
clean = MLObj.kleenex(tweet)
NRCemo = MLObj.NRCEmo(clean)
printDF = json.dumps({"tweet":tweet, "clean":clean,
"prez":prez, "NRCEmo":NRCemo, "time":time, "username":user})
return(printDF)
This code isn't reproducible, because it connects to another file for the NLP/sentiment tagging, plus the frontend isn't included. Let me know if I need to send a link to my github or something to fix this.
Here is the error output:
Exception in thread Thread-6:
Traceback (most recent call last):
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\tweepy\binder.py", line 183, in execute
resp = self.session.request(self.method,
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\adapters.py", line 439, in send
resp = conn.urlopen(
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 670, in urlopen
httplib_response = self._make_request(
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 381, in _make_request
self._validate_conn(conn)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 976, in _validate_conn
conn.connect()
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 342, in connect
self.ssl_context = create_urllib3_context(
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\util\ssl_.py", line 276, in create_urllib3_context
context.options |= options
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 602, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 602, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 602, in options
super(SSLContext, SSLContext).options.__set__(self, value)
[Previous line repeated 481 more times]
RecursionError: maximum recursion depth exceeded
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\swagj\Documents\GitHub\TweePoll\TweePoll_Server_V2.py", line 28, in background_thread
x = streamer2.main(v)
File "C:\Users\swagj\Documents\GitHub\TweePoll\TweePoll_API_nostream.py", line 21, in main
status = self.api.search(q = [keywrd + " #realDonaldTrump", keywrd + " #JoeBiden"], count = 1, result_type = "recent", lang = 'en')[0]
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\tweepy\binder.py", line 250, in _call
return method.execute()
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\tweepy\binder.py", line 191, in execute
six.reraise(TweepError, TweepError('Failed to send request: %s' % e), sys.exc_info()[2])
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\six.py", line 702, in reraise
raise value.with_traceback(tb)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\tweepy\binder.py", line 183, in execute
resp = self.session.request(self.method,
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\requests\adapters.py", line 439, in send
resp = conn.urlopen(
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 670, in urlopen
httplib_response = self._make_request(
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 381, in _make_request
self._validate_conn(conn)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 976, in _validate_conn
conn.connect()
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 342, in connect
self.ssl_context = create_urllib3_context(
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\util\ssl_.py", line 276, in create_urllib3_context
context.options |= options
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 602, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 602, in options
super(SSLContext, SSLContext).options.__set__(self, value)
File "C:\Users\swagj\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 602, in options
super(SSLContext, SSLContext).options.__set__(self, value)
[Previous line repeated 481 more times]
tweepy.error.TweepError: Failed to send request: maximum recursion depth exceeded
Final dump, here is my info:
Windows 10
python = 3.8.3
eventlet = 0.25.2
tweepy = 3.8.0
websocket-client = 0.57.0
websockets = 8.1
Flask = 1.1.2
Flask-SocketIO = 4.3.0
I have no idea why this doesn't work, but I have a feeling it has to do with eventlet. Any clues? Happy to give more info if needed :)
For anyone else stumbling upon this... I was getting this error on a Flask app using eventlet (running Python 3.9):
File "/usr/lib/python3.9/ssl.py", line 603, in options
super(SSLContext, SSLContext).options.set(self, value)
File "/usr/lib/python3.9/ssl.py", line 603, in options
super(SSLContext, SSLContext).options.set(self, value)
File "/usr/lib/python3.9/ssl.py", line 603, in options
super(SSLContext, SSLContext).options.set(self, value)
[Previous line repeated 490 more times]
RecursionError: maximum recursion depth exceeded
To make a long story short:
disabling eventlet.monkey_patch() corrected the issue in tests, but I wanted to keep it.
updating eventlet and dnspython fixed it for good for me.
Before:
dnspython==1.16.0
eventlet==0.30.2
After:
dnspython==2.3.0
eventlet==0.33.3

Proxy to mock ec2.describe_regions() (AWS)

I'm makeing a simple proxy with Flask to mock the call describe_regions() of AWS.
The Flask server has de following code:
from __future__ import unicode_literals
from flask import Flask
from flask import Response
from flask import stream_with_context
# from httpretty import HTTPretty, register_uri
import httpretty
import requests
from flask import request
import time
RESPONSE = u"""<DescribeRegionsResponse xmlns="http://ec2.amazonaws.com/doc/2015-10-01/">
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
<regionInfo>
<item>
<regionName>us-east-1</regionName>
<regionEndpoint>ec2.us-east-1.amazonaws.com</regionEndpoint>
</item>
<item>
<regionName>eu-west-1</regionName>
<regionEndpoint>ec2.eu-west-1amazonaws.com</regionEndpoint>
</item>
</regionInfo>
</DescribeRegionsResponse>"""
app = Flask(__name__)
#app.route('/<path:url>', methods=['GET', 'PUT', 'POST', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS', 'CONNECT'])
def home(url):
return Response(RESPONSE, mimetype='text/xml')
if __name__ == '__main__':
app.run(debug=True)
Then I has the following code to test it. I use Boto3 to call the API for AWS.
from boto3.session import Session
import os
credentials = {
'aws_access_key_id': 'sadasdasda',
'aws_secret_access_key': 'dasdasdasd'
}
os.environ["HTTP_PROXY"] = 'http://localhost:5000/'
os.environ["HTTPS_PROXY"] = 'http://localhost:5000/'
session_boto3 = Session(**credentials)
ec2 = session_boto3.client('ec2', 'eu-west-1', verify=False)
regions = ec2.describe_regions()
print regions
The problem is: the Flask server get the petition, but the Response doesn't like to Boto3 and I get the following traceback error:
Traceback (most recent call last):
File "/pruebas_mock/prueba.py", line 82, in <module>
regions = ec2.describe_regions()
File "/mock_aws/local/lib/python2.7/site-packages/botocore/client.py", line 228, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/client.py", line 475, in _make_api_call
operation_model, request_dict)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/endpoint.py", line 117, in make_request
return self._send_request(request_dict, operation_model)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/endpoint.py", line 146, in _send_request
success_response, exception):
File "/mock_aws/local/lib/python2.7/site-packages/botocore/endpoint.py", line 219, in _needs_retry
caught_exception=caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/hooks.py", line 226, in emit
return self._emit(event_name, kwargs)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/hooks.py", line 209, in _emit
response = handler(**kwargs)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 183, in __call__
if self._checker(attempts, response, caught_exception):
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 250, in __call__
caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 273, in _should_retry
return self._checker(attempt_number, response, caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 313, in __call__
caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 222, in __call__
return self._check_caught_exception(attempt_number, caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 355, in _check_caught_exception
raise caught_exception
botocore.vendored.requests.exceptions.SSLError: [Errno 1] _ssl.c:510: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
How should I make the response with Flask?
Thanks.
By default, boto3 (and all of the other AWS SDK's) will connect to services using SSL. Your proxy Flask server does not appear to be using SSL so you can either use SSL in your proxy or tell boto3 not to use SSL for your proxy server:
ec2 = session_boto3.client('ec2', 'eu-west-1', use_ssl=False, verify=False)
The verify parameter tells boto3 not to try to validate the SSL cert but it will still try to connect via SSL. the use_ssl=False tells it to use plain HTTP to talk to your endpoint.

SSLError: Can't connect to HTTPS URL because the SSL module is not available on google app engine

Want to use wechat sdk to create menu
WeChat.create_menu({
"button":[
{
"type":"click",
"name":"Daily Song",
"key":"V1001_TODAY_MUSIC"
},
{
"type":"click",
"name":" Artist Profile",
"key":"V1001_TODAY_SINGER"
},
{
"name":"Menu",
"sub_button":[
{
"type":"view",
"name":"Search",
"url":"http://www.soso.com/"
},
{
"type":"view",
"name":"Video",
"url":"http://v.qq.com/"
},
{
"type":"click",
"name":"Like us",
"key":"V1001_GOOD"
}]
}]
})
Currently not work because of this error:
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 267, in Handle
result = handler(dict(self._environ), self._StartResponse)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1519, in __call__
response = self._internal_error(e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1511, in __call__
rv = self.handle_exception(request, response, e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1505, in __call__
rv = self.router.dispatch(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1077, in __call__
return handler.dispatch()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 547, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 545, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechatAPIHandler.py", line 72, in post
"key":"V1001_GOOD"
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 355, in create_menu
data=menu_data
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 949, in _post
**kwargs
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 907, in _request
"access_token": self.access_token,
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 849, in access_token
self.grant_token()
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 273, in grant_token
"secret": self.__appsecret,
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 935, in _get
**kwargs
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 917, in _request
**kwargs
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/sessions.py", line 465, in request
resp = self.send(prep, **send_kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/sessions.py", line 573, in send
r = adapter.send(request, **kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
SSLError: Can't connect to HTTPS URL because the SSL module is not available.
python request module is include in the app engine project. Using python 2.7. Being look for ways to solve this problem but have not find very clear way to solve the problem yet
If you're using GAE's Sockets, you can get SSL support without any hacks by simply loading the SSL library.
Simply add this to your app.yaml file:
libraries:
- name: ssl
version: latest
This is documented on Google Cloud's OpenSSL Support documentation.
This blog post details a solution. From the blog post:
The problem is GAE has a “whitelist” of select standard libraries. SSL
(_ssl, _socket) is not one of them. So, we need to tweak the sandbox
environment (dangerous) carefully. The below code uses the standard
Python socket library instead of the GAE-provided in the development
environment. Modify [or create] appengine_config.py:
import os
# Workaround the dev-environment SSL
# http://stackoverflow.com/q/16192916/893652
if os.environ.get('SERVER_SOFTWARE', '').startswith('Development'):
import imp
import os.path
from google.appengine.tools.devappserver2.python import sandbox
sandbox._WHITE_LIST_C_MODULES += ['_ssl', '_socket']
# Use the system socket.
psocket = os.path.join(os.path.dirname(os.__file__), 'socket.py')
imp.load_source('socket', psocket)
Jan Dolejsi,
If you're using GAE's Sockets, you can get SSL support without any
hacks by simply loading the SSL library.
Simply add this to your app.yaml file:
libraries:
- name: ssl
- version: latest
If you're experiencing RAND_egd error, just change "-version: latest" in your app.yaml, to "-version: 2.7"!

Bottle tries to access a socket in a way forbidden by it's permission

I am working with bottle, and have written a simple application
from bottle import *
#route("/")
def index():
return "This is a test."
run(host="0.0.0.0", port=8080)
When I run this I get an error stating:
Traceback (most recent call last):
File "C:\Users\James\Desktop\application.py", line 7, in <module>
run(host="0.0.0.0", port=8080)
File "C:\Python34\lib\site-packages\bottle.py", line 3117, in run
server.run(app)
File "C:\Python34\lib\site-packages\bottle.py", line 2771, in run
srv = make_server(self.host, self.port, app, server_cls, handler_cls)
File "C:\Python34\lib\wsgiref\simple_server.py", line 153, in make_server
server = server_class((host, port), handler_class)
File "C:\Python34\lib\socketserver.py", line 429, in __init__
self.server_bind()
File "C:\Python34\lib\wsgiref\simple_server.py", line 50, in server_bind
HTTPServer.server_bind(self)
File "C:\Python34\lib\http\server.py", line 133, in server_bind
socketserver.TCPServer.server_bind(self)
File "C:\Python34\lib\socketserver.py", line 440, in server_bind
self.socket.bind(self.server_address)
OSError: [WinError 10013] An attempt was made to access a socket in a way forbid
den by its access permissions
Looking at some other SO posts,it seems to be that I need to allow it through the firewall. I did that:
But the error still persists, what do I do to fix this?
Try with 127.0.0.1 instead of localhost
from bottle import route, run, template
#route('/hello/<name>')
def index(name):
return template('<b>Hello {{name}}</b>!', name=name)
run(host='127.0.0.1', port=8080)

how to increase timeout in tornado

I'm trying tornado framework. But I found tornado frequently failed after 30 seconds in the stress test (using multi-mechanize). I use 10 threads in multi-mechanize and run for 100 seconds, around 500 requests / seconds. And it's around 15% failure ratio after 30 seconds. The whole test is about 100 seconds. From the statistics, I realize, the failure may due to timeout after 0.2 seconds. I searched for several ways to increase the timeout on web, but nothing works.
The below is my tornado code:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
#tornado.web.asynchronous
def get(self):
self.write("Hello, world")
self.finish()
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8000)
tornado.ioloop.IOLoop.instance().start()
Here is my multi-mechanize test script:
import requests
import random
import time
class Transaction(object):
def __init__(self):
pass
def run(self):
r = requests.get('http://127.0.0.1:8000')
output = r.raw.read()
assert(r.status_code == 200)
return output
if __name__ == '__main__':
trans = Transaction()
trans.run()
print trans.custom_timers
The following is the error message I got from multimech-run
Traceback (most recent call last):
File "././test_scripts/v_user.py", line 12, in run
r = requests.get('http://127.0.0.1:8000')
File "/Library/Python/2.7/site-packages/requests/api.py", line 54, in get
return request('get', url, **kwargs)
File "/Library/Python/2.7/site-packages/requests/safe_mode.py", line 37, in wrapped
return function(method, url, **kwargs)
File "/Library/Python/2.7/site-packages/requests/api.py", line 42, in request
return s.request(method=method, url=url, **kwargs)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 230, in request
r.send(prefetch=prefetch)
File "/Library/Python/2.7/site-packages/requests/models.py", line 603, in send
timeout=self.timeout,
File "/Library/Python/2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 415, in urlopen
body=body, headers=headers)
File "/Library/Python/2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 267, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 941, in request
self._send_request(method, url, body, headers)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 975, in _send_request
self.endheaders(body)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 937, in endheaders
self._send_output(message_body)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 797, in _send_output
self.send(msg)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 759, in send
self.connect()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 740, in connect
self.timeout, self.source_address)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 571, in create_connection
raise err
error: [Errno 49] Can't assign requested address
To answer your question of how to change the timeout for tornado, you need to modify tornado's bind_socket function to set the time out: http://www.tornadoweb.org/documentation/_modules/tornado/netutil.html
sock.setblocking(0)
sock.bind(sockaddr)
sock.listen(backlog)
sockets.append(sock)
Change the first line to sock.setblocking(1). According to the documentation: http://docs.python.org/library/socket.html#socket.socket.settimeout :
Setting a timeout of None disables timeouts on socket operations
s.settimeout(None) is equivalent to s.setblocking(1).
However, as suggested in the comment, I think you should look at distributing the load.

Categories