Permalink
Browse files

closes GH-13 closes GH-14: use `http` instead of `httplib2`

* renamed `base` to `Spore`
* in `Spore`, add the `user_agent` attribut, (it's an instance of
HTTPClient)
* in `Spore`, no more static attributes
* `Method` have a new signature (useragent and middlewares are passed to
the constructor)
* the `Request` class is now more simpler and based on `http.Request`	
* updated all the tests

Signed-off-by: franck cuny <franck.cuny@gmail.com>
  • Loading branch information...
1 parent 77628b2 commit d3fba6b02c9635d7c872370d1b953cdd6f1139f6 @fcuny fcuny committed Feb 6, 2012
View
@@ -1,5 +1,5 @@
import __future__
-from core import base
+from core import Spore
from errors import *
import os.path
@@ -12,7 +12,7 @@ def new_from_spec(spec_file, base_url=None):
def new_from_string(spec_string, base_url=None):
try:
- spore = base(spec_string=spec_string, base_url=base_url)
+ spore = Spore(spec_string=spec_string, base_url=base_url)
except Exception, e:
raise SpyreObjectBuilder(e)
return spore
View
@@ -1,17 +1,18 @@
import __future__
import json
-from spyre import errors
+import errors
+from httpclient import HTTPClient
from spyre.method import Method
-class base(object):
-
- authentication = None
- middlewares = []
- formats = []
+class Spore(object):
def __init__(self, spec_string=None, base_url=None):
+ self.authentication = None
+ self.middlewares = []
+ self.formats = []
self._methods = []
+ self.user_agent = HTTPClient()
if spec_string is not None:
try:
@@ -22,8 +23,9 @@ def __init__(self, spec_string=None, base_url=None):
self._init_meta(spec, base_url)
self._init_methods(spec)
- # XXX method to list available SPORE methods
- # XXX method to search for a given method
+ # TODO method to validate spec
+ # TODO method to list available SPORE methods
+ # TODO method to search for a given method
def _init_meta(self, spec, base_url=None):
self.name = spec['name'] # XXX see later what to do with this
@@ -49,9 +51,15 @@ def _init_methods(self, spec):
def _attach_method(self, method_name, method_desc):
try:
- new_method = Method(method_name, method_desc, self)
+ new_method = Method(
+ method_name,
+ method_desc,
+ base_url=self.base_url,
+ user_agent=self.user_agent,
+ middlewares=self.middlewares
+ )
except Exception, e:
- raise RuntimeError("foo") # XXX meh
+ raise RuntimeError(e) # XXX meh
setattr(self, method_name, new_method)
self._methods.append(method_name)
View
@@ -1,15 +1,26 @@
import __future__
import re
-from urlparse import urlparse
+from http import Url
from spyre import errors
from spyre.request import Request
class Method(object):
- def __init__(self, name, desc, spore_obj):
+
+ required_attr = ['method', 'path']
+ optional_attr = [
+ 'required_params',
+ 'optional_params',
+ 'expected_status',
+ ]
+
+ def __init__(self, name, desc, base_url, user_agent, middlewares=None):
self.name = name
- self.spore_obj = spore_obj
- self.middlewares = []
+ self.user_agent = user_agent
+
+ if middlewares is None:
+ middlewares = []
+ self.middlewares = middlewares
self.path = None
self.method = None
@@ -25,32 +36,52 @@ def __init__(self, name, desc, spore_obj):
self.optional_params = []
self.expected_status = []
- self.base_url = desc.get('base_url', self.spore_obj.base_url)
+ self.base_url = desc.get('base_url', base_url)
self._init_args(desc)
def _init_args(self, desc):
+ self._required_attributes(desc)
+ self._optional_attirbutes(desc)
- required_attr = ['method', 'path']
- optional_attr = [
- 'required_params',
- 'optional_params',
- 'expected_status',
- ]
-
- for attr in required_attr:
+ def _required_attributes(self, desc):
+ for attr in self.required_attr:
if attr not in desc:
raise errors.SpyreMethodBuilder(attr)
setattr(self, attr, desc[attr])
- for attr in optional_attr:
+ def _optional_attirbutes(self, desc):
+ for attr in self.optional_attr:
if attr in desc:
setattr(self, attr, desc[attr])
+ def _script_name(self, base_url):
+ if base_url.path == '/':
+ return ''
+ else:
+ return base_url.path
+
+ def _userinfo(self, base_url):
+ if base_url.username is not None:
+ return ('%s:%s' % (base_url.username, base_url.password))
+ else:
+ return None
+
+ def _port(self, base_url):
+ if base_url.port is not None:
+ return base_url.port
+
+ if base_url.scheme == 'http':
+ return 80
+ elif base_url.scheme == 'https':
+ return 443
+ else:
+ raise "houla"
+
def __call__(self, **kwargs):
if self.base_url is None:
- raise errors.SpyreMethodCall("meh")
+ raise errors.SpyreMethodCall("`base_url` is missing")
cb_response = []
@@ -60,31 +91,15 @@ def __call__(self, **kwargs):
auth = self._build_auth()
formats = self._build_formats()
- base_url = urlparse(self.base_url)
-
- if base_url.path == '/':
- script_name = ''
- else:
- script_name = base_url.path
+ base_url = Url(string_url=self.base_url)
- if base_url.username is not None:
- userinfo = ('%s:%s' % (base_url.username, base_url.password))
- else:
- userinfo = None
-
- if base_url.port is None:
- if base_url.scheme == 'http':
- port = 80
- elif base_url.scheme == 'https':
- port = 443
- else:
- raise "houla"
- else:
- port = base_url.port
+ script_name = self._script_name(base_url)
+ userinfo = self._userinfo(base_url)
+ port = self._port(base_url)
env = {
'REQUEST_METHOD': self.method,
- 'SERVER_NAME': base_url.hostname,
+ 'SERVER_NAME': base_url.netloc,
'SERVER_PORT': port,
'SCRIPT_NAME': script_name,
'PATH_INFO': self.path,
@@ -101,13 +116,15 @@ def __call__(self, **kwargs):
'spore.formats': formats,
}
- for mw in self.spore_obj.middlewares:
+ for mw in self.middlewares:
if mw[0](env):
cb = mw[1](env)
if cb:
cb_response.append(cb)
- http_response = Request(env).execute()
+ request = Request(env)
+ http_response = self.user_agent.request(request())
+ setattr(http_response, 'env', env)
if self.expected_status:
http_status = int(http_response.status)
@@ -131,6 +148,7 @@ def _build_parameters(self, kwargs):
stuff_remains = kset.difference(
self.required_params + self.optional_params)
+
if stuff_remains:
raise errors.SpyreMethodCall(stuff_remains)
@@ -12,4 +12,6 @@ def __call__(self, env):
return cb
def response_cb(self, response):
+ import inspect
+ print 'caller name:', inspect.stack()[1][3]
response.content = json.loads(response.content)
View
@@ -1,70 +1,59 @@
-import httplib2
-import urllib
+import http
import re
-from spyre.response import Response
from itertools import izip
-def _requestproperty(key, default=None):
-
- def fget(self):
- return self.env.get(key, default)
-
- def fset(self, value):
- self.env[key] = value
- return value
-
- return property(fget, fset)
-
-
class Request(object):
- port = _requestproperty('SERVER_PORT', 80)
- host = _requestproperty('SERVER_NAME', '')
- path = _requestproperty('PATH_INFO', '')
- scheme = _requestproperty('spore.url_scheme', 'http')
-
def __init__(self, env):
self.env = env
+ self.scheme = self.env.get('spore.url_scheme', 'http')
+ self.port = self.env.get('SERVER_PORT', '80')
+ self.path = self.env.get('PATH_INFO', '')
+ self.method = self.env.get('REQUEST_METHOD')
+ self._build_url()
- def execute(self):
- final_url = self._finalize()
- http_response = self._execute_http_request(final_url)
- return http_response
+ @property
+ def host(self):
+ host = self.env.get('HTTP_HOST', None)
+ if host is None:
+ host = self.env.get('SERVER_NAME', '')
+ return host
- def _finalize(self):
- self._expand()
- final_url = self.base()
- query_string = self.env.get('QUERY_STRING', None)
- if query_string is not None:
- final_url = "%s?%s" % (final_url, query_string)
- return final_url
+ @property
+ def uri_base(self):
+ return str(self.url)
@property
def script_name(self):
- script_name = self.env.get('SCRIPT_NAME', '')
- if script_name == '' and self._path_info_start_with_slash() is False:
+ script_name = self.env.get('SCRIPT_NAME', None)
+
+ if script_name is None or script_name == '':
script_name = '/'
return script_name
- @property
- def http_host(self):
- host = self.env.get('HTTP_HOST', None)
- if host is None:
- host = ("%s:%i" % (self.host, self.port))
- return host
-
- def base(self):
- final_url = ("%s://%s%s%s" % (self.scheme, self.http_host,
- urllib.quote(self.script_name, '/'), urllib.quote(self.path, '/')))
- return final_url
-
- def _path_info_start_with_slash(self):
- path_info = self.env.get('PATH_INFO', None)
- if path_info is not None and len(path_info) > 0 and path_info[0] == '/':
- return True
- else:
- return False
+ def __call__(self):
+ # XXX rework this part
+ self._expand()
+ self.url.path.append(self.path)
+ self._query_path()
+ # TODO headers etc
+ request = http.Request(self.method, str(self.url))
+ return request
+
+ def _build_url(self):
+ # TODO username password query params
+ self.url = http.Url(
+ scheme=self.scheme,
+ host=self.host,
+ port=self.port,
+ path=self.script_name,
+ )
+
+ def _query_path(self):
+ query_string = self.env.get('QUERY_STRING', None)
+ if query_string is not None:
+ self.url.query = query_string
def _expand(self):
params = self.env.get('spore.params', None)
@@ -73,33 +62,24 @@ def _expand(self):
return
path_info = self.path
- headers = self.env.get('spore.headers', None)
- form_data = self.env.get('spore.form_data', None)
+# headers = self.env.get('spore.headers', None)
+# form_data = self.env.get('spore.form_data', None)
query = []
- form = {}
- headers = []
+# form = {}
+# headers = []
for k, v in izip(params[::2], params[1::2]):
if path_info:
(path_info, changes) = re.subn(re.compile(":%s" % k), v, path_info)
if changes:
continue
- query.append("%s=%s" % (k,v))
+ query.append((k, v))
path_info = re.sub(":\w+", '', path_info)
self.path = path_info
+ # TODO check what can be moved to Uri
if query:
- self.env['QUERY_STRING'] = '&'.join(query)
-
- def _execute_http_request(self, final_url):
- h = httplib2.Http(disable_ssl_certificate_validation=True)
- headers, content = h.request(final_url, self.env.get('REQUEST_METHOD'))
-
- status = headers['status']
- del headers['status']
- http_response = Response(self.env, status, headers, content)
-
- return http_response
+ self.env['QUERY_STRING'] = query
Oops, something went wrong.

0 comments on commit d3fba6b

Please sign in to comment.