Source code for mtap._labeler

# Copyright 2019 Regents of the University of Minnesota.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import threading
from typing import Generic, ContextManager, TypeVar, TYPE_CHECKING

from mtap._labels import Label

if TYPE_CHECKING:
    from mtap import Document
    from mtap.types import ProtoLabelAdapter

L = TypeVar('L', bound=Label)


[docs] class Labeler(Generic[L], ContextManager['Labeler']): """Object provided by :func:`~'mtap.Document'.get_labeler` which is responsible for adding labels to a label index on a document. """ __slots__ = ( '_client', '_document', '_label_index_name', '_label_adapter', 'is_done', '_current_labels', '_lock' ) def __init__(self, document: 'Document', label_index_name: str, label_adapter: 'ProtoLabelAdapter[L]'): self._document = document self._label_index_name = label_index_name self._label_adapter = label_adapter self.is_done = False self._current_labels = [] self._lock = threading.Lock() def __call__(self, *args, **kwargs) -> L: """Calls the constructor for the label type adding it to the list of labels to be uploaded. Args: args: Arguments passed to the label type's constructor. kwargs: Keyword arguments passed to the label type's constructor. Returns: The object that was created by the label type's constructor. Examples: >>> labeler(0, 25, some_field='some_value', x=3) GenericLabel(start_index=0, end_index=25, some_field='some_value', x=3) """ label = self._label_adapter.create_label(*args, document=self._document, **kwargs) self._current_labels.append(label) return label def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is not None: return False self.done()
[docs] def done(self): """Finalizes the label index, uploads the added labels to the events service. Normally called automatically on exit from a context manager block, but can be manually invoked if the labeler is not used in a context manager block.""" with self._lock: if self.is_done: return self.is_done = True self._document.add_labels(self._label_index_name, self._current_labels, label_adapter=self._label_adapter)