ferrero-opentext/Python-Version/venv/lib/python3.12/site-packages/boxsdk/object/metadata_template.py

294 lines
8.7 KiB
Python

from typing import TYPE_CHECKING, List, Optional, Iterable, Any
from .base_object import BaseObject
from ..util.api_call_decorator import api_call
from ..util.text_enum import TextEnum
if TYPE_CHECKING:
from boxsdk.session.session import Session
class MetadataTemplateUpdate:
"""Represents a set of update operations to a metadata template."""
def __init__(self):
super().__init__()
self._ops = []
def json(self) -> list:
return self._ops
def add_enum_option(self, field_key: str, option_key: str) -> None:
"""
Adds a new option to an enum field.
:param field_key:
The key of the template field to add the option to
:param option_key:
The option to add
"""
self.add_operation({
'op': 'addEnumOption',
'fieldKey': field_key,
'data': {
'key': option_key,
},
})
def add_field(self, field: 'MetadataField') -> None:
"""
Add a new field to the template.
:param field:
The new field to add
"""
self.add_operation({
'op': 'addField',
'data': field.json(),
})
def edit_template(self, data: dict) -> None:
"""
Edit top-level template properties.
:param data:
The properties to modify
"""
self.add_operation({
'op': 'editTemplate',
'data': data,
})
def reorder_enum_options(self, field_key: str, option_keys: List[str]) -> None:
"""
Reorders the options in an enum field, which affects their display in UI.
:param field_key:
The key of the enum field to reorder
:param option_keys:
The option keys in the desired order
"""
self.add_operation({
'op': 'reorderEnumOptions',
'fieldKey': field_key,
'enumOptionKeys': option_keys,
})
def reorder_fields(self, field_keys: List[str]) -> None:
"""
Reorders the fields in a metadata template, which affects their display in UI.
:param field_keys:
The field keys in the desired order
"""
self.add_operation({
'op': 'reorderFields',
'fieldKeys': field_keys,
})
def edit_field(self, field_key: str, field: 'MetadataField') -> None:
"""
Edits a field in the template.
:param field_key:
The key of the field to update
:param field:
The updated field values
"""
self.add_operation({
'op': 'editField',
'fieldKey': field_key,
'data': field.json(),
})
def edit_enum_option_key(self, field_key: str, old_option_key: str, new_option_key: str) -> None:
"""
Change the key of an enum field option.
:param field_key:
The key of the template field in which the option appears
:param old_option_key:
The old option key
:param new_option_key:
The new option key
"""
self.add_operation({
'op': 'editEnumOption',
'fieldKey': field_key,
'enumOptionKey': old_option_key,
'data': {
'key': new_option_key,
},
})
def remove_enum_option(self, field_key: str, option_key: str) -> None:
"""
Remove an option from an enum field.
:param field_key:
The key of the template field in which the option appears
:param option_key:
The key of the enum option to remove
"""
self.add_operation({
'op': 'removeEnumOption',
'fieldKey': field_key,
'enumOptionKey': option_key,
})
def remove_field(self, field_key: str) -> None:
"""
Remove a field from the metadata template.
:param field_key:
The key of the field to remove
"""
self.add_operation({
'op': 'removeField',
'fieldKey': field_key,
})
def add_operation(self, operation: dict) -> None:
"""
Adds an update operation.
:param operation:
The operation to add.
"""
self._ops.append(operation)
class MetadataFieldType(TextEnum):
STRING = 'string'
DATE = 'date'
ENUM = 'enum'
MULTISELECT = 'multiSelect'
FLOAT = 'float'
class MetadataField:
"""Represents a metadata field when creating or updating a metadata template."""
def __init__(
self,
field_type: MetadataFieldType,
display_name: str,
key: Optional[str] = None,
options: Iterable[str] = None,
description: Optional[str] = None,
hidden: Optional[bool] = None
):
"""
:param field_type:
The type of the metadata field
:param display_name:
The human-readable name of the metadata field
:param key:
The machine-readable key for the metadata field
:param options:
For 'enum' or 'multiSelect' fields, the selectable options
:param description:
A description of the field
:param hidden:
Whether this field is hidden in the UI for the user and can only be set through the API instead
"""
super().__init__()
self.type = field_type
self.name = display_name
self.key = key
self.options = options
self.description = description
self.hidden = hidden
def json(self) -> dict:
"""
Returns the correct representation of the template field for the API.
"""
values = {}
if self.type is not None:
values['type'] = self.type
if self.name is not None:
values['displayName'] = self.name
if self.key is not None:
values['key'] = self.key
if self.type in ['enum', 'multiSelect']:
values['options'] = [{'key': opt} for opt in self.options or ()]
if self.description is not None:
values['description'] = self.description
if self.hidden is not None:
values['hidden'] = self.hidden
return values
class MetadataTemplate(BaseObject):
"""Represents a metadata template, which contains the the type information for associated metadata fields."""
_item_type = 'metadata_template'
_untranslated_fields = ('fields',)
_scope = None
_template_key = None
def __init__(self, session: 'Session', object_id: Optional[str], response_object: Optional[dict] = None):
"""
:param session:
The Box session used to make requests.
:param object_id:
The primary GUID key for the metadata template
:param response_object:
A JSON object representing the object returned from a Box API request. This should
contain 'scope' and 'templateKey' properties if the instance is being constructed without
a primary GUID object_id.
"""
super().__init__(session, object_id, response_object)
if response_object:
self._scope = response_object.get('scope', None)
self._template_key = response_object.get('templateKey', None)
elif not object_id:
raise ValueError('Metadata template must be constructed with an ID or scope and templateKey')
@property
def scope(self) -> Optional[str]:
return self._scope
@property
def template_key(self) -> Optional[str]:
return self._template_key
def get_url(self, *args: Any) -> str:
"""
Base class override, since metadata templates have a weird compound ID and non-standard URL format
"""
if self._scope and self._template_key:
return self._session.get_url('metadata_templates', self._scope, self._template_key, 'schema', *args)
return super().get_url(*args)
@staticmethod
def start_update() -> MetadataTemplateUpdate:
"""
Start an update operation on the template.
:returns:
An update object to collect the desired update operations.
"""
return MetadataTemplateUpdate()
@api_call
def update_info(self, *, updates: MetadataTemplateUpdate, **kwargs) -> 'MetadataTemplate':
# pylint: disable=arguments-differ
"""
Update a metadata template with a set of update operations.
:param updates:
The update operations to apply to the template
:returns:
The updated metadata template object
"""
# pylint: disable=arguments-differ
return super().update_info(data=updates.json(), **kwargs)