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'):
|
||||
yield path, a._wsme_definition
|
||||
else:
|
||||
if len(path) < 10:
|
||||
print path
|
||||
for i in scan_api(a, path + [name]):
|
||||
yield i
|
||||
|
||||
@ -70,7 +68,6 @@ class validate(object):
|
||||
def __call__(self, func):
|
||||
fd = FunctionDefinition.get(func)
|
||||
args, varargs, keywords, defaults = inspect.getargspec(func)
|
||||
print args, defaults
|
||||
if args[0] == 'self':
|
||||
args = args[1:]
|
||||
for i, argname in enumerate(args):
|
||||
@ -79,7 +76,6 @@ class validate(object):
|
||||
default = None
|
||||
if not mandatory:
|
||||
default = defaults[i - (len(args) - len(defaults))]
|
||||
print argname, datatype, mandatory, default
|
||||
fd.arguments.append(FunctionArgument(argname, datatype,
|
||||
mandatory, default))
|
||||
return func
|
||||
|
@ -28,7 +28,8 @@ class MissingArgument(ClientSideError):
|
||||
self.msg = msg
|
||||
|
||||
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):
|
||||
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
|
||||
|
||||
html_body = """
|
||||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
%(content)s
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
class RestProtocol(object):
|
||||
name = None
|
||||
@ -17,8 +27,10 @@ class RestProtocol(object):
|
||||
def handle(self, root, request):
|
||||
path = request.path.strip('/').split('/')
|
||||
|
||||
if path[-1].endswith('.' + self.dataformat):
|
||||
path[-1] = path[-1][:-len(self.dataformat) - 1]
|
||||
|
||||
res = webob.Response()
|
||||
res.headers['Content-Type'] = self.content_types[0]
|
||||
|
||||
try:
|
||||
func, funcdef = root._lookup_function(path)
|
||||
@ -28,8 +40,30 @@ class RestProtocol(object):
|
||||
res.body = self.encode_result(result, funcdef.return_type)
|
||||
res.status = "200 OK"
|
||||
except Exception, e:
|
||||
res.status = "500 Error"
|
||||
res.status = 500
|
||||
res.charset = 'utf8'
|
||||
res.body = self.encode_error(
|
||||
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
|
||||
|
@ -90,7 +90,7 @@ def binary_fromjson(datatype, value):
|
||||
class RestJsonProtocol(RestProtocol):
|
||||
name = 'REST+Json'
|
||||
dataformat = 'json'
|
||||
content_types = ['application/json', 'text/json', None]
|
||||
content_types = ['application/json', 'text/json', '', None]
|
||||
|
||||
def decode_args(self, req, arguments):
|
||||
raw_args = json.loads(req.body)
|
||||
|
@ -10,6 +10,7 @@ from simplegeneric import generic
|
||||
|
||||
from wsme.rest import RestProtocol
|
||||
from wsme.controller import register_protocol
|
||||
from wsme.exc import *
|
||||
import wsme.types
|
||||
|
||||
import re
|
||||
@ -116,8 +117,17 @@ class RestXmlProtocol(RestProtocol):
|
||||
content_types = ['text/xml']
|
||||
|
||||
def decode_args(self, req, arguments):
|
||||
el = et.fromstring(req.body)
|
||||
assert el.tag == 'parameters'
|
||||
if req.body:
|
||||
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 = {}
|
||||
for farg in arguments:
|
||||
sub = el.find(farg.name)
|
||||
|
@ -6,6 +6,7 @@ except:
|
||||
|
||||
import wsme.restjson
|
||||
|
||||
|
||||
class TestRestJson(wsme.tests.protocol.ProtocolTestCase):
|
||||
protocol = 'REST+Json'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user