clams-python 1.8.1__tar.gz → 1.8.2__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.
- {clams_python-1.8.1 → clams_python-1.8.2}/CHANGELOG.md +14 -0
- {clams_python-1.8.1/clams_python.egg-info → clams_python-1.8.2}/PKG-INFO +2 -2
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/app/__init__.py +34 -64
- {clams_python-1.8.1 → clams_python-1.8.2/clams_python.egg-info}/PKG-INFO +2 -2
- {clams_python-1.8.1 → clams_python-1.8.2}/clams_python.egg-info/requires.txt +1 -1
- clams_python-1.8.2/clams_python.egg-info/scm_version.json +8 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/target-versions.csv +1 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/pyproject.toml +1 -1
- {clams_python-1.8.1 → clams_python-1.8.2}/tests/test_clamsapp.py +63 -1
- clams_python-1.8.1/clams_python.egg-info/scm_version.json +0 -8
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/codecov.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/container.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/containers.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/issue-assign.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/issue-close.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/issue-infra-project.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/publish.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.github/workflows/release-check.yml +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/.gitignore +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/CONTRIBUTING.md +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/LICENSE +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/README.md +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/build-tools/build.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/build-tools/clean.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/build-tools/docs.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/build-tools/prep_release.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/build-tools/publish.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/build-tools/test.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/appmetadata/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/backends/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/backends/hf.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/.dockerignore.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/.gitignore.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/Containerfile.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/LICENSE.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/README.md.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/app.py.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/cli.py.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/metadata.py.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/requirements.txt.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/gha/for-clams-team.md.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/gha/workflows/issue-apps-project.yml.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/gha/workflows/issue-assign.yml.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/gha/workflows/issue-close.yml.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/gha/workflows/publish.yml.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/utl-tf/__init__.py.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/utl-tf/timeframe.py.template +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/envelop/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/restify/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/serve/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams/ver/__init__.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams_python.egg-info/SOURCES.txt +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams_python.egg-info/dependency_links.txt +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams_python.egg-info/entry_points.txt +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams_python.egg-info/scm_file_list.json +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/clams_python.egg-info/top_level.txt +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/Containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/ffmpeg-hf.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/ffmpeg-hf4.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/ffmpeg-hf5.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/ffmpeg-tf2.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/ffmpeg-torch2.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/ffmpeg.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/generate_containers_yml.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/hf.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/hf4.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/hf5.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/jdk8.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/opencv4-hf.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/opencv4-hf4.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/opencv4-hf5.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/opencv4-tf2.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/opencv4-torch2.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/opencv4.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/tf2.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/container/torch2.containerfile +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/app-baseclasses.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/appdirectory.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/appmetadata.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/autodoc/clams.app.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/autodoc/clams.appmetadata.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/autodoc/clams.backends.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/autodoc/clams.mmif_utils.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/autodoc/clams.restify.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/clamsapp.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/cli.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/conf.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/gpu-apps.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/index.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/input-output.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/introduction.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/modules.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/runtime-params.rst +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/documentation/tutorial.md +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/setup.cfg +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/tests/metadata.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/tests/pillow-logo.png +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/tests/test_backends_hf.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/tests/test_develop.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/tests/test_envelope.py +0 -0
- {clams_python-1.8.1 → clams_python-1.8.2}/tests/test_promptable.py +0 -0
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
|
|
2
|
+
## releasing 1.8.1 (2026-10-27)
|
|
3
|
+
### Overview
|
|
4
|
+
|
|
5
|
+
Updates `mmif-python` to 1.6.0, with many small fixes for the consistency of MMIF files and CLAMS workflows.
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
|
|
9
|
+
* `mmif-python` is updated to 1.6.0 (https://github.com/clamsproject/clams-python/issues/314)
|
|
10
|
+
* view timestamps: consistently in UTC now, instead of local time (https://github.com/clamsproject/clams-python/issues/312)
|
|
11
|
+
* error views: fixed a bug where an error in a run overwrote the view of an earlier run of the same app (part of https://github.com/clamsproject/clams-python/pull/313, found during working on #312)
|
|
12
|
+
* document properties: fixed a bug where the (capital) `Annotation` for properties added to an existing document was attached to a wrong view, when the app produced no other annotations (https://github.com/clamsproject/clams-python/issues/314)
|
|
13
|
+
* `clams develop`: the `utl-tf` recipe is deprecated and no longer baked by default; its helpers are now provided by mmif-python 1.6.0 as `Mmif.get_annotations_of_labels()` and `mmif.utils.video_document_helper.iter_timeframe_images()` (https://github.com/clamsproject/clams-python/issues/314)
|
|
14
|
+
|
|
15
|
+
|
|
2
16
|
## releasing 1.8.0 (2026-10-06)
|
|
3
17
|
### Overview
|
|
4
18
|
Adds runtime parameters that cap the number of images per prompt in promptable apps, and updates `mmif-python` to 1.5.4.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clams-python
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.2
|
|
4
4
|
Summary: A collection of APIs to develop CLAMS app for python
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: homepage, https://clams.ai
|
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
Requires-Dist: mmif-python==1.
|
|
16
|
+
Requires-Dist: mmif-python==1.7.0
|
|
17
17
|
Requires-Dist: Flask>=2
|
|
18
18
|
Requires-Dist: Flask-RESTful>=0.3.9
|
|
19
19
|
Requires-Dist: gunicorn>=20
|
|
@@ -17,7 +17,9 @@ __all__ = ['ClamsApp', 'ClamsPromptableApp', 'ClamsHFPromptableApp',
|
|
|
17
17
|
|
|
18
18
|
from typing import Union, Any, Optional, Dict, List, Mapping, Tuple, cast
|
|
19
19
|
|
|
20
|
-
from mmif import
|
|
20
|
+
from mmif import (
|
|
21
|
+
Mmif, Document, DocumentTypes, View, AnnotationTypes, EmptyOutputWarning,
|
|
22
|
+
)
|
|
21
23
|
from mmif.utils.video_document_helper import (
|
|
22
24
|
SamplingMode, SAMPLING_MODE_DESCRIPTIONS, SAMPLING_MODE_DEFAULT,
|
|
23
25
|
_sampling_mode,
|
|
@@ -53,10 +55,6 @@ falsy_values = [
|
|
|
53
55
|
]
|
|
54
56
|
|
|
55
57
|
|
|
56
|
-
class EmptyOutputWarning(UserWarning):
|
|
57
|
-
"""Raised when an app's ``_annotate()`` produces no non-empty views."""
|
|
58
|
-
|
|
59
|
-
|
|
60
58
|
class ImagesPerPromptMode(Enum):
|
|
61
59
|
"""
|
|
62
60
|
How :py:meth:`ClamsPromptableApp.chunk_tasks` sizes the chunks of a
|
|
@@ -224,7 +222,6 @@ class ClamsApp(ABC):
|
|
|
224
222
|
if not isinstance(mmif, Mmif):
|
|
225
223
|
mmif, runtime_params = unwrap_if_envelope(mmif, runtime_params)
|
|
226
224
|
mmif = Mmif(mmif)
|
|
227
|
-
existing_view_ids = {view.id for view in mmif.views}
|
|
228
225
|
issued_warnings: List[Union[Warning, warnings.WarningMessage]] = []
|
|
229
226
|
for key in runtime_params:
|
|
230
227
|
if key not in self.annotate_param_spec:
|
|
@@ -238,70 +235,43 @@ class ClamsApp(ABC):
|
|
|
238
235
|
if sampling_mode_str is not None:
|
|
239
236
|
_sampling_mode.set(SamplingMode(sampling_mode_str))
|
|
240
237
|
t = datetime.now()
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
runtime_recs['cpu'] = f"{platform.machine()}, {multiprocessing.cpu_count()} cores"
|
|
271
|
-
runtime_recs['cuda'] = []
|
|
272
|
-
# Use cuda_profiler data if available, otherwise fallback to nvidia-smi
|
|
273
|
-
if cuda_profiler:
|
|
274
|
-
for gpu_name, mem_info in cuda_profiler.items():
|
|
275
|
-
total_str = self._cuda_memory_to_str(mem_info['total'])
|
|
276
|
-
available_str = self._cuda_memory_to_str(mem_info['available_before'])
|
|
277
|
-
peak_str = self._cuda_memory_to_str(mem_info['peak'])
|
|
278
|
-
runtime_recs['cuda'].append(
|
|
279
|
-
f"{gpu_name}, {total_str} total, {available_str} available, {peak_str} peak used"
|
|
280
|
-
)
|
|
281
|
-
elif shutil.which('nvidia-smi'):
|
|
282
|
-
for gpu in subprocess.run(['nvidia-smi', '--query-gpu=name,memory.total', '--format=csv,noheader'],
|
|
283
|
-
stdout=subprocess.PIPE).stdout.decode('utf-8').strip().split('\n'):
|
|
284
|
-
name, mem = gpu.split(', ')
|
|
285
|
-
runtime_recs['cuda'].append(self._cuda_device_name_concat(name, mem))
|
|
286
|
-
new_app_views = [v for v in annotated.views
|
|
287
|
-
if v.id not in existing_view_ids
|
|
288
|
-
and v.metadata.app == str(self.metadata.identifier)]
|
|
289
|
-
# all views from this run share the timestamp that mmif-python
|
|
290
|
-
# assigned to the first of them, serving as the "run ID"
|
|
291
|
-
run_id = next((v.metadata.timestamp for v in new_app_views
|
|
292
|
-
if v.metadata.timestamp is not None), None)
|
|
293
|
-
for annotated_view in new_app_views:
|
|
294
|
-
if run_id is not None:
|
|
295
|
-
annotated_view.metadata.timestamp = run_id
|
|
238
|
+
signature = View()
|
|
239
|
+
self.sign_view(signature, refined)
|
|
240
|
+
with mmif.set_producer(signature) as producer:
|
|
241
|
+
with warnings.catch_warnings(record=True) as ws:
|
|
242
|
+
annotated, cuda_profiler = self._profile_cuda_memory(self._annotate)(mmif, **refined)
|
|
243
|
+
producer.add_warnings(*issued_warnings, *ws)
|
|
244
|
+
td = datetime.now() - t
|
|
245
|
+
runningTime = refined.get('runningTime', False)
|
|
246
|
+
hwFetch = refined.get('hwFetch', False)
|
|
247
|
+
runtime_recs: Dict[str, Any] = {}
|
|
248
|
+
if hwFetch:
|
|
249
|
+
import multiprocessing
|
|
250
|
+
import platform, shutil, subprocess
|
|
251
|
+
runtime_recs['cpu'] = f"{platform.machine()}, {multiprocessing.cpu_count()} cores"
|
|
252
|
+
runtime_recs['cuda'] = []
|
|
253
|
+
# Use cuda_profiler data if available, otherwise fallback to nvidia-smi
|
|
254
|
+
if cuda_profiler:
|
|
255
|
+
for gpu_name, mem_info in cuda_profiler.items():
|
|
256
|
+
total_str = self._cuda_memory_to_str(mem_info['total'])
|
|
257
|
+
available_str = self._cuda_memory_to_str(mem_info['available_before'])
|
|
258
|
+
peak_str = self._cuda_memory_to_str(mem_info['peak'])
|
|
259
|
+
runtime_recs['cuda'].append(
|
|
260
|
+
f"{gpu_name}, {total_str} total, {available_str} available, {peak_str} peak used"
|
|
261
|
+
)
|
|
262
|
+
elif shutil.which('nvidia-smi'):
|
|
263
|
+
for gpu in subprocess.run(['nvidia-smi', '--query-gpu=name,memory.total', '--format=csv,noheader'],
|
|
264
|
+
stdout=subprocess.PIPE).stdout.decode('utf-8').strip().split('\n'):
|
|
265
|
+
name, mem = gpu.split(', ')
|
|
266
|
+
runtime_recs['cuda'].append(self._cuda_device_name_concat(name, mem))
|
|
296
267
|
profiling_data: Dict[str, Any] = {}
|
|
297
268
|
if runningTime:
|
|
298
269
|
profiling_data['runningTime'] = str(td)
|
|
299
270
|
if len(runtime_recs) > 0:
|
|
300
271
|
profiling_data['hardware'] = runtime_recs
|
|
301
272
|
if profiling_data:
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
return annotated.serialize(pretty=pretty, sanitize=True)
|
|
273
|
+
producer.set_view_metadata('appProfiling', profiling_data)
|
|
274
|
+
return annotated.serialize(pretty=pretty, sanitize=True)
|
|
305
275
|
|
|
306
276
|
@abstractmethod
|
|
307
277
|
def _annotate(self, mmif: Mmif, _raw_parameters=None, **refined_parameters) -> Mmif:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clams-python
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.2
|
|
4
4
|
Summary: A collection of APIs to develop CLAMS app for python
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: homepage, https://clams.ai
|
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
Requires-Dist: mmif-python==1.
|
|
16
|
+
Requires-Dist: mmif-python==1.7.0
|
|
17
17
|
Requires-Dist: Flask>=2
|
|
18
18
|
Requires-Dist: Flask-RESTful>=0.3.9
|
|
19
19
|
Requires-Dist: gunicorn>=20
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"``clams-python`` version","``mmif-python`` version","Target MMIF Specification"
|
|
2
|
+
`1.8.2 <https://pypi.org/project/clams-python/1.8.2/>`__,`1.7.0 <https://pypi.org/project/mmif-python/1.7.0/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
2
3
|
`1.8.1 <https://pypi.org/project/clams-python/1.8.1/>`__,`1.6.0 <https://pypi.org/project/mmif-python/1.6.0/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
3
4
|
`1.8.0 <https://pypi.org/project/clams-python/1.8.0/>`__,`1.5.4 <https://pypi.org/project/mmif-python/1.5.4/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
4
5
|
`1.7.4 <https://pypi.org/project/clams-python/1.7.4/>`__,`1.5.3 <https://pypi.org/project/mmif-python/1.5.3/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
@@ -11,7 +11,10 @@ from unittest.mock import patch
|
|
|
11
11
|
|
|
12
12
|
import jsonschema
|
|
13
13
|
import pytest
|
|
14
|
-
from mmif import
|
|
14
|
+
from mmif import (
|
|
15
|
+
Mmif, Document, DocumentTypes, AnnotationTypes, View, EmptyOutputWarning,
|
|
16
|
+
__specver__,
|
|
17
|
+
)
|
|
15
18
|
from mmif.serialize.mmif import ViewsList
|
|
16
19
|
|
|
17
20
|
import clams.app
|
|
@@ -518,6 +521,65 @@ class TestClamsApp(unittest.TestCase):
|
|
|
518
521
|
self.assertEqual(len(view.annotations), 1)
|
|
519
522
|
self.assertFalse(view.has_warnings())
|
|
520
523
|
|
|
524
|
+
def _in_mmif_with_earlier_view(self):
|
|
525
|
+
in_mmif = Mmif(self.in_mmif)
|
|
526
|
+
doc_id = next(iter(in_mmif.documents)).id
|
|
527
|
+
earlier = in_mmif.new_view()
|
|
528
|
+
earlier.metadata.app = 'http://apps.clams.ai/earlier-app/v1'
|
|
529
|
+
earlier.new_contain(AnnotationTypes.TimeFrame, document=doc_id)
|
|
530
|
+
earlier.new_annotation(AnnotationTypes.TimeFrame, start=0, end=1)
|
|
531
|
+
return in_mmif.serialize()
|
|
532
|
+
|
|
533
|
+
def test_document_properties_go_to_a_new_signed_view(self):
|
|
534
|
+
class DocPropClamsApp(clams.app.ClamsApp):
|
|
535
|
+
def _appmetadata(self):
|
|
536
|
+
pass
|
|
537
|
+
def _annotate(self, mmif, **kwargs):
|
|
538
|
+
next(iter(mmif.documents)).add_property('duration', 1000)
|
|
539
|
+
return mmif
|
|
540
|
+
app = DocPropClamsApp()
|
|
541
|
+
in_str = self._in_mmif_with_earlier_view()
|
|
542
|
+
out_str = app.annotate(in_str)
|
|
543
|
+
self.assertEqual(json.loads(in_str)['views'][0],
|
|
544
|
+
json.loads(out_str)['views'][0])
|
|
545
|
+
out_views = list(Mmif(out_str).views)
|
|
546
|
+
self.assertEqual(len(out_views), 2)
|
|
547
|
+
self.assertEqual(out_views[1].metadata.app,
|
|
548
|
+
str(app.metadata.identifier))
|
|
549
|
+
records = list(out_views[1].get_annotations(AnnotationTypes.Annotation))
|
|
550
|
+
self.assertEqual(len(records), 1)
|
|
551
|
+
self.assertEqual(records[0].get_property('duration'), 1000)
|
|
552
|
+
self.assertFalse(out_views[1].has_warnings())
|
|
553
|
+
|
|
554
|
+
def test_earlier_views_are_written_unchanged(self):
|
|
555
|
+
in_str = self._in_mmif_with_earlier_view()
|
|
556
|
+
out_str = self.app.annotate(in_str)
|
|
557
|
+
self.assertEqual(json.loads(in_str)['views'][0],
|
|
558
|
+
json.loads(out_str)['views'][0])
|
|
559
|
+
|
|
560
|
+
def test_failed_run_leaves_mmif_reusable(self):
|
|
561
|
+
class FlakyClamsApp(clams.app.ClamsApp):
|
|
562
|
+
attempts = 0
|
|
563
|
+
def _appmetadata(self):
|
|
564
|
+
pass
|
|
565
|
+
def _annotate(self, mmif, **kwargs):
|
|
566
|
+
self.attempts += 1
|
|
567
|
+
if self.attempts == 1:
|
|
568
|
+
raise ValueError('first attempt fails')
|
|
569
|
+
new_view = mmif.new_view()
|
|
570
|
+
self.sign_view(new_view, kwargs)
|
|
571
|
+
new_view.new_contain(AnnotationTypes.TimeFrame)
|
|
572
|
+
new_view.new_annotation(AnnotationTypes.TimeFrame, start=0, end=1)
|
|
573
|
+
return mmif
|
|
574
|
+
app = FlakyClamsApp()
|
|
575
|
+
in_mmif = Mmif(self.in_mmif)
|
|
576
|
+
with self.assertRaises(ValueError):
|
|
577
|
+
app.annotate(in_mmif)
|
|
578
|
+
self.assertEqual(len(Mmif(app.annotate(in_mmif)).views), 1)
|
|
579
|
+
|
|
580
|
+
def test_empty_output_warning_is_importable_from_clams(self):
|
|
581
|
+
self.assertIs(clams.app.EmptyOutputWarning, EmptyOutputWarning)
|
|
582
|
+
|
|
521
583
|
def test_self_reported_error_view_is_not_pruned(self):
|
|
522
584
|
class ErroringClamsApp(clams.app.ClamsApp):
|
|
523
585
|
def _appmetadata(self):
|
|
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
|
{clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/.dockerignore.template
RENAMED
|
File without changes
|
|
File without changes
|
{clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/Containerfile.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/app/requirements.txt.template
RENAMED
|
File without changes
|
{clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/gha/for-clams-team.md.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/gha/workflows/publish.yml.template
RENAMED
|
File without changes
|
{clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/utl-tf/__init__.py.template
RENAMED
|
File without changes
|
{clams_python-1.8.1 → clams_python-1.8.2}/clams/develop/templates/utl-tf/timeframe.py.template
RENAMED
|
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
|
|
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
|
|
File without changes
|