civisanalytics / civis-r

Civis API Client for R: https://civisanalytics.com/products/civis-platform/
Other
16 stars 12 forks source link

Adding project/report sharing utility code #212

Open crich011 opened 5 years ago

crich011 commented 5 years ago

I have utility code developed for a client engagement that pulls all of the reports from a given project (get_report_ids) and then shares those reports with a list of group ID's (share_list_of_reports).

I think the questions are: (1) is this code worth adding in its present function? and (2) does it generalize to anything nice?

This code may or may not generalize nicely. For example, I can think of an inelegant way to generalize one or both functions which involves catching exceptions, but a more sophisticated way of doing it currently escapes me.

patr1ckm commented 5 years ago

Sharing many objects with one or more users and groups seems like a great utility. I think it can be even used immediately for e.g. #198. What about the following interface?

share_objects(ids, object_type, users = NULL, groups = NULL)

We should also have error handling in case some users or groups cannot be shared on the items.

I think get_report_ids should be a generic fetcher of items from projects analogous to fetch_output and fetch_output_file_ids for working with scripts.

We could even write a read_civis generic for projects that uses these utilities to download items in the project automatically.

read_civis(civis_project(id), ...)
crich011 commented 5 years ago

I like the share_objects interface! So the idea here is a user provides one or more objects of a given type per call of share_objects?

Working on that error handling will be fun, since I've never actually had to build in good manual error handling before. Do you have strong preferences about how it should work? Just try and then catch the exception and surface as a warning to the user that the object doesn't exist or they don't have sufficient permissions (which, if memory serves, is close to or exactly what the API does currently, albeit as an error)?

And oh I really like the idea of fetch_project_objects (or whatever name you feel like calling it) as a generic function, because we have sufficient information from the projects_get to pick the appropriate sharing functions for a given object, right? Woah, that's fun.

patr1ckm commented 5 years ago

I like the share_objects interface! So the idea here is a user provides one or more objects of a given type per call of share_objects?

Yes!

Do you have strong preferences about how it should work?

Something like tryCatch(f(...), error = function(e) warning(e) e) where f is the sharing function. This turns an error into a warning, and then returns the error object. And yes, we want to return the API error object back to the user.

I'm thinking that the output should be a list list(users = ...., groups = ...). The item of each of these lists should be either the error or the output of the sharing api call.

because we have sufficient information from the projects_get to pick the appropriate sharing functions for a given object, right?

Yes, from the documentation it seems that projects_get returns what we need to know to pick the right sharing function! So fetch_project_objects should return a named vector of ids, with names being the object type from projects_get. Then we'll just have a mapping of these object names to the API functions that we can lookup.