[ckan-dev] Conditional validation on custom Datasets
Richard Claydon
richard at icdw.co.uk
Wed Mar 5 16:52:09 UTC 2014
Hi
before_action and after_action hooks would have been ideal for this
situation, that's a shame it didn't make the release. Do you know when
they are likely to be included?
For what it's worth, I am using v2.2 2014-02-04.
Here is the traceback you requested:
File '/vagrant/src/ckan/ckan/controllers/package.py', line 672 in new_resource
get_action('resource_create')(context, data)
File '/vagrant/src/ckan/ckan/logic/__init__.py', line 419 in wrapped
result = _action(context, data_dict, **kw)
File '/vagrant/src/ckanext-feeder/ckanext/feeder/plugin.py', line 44
in feeder_resource_create
return logic.action.create.resource_create(context, data_dict)
File '/vagrant/src/ckan/ckan/logic/__init__.py', line 456 in warn
return get_action(action_name)(context, data_dict)
File '/vagrant/src/ckan/ckan/logic/__init__.py', line 419 in wrapped
result = _action(context, data_dict, **kw)
Then it repeats. The code is as you suggested:
def feeder_resource_create(context, data_dict):
import ckan.logic as logic
context['schema'] = FeederForm().create_package_schema()
return logic.action.create.resource_create(context, data_dict)
Where FeederForm is defined as
class FeederForm(SingletonPlugin, tk.DefaultDatasetForm):
implements(IDatasetForm, inherit=False)
Thanks
Richard
On 5 March 2014 11:53, David Raznick <david.raznick at okfn.org> wrote:
> 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
> _______________________________________________
> 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