Commit 31c6946f authored by Jacek Furmankiewicz's avatar Jacek Furmankiewicz

formencode validators - WIP

parent 860de26f
...@@ -19,7 +19,7 @@ class RequestRouter: ...@@ -19,7 +19,7 @@ class RequestRouter:
__urlRegexReplace = {"":r"(?P<arg>.+)","int":r"(?P<arg>\d+)","float":r"(?P<arg>\d+.?\d*)"} __urlRegexReplace = {"":r"(?P<arg>.+)","int":r"(?P<arg>\d+)","float":r"(?P<arg>\d+.?\d*)"}
__typeConverters = {"int":int,"float":float} __typeConverters = {"int":int,"float":float}
def __init__(self,f,url,method,accepts,produces,cache): def __init__(self,f,url,method,accepts,produces,cache, schema):
self.__url = url self.__url = url
self.__method = method self.__method = method
self.__accepts = accepts self.__accepts = accepts
...@@ -27,6 +27,7 @@ class RequestRouter: ...@@ -27,6 +27,7 @@ class RequestRouter:
self.__cache = cache self.__cache = cache
self.__f = f self.__f = f
self.__argConverters = {} # dict of arg names -> group index self.__argConverters = {} # dict of arg names -> group index
self.__schema = schema
#parse URL into regex used for matching #parse URL into regex used for matching
m = RequestRouter.__urlMatcher.findall(url) m = RequestRouter.__urlMatcher.findall(url)
...@@ -51,6 +52,11 @@ class RequestRouter: ...@@ -51,6 +52,11 @@ class RequestRouter:
"""Indicates if this URL should be cached or not""" """Indicates if this URL should be cached or not"""
return self.__cache return self.__cache
@property
def schema(self):
"""Returns the formencode Schema, if this URL uses custom validation schema"""
return self.__schema
def getArguments(self,url): def getArguments(self,url):
""" """
Returns None if nothing matched (i.e. URL does not match), empty dict if no args found (i,e, static URL) Returns None if nothing matched (i.e. URL does not match), empty dict if no args found (i,e, static URL)
...@@ -96,7 +102,7 @@ class CorePost(Resource): ...@@ -96,7 +102,7 @@ class CorePost(Resource):
''' '''
isLeaf = True isLeaf = True
def __init__(self,path=''): def __init__(self,path='',schema=None):
''' '''
Constructor Constructor
''' '''
...@@ -105,26 +111,27 @@ class CorePost(Resource): ...@@ -105,26 +111,27 @@ class CorePost(Resource):
self.__cachedUrls = defaultdict(dict) self.__cachedUrls = defaultdict(dict)
self.__methods = {} self.__methods = {}
self.__path = path self.__path = path
self.__schema = schema
@property @property
def path(self): def path(self):
return self.__path return self.__path
def __registerFunction(self,f,url,methods,accepts,produces,cache): def __registerFunction(self,f,url,methods,accepts,produces,cache,schema):
if f not in self.__methods.values(): if f not in self.__methods.values():
if not isinstance(methods,(list,tuple)): if not isinstance(methods,(list,tuple)):
methods = (methods,) methods = (methods,)
for method in methods: for method in methods:
rq = RequestRouter(f, url, method, accepts, produces,cache) rq = RequestRouter(f, url, method, accepts, produces,cache,schema)
self.__urls[method][url] = rq self.__urls[method][url] = rq
self.__methods[url] = f self.__methods[url] = f
def route(self,url,methods=(Http.GET,),accepts=MediaType.WILDCARD,produces=None,cache=True): def route(self,url,methods=(Http.GET,),accepts=MediaType.WILDCARD,produces=None,cache=True, schema=None):
"""Main decorator for registering REST functions """ """Main decorator for registering REST functions """
def wrap(f): def wrap(f):
self.__registerFunction(f, url, methods, accepts, produces,cache) self.__registerFunction(f, url, methods, accepts, produces,cache, schema)
return f return f
return wrap return wrap
...@@ -180,8 +187,10 @@ class CorePost(Resource): ...@@ -180,8 +187,10 @@ class CorePost(Resource):
# if POST/PUT, check if we need to automatically parse JSON # if POST/PUT, check if we need to automatically parse JSON
# TODO # TODO
#handle Deferreds natively #validate input against formencode schema if defined
self.__validateArguments(urlrouter, request, allargs)
#handle Deferreds natively
val = urlrouter.call(request,**allargs) val = urlrouter.call(request,**allargs)
if isinstance(val,defer.Deferred): if isinstance(val,defer.Deferred):
# we assume the method will call request.finish() # we assume the method will call request.finish()
...@@ -192,6 +201,13 @@ class CorePost(Resource): ...@@ -192,6 +201,13 @@ class CorePost(Resource):
else: else:
return self.__renderError(request,404,"URL '%s' not found\n" % request.path) return self.__renderError(request,404,"URL '%s' not found\n" % request.path)
def __validateArguments(self,urlrouter,request,allargs):
schema = urlrouter.schema if urlrouter.schema != None else self.__schema
if schema != None:
from formencode import Schema
def __renderError(self,request,code,message): def __renderError(self,request,code,message):
"""Common method for rendering errors""" """Common method for rendering errors"""
request.setResponseCode(code) request.setResponseCode(code)
......
...@@ -39,16 +39,13 @@ Links ...@@ -39,16 +39,13 @@ Links
import os import os
from setuptools import setup from setuptools import setup
import markdown
# Utility function to read the README file. # Utility function to read the README file.
# Used for the long_description. It's nice, because now 1) we have a top level # Used for the long_description. It's nice, because now 1) we have a top level
# README file and 2) it's easier to type in the README file than to put a raw # README file and 2) it's easier to type in the README file than to put a raw
# string in below ... # string in below ...
def read(fname): def read(fname):
md = open(os.path.join(os.path.dirname(__file__), fname)).read() return open(os.path.join(os.path.dirname(__file__), fname)).read()
return md
#return "<html>%s<html>" % markdown.markdown(md)
setup( setup(
name="CorePost", name="CorePost",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment