Changeset 2564


Ignore:
Timestamp:
08/06/07 12:21:26 (12 years ago)
Author:
spascoe
Message:

Moved OWS parameter handling into the @operation decorator. Missing operation parameters are now trapped automatically.

Location:
TI05-delivery/ows_framework/trunk/ows_server/ows_server
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/csml_wms.py

    r2561 r2564  
    2626        'ExceptionFormat': make_domain(['text/xml']), 
    2727        } 
    28  
    29     _ows_versions = ['1.1.0'] 
    3028 
    3129    #_ows_constraints = { 
     
    5856    @operation 
    5957    @parameter('Format', possibleValues=['text/xml']) 
    60     @parameter('Service', possibleValues=['WMS']) 
     58    @parameter('Service', possibleValues=['WMS'], required=True) 
     59    @parameter('Version', possibleValues=['1.1.0']) 
    6160    def GetCapabilities(self, file, service=None, version=None): 
    6261        """ 
     
    6564 
    6665        """ 
    67  
    68         #!TODO: This error checking could be done automatically based on the method 
    69         #       decorators. 
    70         if service is None: 
    71             raise OWS_E.MissingParameterValue('SERVICE parameter not specified', 
    72                                               'SERVICE') 
    73         if service != 'WMS': 
    74             raise OWS_E.InvalidParameterValue('SERVICE parameter must be "WMS"', 
    75                                               'SERVICE') 
    76  
    77         #!TODO: Version negotiation could be done automatically 
    78         if version not in self._ows_versions: 
    79             raise OWS_E.InvalidParameterValue('VERSION parameter must be one of %s' 
    80                                               % ','.join(self._ows_versions), 
    81                                               'VERSION') 
    8266         
    8367        c.dataset = get_csml_doc(file) 
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/base.py

    r2529 r2564  
    3232        try: 
    3333            self._fix_ows_action(environ) 
    34             return WSGIController.__call__(self, environ, start_response)   
     34            return super(OwsController, self).__call__(environ, start_response) 
    3535        except OWS_E.OwsError, e: 
    3636            return render_response('exception_report', report=e.report, 
     
    5353        del self.ows_params['request'] 
    5454 
    55     def _get_method_args(self): 
    56         """Extends Controller._get_method_args to retrieve arguments 
    57         from the query string. 
     55### This should be handled by the decorators now. 
     56##     def _get_method_args(self): 
     57##         """Extends Controller._get_method_args to retrieve arguments 
     58##         from the query string. 
     59     
     60##         See the docstring for Controller._get_method_args for details. 
    5861 
    59         See the docstring for Controller._get_method_args for details. 
     62##         """ 
    6063 
    61         """ 
     64##         # Get the method arguments and add the query string arguments 
     65##         kargs = WSGIController._get_method_args(self) 
     66##         kargs.update(self.ows_params) 
    6267 
    63         # Get the method arguments and add the query string arguments 
    64         kargs = WSGIController._get_method_args(self) 
    65         kargs.update(self.ows_params) 
    66  
    67         return kargs 
     68##         return kargs 
    6869 
    6970    def _load_capabilities(self): 
  • TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/decorators.py

    r2561 r2564  
    1111 
    1212from ows_common.util import make_domain 
     13from ows_common.exceptions import *  
     14import inspect 
    1315 
    1416def operation(method): 
    1517    """ 
    16     A decorator which tags a method as a OWS operation. 
    17  
    18     """ 
    19     method._ows_name = method.__name__ 
    20  
    21     return method 
     18    A decorator which defines a method as a OWS operation. 
     19 
     20    The decorator assumes it is used in the context of an OwsController object with the 
     21    attribute self.ows_params available. 
     22 
     23 
     24    The method is wrapped in function that performs various OWS compatible checks: 
     25     1. Parameters from the request are checked against the methods _ows_parameters attribute 
     26        to ensure they conform to possibleValues.  Valid parameters are passed to the method 
     27        as arguments, invalid parameters trigger an exception. 
     28 
     29    @note: It would seem natural to implement this as a decorator class 
     30        but I can't make it work. 
     31 
     32    """ 
     33 
     34    argspec = inspect.getargspec(method) 
     35 
     36    def wrapper(self, **kw): 
     37        """ 
     38        This wrapper assumes invocation via GET with KVP encoding.  Future implementations 
     39        could detect POST and support XML encoding. 
     40 
     41        @param mself: The object of the method being called. 
     42        @param kw: All other keyword arguments are passed to the method. 
     43         
     44        """ 
     45 
     46        # Remove unwanted arguments from kw 
     47        if not argspec[2]: 
     48            kw2 = {} 
     49            for k, v in kw.iteritems(): 
     50                if k in argspec[0]: 
     51                    kw2[k] = v 
     52            kw = kw2 
     53                     
     54 
     55        # Add arguments to kw according to self._ows_parameters 
     56        for param in wrapper._ows_parameters: 
     57            try: 
     58                pl = param.lower() 
     59                kw[pl] = self.ows_params[pl] 
     60            except KeyError: 
     61                if param in wrapper._ows_required_parameters: 
     62                    raise MissingParameterValue('%s parameter is not specified' % param, 
     63                                                param) 
     64        return method(self, **kw) 
     65 
     66    # Propergate the OWS protocol attributes up to the wrapper 
     67    wrapper._ows_name = method.__name__ 
     68    wrapper._ows_parameters = getattr(method, '_ows_parameters', {}) 
     69    wrapper._ows_constraints = getattr(method, '_ows_constraints', {}) 
     70    wrapper._ows_required_parameters = getattr(method, '_ows_required_parameters', [])         
     71 
     72    return wrapper 
     73 
    2274 
    2375def parameter(name, value=None, possibleValues=None, 
    24               meaning=None, dataType=None, valuesUnit=None): 
     76              meaning=None, dataType=None, valuesUnit=None, required=False): 
    2577    """ 
    2678    A decorator to add a parameter to an operation. 
     
    3082    @param possibleValues: None or a list of allowed values or a 
    3183        PossibleValues instance. 
     84    @param required: A boolean that indicates whether to raise an exception if the parameter 
     85       is missing. 
    3286     
    3387    """ 
     
    3993                                                 dataType=dataType, 
    4094                                                 valuesUnit=valuesUnit) 
     95        method._ows_required_parameters = getattr(method, '_ows_required_parameters', []) 
     96        if required: 
     97            method._ows_required_parameters.append(name) 
     98             
    4199        return method 
    42100 
    43101    return d 
     102 
    44103 
    45104def constraint(name, value=None, possibleValues=None, 
     
    115174               domain.possibleValues.ALLOWED_VALUES 
    116175        assert domain.possibleValues.allowedValues == [1,2,3] 
     176 
     177 
     178class TestOperationDecorator(TestCase): 
     179    def setUp(self): 
     180        class Foo(object): 
     181            @operation 
     182            @parameter('Bar', required=True) 
     183            def MyOp(self, bar): 
     184                return bar+1 
     185 
     186        self.foo = Foo() 
     187 
     188    def testOwsProtocol(self): 
     189        # Check OWS protocol is adhered to 
     190        assert self.foo.MyOp._ows_name == 'MyOp' 
     191        assert self.foo.MyOp._ows_parameters.keys() == ['Bar'] 
     192        assert self.foo.MyOp._ows_constraints == {} 
     193        assert self.foo.MyOp._ows_required_parameters == ['Bar'] 
     194 
     195    def testCall(self): 
     196        self.foo.ows_params = {'bar': 2} 
     197        assert self.foo.MyOp() == 3 
     198 
     199    def testCallFail(self): 
     200        self.foo.ows_params = {'baz': 2} 
     201        self.assertRaises(MissingParameterValue, self.foo.MyOp) 
Note: See TracChangeset for help on using the changeset viewer.