:py:mod:`medkit.core`
=====================

.. py:module:: medkit.core


Subpackages
-----------
.. toctree::
   :titlesonly:
   :maxdepth: 3

   audio/index.rst
   text/index.rst


Submodules
----------
.. toctree::
   :titlesonly:
   :maxdepth: 1

   _prov_graph/index.rst
   annotation/index.rst
   annotation_container/index.rst
   attribute/index.rst
   attribute_container/index.rst
   collection/index.rst
   conversion/index.rst
   data_item/index.rst
   dict_conv/index.rst
   doc_pipeline/index.rst
   document/index.rst
   id/index.rst
   operation/index.rst
   operation_desc/index.rst
   pipeline/index.rst
   prov_store/index.rst
   prov_tracer/index.rst
   store/index.rst
   utils/index.rst


Package Contents
----------------

Classes
~~~~~~~

.. autoapisummary::

   medkit.core.AnnotationContainer
   medkit.core.Attribute
   medkit.core.AttributeContainer
   medkit.core.Collection
   medkit.core.InputConverter
   medkit.core.OutputConverter
   medkit.core.IdentifiableDataItem
   medkit.core.IdentifiableDataItemWithAttrs
   medkit.core.DocPipeline
   medkit.core.Document
   medkit.core.DocOperation
   medkit.core.Operation
   medkit.core.OperationDescription
   medkit.core.DescribableOperation
   medkit.core.Pipeline
   medkit.core.PipelineCompatibleOperation
   medkit.core.PipelineStep
   medkit.core.ProvCompatibleOperation
   medkit.core.ProvStore
   medkit.core.Prov
   medkit.core.ProvTracer
   medkit.core.GlobalStore
   medkit.core.Store



Functions
~~~~~~~~~

.. autoapisummary::

   medkit.core.generate_deterministic_id
   medkit.core.generate_id
   medkit.core.create_prov_store



Attributes
~~~~~~~~~~

.. autoapisummary::

   medkit.core.AnnotationType


.. py:data:: AnnotationType

   

.. py:class:: AnnotationContainer(doc_id: str)


   Bases: :py:obj:`Generic`\ [\ :py:obj:`medkit.core.annotation.AnnotationType`\ ]

   
   Manage a list of annotations belonging to a document.

   This behaves more or less like a list: calling `len()` and iterating are
   supported. Additional filtering is available through the `get()` method.

   The annotations will be stored in a :class:`~medkit.core.Store`, which can
   rely on a simple dict or something more
   complicated like a database.

   This global store may be initialized using :class:~medkit.core.GlobalStore.
   Otherwise, a default one (i.e. dict store) is used.

   :Parameters:

       **doc_id** : str
           The identifier of the document which annotations belong to.














   ..
       !! processed by numpydoc !!
   .. py:method:: add(ann: medkit.core.annotation.AnnotationType)

      
      Attach an annotation to the document.


      :Parameters:

          **ann** : AnnotationType
              Annotation to add.





      :Raises:

          ValueError
              If the annotation is already attached to the document
              (based on `annotation.uid`)









      ..
          !! processed by numpydoc !!

   .. py:method:: __len__() -> int

      
      Add support for calling `len()`.
















      ..
          !! processed by numpydoc !!

   .. py:method:: __iter__() -> Iterator[medkit.core.annotation.AnnotationType]

      
      Add support for iterating over each attribute.
















      ..
          !! processed by numpydoc !!

   .. py:method:: __getitem__(key: int | slice) -> medkit.core.annotation.AnnotationType | list[medkit.core.annotation.AnnotationType]

      
      Add support for subscript access.
















      ..
          !! processed by numpydoc !!

   .. py:method:: get(*, label: str | None = None, key: str | None = None) -> list[medkit.core.annotation.AnnotationType]

      
      Return a list of the annotations of the document.


      :Parameters:

          **label** : str, optional
              Label to use to filter annotations.

          **key** : str, optional
              Key to use to filter annotations.














      ..
          !! processed by numpydoc !!

   .. py:method:: get_ids(*, label: str | None = None, key: str | None = None) -> Iterator[str]

      
      Return an iterator of the identifiers of the annotations of the document.

      This method is provided to facilitate additional filtering by subclasses.

      :Parameters:

          **label** : str, optional
              Label to use to filter annotations.

          **key** : str, optional
              Key to use to filter annotations.














      ..
          !! processed by numpydoc !!

   .. py:method:: get_by_id(uid: str) -> medkit.core.annotation.AnnotationType

      
      Return the annotation corresponding to a specific identifier.


      :Parameters:

          **uid** : str
              Identifier of the annotation to return.














      ..
          !! processed by numpydoc !!

   .. py:method:: __eq__(other: object) -> bool

      
      Return self==value.
















      ..
          !! processed by numpydoc !!

   .. py:method:: __repr__() -> str

      
      Return repr(self).
















      ..
          !! processed by numpydoc !!


.. py:class:: Attribute(label: str, value: Any | None = None, metadata: dict[str, Any] | None = None, uid: str | None = None)


   Bases: :py:obj:`medkit.core.dict_conv.SubclassMapping`

   
   Medkit attribute, to be added to an annotation.














   :Attributes:

       **label: str**
           The attribute label

       **value: Any, optional**
           The value of the attribute. Should be either simple built-in types (int,
           float, bool, str) or collections of these types (list, dict, tuple). If
           you need structured complex data you should create a subclass of
           `Attribute`.

       **metadata: dict of str to Any**
           The metadata of the attribute

       **uid: str**
           The identifier of the attribute


   ..
       !! processed by numpydoc !!
   .. py:attribute:: label
      :type: str

      

   .. py:attribute:: value
      :type: Any | None

      

   .. py:attribute:: metadata
      :type: dict[str, Any]

      

   .. py:attribute:: uid
      :type: str

      

   .. py:method:: __init_subclass__()
      :classmethod:


   .. py:method:: to_dict() -> dict[str, Any]


   .. py:method:: to_brat() -> Any | None

      
      Return a value compatible with the brat format.
















      ..
          !! processed by numpydoc !!

   .. py:method:: to_spacy() -> Any | None

      
      Return a value compatible with spaCy.
















      ..
          !! processed by numpydoc !!

   .. py:method:: copy() -> Attribute

      
      Create a copy of the attribute with a new identifier.

      This is used when we want to duplicate an existing attribute onto a
      different annotation.















      ..
          !! processed by numpydoc !!

   .. py:method:: from_dict(attribute_dict: dict[str, Any]) -> typing_extensions.Self
      :classmethod:

      
      Create an Attribute from a dict.


      :Parameters:

          **attribute_dict: dict of str to Any**
              A dictionary from a serialized Attribute as generated by to_dict()














      ..
          !! processed by numpydoc !!


.. py:class:: AttributeContainer(owner_id: str)


   
   Manage a list of attributes attached to another data structure.

   For example, it may be a document or an annotation.

   This behaves more or less like a list: calling `len()` and iterating are
   supported. Additional filtering is available through the `get()` method.

   The attributes will be stored in a :class:`~medkit.core.Store`, which can
   rely on a simple dict or something more complicated like a database.

   This global store may be initialized using :class:~medkit.core.GlobalStore.
   Otherwise, a default one (i.e. dict store) is used.















   ..
       !! processed by numpydoc !!
   .. py:method:: __len__() -> int

      
      Add support for calling `len()`.
















      ..
          !! processed by numpydoc !!

   .. py:method:: __iter__() -> Iterator[medkit.core.attribute.Attribute]

      
      Add support for iterating over each attribute.
















      ..
          !! processed by numpydoc !!

   .. py:method:: __getitem__(key: int | slice) -> medkit.core.attribute.Attribute | list[medkit.core.attribute.Attribute]

      
      Add support for subscript access.
















      ..
          !! processed by numpydoc !!

   .. py:method:: get(*, label: str | None = None) -> list[medkit.core.attribute.Attribute]

      
      Return a list of the attributes of the annotation.


      :Parameters:

          **label** : str, optional
              Label to use to filter attributes.

      :Returns:

          list of Attribute
              The list of all attributes of the annotation, filtered by label if specified.













      ..
          !! processed by numpydoc !!

   .. py:method:: add(attr: medkit.core.attribute.Attribute)

      
      Attach an attribute to the annotation.


      :Parameters:

          **attr** : Attribute
              Attribute to add.





      :Raises:

          ValueError
              If the attribute is already attached to the annotation (based on
              `attr.uid`).









      ..
          !! processed by numpydoc !!

   .. py:method:: get_by_id(uid: str) -> medkit.core.attribute.Attribute

      
      Return the attribute corresponding to a specific identifier.


      :Parameters:

          **uid** : str
              Identifier of the attribute to return.

      :Returns:

          Attribute
              The attribute corresponding to the identifier













      ..
          !! processed by numpydoc !!

   .. py:method:: __eq__(other: object) -> bool

      
      Return self==value.
















      ..
          !! processed by numpydoc !!

   .. py:method:: __repr__() -> str

      
      Return repr(self).
















      ..
          !! processed by numpydoc !!


.. py:class:: Collection(*, text_docs: list[medkit.core.text.TextDocument] | None = None, audio_docs: list[medkit.core.audio.AudioDocument] | None = None)


   
   Collection of documents of any modality (text, audio).

   This class allows to group together a set of documents representing a common
   unit (for instance a patient), even if they don't belong to the same modality.

   This class is still a work-in-progress. In the future it should be possible to attach
   additional information to a `Collection`.

   :Parameters:

       **text_docs** : list of TextDocument, optional
           List of text documents.

       **audio_docs: list of TextDocument, optional**
           List of audio documents.














   ..
       !! processed by numpydoc !!
   .. py:property:: all_docs
      :type: list[medkit.core.document.Document]

      
      Return all documents belonging to the collection.
















      ..
          !! processed by numpydoc !!

   .. py:method:: to_dict() -> dict[str, Any]



.. py:class:: InputConverter


   
   Abstract class for converting external document to medkit documents.
















   ..
       !! processed by numpydoc !!
   .. py:method:: load(**kwargs) -> list[medkit.core.document.Document]
      :abstractmethod:



.. py:class:: OutputConverter


   
   Abstract class for converting medkit document to external format.
















   ..
       !! processed by numpydoc !!
   .. py:method:: save(docs: list[medkit.core.document.Document], **kwargs) -> list | None
      :abstractmethod:



.. py:class:: IdentifiableDataItem


   Bases: :py:obj:`typing_extensions.Protocol`

   
   Base class for protocol classes.

   Protocol classes are defined as::

       class Proto(Protocol):
           def meth(self) -> int:
               ...

   Such classes are primarily used with static type checkers that recognize
   structural subtyping (static duck-typing).

   For example::

       class C:
           def meth(self) -> int:
               return 0

       def func(x: Proto) -> int:
           return x.meth()

       func(C())  # Passes static type check

   See PEP 544 for details. Protocol classes decorated with
   @typing.runtime_checkable act as simple-minded runtime protocols that check
   only the presence of given attributes, ignoring their type signatures.
   Protocol classes can be generic, they are defined as::

       class GenProto(Protocol[T]):
           def meth(self) -> T:
               ...















   ..
       !! processed by numpydoc !!
   .. py:attribute:: uid
      :type: str

      


.. py:class:: IdentifiableDataItemWithAttrs


   Bases: :py:obj:`typing_extensions.Protocol`\ [\ :py:obj:`IdentifiableDataItemType`\ ]

   .. py:attribute:: attrs
      :type: Iterable[IdentifiableDataItemType]

      


.. py:class:: DocPipeline(pipeline: medkit.core.pipeline.Pipeline, labels_by_input_key: dict[str, list[str]] | None = None, uid: str | None = None)


   Bases: :py:obj:`medkit.core.operation.DocOperation`, :py:obj:`Generic`\ [\ :py:obj:`medkit.core.annotation.AnnotationType`\ ]

   
   Convenience wrapper to facilitate running pipelines on a collection of documents.

   Wrapper around the `Pipeline` class that runs a pipeline on a list
   (or collection) of documents, retrieving input annotations from each document
   and attaching output annotations back to documents.

   :Parameters:

       **pipeline** : Pipeline
           Pipeline to execute on documents.
           Annotations given to `pipeline` (corresponding to its `input_keys`) will
           be retrieved from documents, according to `labels_by_input`.
           Annotations returned by `pipeline` (corresponding to its `output_keys`)
           will be added to documents.

       **labels_by_input_key** : dict of str to list of str, optional
           Optional labels of existing annotations that should be retrieved from
           documents and passed to the pipeline as input. One list of labels
           per input key.
           
           When `labels_by_input_key` is not provided, it is assumed that the
           `pipeline` just expects the document raw segments as input.
           
           For the use case where the documents contain pre-existing sentence segments
           labelled as "SENTENCE", that we want to pass the "sentences" input
           key of the pipeline:











   .. rubric:: Examples

   >>> doc_pipeline = DocPipeline(
   >>>     pipeline,
   >>>     labels_by_input={"sentences": ["SENTENCE"]},
   >>> )

   Because the values of `labels_by_input_key` are lists (one per input),
   it is possible to use annotation with different labels for the same input key.



   ..
       !! processed by numpydoc !!
   .. py:method:: set_prov_tracer(prov_tracer: medkit.core.prov_tracer.ProvTracer)

      
      Enable provenance tracing.


      :Parameters:

          **prov_tracer: ProvTracer**
              The provenance tracer used to trace the provenance.














      ..
          !! processed by numpydoc !!

   .. py:method:: run(docs: list[medkit.core.document.Document[medkit.core.annotation.AnnotationType]]) -> None

      
      Run the pipeline on a list of documents, adding the output annotations to each document.


      :Parameters:

          **docs** : list of Document
              The documents on which to run the pipeline.
              Labels to input keys association will be used to retrieve existing
              annotations from each document, and all output annotations will also
              be added to each corresponding document.














      ..
          !! processed by numpydoc !!

   .. py:method:: _process_doc(doc: medkit.core.document.Document[medkit.core.annotation.AnnotationType])



.. py:class:: Document


   Bases: :py:obj:`typing_extensions.Protocol`\ [\ :py:obj:`medkit.core.annotation.AnnotationType`\ ]

   
   Base protocol for document classes of any modality (text, audio, etc).

   Documents can contain :class:`~medkit.core.annotation.Annotation` objects.













   :Attributes:

       **uid:**
           Unique identifier of the document

       **anns:**
           Annotations of the document, stored in an
           :class:`~medkit.core.annotation_container.AnnotationContainer` for
           easier access (can be subclassed to add modality-specific features).

       **attrs:**
           Attributes of the document, stored in an
           :class: `~medkit.core.attribute_container.AttributeContainer` for
           easier access

       **raw_segment:**
           Auto-generated segment containing the full unprocessed document.


   ..
       !! processed by numpydoc !!
   .. py:attribute:: uid
      :type: str

      

   .. py:attribute:: anns
      :type: medkit.core.annotation_container.AnnotationContainer[medkit.core.annotation.AnnotationType]

      

   .. py:attribute:: attrs
      :type: medkit.core.attribute_container.AttributeContainer

      

   .. py:attribute:: raw_segment
      :type: medkit.core.annotation.AnnotationType

      


.. py:function:: generate_deterministic_id(reference_id: str) -> uuid.UUID

   
   Generate a deterministic UUID based on reference_id.

   The generated UUID will be the same if the reference_id is the same.

   :Parameters:

       **reference_id**
           A string representation of an UID

   :Returns:

       uuid.UUID
           The UUID object













   ..
       !! processed by numpydoc !!

.. py:function:: generate_id() -> str


.. py:class:: DocOperation(uid: str | None = None, name: str | None = None, **kwargs)


   Bases: :py:obj:`Operation`

   
   Abstract operation directly executed on text documents.

   It uses a list of documents as input for running the operation and creates
   annotations that are directly appended to these documents.















   ..
       !! processed by numpydoc !!
   .. py:method:: run(docs: list[medkit.core.document.Document]) -> None
      :abstractmethod:



.. py:class:: Operation(uid: str | None = None, name: str | None = None, **kwargs)


   Bases: :py:obj:`abc.ABC`

   
   Abstract class for all annotator modules.


   :Parameters:

       **uid: str, optional**
           Operation identifier

       **name: str, optional**
           Operation name (defaults to class name)

       **kwargs:**
           All other arguments of the child init useful to describe the operation











   .. rubric:: Examples

   In the `__init__` function of your annotator, use:

   >>> init_args = locals()
   >>> init_args.pop("self")
   >>> super().__init__(**init_args)



   ..
       !! processed by numpydoc !!
   .. py:property:: description
      :type: medkit.core.operation_desc.OperationDescription

      
      Contains all the operation init parameters.
















      ..
          !! processed by numpydoc !!

   .. py:attribute:: uid
      :type: str

      

   .. py:attribute:: _description
      :type: medkit.core.operation_desc.OperationDescription | None

      

   .. py:attribute:: _prov_tracer
      :type: medkit.core.prov_tracer.ProvTracer | None

      

   .. py:method:: set_prov_tracer(prov_tracer: medkit.core.prov_tracer.ProvTracer)

      
      Enable provenance tracing.


      :Parameters:

          **prov_tracer: ProvTracer**
              The provenance tracer used to trace the provenance.














      ..
          !! processed by numpydoc !!

   .. py:method:: check_sanity() -> bool



.. py:class:: OperationDescription


   
   Description of a specific instance of an operation.














   :Attributes:

       **uid** : str
           The unique identifier of the instance described

       **name** : str
           The name of the operation. Can be the same as `class_name` or something
           more specific, for operations with a behavior that can be customized
           (for instance a rule-based entity matcher with user-provided rules, or a
           model-based entity matcher with a user-provided model)

       **class_name** : str, optional
           The name of the class of the operation

       **config** : dict of str to Any, optional
           The specific configuration of the instance


   ..
       !! processed by numpydoc !!
   .. py:attribute:: uid
      :type: str

      

   .. py:attribute:: name
      :type: str

      

   .. py:attribute:: class_name
      :type: str | None

      

   .. py:attribute:: config
      :type: dict[str, Any]

      

   .. py:method:: to_dict() -> dict[str, Any]



.. py:class:: DescribableOperation


   Bases: :py:obj:`typing_extensions.Protocol`

   
   Base class for protocol classes.

   Protocol classes are defined as::

       class Proto(Protocol):
           def meth(self) -> int:
               ...

   Such classes are primarily used with static type checkers that recognize
   structural subtyping (static duck-typing).

   For example::

       class C:
           def meth(self) -> int:
               return 0

       def func(x: Proto) -> int:
           return x.meth()

       func(C())  # Passes static type check

   See PEP 544 for details. Protocol classes decorated with
   @typing.runtime_checkable act as simple-minded runtime protocols that check
   only the presence of given attributes, ignoring their type signatures.
   Protocol classes can be generic, they are defined as::

       class GenProto(Protocol[T]):
           def meth(self) -> T:
               ...















   ..
       !! processed by numpydoc !!
   .. py:attribute:: description
      :type: medkit.core.operation_desc.OperationDescription

      


.. py:class:: Pipeline(steps: list[PipelineStep], input_keys: list[str], output_keys: list[str], name: str | None = None, uid: str | None = None)


   
   Graph of processing operations.

   A pipeline is made of pipeline steps, connecting together different processing
   operations by the use of input/output keys. Each operation can be seen as a node
   and the keys are its edge. Two operations can be chained by using the same string
   as an output key for the first operation and as an input key to the second.

   Steps must be added in the order of execution, there isn't any sort of dependency
   detection mechanism.

   :Parameters:

       **steps** : list of PipelineStep
           List of pipeline steps
           These steps will be executed in the order in which they were added,
           so make sure to add first the steps generating data used by other steps.

       **input_keys** : list of str
           List of keys corresponding to the inputs passed to `run()`

       **output_keys** : list of str
           List of keys corresponding to the outputs returned by `run()`

       **name** : str, optional
           Name describing the pipeline (defaults to the class name)

       **uid** : str, optional
           Identifier of the pipeline














   ..
       !! processed by numpydoc !!
   .. py:property:: description
      :type: medkit.core.operation_desc.OperationDescription


   .. py:method:: set_prov_tracer(prov_tracer: medkit.core.prov_tracer.ProvTracer)


   .. py:method:: run(*all_input_data: list[Any]) -> list[Any] | tuple[list[Any], Ellipsis] | None

      
      Run the pipeline.


      :Parameters:

          **\*all_input_data** : list of Any
              Input data expected by the pipeline, must be of same length as the
              pipeline `input_keys`.
              
              For each input key, the corresponding input data must be a list of
              items than can be of any type.

      :Returns:

          list of Any or tuple of list, optional
              All output data returned by the pipeline, will be of same length as
              the pipeline `output_keys`.
              
              For each output key, the corresponding output will be a list of
              items that can be of any type.
              
              If the pipeline has only one output key, then the corresponding output
              will be directly returned, not wrapped in a tuple. If the pipeline
              doesn't have any output key, nothing (ie `None`) will be returned.













      ..
          !! processed by numpydoc !!

   .. py:method:: _perform_step(step: PipelineStep, data_by_key: dict[str, Any])


   .. py:method:: _add_provenance(all_output_data: tuple[list[Any], Ellipsis])


   .. py:method:: check_sanity()



.. py:class:: PipelineCompatibleOperation


   Bases: :py:obj:`typing_extensions.Protocol`

   
   Base class for protocol classes.

   Protocol classes are defined as::

       class Proto(Protocol):
           def meth(self) -> int:
               ...

   Such classes are primarily used with static type checkers that recognize
   structural subtyping (static duck-typing).

   For example::

       class C:
           def meth(self) -> int:
               return 0

       def func(x: Proto) -> int:
           return x.meth()

       func(C())  # Passes static type check

   See PEP 544 for details. Protocol classes decorated with
   @typing.runtime_checkable act as simple-minded runtime protocols that check
   only the presence of given attributes, ignoring their type signatures.
   Protocol classes can be generic, they are defined as::

       class GenProto(Protocol[T]):
           def meth(self) -> T:
               ...















   ..
       !! processed by numpydoc !!
   .. py:method:: run(*all_input_data: list[Any]) -> list[Any] | tuple[list[Any], Ellipsis] | None

      
      Run the operation.


      :Parameters:

          **all_input_data** : list of Any
              One or several list of data items to process
              (according to the number of input the operation needs)

      :Returns:

          list of Any or tuple of list, optional
              Tuple of list of all new data items created by the operation.
              Can be None if the operation does not create any new data items
              but rather modify existing items in-place (for instance by
              adding attributes to existing annotations).
              If there is only one list of created data items, it is possible
              to return directly that list without wrapping it in a tuple.













      ..
          !! processed by numpydoc !!


.. py:class:: PipelineStep


   
   Pipeline step describing how a processing operation is connected to other.














   :Attributes:

       **operation** : PipelineCompatibleOperation
           The operation to use at that step

       **input_keys** : list of str
           For each input of `operation`, the key to use to retrieve the
           corresponding annotations (either retrieved from a document
           or generated by an earlier pipeline step)

       **output_keys** : list of str
           For each output of `operation`, the key used to pass output annotations
           to the next Pipeline step. Can be empty if `operation` doesn't return
           new annotations.

       **aggregate_input_keys** : bool, default=False
           If True, all the annotations from multiple input keys are aggregated in a single list. Defaults to False


   ..
       !! processed by numpydoc !!
   .. py:attribute:: operation
      :type: PipelineCompatibleOperation

      

   .. py:attribute:: input_keys
      :type: list[str]

      

   .. py:attribute:: output_keys
      :type: list[str]

      

   .. py:attribute:: aggregate_input_keys
      :type: bool
      :value: False

      

   .. py:method:: to_dict() -> dict[str, Any]



.. py:class:: ProvCompatibleOperation


   Bases: :py:obj:`typing_extensions.Protocol`

   
   Base class for protocol classes.

   Protocol classes are defined as::

       class Proto(Protocol):
           def meth(self) -> int:
               ...

   Such classes are primarily used with static type checkers that recognize
   structural subtyping (static duck-typing).

   For example::

       class C:
           def meth(self) -> int:
               return 0

       def func(x: Proto) -> int:
           return x.meth()

       func(C())  # Passes static type check

   See PEP 544 for details. Protocol classes decorated with
   @typing.runtime_checkable act as simple-minded runtime protocols that check
   only the presence of given attributes, ignoring their type signatures.
   Protocol classes can be generic, they are defined as::

       class GenProto(Protocol[T]):
           def meth(self) -> T:
               ...















   ..
       !! processed by numpydoc !!
   .. py:method:: set_prov_tracer(prov_tracer: medkit.core.prov_tracer.ProvTracer)



.. py:class:: ProvStore


   Bases: :py:obj:`typing_extensions.Protocol`

   
   Base class for protocol classes.

   Protocol classes are defined as::

       class Proto(Protocol):
           def meth(self) -> int:
               ...

   Such classes are primarily used with static type checkers that recognize
   structural subtyping (static duck-typing).

   For example::

       class C:
           def meth(self) -> int:
               return 0

       def func(x: Proto) -> int:
           return x.meth()

       func(C())  # Passes static type check

   See PEP 544 for details. Protocol classes decorated with
   @typing.runtime_checkable act as simple-minded runtime protocols that check
   only the presence of given attributes, ignoring their type signatures.
   Protocol classes can be generic, they are defined as::

       class GenProto(Protocol[T]):
           def meth(self) -> T:
               ...















   ..
       !! processed by numpydoc !!
   .. py:method:: store_data_item(data_item: medkit.core.data_item.IdentifiableDataItem)


   .. py:method:: get_data_item(data_item_id: str) -> medkit.core.data_item.IdentifiableDataItem


   .. py:method:: store_op_desc(op_desc: medkit.core.operation_desc.OperationDescription)


   .. py:method:: get_op_desc(operation_id: str) -> medkit.core.operation_desc.OperationDescription



.. py:function:: create_prov_store(store_type: StoreType = 'dict')


.. py:class:: Prov


   
   Provenance information for a specific data item.


   :Parameters:

       **data_item** : IdentifiableDataItem
           Data item that was created (for instance an annotation or an
           attribute).

       **op_desc: OperationDescription, optional**
           Description of the operation that created the data item.

       **source_data_items** : list of IdentifiableDataItem
           Data items that were used by the operation to create the data item.

       **derived_data_items** : list of IdentifiableDataItem
           Data items that were created by other operations using this data item.














   ..
       !! processed by numpydoc !!
   .. py:attribute:: data_item
      :type: medkit.core.data_item.IdentifiableDataItem

      

   .. py:attribute:: op_desc
      :type: medkit.core.operation_desc.OperationDescription | None

      

   .. py:attribute:: source_data_items
      :type: list[medkit.core.data_item.IdentifiableDataItem]

      

   .. py:attribute:: derived_data_items
      :type: list[medkit.core.data_item.IdentifiableDataItem]

      


.. py:class:: ProvTracer(store: medkit.core.prov_store.ProvStore | None = None, _graph: medkit.core._prov_graph.ProvGraph | None = None)


   
   Provenance tracing component.

   `ProvTracer` is intended to gather provenance information about how all data
   generated by medkit. For each data item (for instance an annotation or an
   attribute), `ProvTracer` can tell the operation that created it, the data
   items that were used to create it, and reciprocally, the data items that were
   derived from it (cf. :class:`~Prov`).

   Provenance-compatible operations should inform the provenance tracer of each
   data item that through the :meth:`~.add_prov` method.

   Users wanting to gather provenance information should instantiate one unique
   `ProvTracer` object and provide it to all operations involved in their data
   processing flow. Once all operations have been executed, they may then
   retrieve provenance info for specific data items through
   :meth:`~.get_prov`, or for all items with :meth:`~.get_provs`.

   Composite operations relying on inner operations (such as pipelines)
   shouldn't call :meth:`~.add_prov` method. Instead, they should instantiate
   their own internal `ProvTracer` and provide it to the operations they rely
   on, then use :meth:`~.add_prov_from_sub_tracer` to integrate
   information from this internal sub-provenance tracer into the main
   provenance tracer that was provided to them.

   This will build sub-provenance information, that can be retrieved later
   through :meth:`~.get_sub_prov_tracer` or :meth:`~.get_sub_prov_tracers`. The
   inner operations of a composite operation can themselves be composite
   operations, leading to a tree-like structure of nested provenance tracers.

   :Parameters:

       **store:**
           Store that will contain all traced data items.














   ..
       !! processed by numpydoc !!
   .. py:method:: add_prov(data_item: medkit.core.data_item.IdentifiableDataItem, op_desc: medkit.core.operation_desc.OperationDescription, source_data_items: list[medkit.core.data_item.IdentifiableDataItem])

      
      Append provenance information about a specific data item.


      :Parameters:

          **data_item** : IdentifiableDataItem
              Data item that was created.

          **op_desc** : OperationDescription
              Description of the operation that created the data item.

          **source_data_items** : list of IdentifiableDataItem
              Data items that were used by the operation to create the data item.














      ..
          !! processed by numpydoc !!

   .. py:method:: add_prov_from_sub_tracer(data_items: list[medkit.core.data_item.IdentifiableDataItem], op_desc: medkit.core.operation_desc.OperationDescription, sub_tracer: ProvTracer)

      
      Add provenance information about data items to a specific tracer.

      Append provenance information about data items created by a composite
      operation relying on inner operations (such as a pipeline) having its
      own internal sub-provenance tracer.

      :Parameters:

          **data_items** : list of IdentifiableDataItem
              Data items created by the composite operation. Should not include
              internal intermediate data items, only the output of the operation.

          **op_desc** : OperationDescription
              Description of the composite operation that created the data items.

          **sub_tracer** : ProvTracer
              Internal sub-provenance tracer of the composite operation.














      ..
          !! processed by numpydoc !!

   .. py:method:: _add_prov_from_sub_tracer_for_data_item(data_item_id: str, operation_id: str, sub_graph: medkit.core._prov_graph.ProvGraph)


   .. py:method:: has_prov(data_item_id: str) -> bool

      
      Check whether a specific data item has provenance information.

      .. note::
          This will return `False` if we have provenance info about a data
          item but only in a sub-provenance tracer.

      :Parameters:

          **data_item_id** : str
              Id of the data item.

      :Returns:

          bool:
              `True` if there is provenance info that can be retrieved with
              :meth:`~get_prov()`.













      ..
          !! processed by numpydoc !!

   .. py:method:: get_prov(data_item_id: str) -> Prov

      
      Return provenance information about a specific data item.


      :Parameters:

          **data_item_id** : str
              Id of the data item.

      :Returns:

          Prov:
              Provenance info about the data item.













      ..
          !! processed by numpydoc !!

   .. py:method:: get_provs() -> list[Prov]

      
      Return all provenance information about all data items known to the tracer.

      .. note::
          Nested provenance info from sub-provenance tracers will not be returned.


      :Returns:

          list of Prov
              Provenance info about all known data items.













      ..
          !! processed by numpydoc !!

   .. py:method:: has_sub_prov_tracer(operation_id: str) -> bool

      
      Check whether the provenance tracer has a sub-provenance tracer for an operation.

      .. note::
          This will return `False` if there is a sub-provenance tracer for
          the operation but that is not a direct child (i.e. that is deeper
          in the hierarchy).

      :Parameters:

          **operation_id** : str
              Id of the composite operation.

      :Returns:

          bool
              `True` if there is a sub-provenance tracer for the operation.













      ..
          !! processed by numpydoc !!

   .. py:method:: get_sub_prov_tracer(operation_id: str) -> ProvTracer

      
      Return a sub-provenance tracer containing sub-provenance information for an operation.


      :Parameters:

          **operation_id** : str
              Id of the composite operation.

      :Returns:

          ProvTracer
              The sub-provenance tracer containing sub-provenance information from the
              operation.













      ..
          !! processed by numpydoc !!

   .. py:method:: get_sub_prov_tracers() -> list[ProvTracer]

      
      Return all sub-provenance tracers of the provenance tracer.

      .. note::
          This will not return sub-provenance tracers that are not direct
          children of this tracer (i.e. that are deeper in the hierarchy).


      :Returns:

          List[ProvTracer]
              All sub-provenance tracers of this provenance tracer.













      ..
          !! processed by numpydoc !!

   .. py:method:: _build_prov_from_node(node: medkit.core._prov_graph.ProvNode)



.. py:class:: GlobalStore


   
   Global store.
















   ..
       !! processed by numpydoc !!
   .. py:attribute:: _store
      :type: Store | None

      

   .. py:method:: init_store(store: Store)
      :classmethod:

      
      Initialize the global store for your application.


      :Parameters:

          **store** : Store
              Store for all the data items





      :Raises:

          RuntimeError
              If global store is already set









      ..
          !! processed by numpydoc !!

   .. py:method:: get_store() -> Store
      :classmethod:

      
      Return the global store object.



      :Returns:

          Store
              the global store













      ..
          !! processed by numpydoc !!

   .. py:method:: del_store()
      :classmethod:

      
      Delete the global store object.
















      ..
          !! processed by numpydoc !!


.. py:class:: Store


   Bases: :py:obj:`typing_extensions.Protocol`

   
   Store protocol.
















   ..
       !! processed by numpydoc !!
   .. py:method:: store_data_item(data_item: medkit.core.data_item.IdentifiableDataItem, parent_id: str)


   .. py:method:: get_data_item(data_item_id: str) -> medkit.core.data_item.IdentifiableDataItem | None


   .. py:method:: get_parent_item(data_item) -> medkit.core.data_item.IdentifiableDataItem | None



