diff --git a/dev_server/dev_server.py b/dev_server/dev_server.py index 895537b..2b22c8b 100755 --- a/dev_server/dev_server.py +++ b/dev_server/dev_server.py @@ -17,13 +17,6 @@ from sae.channel import _channel_wrapper -app_root = search_file_bottom_up('config.yaml') -if app_root is None: - print >> sys.stderr, \ - 'Error: Not an app directory(or any of the parent directories)' - sys.exit(1) -if app_root != os.getcwd(): os.chdir(app_root) - def setup_sae_environ(conf): # Add dummy pylibmc module import sae.memcache @@ -61,6 +54,7 @@ def setup_sae_environ(conf): sae.const.MYSQL_PASS = password sae.const.MYSQL_PORT = port sae.const.MYSQL_HOST = host + sae.const.MYSQL_HOST_S = host print 'MySQL: %s.%s' % (conf.mysql, dbname) else: @@ -202,4 +196,11 @@ def main(options): parser.add_option("--kvdb-file", dest="kvdb", help="File to save kvdb data") (options, args) = parser.parse_args() + app_root = search_file_bottom_up('config.yaml') + if app_root is None: + print >> sys.stderr, \ + 'Error: Not an app directory(or any of the parent directories)' + sys.exit(1) + if app_root != os.getcwd(): os.chdir(app_root) + main(options) diff --git a/dev_server/sae/__init__.py b/dev_server/sae/__init__.py index 32cb350..e4f1229 100644 --- a/dev_server/sae/__init__.py +++ b/dev_server/sae/__init__.py @@ -10,3 +10,31 @@ def create_wsgi_app(app): def dev_server(conf): core.environ = conf + +import sys, os.path +_PYTHON_VERSION = 'python%d.%d' % (sys.version_info[0], sys.version_info[1]) + +def add_vendor_dir(path, index=1): + """Insert site dir or virtualenv at a given index in sys.path. + + Args: + path: relative path to a site dir or virtualenv. + index: sys.path position to insert the site dir. + + Raises: + ValueError: path doesn't exist. + """ + venv_path = os.path.join(path, 'lib', _PYTHON_VERSION, 'site-packages') + if os.path.isdir(venv_path): + site_dir = venv_path + elif os.path.isdir(path): + site_dir = path + else: + raise ValueError('virtualenv: cannot access %s: ' + 'No such virtualenv or site directory' % path) + + sys_path = sys.path[:] + del sys.path[index:] + import site + site.addsitedir(site_dir) + sys.path.extend(sys_path[index:]) diff --git a/dev_server/sae/channel.py b/dev_server/sae/channel.py index 2b612b8..373c74f 100644 --- a/dev_server/sae/channel.py +++ b/dev_server/sae/channel.py @@ -61,7 +61,7 @@ def create_channel(name, duration=None): _cache[name] = [] return 'http://%s/_sae/channel/%s' % (os.environ['HTTP_HOST'], name) -def send_message(name, message): +def send_message(name, message, async=False): client_id = name if isinstance(message, unicode): diff --git a/dev_server/saecloud b/dev_server/saecloud index 10f99ed..c9520e2 100755 --- a/dev_server/saecloud +++ b/dev_server/saecloud @@ -168,7 +168,7 @@ def install(args): import tempfile tmpdir = tempfile.gettempdir() - argv = ['install', '-I', + argv = ['install', '-I', '--allow-all-external', '--install-option=--install-lib=%s' % dest, '--install-option=--install-data=%s' % dest, '--install-option=--install-scripts=%s' % tmpdir] diff --git a/dev_server/setup.py b/dev_server/setup.py index b42f7c2..f311a94 100755 --- a/dev_server/setup.py +++ b/dev_server/setup.py @@ -2,7 +2,7 @@ import os.path from setuptools import setup, find_packages -VERSION = '1.3.2' +VERSION = '1.3.6' scripts = ['dev_server.py', 'saecloud', 'cloudsql.py'] diff --git a/examples/apibus/README b/examples/apibus/README deleted file mode 100644 index 2e21d57..0000000 --- a/examples/apibus/README +++ /dev/null @@ -1 +0,0 @@ -如何在外部调用SAE服务。 diff --git a/examples/apibus/apibus_handler.py b/examples/apibus/apibus_handler.py index 9cba8bb..14bc4fd 100644 --- a/examples/apibus/apibus_handler.py +++ b/examples/apibus/apibus_handler.py @@ -1,27 +1,31 @@ #-*-coding: utf8 -*- """ -urllib2 handler for SAE APIBus Service +SAE API auth handler for urllib2 and requests -Usage: +urllib2: -import urllib2 -from apibus_handler import APIBusHandler -opener = urllib2.build_opener(APIBusHandler(ACCESSKEY, SECRETKEY)) +>>> import urllib2 +>>> apibus_handler = SaeApibusAuthHandler(ACCESSKEY, SECRETKEY) +>>> opener = urllib2.build_opener(apibus_handler) +>>> print opener.open('http://g.sae.sina.com.cn/log/http/2015-06-18/1-access.log').read() -Then you can use *opener* to request sae internal service such as segement, -sms as you want. +requests: + +>>> import requests +>>> print requests.get('http://g.sae.sina.com.cn/log/http/2015-06-18/1-access.log?head/0/10|fields/ /1/2/3/4', auth=SaeApibusAuth(ACCESSKEY, SECRETKEY)).content """ import hmac import base64 import hashlib import time +import urllib from urllib2 import BaseHandler, Request -_APIBUS_ENDPOINT = 'http://g.apibus.io' +_APIBUS_URL_PREFIX = 'http://g.sae.sina.com.cn/' -class APIBusHandler(BaseHandler): +class SaeApibusAuthHandler(BaseHandler): # apibus handler must be in front handler_order = 100 @@ -29,26 +33,52 @@ def __init__(self, accesskey, secretkey): self.accesskey = accesskey self.secretkey = secretkey - def _signature(self, headers): - msg = ''.join([k + v for k, v in headers]) - h = hmac.new(self.secretkey, msg, hashlib.sha256).digest() - return base64.b64encode(h) - def http_request(self, req): orig_url = req.get_full_url() + if not orig_url.startswith(_APIBUS_URL_PREFIX): + return req + timestamp = str(int(time.time())) headers = [ - ('Fetchurl', orig_url), - ('Timestamp', timestamp), - ('Accesskey', self.accesskey), + ('x-sae-timestamp', timestamp), + ('x-sae-accesskey', self.accesskey), ] - headers.append(('Signature', self._signature(headers))) - # Create a new request - _req = Request(_APIBUS_ENDPOINT, req.get_data(), origin_req_host=orig_url) - _req.headers.update(req.header_items()) - _req.headers.update(headers) - _req.timeout = req.timeout - return _req + req.headers.update(headers) + + method = req.get_method() + resource = urllib.unquote(req.get_full_url()[len(_APIBUS_URL_PREFIX)-1:]) + sae_headers = [(k.lower(), v.lower()) for k, v in req.headers.items() if k.lower().startswith('x-sae-')] + req.add_header('Authorization', _signature(self.secretkey, method, resource, sae_headers)) + return req https_request = http_request +try: + from requests.auth import AuthBase + + class SaeApibusAuth(AuthBase): + """Attaches HTTP Basic Authentication to the given Request object.""" + def __init__(self, accesskey, secretkey): + self.accesskey = accesskey + self.secretkey = secretkey + + def __call__(self, r): + timestamp = str(int(time.time())) + r.headers['x-sae-timestamp'] = timestamp + r.headers['x-sae-accesskey'] = self.accesskey + resource = urllib.unquote(r.url[len(_APIBUS_URL_PREFIX)-1:]) + #resource = r.url[len(_APIBUS_URL_PREFIX)-1:] + sae_headers = [(k.lower(), v.lower()) for k, v in r.headers.items() if k.lower().startswith('x-sae-')] + r.headers['Authorization'] = _signature(self.secretkey, r.method, resource, sae_headers) + return r +except ImportError: + # requests was not present! + pass + +def _signature(secret, method, resource, headers): + msgToSign = "\n".join([ + method, resource, + "\n".join([(k + ":" + v) for k, v in sorted(headers)]), + ]) + return "SAEV1_HMAC_SHA256 " + base64.b64encode(hmac.new(secret, msgToSign, hashlib.sha256).digest()) + diff --git a/examples/apibus/demo.py b/examples/apibus/demo.py deleted file mode 100644 index 4777456..0000000 --- a/examples/apibus/demo.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*-coding: utf8 -*- - -import urllib -import urllib2 -from apibus_handler import APIBusHandler - -ACCESSKEY = '你的某个开启了服务的应用的accesskey' -SECRETKEY = '你的某个开启了服务的应用的secretkey' - -apibus_handler = APIBusHandler(ACCESSKEY, SECRETKEY) -opener = urllib2.build_opener(apibus_handler) - -print 'call sae segment api:' -chinese_text = '中文文本' -url = 'http://segment.sae.sina.com.cn/urlclient.php?word_tag=1&encoding=UTF-8' -payload = urllib.urlencode([('context', chinese_text),]) -print opener.open(url, payload).read() - -# sending sms -print 'call sae sms api:' -url = 'http://inno.smsinter.sina.com.cn/sae_sms_service/sendsms.php' -payload = 'mobile=186****8203&msg=helloworld' -print opener.open(url, payload).read()