Missing API functionality

In the 1.2 installation we used the http api to get a nice registrant data export:

“https:///indico/export/event//registrant/.json?detail=basic&”

In the new system these endpoints are not available anymore.

I now use the the new REST api endpoint:

https://<host>/api/events/<eventid>/registrants/%s' % r['registrant_id']

to get the data. But I had to patch the function to return all the registration form fields and the total price,
as these were missing in the new version.

But now the question: What’s the best way to fix this in a future proof way? Via plugin or via a new endpoint?

current patch looks like:
File: indico/modules/events/registration/util.py

 +def getdatatitle(regform, key):
 +    for i in regform.form_items:
 +        if i.id == key:
 +            return i.title
 +    return ''
 +
 +
 def build_registration_api_data(registration):
      registration_info = _build_base_registration_info(registration)
      registration_info['amount_paid'] = registration.price if registration.is_paid else 0
 +    registration_info['price'] = registration.price
      registration_info['registration_date'] = registration.submitted_dt.isoformat()
      registration_info['paid'] = registration.is_paid
      registration_info['checkin_date'] = registration.checked_in_dt.isoformat() if  registration.checked_in_dt else ''
      registration_info['event_id'] = registration.event_id
 +    data = registration.data_by_field
 +    registration_info['data'] = {}
 +    registration_info['datatitle'] = {}
 +    for key, item in data.iteritems():
 +        registration_info['data'][key] = item.friendly_data
 +        registration_info['datatitle'][key] = getdatatitle(registration.registration_form, key)
 +
     return registration_info

We intend to add a proper registration API at some point (future version) and, more important, merge the OAuth and APIKey authorization (currently that particular API only works with OAuth, which is probably not ideal for your use case. There’s this GitHub issue related to it:

For now, I would recommend you to add a classic API endpoint for this in a plugin (you can check the cern audiovisual plugin for an example how to register an API endpoint from a plugin - search for AVExportHook)

Regarding your code, I would not iterate over the data_by_field but rather do something like this:

from collections import defaultdict

reg_data = registration.data_by_field
data = defaultdict(dict)
for section in registration.sections_with_answered_fields:
    for field in section.active_fields:
        if field.id not in reg_data:
            continue
        data[section.title][field.title] = reg_data[field.id].friendly_data
registration_info['data']  = dict(data)

This will give you more structured data. Note that this assumes unique section and field titles. Use IDs instead of titles if you cannot guarantee this.

Thanks for the info. I’ll go the plugin way then. Flattening the data was intended in this case and titles may currently be non-unique.
But the code seems also usefull for the badge/ticket enhancements I am working on (there I also want full access to all registration fields, see the not yet finshed https://github.com/indico/indico/pull/3164)

OK, in that case iterate over registration.registration_form.form_items (all items, without nesting) or keep my nested iteration and just create the flat structure. Your code still has the problem of being close to O(n²) since you iterate over all fields for each item.

The plugin is now done and the tests seem fine.
You can find it on GitHub.

2 Likes

Just found this and though I’d ask here rather than starting a new thread (though I can if that’s preferred - let me know).

re ‘We intend to add a proper registration API at some point (future version)’ - do you mind me asking when is that likely to be?

The requirement I have is to be able to report on all events that people affiliated to ‘company X’ have registered on (past, present, and future).

I don’t think such a search would be possible even with a better API unless you intend to simply retrieve the list of registrations for all events and then do the checking using a custom script.

Anyway, there’s no ETA so far, so not in the short term I’m afraid. However, you could already use indico shell to retrieve this data (assuming some Python knowledge).

Thanks for the quick reply.

I’m happy retrieving structured data into javascript objects and then iterating over and manipulating the object to get what I want, so that’s an option if the data exists.

No python knowledge I’m afraid (though thinking I really should extend my knowledge…) - I’m mostly front-end only, hence interest in the http api.

So excuse my ignorance - is asking our devs to make me a plugin to get all events and registrations in a list a way forward?

Writing a plugin for it would indeed be the easiest option for now if you want something less hacky than running a snippet of python code in the indico shell.

Thanks again for the quick reply - I’ll go that route for now.