Experimenting with promises, tornado.AsyncHTTPClient, very limited options

This commit is contained in:
James Barnsley
2017-10-13 10:02:06 +13:00
parent ebe6c90168
commit cab8e50bac
3 changed files with 86 additions and 22 deletions

View File

@ -5,7 +5,9 @@ import random, string, logging, json, pykka, pylast, urllib, urllib2, os, sys, m
import tornado.web
import tornado.websocket
import tornado.ioloop
import tornado.httpclient
import requests
from promise import Promise
from mopidy import config, ext
from mopidy.core import CoreListener
from pkg_resources import parse_version
@ -584,7 +586,6 @@ class IrisCore(object):
}
##
# Proxy a request to an external provider
#
@ -594,6 +595,9 @@ class IrisCore(object):
##
def proxy_request(self, *args, **kwargs):
callback = kwargs.get('callback', None)
origin_request = kwargs.get('request', None)
try:
data = kwargs.get('data', {})
except:
@ -604,7 +608,6 @@ class IrisCore(object):
'source': 'proxy_request'
}
origin_request = kwargs.get('request', None)
# Our request includes data, so make sure we POST the data
if 'url' not in data:
@ -645,7 +648,9 @@ class IrisCore(object):
try:
# Our request includes data, so make sure we POST the data
if ('data' in data and data['data']):
response = requests.post(data['url'], data=data['data'], headers=headers, verify=False)
http_client = tornado.httpclient.AsyncHTTPClient()
request = tornado.httpclient.HTTPRequest(data['url'], method='POST', data=data['data'], headers=headers, validate_cert=False)
http_client.fetch(request, callback=callback)
# No data, so just a simple GET request
else:
@ -655,7 +660,9 @@ class IrisCore(object):
if "Content-Length" in headers:
del headers["Content-Length"]
response = requests.get(data['url'], headers=headers, verify=False)
http_client = tornado.httpclient.AsyncHTTPClient()
request = tornado.httpclient.HTTPRequest(data['url'], headers=headers, validate_cert=False)
http_client.fetch(request, callback=callback)
# Attempt to decode body as JSON, otherwise just return plain text
@ -679,3 +686,25 @@ class IrisCore(object):
'response_code': int(e.response_code),
'original_request': data
}
def test(self, *args, **kwargs):
print "running test 1"
response = requests.get("http://platform.james.plasticstudio.co/test.php?sleep=1")
return Promise(
lambda resolve, reject: resolve(response.text)
)
def test2(self, *args, **kwargs):
print "running test 5"
response = requests.get("http://test.barnsley.nz/test.php?sleep=5")
return Promise(
lambda resolve, reject: resolve(response.text)
)

View File

@ -3,7 +3,7 @@ from __future__ import unicode_literals
from datetime import datetime
from tornado.escape import json_encode, json_decode
import tornado.ioloop, tornado.web, tornado.websocket, tornado.template
import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, urllib2, mem
import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, urllib2, mem, requests
logger = logging.getLogger(__name__)
@ -76,22 +76,17 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
data['connection_id'] = self.connection_id
if 'request_id' in message:
request_id = message['request_id']
data['request_id'] = message['request_id']
else:
request_id = False
data['request_id'] = False
# call the method, as specified in payload
if 'method' in message:
# make sure the method exists
if hasattr(mem.iris, message['method']):
getattr(mem.iris, message['method'])(data=data, callback=self.handle_response)
# make the call, and return it's response
response = getattr(mem.iris, message['method'])(data=data)
if response:
response['request_id'] = request_id
mem.iris.send_message(connection_id=self.connection_id, data=response)
else:
mem.iris.raven_client.captureMessage("Method "+message['method']+" does not exist")
response = {
@ -113,6 +108,23 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
def on_close(self):
mem.iris.remove_connection(connection_id=self.connection_id)
##
# Handle a response from our core
# This is just our callback from an Async request
##
def handle_response(self, response):
if isinstance(response, tornado.httpclient.HTTPResponse):
response_obj = {
'body': response.body,
'request_id': request_id
}
else:
response['request_id'] = request_id
mem.iris.send_message(connection_id=self.connection_id, data=response)
mem.iris.send_message(connection_id=self.connection_id, data=response)
self.finish()
@ -134,39 +146,61 @@ class HttpHandler(tornado.web.RequestHandler):
self.set_status(204)
self.finish()
@tornado.web.asynchronous
def get(self, slug=None):
# make sure the method exists
if hasattr(mem.iris, slug):
self.handle_request(getattr(mem.iris, slug)(request=self.request))
# make the call, and return it's response
self.write(getattr(mem.iris, slug)(request=self.request))
else:
mem.iris.raven_client.captureMessage("Method "+slug+" does not exist")
self.write({
'error': 'Method "'+slug+'" does not exist'
})
self.finish()
@tornado.web.asynchronous
def post(self, slug=None):
# make sure the method exists
if hasattr(mem.iris, slug):
try:
data = json.loads(self.request.body.decode('utf-8'))
# make the call, and return it's response
self.write(getattr(mem.iris, slug)(data=data, request=self.request))
getattr(mem.iris, slug)(data=data, request=self.request, callback=self.handle_response)
except urllib2.HTTPError as e:
self.raven_client.captureException()
self.write({
'error': 'Invalid JSON payload'
})
self.finish()
else:
mem.iris.raven_client.captureMessage("Method "+slug+" does not exist")
self.write({
'error': 'Method "'+slug+'" does not exist'
})
self.finish()
##
# Handle a response from our core
# This is just our callback from an Async request
##
def handle_request(self, request):
response = request.then(lambda response: response).get()
self.write(response)
self.finish()
##
# Handle a response from our core
# This is just our callback from an Async request
##
def handle_response(self, response):
if isinstance(response, tornado.httpclient.HTTPResponse):
self.write(response.body)
else:
self.write(response)
self.finish()

View File

@ -26,7 +26,8 @@ setup(
'Mopidy-Local-Images >= 1.0',
'ConfigObj >= 5.0.6',
'raven >= 6.1.0',
'requests >= 2.0.0'
'requests >= 2.0.0',
'promise >= 2.0.1'
],
classifiers=[
'Environment :: No Input/Output (Daemon)',