media-engine 0.1.0__tar.gz → 0.1.1__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 (97) hide show
  1. {media_engine-0.1.0 → media_engine-0.1.1}/PKG-INFO +3 -2
  2. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/_version.py +2 -2
  3. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/routers/models.py +27 -11
  4. {media_engine-0.1.0 → media_engine-0.1.1}/pyproject.toml +2 -1
  5. media_engine-0.1.1/tests/test_dependencies.py +176 -0
  6. {media_engine-0.1.0 → media_engine-0.1.1}/.github/workflows/ci.yml +0 -0
  7. {media_engine-0.1.0 → media_engine-0.1.1}/.github/workflows/release.yml +0 -0
  8. {media_engine-0.1.0 → media_engine-0.1.1}/.gitignore +0 -0
  9. {media_engine-0.1.0 → media_engine-0.1.1}/API.md +0 -0
  10. {media_engine-0.1.0 → media_engine-0.1.1}/CLAUDE.md +0 -0
  11. {media_engine-0.1.0 → media_engine-0.1.1}/Dockerfile +0 -0
  12. {media_engine-0.1.0 → media_engine-0.1.1}/Dockerfile.cuda +0 -0
  13. {media_engine-0.1.0 → media_engine-0.1.1}/Dockerfile.mlx +0 -0
  14. {media_engine-0.1.0 → media_engine-0.1.1}/LICENSE +0 -0
  15. {media_engine-0.1.0 → media_engine-0.1.1}/MANIFEST.in +0 -0
  16. {media_engine-0.1.0 → media_engine-0.1.1}/README.md +0 -0
  17. {media_engine-0.1.0 → media_engine-0.1.1}/cli/clip.py +0 -0
  18. {media_engine-0.1.0 → media_engine-0.1.1}/cli/faces.py +0 -0
  19. {media_engine-0.1.0 → media_engine-0.1.1}/cli/metadata.py +0 -0
  20. {media_engine-0.1.0 → media_engine-0.1.1}/cli/motion.py +0 -0
  21. {media_engine-0.1.0 → media_engine-0.1.1}/cli/objects.py +0 -0
  22. {media_engine-0.1.0 → media_engine-0.1.1}/cli/ocr.py +0 -0
  23. {media_engine-0.1.0 → media_engine-0.1.1}/cli/scenes.py +0 -0
  24. {media_engine-0.1.0 → media_engine-0.1.1}/cli/telemetry.py +0 -0
  25. {media_engine-0.1.0 → media_engine-0.1.1}/cli/transcript.py +0 -0
  26. {media_engine-0.1.0 → media_engine-0.1.1}/demo/index.html +0 -0
  27. {media_engine-0.1.0 → media_engine-0.1.1}/demo/run.sh +0 -0
  28. {media_engine-0.1.0 → media_engine-0.1.1}/demo/server.py +0 -0
  29. {media_engine-0.1.0 → media_engine-0.1.1}/docker-compose.yml +0 -0
  30. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/__init__.py +0 -0
  31. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/app.py +0 -0
  32. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/batch/__init__.py +0 -0
  33. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/batch/models.py +0 -0
  34. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/batch/processor.py +0 -0
  35. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/batch/queue.py +0 -0
  36. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/batch/state.py +0 -0
  37. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/batch/timing.py +0 -0
  38. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/cli.py +0 -0
  39. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/config.py +0 -0
  40. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/__init__.py +0 -0
  41. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/clip.py +0 -0
  42. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/faces.py +0 -0
  43. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/frame_buffer.py +0 -0
  44. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/frames.py +0 -0
  45. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/__init__.py +0 -0
  46. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/apple.py +0 -0
  47. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/arri.py +0 -0
  48. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/avchd.py +0 -0
  49. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/avchd_gps.py +0 -0
  50. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/base.py +0 -0
  51. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/blackmagic.py +0 -0
  52. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/camera_360.py +0 -0
  53. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/canon.py +0 -0
  54. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/dji.py +0 -0
  55. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/dv.py +0 -0
  56. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/ffmpeg.py +0 -0
  57. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/generic.py +0 -0
  58. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/gopro.py +0 -0
  59. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/red.py +0 -0
  60. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/registry.py +0 -0
  61. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/sony.py +0 -0
  62. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/metadata/tesla.py +0 -0
  63. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/motion.py +0 -0
  64. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/objects.py +0 -0
  65. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/objects_qwen.py +0 -0
  66. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/ocr.py +0 -0
  67. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/scenes.py +0 -0
  68. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/shot_type.py +0 -0
  69. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/telemetry.py +0 -0
  70. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/transcribe.py +0 -0
  71. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/translate.py +0 -0
  72. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/extractors/vad.py +0 -0
  73. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/main.py +0 -0
  74. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/py.typed +0 -0
  75. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/routers/__init__.py +0 -0
  76. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/routers/batch.py +0 -0
  77. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/routers/health.py +0 -0
  78. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/routers/settings.py +0 -0
  79. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/routers/utils.py +0 -0
  80. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/schemas.py +0 -0
  81. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/utils/__init__.py +0 -0
  82. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/utils/logging.py +0 -0
  83. {media_engine-0.1.0 → media_engine-0.1.1}/media_engine/utils/memory.py +0 -0
  84. {media_engine-0.1.0 → media_engine-0.1.1}/tests/__init__.py +0 -0
  85. {media_engine-0.1.0 → media_engine-0.1.1}/tests/conftest.py +0 -0
  86. {media_engine-0.1.0 → media_engine-0.1.1}/tests/stress_test.py +0 -0
  87. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_api.py +0 -0
  88. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_batch_api.py +0 -0
  89. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_clip.py +0 -0
  90. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_faces.py +0 -0
  91. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_memory.py +0 -0
  92. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_metadata.py +0 -0
  93. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_model_lifecycle.py +0 -0
  94. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_objects.py +0 -0
  95. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_ocr.py +0 -0
  96. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_scenes.py +0 -0
  97. {media_engine-0.1.0 → media_engine-0.1.1}/tests/test_transcribe.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: media-engine
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: AI-powered video extraction API for metadata, transcripts, faces, scenes, objects, and more
5
5
  Project-URL: Repository, https://github.com/thetrainroom/media-engine
6
6
  Project-URL: Issues, https://github.com/thetrainroom/media-engine/issues
@@ -28,6 +28,8 @@ Requires-Dist: psutil>=5.9.0
28
28
  Requires-Dist: pydantic-settings>=2.0.0
29
29
  Requires-Dist: pydantic>=2.0.0
30
30
  Requires-Dist: scenedetect[opencv]>=0.6.0
31
+ Requires-Dist: tf-keras>=2.16.0
32
+ Requires-Dist: transformers>=4.40.0
31
33
  Requires-Dist: uvicorn>=0.27.0
32
34
  Requires-Dist: webrtcvad>=2.0.10
33
35
  Provides-Extra: cpu
@@ -58,7 +60,6 @@ Provides-Extra: qwen
58
60
  Requires-Dist: accelerate>=0.30.0; extra == 'qwen'
59
61
  Requires-Dist: qwen-vl-utils>=0.0.8; extra == 'qwen'
60
62
  Requires-Dist: torch>=2.0.0; extra == 'qwen'
61
- Requires-Dist: transformers>=4.40.0; extra == 'qwen'
62
63
  Description-Content-Type: text/markdown
63
64
 
64
65
  # Media Engine
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.0'
32
- __version_tuple__ = version_tuple = (0, 1, 0)
31
+ __version__ = version = '0.1.1'
32
+ __version_tuple__ = version_tuple = (0, 1, 1)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -33,22 +33,38 @@ def _run_model_checks(check_id: str) -> None:
33
33
  _model_check_status[check_id] = "running"
34
34
 
35
35
  try:
36
- # Test Qwen 2B
37
- logger.info("Testing Qwen 2B model...")
38
- start = time.time()
36
+ # Test Qwen 2B (requires qwen extras: pip install media-engine[qwen])
39
37
  try:
40
- _get_qwen_model("Qwen/Qwen2-VL-2B-Instruct")
41
- results["qwen_2b"] = {
42
- "canLoad": True,
43
- "error": None,
44
- "loadTimeSeconds": round(time.time() - start, 1),
45
- }
46
- unload_qwen_model()
38
+ import importlib.util
39
+
40
+ if importlib.util.find_spec("transformers") is None:
41
+ results["qwen_2b"] = {
42
+ "canLoad": False,
43
+ "error": "transformers not installed. Install with: pip install media-engine[qwen]",
44
+ "loadTimeSeconds": 0,
45
+ }
46
+ else:
47
+ logger.info("Testing Qwen 2B model...")
48
+ start = time.time()
49
+ try:
50
+ _get_qwen_model("Qwen/Qwen2-VL-2B-Instruct")
51
+ results["qwen_2b"] = {
52
+ "canLoad": True,
53
+ "error": None,
54
+ "loadTimeSeconds": round(time.time() - start, 1),
55
+ }
56
+ unload_qwen_model()
57
+ except Exception as e:
58
+ results["qwen_2b"] = {
59
+ "canLoad": False,
60
+ "error": str(e),
61
+ "loadTimeSeconds": round(time.time() - start, 1),
62
+ }
47
63
  except Exception as e:
48
64
  results["qwen_2b"] = {
49
65
  "canLoad": False,
50
66
  "error": str(e),
51
- "loadTimeSeconds": round(time.time() - start, 1),
67
+ "loadTimeSeconds": 0,
52
68
  }
53
69
 
54
70
  # Test Whisper large-v3
@@ -25,6 +25,8 @@ dependencies = [
25
25
  "ffmpeg-python>=0.2.0",
26
26
  "scenedetect[opencv]>=0.6.0",
27
27
  "deepface>=0.0.79",
28
+ "tf-keras>=2.16.0", # Required by deepface with TensorFlow 2.16+
29
+ "transformers>=4.40.0", # Required for Qwen VLM
28
30
  "paddleocr>=2.7.0",
29
31
  "paddlepaddle>=2.5.0",
30
32
  "webrtcvad>=2.0.10",
@@ -70,7 +72,6 @@ cpu = [
70
72
  "ultralytics>=8.0.0",
71
73
  ]
72
74
  qwen = [
73
- "transformers>=4.40.0",
74
75
  "accelerate>=0.30.0",
75
76
  "qwen-vl-utils>=0.0.8",
76
77
  "torch>=2.0.0",
@@ -0,0 +1,176 @@
1
+ """Test that all required dependencies are importable."""
2
+
3
+ import importlib
4
+ import importlib.util
5
+
6
+ import pytest
7
+
8
+ # Modules that crash on import (e.g., paddle on macOS) - check with find_spec only
9
+ SPEC_CHECK_ONLY = {"paddle"}
10
+
11
+
12
+ class TestBaseDependencies:
13
+ """Test base dependencies that are always required."""
14
+
15
+ @pytest.mark.parametrize(
16
+ "module",
17
+ [
18
+ "fastapi",
19
+ "uvicorn",
20
+ "pydantic",
21
+ "pydantic_settings",
22
+ "ffmpeg",
23
+ "scenedetect",
24
+ "deepface",
25
+ "tf_keras",
26
+ "transformers",
27
+ "paddleocr",
28
+ "paddle",
29
+ "webrtcvad",
30
+ "psutil",
31
+ "langdetect",
32
+ "httpx",
33
+ ],
34
+ )
35
+ def test_base_dependency_importable(self, module: str):
36
+ """Verify base dependency can be imported."""
37
+ if module in SPEC_CHECK_ONLY:
38
+ # Some modules crash on import but are installed - just check spec
39
+ if importlib.util.find_spec(module) is None:
40
+ pytest.fail(f"Base dependency '{module}' not installed")
41
+ return
42
+
43
+ try:
44
+ importlib.import_module(module)
45
+ except ImportError as e:
46
+ pytest.fail(f"Base dependency '{module}' not importable: {e}")
47
+
48
+
49
+ class TestMLXDependencies:
50
+ """Test MLX dependencies (Apple Silicon)."""
51
+
52
+ @pytest.mark.parametrize(
53
+ "module",
54
+ [
55
+ "mlx",
56
+ "mlx_whisper",
57
+ "open_clip",
58
+ "torch",
59
+ "ultralytics",
60
+ ],
61
+ )
62
+ def test_mlx_dependency_importable(self, module: str):
63
+ """Verify MLX dependency can be imported if MLX extras installed."""
64
+ if importlib.util.find_spec("mlx") is None:
65
+ pytest.skip("MLX extras not installed")
66
+ try:
67
+ importlib.import_module(module)
68
+ except ImportError as e:
69
+ pytest.fail(f"MLX dependency '{module}' not importable: {e}")
70
+
71
+
72
+ class TestCUDADependencies:
73
+ """Test CUDA dependencies (NVIDIA GPU)."""
74
+
75
+ @pytest.mark.parametrize(
76
+ "module",
77
+ [
78
+ "faster_whisper",
79
+ "open_clip",
80
+ "torch",
81
+ "ultralytics",
82
+ ],
83
+ )
84
+ def test_cuda_dependency_importable(self, module: str):
85
+ """Verify CUDA dependency can be imported if CUDA extras installed."""
86
+ if importlib.util.find_spec("faster_whisper") is None:
87
+ pytest.skip("CUDA extras not installed")
88
+ try:
89
+ importlib.import_module(module)
90
+ except ImportError as e:
91
+ pytest.fail(f"CUDA dependency '{module}' not importable: {e}")
92
+
93
+
94
+ class TestCPUDependencies:
95
+ """Test CPU dependencies (fallback)."""
96
+
97
+ @pytest.mark.parametrize(
98
+ "module",
99
+ [
100
+ "whisper",
101
+ "open_clip",
102
+ "torch",
103
+ "ultralytics",
104
+ ],
105
+ )
106
+ def test_cpu_dependency_importable(self, module: str):
107
+ """Verify CPU dependency can be imported if CPU extras installed."""
108
+ if importlib.util.find_spec("whisper") is None:
109
+ pytest.skip("CPU extras not installed")
110
+ try:
111
+ importlib.import_module(module)
112
+ except ImportError as e:
113
+ pytest.fail(f"CPU dependency '{module}' not importable: {e}")
114
+
115
+
116
+ class TestQwenDependencies:
117
+ """Test Qwen dependencies (VLM)."""
118
+
119
+ @pytest.mark.parametrize(
120
+ "module",
121
+ [
122
+ "accelerate",
123
+ "qwen_vl_utils",
124
+ ],
125
+ )
126
+ def test_qwen_dependency_importable(self, module: str):
127
+ """Verify Qwen dependency can be imported if Qwen extras installed."""
128
+ if importlib.util.find_spec("qwen_vl_utils") is None:
129
+ pytest.skip("Qwen extras not installed")
130
+ try:
131
+ importlib.import_module(module)
132
+ except ImportError as e:
133
+ pytest.fail(f"Qwen dependency '{module}' not importable: {e}")
134
+
135
+
136
+ class TestMediaEngineImports:
137
+ """Test that media_engine modules are importable."""
138
+
139
+ @pytest.mark.parametrize(
140
+ "module",
141
+ [
142
+ "media_engine",
143
+ "media_engine.main",
144
+ "media_engine.config",
145
+ "media_engine.schemas",
146
+ "media_engine.extractors",
147
+ "media_engine.extractors.metadata",
148
+ "media_engine.extractors.scenes",
149
+ "media_engine.extractors.ocr",
150
+ "media_engine.extractors.telemetry",
151
+ ],
152
+ )
153
+ def test_media_engine_module_importable(self, module: str):
154
+ """Verify media_engine module can be imported."""
155
+ try:
156
+ importlib.import_module(module)
157
+ except ImportError as e:
158
+ pytest.fail(f"Module '{module}' not importable: {e}")
159
+
160
+ def test_extractors_with_torch(self):
161
+ """Verify extractors requiring torch are importable when torch is available."""
162
+ if importlib.util.find_spec("torch") is None:
163
+ pytest.skip("torch not installed")
164
+
165
+ modules = [
166
+ "media_engine.extractors.faces",
167
+ "media_engine.extractors.objects",
168
+ "media_engine.extractors.objects_qwen",
169
+ "media_engine.extractors.clip",
170
+ "media_engine.extractors.transcribe",
171
+ ]
172
+ for module in modules:
173
+ try:
174
+ importlib.import_module(module)
175
+ except ImportError as e:
176
+ pytest.fail(f"Module '{module}' not importable: {e}")
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