-
Notifications
You must be signed in to change notification settings - Fork 220
Metadata template endpoints #353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…template_endpoints
|
Verified that @mattwiller has signed the CLA. Thanks for the pull request! |
Pull Request Test Coverage Report for Build 1308
💛 - Coveralls |
boxsdk/util/translator.py
Outdated
| `bool` | ||
| """ | ||
|
|
||
| return 'displayName' in obj and obj['type'] != 'metadata_template' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pretty ugly hack, and could easily break in the future, if the API ever returns another object with displayName as a field.
Perhaps we could solve this issue a different way.
- Add an optional
parentobject parameter to the translate method so that it could determine if the parent is ametadata_template. - Add blacklist fields to object classes. When we come across a
metadata_template, perhaps we know not to translate itsfields.
boxsdk/util/translator.py
Outdated
| :return: | ||
| """ | ||
| if obj.get('type', '') == 'event': | ||
| obj_type = obj.get('type') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic probably belongs in object classes. I know this method isn't new as of this review, but it's becoming more obvious that this is the wrong place for this logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. Once we know the type, we can call a staticmethod on the class to get the ID.
But I hate that we have to do this. As I said below, I think we can get rid of the event_id lookup, because we end up throwing it away anyway.
That leaves only metadata_template which requires this logic. And I wish they would standardize all of their APIs around PKs instead of scope/template. Can we at least, in the SDK, standardize around PK?
|
@Jeff-Meadows I added the field exclusion mechanism so object classes can specify which fields should not be translated. I wasn't certain how we might want to decentralize the logic for finding an ID, so I left it in the translator for now. |
| ) | ||
|
|
||
| @api_call | ||
| def create_metadata_template(self, display_name, fields, template_key=None, hidden=False, scope='enterprise'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personal taste, I feel like scope should come before the other optional parameters.
scope is logically the most important part of this operation. And in the APIs, scope always proceeds templateKey.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind moving it, but I put it last since at this time only enterprise scope templates can be created. Nobody calling this method today (and likely for the near future) will be setting that parameter, whereas they will likely want to set the others.
boxsdk/util/translator.py
Outdated
| :return: | ||
| """ | ||
| if obj.get('type', '') == 'event': | ||
| obj_type = obj.get('type') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. Once we know the type, we can call a staticmethod on the class to get the ID.
But I hate that we have to do this. As I said below, I think we can get rid of the event_id lookup, because we end up throwing it away anyway.
That leaves only metadata_template which requires this logic. And I wish they would standardize all of their APIs around PKs instead of scope/template. Can we at least, in the SDK, standardize around PK?
boxsdk/client/client.py
Outdated
| """ | ||
| return self.translator.get('metadata_template')( | ||
| session=self._session, | ||
| object_id='{0}/{1}'.format(scope, template_key), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't like doing this.
Can we flip things around here?
object_idis always the primary keyid. For thetemplate_idconstructor, we pass it in as-is, without any GET requests.- For the
scope, template_keyconstructor, we do the GET call in order to get theid. And we also pass theresponse_object, so that we keep thescopeandtemplate_keyaround. Also, we pass in an extra boolean flag (which is normally defaulted toFalse, but we would passTruehere) specifying that the client wants to use the scope/templateKey, not the ID. - For APIs that only work with scope/templateKey, always use scope/templateKey
- For APIs that work with either id or scope/templateKey, default to using
id. But usescope/templateKeyif that optional boolean was set toTrue, indicating that scope/templateKey is the desired client behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this more, I feel even more strongly that we should make this change.
I think the current approach is going to cause us problems, now and in the future.
You can already see one problem forming in this PR, where there's a bunch of places in the code where we need to manually concat the scope and templateKey to form the object_id.
Another place we're going to run into problems is with POST and PUT operations where the body expects metadata template. If we naively do template.object_id, that might be incorrect if the API expects the actual id (I know of at least one API that was supposed to be doing this in the future). If we do template.id, that field might not actually be available, if it wasn't constructed with one.
For simplicity, we could make it so that if we're constructed with the id, we fetch the scope and templateKey, and also vice-versa, that way we always have all of those pieces of information available.
boxsdk/client/client.py
Outdated
| ) | ||
|
|
||
| @api_call | ||
| def get_metadata_template_by_id(self, template_id): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we get rid of the .get() behavior here? (and if so, rename the method)
|
|
||
| if metadata_template_response.get('scope') and metadata_template_response.get('templateKey'): | ||
| assert metadata_template.scope == metadata_template_response['scope'] | ||
| assert metadata_template.template_key == metadata_template_response['templateKey'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have this in a different test too, but just for completeness, can we assert that metadata_template.object_id is None if metadata_template_response.get('id') is None
No description provided.