[Kimchi-devel] [PATCHv7 1/8] Support params for GET method

Mark Wu wudxw at linux.vnet.ibm.com
Thu Jan 16 09:25:58 UTC 2014


On 01/14/2014 11:47 PM, lvroyce0210 at gmail.com wrote:
> From: Royce Lv <lvroyce at linux.vnet.ibm.com>
>
> Add support for passing params for GET method,
> This include add param to get_list method,
> and filter the result with given params.
> we will call it like:
>      GET /collection?filter_field=value
> With current implementation with a wrapper,
> we can easily support any collection query with param.
>
> Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
> ---
>   src/kimchi/control/base.py           | 28 ++++++++++++++++++++--------
>   src/kimchi/control/storagepools.py   |  4 ++--
>   src/kimchi/control/storagevolumes.py |  2 +-
>   src/kimchi/control/utils.py          |  2 ++
>   4 files changed, 25 insertions(+), 11 deletions(-)
>
> diff --git a/src/kimchi/control/base.py b/src/kimchi/control/base.py
> index 185c8d8..a477abb 100644
> --- a/src/kimchi/control/base.py
> +++ b/src/kimchi/control/base.py
> @@ -28,7 +28,7 @@ import urllib2
>
>   import kimchi.template
>   from kimchi.control.utils import get_class_name, internal_redirect, model_fn
> -from kimchi.control.utils import parse_request, validate_method
> +from kimchi.control.utils import parse_request, parse_param, validate_method
>   from kimchi.control.utils import validate_params
>   from kimchi.exception import InvalidOperation, InvalidParameter
>   from kimchi.exception import MissingParameter, NotFoundError,  OperationFailed
> @@ -212,10 +212,10 @@ class Collection(object):
>
>           return res.get()
>
> -    def _get_resources(self):
> +    def _get_resources(self, filter_params):
>           try:
>               get_list = getattr(self.model, model_fn(self, 'get_list'))
> -            idents = get_list(*self.model_args)
> +            idents = get_list(*self.model_args, **filter_params)
For the methods doesn't support filter params,  it will break if add a 
param in url.
>               res_list = []
>               for ident in idents:
>                   # internal text, get_list changes ident to unicode for sorted
> @@ -234,19 +234,31 @@ class Collection(object):
>               args = self.resource_args + [ident.decode("utf-8")]
>               return self.resource(self.model, *args)
>
> -    def get(self):
> -        resources = self._get_resources()
> +    def filter_data(self, resources, filter_params):
>           data = []
>           for res in resources:
> -            data.append(res.data)
> +            valid = True
> +            for key, val in filter_params.items():
> +                if key in res.data and res.data[key] != val:
> +                    valid = False
> +                    break
> +            if valid:
                       if all(key in res.data and res.data[key] == val  
for key, val in filter_params.iteritems()):
                            data.append(res.data)

> +                data.append(res.data)
> +        return data

or  return  [res.data for res in resources
                   if all(key in res.data and res.data[key] == val for 
key, val in filter_params.iteritems())]

:)
> +
> +    def get(self, filter_params):
> +        resources = self._get_resources(filter_params)
> +        data = self.filter_data(resources, filter_params)
I guess there're two kinds of filter parameters in your mind: one takes 
effect during model's get_list method while the other works based the 
return value from model.   So please make those two params explicit and 
ensure one param only can take effect in one place.
>           return kimchi.template.render(get_class_name(self), data)
>
>       @cherrypy.expose
> -    def index(self, *args):
> +    def index(self, *args, **kwargs):
>           method = validate_method(('GET', 'POST'))
>           if method == 'GET':
>               try:
> -                return self.get()
> +                filter_params = parse_param()
> +                validate_params(filter_params, self, 'get_list')
> +                return self.get(filter_params)
>               except InvalidOperation, param:
>                   error = "Invalid operation: '%s'" % param
>                   raise cherrypy.HTTPError(400, error)
> diff --git a/src/kimchi/control/storagepools.py b/src/kimchi/control/storagepools.py
> index 782f5a6..e3236a7 100644
> --- a/src/kimchi/control/storagepools.py
> +++ b/src/kimchi/control/storagepools.py
> @@ -63,9 +63,9 @@ class StoragePools(Collection):
>
>           return resp
>
> -    def _get_resources(self):
> +    def _get_resources(self, filter_params):
>           try:
> -            res_list = super(StoragePools, self)._get_resources()
> +            res_list = super(StoragePools, self)._get_resources(filter_params)
>               # Append reserved pools
>               isos = getattr(self, ISO_POOL_NAME)
>               isos.lookup()
> diff --git a/src/kimchi/control/storagevolumes.py b/src/kimchi/control/storagevolumes.py
> index d541807..cd15bcc 100644
> --- a/src/kimchi/control/storagevolumes.py
> +++ b/src/kimchi/control/storagevolumes.py
> @@ -70,7 +70,7 @@ class IsoVolumes(Collection):
>           super(IsoVolumes, self).__init__(model)
>           self.pool = pool
>
> -    def get(self):
> +    def get(self, filter_params):
>           res_list = []
>           try:
>               get_list = getattr(self.model, model_fn(self, 'get_list'))
> diff --git a/src/kimchi/control/utils.py b/src/kimchi/control/utils.py
> index c3c5f8e..4b3c4b0 100644
> --- a/src/kimchi/control/utils.py
> +++ b/src/kimchi/control/utils.py
> @@ -81,6 +81,8 @@ def parse_request():
>           raise cherrypy.HTTPError(415, "This API only supports"
>                                         " 'application/json'")
>
> +def parse_param():
> +    return cherrypy.request.params
It's not a good function name for me,  because you didn't do any parsing 
in it.  get_query_params or
just use cherrypy.request.params?
>
>   def internal_redirect(url):
>       raise cherrypy.InternalRedirect(url.encode("utf-8"))




More information about the Kimchi-devel mailing list