mmif-python 1.0.11__tar.gz → 1.0.13__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {mmif-python-1.0.11/mmif_python.egg-info → mmif-python-1.0.13}/PKG-INFO +1 -1
  2. mmif-python-1.0.13/VERSION +1 -0
  3. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/annotation.py +15 -1
  4. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/mmif.py +11 -14
  5. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/model.py +4 -1
  6. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/view.py +3 -3
  7. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/timeunit_helper.py +4 -4
  8. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/video_document_helper.py +10 -8
  9. mmif-python-1.0.13/mmif/ver/__init__.py +2 -0
  10. {mmif-python-1.0.11 → mmif-python-1.0.13/mmif_python.egg-info}/PKG-INFO +1 -1
  11. mmif-python-1.0.11/VERSION +0 -1
  12. mmif-python-1.0.11/mmif/ver/__init__.py +0 -2
  13. {mmif-python-1.0.11 → mmif-python-1.0.13}/LICENSE +0 -0
  14. {mmif-python-1.0.11 → mmif-python-1.0.13}/MANIFEST.in +0 -0
  15. {mmif-python-1.0.11 → mmif-python-1.0.13}/README.md +0 -0
  16. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/__init__.py +0 -0
  17. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/__init__.py +0 -0
  18. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/clams.vocabulary.yaml +0 -0
  19. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/do-not-edit.txt +0 -0
  20. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/mmif.json +0 -0
  21. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/__init__.py +0 -0
  22. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/__init__.py +0 -0
  23. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/sequence_helper.py +0 -0
  24. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/ver/do-not-edit.txt +0 -0
  25. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/__init__.py +0 -0
  26. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/annotation_types.py +0 -0
  27. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/base_types.py +0 -0
  28. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/do-not-edit.txt +0 -0
  29. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/document_types.py +0 -0
  30. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_docloc_http/__init__.py +0 -0
  31. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/SOURCES.txt +0 -0
  32. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/dependency_links.txt +0 -0
  33. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/requires.txt +0 -0
  34. {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/top_level.txt +0 -0
  35. {mmif-python-1.0.11 → mmif-python-1.0.13}/requirements.cv +0 -0
  36. {mmif-python-1.0.11 → mmif-python-1.0.13}/requirements.seq +0 -0
  37. {mmif-python-1.0.11 → mmif-python-1.0.13}/requirements.txt +0 -0
  38. {mmif-python-1.0.11 → mmif-python-1.0.13}/setup.cfg +0 -0
  39. {mmif-python-1.0.11 → mmif-python-1.0.13}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mmif-python
3
- Version: 1.0.11
3
+ Version: 1.0.13
4
4
  Summary: Python implementation of MultiMedia Interchange Format specification. (https://mmif.clams.ai)
5
5
  Home-page: https://mmif.clams.ai
6
6
  Author: Brandeis Lab for Linguistics and Computation
@@ -0,0 +1 @@
1
+ 1.0.13
@@ -26,7 +26,7 @@ __all__ = ['Annotation', 'AnnotationProperties', 'Document', 'DocumentProperties
26
26
 
27
27
  T = TypeVar('T')
28
28
  LIST_PRMTV = typing.List[PRMTV_TYPES] # list of values (most cases for annotation props)
29
- LIST_LIST_PRMTV = typing.List[LIST_PRMTV] # list of list of values (e.g. for coordinates)
29
+ LIST_LIST_PRMTV = typing.List[LIST_PRMTV] # list of lists of values (e.g. for coordinates)
30
30
  DICT_PRMTV = typing.Dict[str, PRMTV_TYPES] # dict of values (`text` prop of `TextDocument` and other complex props)
31
31
  DICT_LIST_PRMTV = typing.Dict[str, LIST_PRMTV] # dict of list of values (even more complex props)
32
32
 
@@ -127,6 +127,20 @@ class Annotation(MmifObject):
127
127
  def id(self, aid: str) -> None:
128
128
  self.properties.id = aid
129
129
 
130
+ @property
131
+ def long_id(self) -> str:
132
+ if self.parent is not None and len(self.parent) > 0:
133
+ return f"{self.parent}{self.id_delimiter}{self.id}"
134
+ else:
135
+ return self.id
136
+
137
+ @long_id.setter
138
+ def long_id(self, long_id: str) -> None:
139
+ if self.id_delimiter in long_id:
140
+ self.parent, self.id = long_id.split(self.id_delimiter)
141
+ else:
142
+ self.id = long_id
143
+
130
144
  @staticmethod
131
145
  def check_prop_value_is_simple_enough(
132
146
  value: Union[PRMTV_TYPES, LIST_PRMTV, LIST_LIST_PRMTV, DICT_PRMTV, DICT_LIST_PRMTV]) -> bool:
@@ -10,13 +10,13 @@ import math
10
10
  import warnings
11
11
  from collections import defaultdict
12
12
  from datetime import datetime
13
- from typing import List, Union, Optional, Dict, ClassVar, cast
13
+ from typing import List, Union, Optional, Dict, cast
14
14
 
15
15
  import jsonschema.validators
16
+
16
17
  import mmif
17
18
  from mmif import ThingTypesBase
18
19
  from mmif.vocabulary import AnnotationTypes, DocumentTypes
19
-
20
20
  from .annotation import Annotation, Document
21
21
  from .model import MmifObject, DataList
22
22
  from .view import View
@@ -32,9 +32,6 @@ class Mmif(MmifObject):
32
32
  :param validate: whether to validate the data against the MMIF JSON schema.
33
33
  """
34
34
 
35
- view_prefix: ClassVar[str] = 'v_'
36
- id_delimiter: ClassVar[str] = ':'
37
-
38
35
  def __init__(self, mmif_obj: Optional[Union[bytes, str, dict]] = None, *, validate: bool = True) -> None:
39
36
  self.metadata: MmifMetadata = MmifMetadata()
40
37
  self.documents: DocumentsList = DocumentsList()
@@ -362,8 +359,8 @@ class Mmif(MmifObject):
362
359
  :return: a reference to the corresponding document, if it exists
363
360
  :raises KeyError: if there is no corresponding document
364
361
  """
365
- if Mmif.id_delimiter in doc_id:
366
- vid, did = doc_id.split(Mmif.id_delimiter)
362
+ if self.id_delimiter in doc_id:
363
+ vid, did = doc_id.split(self.id_delimiter)
367
364
  view = self[vid]
368
365
  if isinstance(view, View):
369
366
  return view.get_document_by_id(did)
@@ -410,8 +407,8 @@ class Mmif(MmifObject):
410
407
  aligned_types = set()
411
408
  for ann_id in [alignment['target'], alignment['source']]:
412
409
  ann_id = cast(str, ann_id)
413
- if Mmif.id_delimiter in ann_id:
414
- view_id, ann_id = ann_id.split(Mmif.id_delimiter)
410
+ if self.id_delimiter in ann_id:
411
+ view_id, ann_id = ann_id.split(self.id_delimiter)
415
412
  aligned_type = cast(Annotation, self[view_id][ann_id]).at_type
416
413
  else:
417
414
  aligned_type = cast(Annotation, alignment_view[ann_id]).at_type
@@ -438,8 +435,8 @@ class Mmif(MmifObject):
438
435
  except StopIteration:
439
436
  # means search failed by the full doc_id string,
440
437
  # now try trimming the view_id from the string and re-do the search
441
- if Mmif.id_delimiter in doc_id:
442
- vid, did = doc_id.split(Mmif.id_delimiter)
438
+ if self.id_delimiter in doc_id:
439
+ vid, did = doc_id.split(self.id_delimiter)
443
440
  if view.id == vid:
444
441
  annotations = view.get_annotations(document=did)
445
442
  try:
@@ -506,8 +503,8 @@ class Mmif(MmifObject):
506
503
  elif 'targets' in props:
507
504
 
508
505
  def get_target_ann(cur_ann, target_id):
509
- if Mmif.id_delimiter not in target_id:
510
- target_id = Mmif.id_delimiter.join((cur_ann.parent, target_id))
506
+ if self.id_delimiter not in target_id:
507
+ target_id = self.id_delimiter.join((cur_ann.parent, target_id))
511
508
  return self.__getitem__(target_id)
512
509
 
513
510
  if not targets_sorted:
@@ -549,7 +546,7 @@ class Mmif(MmifObject):
549
546
  """
550
547
  if item in self._named_attributes():
551
548
  return self.__dict__[item]
552
- split_attempt = item.split(Mmif.id_delimiter)
549
+ split_attempt = item.split(self.id_delimiter)
553
550
 
554
551
  document_result = self.documents.get(split_attempt[0])
555
552
  view_result = self.views.get(split_attempt[0])
@@ -14,7 +14,7 @@ for the different components of MMIF is added in the subclasses.
14
14
 
15
15
  import json
16
16
  from datetime import datetime
17
- from typing import Union, Any, Dict, Optional, TypeVar, Generic, Generator, Iterator, Type, Set
17
+ from typing import Union, Any, Dict, Optional, TypeVar, Generic, Generator, Iterator, Type, Set, ClassVar
18
18
 
19
19
  from deepdiff import DeepDiff
20
20
 
@@ -79,6 +79,9 @@ class MmifObject(object):
79
79
  an ID value automatically generated, based on its parent object.
80
80
  """
81
81
 
82
+ view_prefix: ClassVar[str] = 'v_'
83
+ id_delimiter: ClassVar[str] = ':'
84
+
82
85
  # these are the reserved names that cannot be used as attribute names, and
83
86
  # they won't be serialized
84
87
  reserved_names: Set[str] = {
@@ -245,7 +245,7 @@ class ViewMetadata(MmifObject):
245
245
  self.app: str = ''
246
246
  self.contains: ContainsDict = ContainsDict()
247
247
  self.parameters: Dict[str, str] = {}
248
- self.app_configuration: Dict[str, Union[PRMTV_TYPES, List[PRMTV_TYPES]]] = {}
248
+ self.appConfiguration: Dict[str, Union[PRMTV_TYPES, List[PRMTV_TYPES]]] = {}
249
249
  self.error: Union[dict, ErrorDict] = {}
250
250
  self.warnings: List[str] = []
251
251
  self._required_attributes = ["app"]
@@ -291,14 +291,14 @@ class ViewMetadata(MmifObject):
291
291
  """
292
292
  Add a configuration key-value pair to the app_configuration dictionary.
293
293
  """
294
- self.app_configuration[config_key] = config_value
294
+ self.appConfiguration[config_key] = config_value
295
295
 
296
296
  def get_app_configuration(self, config_key: str) -> Union[PRMTV_TYPES, List[PRMTV_TYPES]]:
297
297
  """
298
298
  Get a configuration value from the app_configuration dictionary.
299
299
  """
300
300
  try:
301
- return self.app_configuration[config_key]
301
+ return self.appConfiguration[config_key]
302
302
  except KeyError:
303
303
  raise KeyError(f"app is not configured for \"{config_key}\" key in the view: {self.serialize()}")
304
304
 
@@ -68,17 +68,17 @@ def convert(t: Union[int, float, str], in_unit: str, out_unit: str, fps: float)
68
68
  elif out_unit == 'frame':
69
69
  # ms>f
70
70
  if 'millisecond' == in_unit:
71
- return int(t / 1000 * fps)
71
+ return round(t / 1000 * fps)
72
72
  # s>f
73
73
  elif 'second' == in_unit:
74
- return int(t * fps)
74
+ return round(t * fps)
75
75
  # s>(ms or i)
76
76
  elif in_unit == 'second':
77
- return int(t * 1000) if out_unit == 'millisecond' else _second_to_isoformat(t)
77
+ return round(t * 1000) if out_unit == 'millisecond' else _second_to_isoformat(t)
78
78
  # ms>(s or i)
79
79
  elif in_unit == 'millisecond':
80
80
  return t / 1000 if out_unit == 'second' else _millisecond_to_isoformat(t)
81
81
  # f>ms, f>s
82
82
  else:
83
- return (t / fps) if out_unit == 'second' else (round(t / fps, 3) * 1000) # pytype: disable=bad-return-type
83
+ return (t / fps) if out_unit == 'second' else round(round(t / fps, 3) * 1000) # pytype: disable=bad-return-type
84
84
 
@@ -1,6 +1,7 @@
1
1
  import importlib
2
2
  import warnings
3
3
  from typing import List, Union, Tuple
4
+ import math
4
5
 
5
6
  import mmif
6
7
  from mmif import Annotation, Document, Mmif
@@ -124,22 +125,23 @@ def extract_mid_frame(mmif: Mmif, time_frame: Annotation, as_PIL: bool = False):
124
125
  return extract_frames_as_images(vd, [get_mid_framenum(mmif, time_frame)], as_PIL=as_PIL)[0]
125
126
 
126
127
 
127
- def sample_frames(start_frame: int, end_frame: int, sample_ratio: int = 1) -> List[int]:
128
+ def sample_frames(start_frame: int, end_frame: int, sample_rate: float = 1) -> List[int]:
128
129
  """
129
130
  Helper function to sample frames from a time interval.
130
- Can also be used as a "cutoff" function when used with ``start_frame==0`` and ``sample_ratio==1``.
131
+ Can also be used as a "cutoff" function when used with ``start_frame==0`` and ``sample_rate==1``.
131
132
 
132
133
  :param start_frame: start frame of the interval
133
134
  :param end_frame: end frame of the interval
134
- :param sample_ratio: sample ratio (or step) to configure how often to take a frame, default is 1, meaning all consecutive frames are sampled
135
+ :param sample_rate: sampling rate (or step) to configure how often to take a frame, default is 1, meaning all consecutive frames are sampled
135
136
 
136
137
  """
137
- sample_ratio = int(sample_ratio)
138
- if sample_ratio < 1:
139
- raise ValueError(f"Sample ratio must be greater than 1, but got {sample_ratio}")
138
+ if sample_rate < 1:
139
+ raise ValueError(f"Sample rate must be greater than 1, but got {sample_rate}")
140
140
  frame_nums: List[int] = []
141
- for i in range(start_frame, end_frame, sample_ratio):
142
- frame_nums.append(i)
141
+ cur_f = start_frame
142
+ while cur_f < end_frame:
143
+ frame_nums.append(math.ceil(cur_f))
144
+ cur_f += sample_rate
143
145
  return frame_nums
144
146
 
145
147
 
@@ -0,0 +1,2 @@
1
+ __version__ = "1.0.13"
2
+ __specver__ = "1.0.4"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mmif-python
3
- Version: 1.0.11
3
+ Version: 1.0.13
4
4
  Summary: Python implementation of MultiMedia Interchange Format specification. (https://mmif.clams.ai)
5
5
  Home-page: https://mmif.clams.ai
6
6
  Author: Brandeis Lab for Linguistics and Computation
@@ -1 +0,0 @@
1
- 1.0.11
@@ -1,2 +0,0 @@
1
- __version__ = "1.0.11"
2
- __specver__ = "1.0.4"
File without changes
File without changes
File without changes
File without changes
File without changes