mediaref 0.1.0__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.
@@ -0,0 +1,32 @@
1
+ name: "Publish"
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ # Publish on any tag starting with a `v`, e.g., v0.1.0
7
+ - v*
8
+
9
+ jobs:
10
+ run:
11
+ runs-on: ubuntu-latest
12
+ environment:
13
+ name: pypi
14
+ permissions:
15
+ id-token: write
16
+ contents: read
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v5
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v6
22
+ - name: Install Python 3.13
23
+ run: uv python install 3.13
24
+ - name: Build
25
+ run: uv build
26
+ # Check that basic features work and we didn't miss to include crucial files
27
+ # - name: Smoke test (wheel)
28
+ # run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
29
+ # - name: Smoke test (source distribution)
30
+ # run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
31
+ - name: Publish
32
+ run: uv publish
@@ -0,0 +1,32 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main, develop ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ matrix:
14
+ os: [ubuntu-latest, macos-latest, windows-latest]
15
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v5
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v7
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Setup environments
25
+ run: |
26
+ uv venv
27
+ uv pip install -e ".[loader,dev]"
28
+
29
+ - name: Run tests
30
+ run: |
31
+ uv run pytest --cov=mediaref --cov-report=xml --cov-report=term
32
+
@@ -0,0 +1,216 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+
204
+ # Ruff stuff:
205
+ .ruff_cache/
206
+
207
+ # PyPI configuration file
208
+ .pypirc
209
+
210
+ # Marimo
211
+ marimo/_static/
212
+ marimo/_lsp/
213
+ __marimo__/
214
+
215
+ # Streamlit
216
+ .streamlit/secrets.toml
@@ -0,0 +1,58 @@
1
+ # Contributing to MediaRef
2
+
3
+ Thank you for your interest in contributing to MediaRef!
4
+
5
+ ## Development Setup
6
+
7
+ 1. Clone the repository:
8
+ ```bash
9
+ git clone https://github.com/open-world-agents/mediaref.git
10
+ cd mediaref
11
+ ```
12
+
13
+ 2. Install in development mode with all dependencies:
14
+ ```bash
15
+ pip install -e ".[loader,dev]"
16
+ ```
17
+
18
+ ## Running Tests
19
+
20
+ ```bash
21
+ # Run all tests
22
+ pytest
23
+
24
+ # Run with coverage
25
+ pytest --cov=mediaref --cov-report=html
26
+
27
+ # Run specific test
28
+ pytest tests/test_mediaref.py::TestMediaRefLoading::test_to_rgb_array
29
+ ```
30
+
31
+ ## Code Style
32
+
33
+ - Follow PEP 8
34
+ - Use type hints
35
+ - Write docstrings for public APIs
36
+ - Keep functions focused and small
37
+
38
+ ## Making Changes
39
+
40
+ 1. Create a new branch for your feature/fix
41
+ 2. Make your changes
42
+ 3. Add tests for new functionality
43
+ 4. Ensure all tests pass
44
+ 5. Update documentation if needed
45
+ 6. Submit a pull request
46
+
47
+ ## Reporting Issues
48
+
49
+ Please include:
50
+ - Python version
51
+ - MediaRef version
52
+ - Minimal reproducible example
53
+ - Expected vs actual behavior
54
+
55
+ ## Questions?
56
+
57
+ Open an issue or discussion on GitHub.
58
+
mediaref-0.1.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Open World Agents Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.4
2
+ Name: mediaref
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author-email: Suhwan Choi <milkclouds00@gmail.com>
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.9
8
+ Requires-Dist: pydantic>=2.0
9
+ Provides-Extra: dev
10
+ Requires-Dist: ipython; extra == 'dev'
11
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
12
+ Requires-Dist: pytest>=7.0; extra == 'dev'
13
+ Provides-Extra: loader
14
+ Requires-Dist: av>=15.0; extra == 'loader'
15
+ Requires-Dist: loguru; extra == 'loader'
16
+ Requires-Dist: numpy; extra == 'loader'
17
+ Requires-Dist: opencv-python; extra == 'loader'
18
+ Requires-Dist: pillow; extra == 'loader'
19
+ Requires-Dist: requests; extra == 'loader'
20
+ Description-Content-Type: text/markdown
21
+
22
+ # MediaRef
23
+
24
+ Pydantic-based media reference for images and video frames. Supports file paths, URLs, data URIs, and video timestamps. Designed for dataset metadata and lazy loading.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ # Core package (MediaRef definition only)
30
+ pip install -e .
31
+
32
+ # With loader support (includes batch loading, video decoders)
33
+ pip install -e ".[loader]"
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ```python
39
+ from mediaref import MediaRef, load_batch
40
+
41
+ # Reference creation - supports multiple URI schemes
42
+ MediaRef(uri="image.png") # Local file
43
+ MediaRef(uri="https://example.com/image.jpg") # Remote URL
44
+ MediaRef(uri="video.mp4", pts_ns=1_000_000_000) # Video frame at 1.0s
45
+ MediaRef(uri="data:image/png;base64,...") # Embedded data URI
46
+
47
+ # Loading
48
+ ref.to_rgb_array() # Returns (H, W, 3) numpy array
49
+ ref.to_pil_image() # Returns PIL.Image
50
+
51
+ # Batch loading with automatic caching (default: PyAV decoder)
52
+ refs = [MediaRef(uri="video.mp4", pts_ns=i*1e9) for i in range(10)]
53
+ frames = load_batch(refs) # Reuses video container
54
+
55
+ # Use TorchCodec decoder for GPU acceleration (requires torchcodec>=0.4.0)
56
+ frames = load_batch(refs, decoder="torchcodec")
57
+
58
+ # Embedding
59
+ data_uri = ref.embed_as_data_uri(format="png") # Encode to data URI
60
+ MediaRef(uri=data_uri) # Create from data URI
61
+
62
+ # Path resolution for MCAP/rosbag datasets
63
+ ref = MediaRef(uri="relative/video.mkv", pts_ns=123456)
64
+ ref.resolve_relative_path("/data/recording.mcap") # Returns absolute path
65
+
66
+ # Serialization (Pydantic-based)
67
+ ref.model_dump() # {'uri': '...', 'pts_ns': ...}
68
+ ref.model_dump_json() # '{"uri":"...","pts_ns":...}'
69
+ MediaRef.model_validate(data) # From dict
70
+ MediaRef.model_validate_json(json_str) # From JSON string
71
+ ```
72
+
73
+ ## API Reference
74
+
75
+ ### MediaRef(uri: str, pts_ns: int | None = None)
76
+
77
+ **Properties:** `is_embedded`, `is_video`, `is_remote`, `is_local`, `is_relative_path`
78
+
79
+ **Methods:**
80
+ - `to_rgb_array(**kwargs) -> np.ndarray` - Load as RGB array (H, W, 3)
81
+ - `to_pil_image(**kwargs) -> PIL.Image` - Load as PIL Image
82
+ - `embed_as_data_uri(format="png", quality=None) -> str` - Encode to data URI
83
+ - `resolve_relative_path(base_path, allow_nonlocal=False) -> MediaRef` - Resolve relative paths
84
+ - `validate_uri() -> bool` - Check if URI exists (local files only)
85
+ - `model_dump() -> dict` - Serialize to dict
86
+ - `model_dump_json() -> str` - Serialize to JSON
87
+ - `model_validate(data) -> MediaRef` - Deserialize from dict
88
+ - `model_validate_json(json_str) -> MediaRef` - Deserialize from JSON
89
+
90
+ ### Functions
91
+
92
+ - `load_batch(refs: list[MediaRef], **kwargs) -> list[np.ndarray]` - Batch load with caching
93
+ - `cleanup_cache()` - Clear video container cache
94
+
95
+ ### Video Decoders (requires `[loader]` extra)
96
+
97
+ - `PyAVVideoDecoder(video_path)` - PyAV-based decoder with TorchCodec-compatible interface
98
+ - `TorchCodecVideoDecoder(video_path)` - TorchCodec-based decoder (requires `torchcodec>=0.4.0`)
99
+
100
+ ## Design Notes
101
+
102
+ - Video container caching uses reference counting with LRU eviction (default: 10 containers)
103
+ - MCAP file path resolution: detects `.mcap` suffix and uses parent directory as base
104
+ - Garbage collection triggered every 10 PyAV operations to handle reference cycles
105
+ - Cache size configurable via `AV_CACHE_SIZE` environment variable
106
+
107
+ ## Acknowledgments
108
+
109
+ The video decoder interface design references [TorchCodec](https://github.com/pytorch/torchcodec)'s API design.
110
+
111
+ ## Dependencies
112
+
113
+ **Core:** `pydantic>=2.0` (requires Pydantic v2 API)
114
+
115
+ **Loader (optional):** `numpy`, `opencv-python`, `pillow`, `av`, `requests`
116
+
117
+ The loader dependencies use stable APIs with no version constraints. Install with `pip install mediaref[loader]` to enable batch loading and video decoding.
118
+
@@ -0,0 +1,97 @@
1
+ # MediaRef
2
+
3
+ Pydantic-based media reference for images and video frames. Supports file paths, URLs, data URIs, and video timestamps. Designed for dataset metadata and lazy loading.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Core package (MediaRef definition only)
9
+ pip install -e .
10
+
11
+ # With loader support (includes batch loading, video decoders)
12
+ pip install -e ".[loader]"
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```python
18
+ from mediaref import MediaRef, load_batch
19
+
20
+ # Reference creation - supports multiple URI schemes
21
+ MediaRef(uri="image.png") # Local file
22
+ MediaRef(uri="https://example.com/image.jpg") # Remote URL
23
+ MediaRef(uri="video.mp4", pts_ns=1_000_000_000) # Video frame at 1.0s
24
+ MediaRef(uri="data:image/png;base64,...") # Embedded data URI
25
+
26
+ # Loading
27
+ ref.to_rgb_array() # Returns (H, W, 3) numpy array
28
+ ref.to_pil_image() # Returns PIL.Image
29
+
30
+ # Batch loading with automatic caching (default: PyAV decoder)
31
+ refs = [MediaRef(uri="video.mp4", pts_ns=i*1e9) for i in range(10)]
32
+ frames = load_batch(refs) # Reuses video container
33
+
34
+ # Use TorchCodec decoder for GPU acceleration (requires torchcodec>=0.4.0)
35
+ frames = load_batch(refs, decoder="torchcodec")
36
+
37
+ # Embedding
38
+ data_uri = ref.embed_as_data_uri(format="png") # Encode to data URI
39
+ MediaRef(uri=data_uri) # Create from data URI
40
+
41
+ # Path resolution for MCAP/rosbag datasets
42
+ ref = MediaRef(uri="relative/video.mkv", pts_ns=123456)
43
+ ref.resolve_relative_path("/data/recording.mcap") # Returns absolute path
44
+
45
+ # Serialization (Pydantic-based)
46
+ ref.model_dump() # {'uri': '...', 'pts_ns': ...}
47
+ ref.model_dump_json() # '{"uri":"...","pts_ns":...}'
48
+ MediaRef.model_validate(data) # From dict
49
+ MediaRef.model_validate_json(json_str) # From JSON string
50
+ ```
51
+
52
+ ## API Reference
53
+
54
+ ### MediaRef(uri: str, pts_ns: int | None = None)
55
+
56
+ **Properties:** `is_embedded`, `is_video`, `is_remote`, `is_local`, `is_relative_path`
57
+
58
+ **Methods:**
59
+ - `to_rgb_array(**kwargs) -> np.ndarray` - Load as RGB array (H, W, 3)
60
+ - `to_pil_image(**kwargs) -> PIL.Image` - Load as PIL Image
61
+ - `embed_as_data_uri(format="png", quality=None) -> str` - Encode to data URI
62
+ - `resolve_relative_path(base_path, allow_nonlocal=False) -> MediaRef` - Resolve relative paths
63
+ - `validate_uri() -> bool` - Check if URI exists (local files only)
64
+ - `model_dump() -> dict` - Serialize to dict
65
+ - `model_dump_json() -> str` - Serialize to JSON
66
+ - `model_validate(data) -> MediaRef` - Deserialize from dict
67
+ - `model_validate_json(json_str) -> MediaRef` - Deserialize from JSON
68
+
69
+ ### Functions
70
+
71
+ - `load_batch(refs: list[MediaRef], **kwargs) -> list[np.ndarray]` - Batch load with caching
72
+ - `cleanup_cache()` - Clear video container cache
73
+
74
+ ### Video Decoders (requires `[loader]` extra)
75
+
76
+ - `PyAVVideoDecoder(video_path)` - PyAV-based decoder with TorchCodec-compatible interface
77
+ - `TorchCodecVideoDecoder(video_path)` - TorchCodec-based decoder (requires `torchcodec>=0.4.0`)
78
+
79
+ ## Design Notes
80
+
81
+ - Video container caching uses reference counting with LRU eviction (default: 10 containers)
82
+ - MCAP file path resolution: detects `.mcap` suffix and uses parent directory as base
83
+ - Garbage collection triggered every 10 PyAV operations to handle reference cycles
84
+ - Cache size configurable via `AV_CACHE_SIZE` environment variable
85
+
86
+ ## Acknowledgments
87
+
88
+ The video decoder interface design references [TorchCodec](https://github.com/pytorch/torchcodec)'s API design.
89
+
90
+ ## Dependencies
91
+
92
+ **Core:** `pydantic>=2.0` (requires Pydantic v2 API)
93
+
94
+ **Loader (optional):** `numpy`, `opencv-python`, `pillow`, `av`, `requests`
95
+
96
+ The loader dependencies use stable APIs with no version constraints. Install with `pip install mediaref[loader]` to enable batch loading and video decoding.
97
+