Add a small demo, and fix a few problems
This commit is contained in:
parent
d77a4ef8a0
commit
585c6d703f
7
examples/demo/demo.cfg
Normal file
7
examples/demo/demo.cfg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[app:main]
|
||||||
|
paste.app_factory = demo:app_factory
|
||||||
|
|
||||||
|
[server:main]
|
||||||
|
use = egg:PasteScript#wsgiutils
|
||||||
|
host = 127.0.0.1
|
||||||
|
port = 8989
|
16
examples/demo/demo.py
Normal file
16
examples/demo/demo.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from webob.dec import wsgify
|
||||||
|
from wsme import *
|
||||||
|
|
||||||
|
import wsme.restjson
|
||||||
|
import wsme.restxml
|
||||||
|
|
||||||
|
|
||||||
|
class DemoRoot(WSRoot):
|
||||||
|
@expose(int)
|
||||||
|
@validate(int, int)
|
||||||
|
def multiply(self, a, b):
|
||||||
|
return a * b
|
||||||
|
|
||||||
|
|
||||||
|
def app_factory(global_config, **local_conf):
|
||||||
|
return wsgify(DemoRoot()._handle_request)
|
10
examples/demo/setup.py
Normal file
10
examples/demo/setup.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
setup(name='demo',
|
||||||
|
install_requires=[
|
||||||
|
'wsme',
|
||||||
|
'PasteScript',
|
||||||
|
'PasteDeploy',
|
||||||
|
'WSGIUtils',
|
||||||
|
],
|
||||||
|
package=['demo'])
|
@ -18,8 +18,6 @@ def scan_api(controller, path=[]):
|
|||||||
if hasattr(a, '_wsme_definition'):
|
if hasattr(a, '_wsme_definition'):
|
||||||
yield path, a._wsme_definition
|
yield path, a._wsme_definition
|
||||||
else:
|
else:
|
||||||
if len(path) < 10:
|
|
||||||
print path
|
|
||||||
for i in scan_api(a, path + [name]):
|
for i in scan_api(a, path + [name]):
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
@ -70,7 +68,6 @@ class validate(object):
|
|||||||
def __call__(self, func):
|
def __call__(self, func):
|
||||||
fd = FunctionDefinition.get(func)
|
fd = FunctionDefinition.get(func)
|
||||||
args, varargs, keywords, defaults = inspect.getargspec(func)
|
args, varargs, keywords, defaults = inspect.getargspec(func)
|
||||||
print args, defaults
|
|
||||||
if args[0] == 'self':
|
if args[0] == 'self':
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
for i, argname in enumerate(args):
|
for i, argname in enumerate(args):
|
||||||
@ -79,7 +76,6 @@ class validate(object):
|
|||||||
default = None
|
default = None
|
||||||
if not mandatory:
|
if not mandatory:
|
||||||
default = defaults[i - (len(args) - len(defaults))]
|
default = defaults[i - (len(args) - len(defaults))]
|
||||||
print argname, datatype, mandatory, default
|
|
||||||
fd.arguments.append(FunctionArgument(argname, datatype,
|
fd.arguments.append(FunctionArgument(argname, datatype,
|
||||||
mandatory, default))
|
mandatory, default))
|
||||||
return func
|
return func
|
||||||
|
@ -28,7 +28,8 @@ class MissingArgument(ClientSideError):
|
|||||||
self.msg = msg
|
self.msg = msg
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return _(u"Missing argument: %s. %s") % (self.argname, self.msg)
|
return _(u'Missing argument: "%s"%s') % (
|
||||||
|
self.argname, self.msg and ": " + self.msg or "")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return unicode(self).encode('utf8', 'ignore')
|
return unicode(self).encode('utf8', 'ignore')
|
||||||
|
38
wsme/rest.py
38
wsme/rest.py
@ -3,6 +3,16 @@ import sys
|
|||||||
|
|
||||||
from wsme.exc import UnknownFunction
|
from wsme.exc import UnknownFunction
|
||||||
|
|
||||||
|
html_body = """
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<pre>
|
||||||
|
%(content)s
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class RestProtocol(object):
|
class RestProtocol(object):
|
||||||
name = None
|
name = None
|
||||||
@ -17,8 +27,10 @@ class RestProtocol(object):
|
|||||||
def handle(self, root, request):
|
def handle(self, root, request):
|
||||||
path = request.path.strip('/').split('/')
|
path = request.path.strip('/').split('/')
|
||||||
|
|
||||||
|
if path[-1].endswith('.' + self.dataformat):
|
||||||
|
path[-1] = path[-1][:-len(self.dataformat) - 1]
|
||||||
|
|
||||||
res = webob.Response()
|
res = webob.Response()
|
||||||
res.headers['Content-Type'] = self.content_types[0]
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
func, funcdef = root._lookup_function(path)
|
func, funcdef = root._lookup_function(path)
|
||||||
@ -28,8 +40,30 @@ class RestProtocol(object):
|
|||||||
res.body = self.encode_result(result, funcdef.return_type)
|
res.body = self.encode_result(result, funcdef.return_type)
|
||||||
res.status = "200 OK"
|
res.status = "200 OK"
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
res.status = "500 Error"
|
res.status = 500
|
||||||
|
res.charset = 'utf8'
|
||||||
res.body = self.encode_error(
|
res.body = self.encode_error(
|
||||||
root._format_exception(sys.exc_info()))
|
root._format_exception(sys.exc_info()))
|
||||||
|
|
||||||
|
# Attempt to correctly guess what content-type we should return.
|
||||||
|
res_content_type = None
|
||||||
|
|
||||||
|
last_q = 0
|
||||||
|
if hasattr(request.accept, '_parsed'):
|
||||||
|
for mimetype, q in request.accept._parsed:
|
||||||
|
if mimetype in self.content_types and last_q < q:
|
||||||
|
res_content_type = mimetype
|
||||||
|
else:
|
||||||
|
res_content_type = request.accept.best_match([
|
||||||
|
ct for ct in self.content_types if ct])
|
||||||
|
|
||||||
|
# If not we will attempt to convert the body to an accepted
|
||||||
|
# output format.
|
||||||
|
if res_content_type is None:
|
||||||
|
if "text/html" in request.accept:
|
||||||
|
res_content_type = "text/html"
|
||||||
|
res.body = html_body % dict(content=res.body)
|
||||||
|
|
||||||
|
res.headers['Content-Type'] = res_content_type
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
@ -90,7 +90,7 @@ def binary_fromjson(datatype, value):
|
|||||||
class RestJsonProtocol(RestProtocol):
|
class RestJsonProtocol(RestProtocol):
|
||||||
name = 'REST+Json'
|
name = 'REST+Json'
|
||||||
dataformat = 'json'
|
dataformat = 'json'
|
||||||
content_types = ['application/json', 'text/json', None]
|
content_types = ['application/json', 'text/json', '', None]
|
||||||
|
|
||||||
def decode_args(self, req, arguments):
|
def decode_args(self, req, arguments):
|
||||||
raw_args = json.loads(req.body)
|
raw_args = json.loads(req.body)
|
||||||
|
@ -10,6 +10,7 @@ from simplegeneric import generic
|
|||||||
|
|
||||||
from wsme.rest import RestProtocol
|
from wsme.rest import RestProtocol
|
||||||
from wsme.controller import register_protocol
|
from wsme.controller import register_protocol
|
||||||
|
from wsme.exc import *
|
||||||
import wsme.types
|
import wsme.types
|
||||||
|
|
||||||
import re
|
import re
|
||||||
@ -116,8 +117,17 @@ class RestXmlProtocol(RestProtocol):
|
|||||||
content_types = ['text/xml']
|
content_types = ['text/xml']
|
||||||
|
|
||||||
def decode_args(self, req, arguments):
|
def decode_args(self, req, arguments):
|
||||||
el = et.fromstring(req.body)
|
if req.body:
|
||||||
assert el.tag == 'parameters'
|
try:
|
||||||
|
el = et.fromstring(req.body)
|
||||||
|
except Exception, e:
|
||||||
|
raise ClientSideError(str(e))
|
||||||
|
else:
|
||||||
|
el = et.Element('parameters')
|
||||||
|
|
||||||
|
if el.tag != 'parameters':
|
||||||
|
raise ClientSideError("Input should be a 'parameters' xml tag")
|
||||||
|
|
||||||
kw = {}
|
kw = {}
|
||||||
for farg in arguments:
|
for farg in arguments:
|
||||||
sub = el.find(farg.name)
|
sub = el.find(farg.name)
|
||||||
|
@ -6,6 +6,7 @@ except:
|
|||||||
|
|
||||||
import wsme.restjson
|
import wsme.restjson
|
||||||
|
|
||||||
|
|
||||||
class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
|
class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
|
||||||
protocol = 'REST+Json'
|
protocol = 'REST+Json'
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user