[ckan-dev] Conditional validation on custom Datasets

David Raznick david.raznick at okfn.org
Wed Mar 5 11:53:55 UTC 2014


On 5 March 2014 10:46, Richard Claydon <richard at icdw.co.uk> wrote:
> Hi David
>
> Thank you for replying, I understand now why the package is validated
> as well. I took your example but unfortunately when I call the
> resource_create in the manner you have, I get a recursion error. CKAN
> will warn that I am calling the logic action direct...

hmm we do this is may extensions and am confused as to why there is a
recursion error (I think there would be one if you use get_action to
call the action function)  Could you give the traceback of the few
lines where the recursion is.

>
>             def warn(context, data_dict):
>                 log.critical('Action `%s` is being called directly '
>                              'all action calls should be accessed via '
>                              'logic.get_action' % action_name)
>

I think this can be safely ignored in this case, not sure why we added
this warning as your use case is fairly common (tweaking the odd
action function).



> ... and then proceed to call my_resource_create anyway.
>
> I can put the core CKAN resource_create code in mine, which isn't
> ideal. Do you know if there's any interface like IAction (or if
> IAction does it too) that allows me to chain logic calls instead of
> overriding?

No sadly not as not all action functions are chainable in a sane way.
The idea was to be able to wrap them like above.  We are planning
though of having a before_action and after_action hooks so you can
modify the data_dict or context before or after any logic call but
sadly that did not make it in the release.

>
> If I work something out, I'll update here.
>
> Thanks
> Richard
>
> On 4 March 2014 14:08, David Raznick <david.raznick at okfn.org> wrote:
>> Hello
>>
>> The reason that it is validated here is that people can write
>> validators than depend on both resource and dataset data at the same
>> time.  i.e a validator that states then can be no more than 4
>> resources in a dataset.
>> So all the package data has to be validated together or we could break
>> people code.
>>
>>
>> For this case I think you will have to use an IAction extension point
>> to override resource_create.  It is recommended you call the original
>> function from your overriden one like this:
>>
>> https://github.com/okfn/ckanext-ecportal/blob/master/ckanext/ecportal/logic.py#L401
>>
>> Your case looks difficult though and you may have to override the
>> whole function.  You "could" just call the original and catch the
>> KeyError but that is clearly not nice.  Or you can put in the context
>> a new lenient schema for this case.  A schema in the context. i.e
>> context['schema'] = {new schema}  will override your defined
>> package_update one making sure no errors could ever happen in the
>> package_update.
>>
>> So your code would look somehting like
>>
>> import ckan.logic as logic
>>
>> def my_resource_create(context, data_dict):
>>     context['schema'] = new_lenient_schema
>>     return logic.action.create.resource_create(context, data_dict)
>>
>> class YourPlugin(p.SingletonPlugin):
>>     p.implements(p.IActions)
>>
>>     def get_actions(self):
>>         return {
>>             'resource_create': my_resource_create,
>>         }
>>
>>
>> Hope that helps
>>
>> David
>>
>> On 4 March 2014 12:39, Richard Claydon <richard at icdw.co.uk> wrote:
>>> Hi
>>>
>>> I have a requirement to not validate custom data on a package when a
>>> package is created, only to validate when the package is updated. I
>>> have achieved this by creating a custom form derived from
>>> DefaultDatasetForm, adding the relevant rules in
>>> create_package_schema() and update_package_schema().
>>>
>>> So far so good.
>>>
>>> The problem I am currently facing is, when I add a resource, the
>>> package is validated because the package_update action is called
>>> within the resource_create function inside actions/create.py.
>>> Unfortunately the exception handler in resource_create assumes the
>>> problem is with the resources and an unhandled KeyError exception is
>>> thrown. Here is the code in CKAN.
>>>
>>>     try:
>>>         context['defer_commit'] = True
>>>         context['use_cache'] = False
>>>         _get_action('package_update')(context, pkg_dict)
>>>         context.pop('defer_commit')
>>>     except ValidationError, e:
>>>         errors = e.error_dict['resources'][-1] # <--- assumes
>>> validation error is in the resource.
>>>         raise ValidationError(errors)
>>>
>>> My question is; can anyone suggest how I can suppress package
>>> validation when a resource is added? Resource validation is fine, but
>>> the "new_resource" view in CKAN by default does not include the rest
>>> of the package data, so IMO that shouldn't be validated here.
>>>
>>> I would like to try and avoid overriding core code if possible.
>>>
>>> Open to suggestions!
>>>
>>> Thanks
>>> Richard
>>> _______________________________________________
>>> ckan-dev mailing list
>>> ckan-dev at lists.okfn.org
>>> https://lists.okfn.org/mailman/listinfo/ckan-dev
>>> Unsubscribe: https://lists.okfn.org/mailman/options/ckan-dev
>> _______________________________________________
>> ckan-dev mailing list
>> ckan-dev at lists.okfn.org
>> https://lists.okfn.org/mailman/listinfo/ckan-dev
>> Unsubscribe: https://lists.okfn.org/mailman/options/ckan-dev
> _______________________________________________
> ckan-dev mailing list
> ckan-dev at lists.okfn.org
> https://lists.okfn.org/mailman/listinfo/ckan-dev
> Unsubscribe: https://lists.okfn.org/mailman/options/ckan-dev



More information about the ckan-dev mailing list