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.
- {mmif-python-1.0.11/mmif_python.egg-info → mmif-python-1.0.13}/PKG-INFO +1 -1
- mmif-python-1.0.13/VERSION +1 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/annotation.py +15 -1
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/mmif.py +11 -14
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/model.py +4 -1
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/view.py +3 -3
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/timeunit_helper.py +4 -4
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/video_document_helper.py +10 -8
- mmif-python-1.0.13/mmif/ver/__init__.py +2 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13/mmif_python.egg-info}/PKG-INFO +1 -1
- mmif-python-1.0.11/VERSION +0 -1
- mmif-python-1.0.11/mmif/ver/__init__.py +0 -2
- {mmif-python-1.0.11 → mmif-python-1.0.13}/LICENSE +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/MANIFEST.in +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/README.md +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/__init__.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/__init__.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/clams.vocabulary.yaml +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/do-not-edit.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/res/mmif.json +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/serialize/__init__.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/__init__.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/utils/sequence_helper.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/ver/do-not-edit.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/__init__.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/annotation_types.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/base_types.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/do-not-edit.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif/vocabulary/document_types.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_docloc_http/__init__.py +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/SOURCES.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/dependency_links.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/requires.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/mmif_python.egg-info/top_level.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/requirements.cv +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/requirements.seq +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/requirements.txt +0 -0
- {mmif-python-1.0.11 → mmif-python-1.0.13}/setup.cfg +0 -0
- {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.
|
|
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
|
|
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,
|
|
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
|
|
366
|
-
vid, did = doc_id.split(
|
|
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
|
|
414
|
-
view_id, ann_id = ann_id.split(
|
|
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
|
|
442
|
-
vid, did = doc_id.split(
|
|
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
|
|
510
|
-
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(
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
71
|
+
return round(t / 1000 * fps)
|
|
72
72
|
# s>f
|
|
73
73
|
elif 'second' == in_unit:
|
|
74
|
-
return
|
|
74
|
+
return round(t * fps)
|
|
75
75
|
# s>(ms or i)
|
|
76
76
|
elif in_unit == 'second':
|
|
77
|
-
return
|
|
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,
|
|
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 ``
|
|
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
|
|
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
|
-
|
|
138
|
-
|
|
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
|
-
|
|
142
|
-
|
|
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
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mmif-python
|
|
3
|
-
Version: 1.0.
|
|
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
|
mmif-python-1.0.11/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.0.11
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|