track-id 0.1.3__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 (34) hide show
  1. track_id-0.1.3/.cursor/rules/uv-track-id-setup.mdc +25 -0
  2. track_id-0.1.3/.github/workflows/package-validation.yml +34 -0
  3. track_id-0.1.3/.github/workflows/publish-pypi.yml +47 -0
  4. track_id-0.1.3/.gitignore +27 -0
  5. track_id-0.1.3/.python-version +1 -0
  6. track_id-0.1.3/CLAUDE.md +72 -0
  7. track_id-0.1.3/LICENSE +21 -0
  8. track_id-0.1.3/PKG-INFO +184 -0
  9. track_id-0.1.3/README.md +132 -0
  10. track_id-0.1.3/docs/pypi-release-guide.md +53 -0
  11. track_id-0.1.3/pyproject.toml +60 -0
  12. track_id-0.1.3/tests/__init__.py +1 -0
  13. track_id-0.1.3/tests/conftest.py +39 -0
  14. track_id-0.1.3/tests/test_artwork.py +141 -0
  15. track_id-0.1.3/tests/test_bandcamp_api.py +221 -0
  16. track_id-0.1.3/tests/test_data_sources.py +317 -0
  17. track_id-0.1.3/tests/test_discogs_api.py +256 -0
  18. track_id-0.1.3/tests/test_filename_parsing.py +109 -0
  19. track_id-0.1.3/tests/test_id3_tags.py +44 -0
  20. track_id-0.1.3/tests/test_integration.py +117 -0
  21. track_id-0.1.3/tests/test_musicbrainz_api.py +290 -0
  22. track_id-0.1.3/tests/test_track_id.py +321 -0
  23. track_id-0.1.3/track_id/__init__.py +6 -0
  24. track_id-0.1.3/track_id/bandcamp_api.py +88 -0
  25. track_id-0.1.3/track_id/data_sources.py +202 -0
  26. track_id-0.1.3/track_id/discogs_api.py +169 -0
  27. track_id-0.1.3/track_id/display.py +387 -0
  28. track_id-0.1.3/track_id/enrichment_handlers.py +75 -0
  29. track_id-0.1.3/track_id/id3_tags.py +49 -0
  30. track_id-0.1.3/track_id/mp3_utils.py +288 -0
  31. track_id-0.1.3/track_id/musicbrainz_api.py +156 -0
  32. track_id-0.1.3/track_id/track_id.py +88 -0
  33. track_id-0.1.3/track_id/unified_api.py +52 -0
  34. track_id-0.1.3/uv.lock +541 -0
@@ -0,0 +1,25 @@
1
+ ---
2
+ description:
3
+ globs:
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Cursor Rules for track-id project
8
+
9
+ ## Project Setup
10
+ - This is a Python project using uv for dependency management
11
+ - Main package: `track_id`
12
+ - Entry point: `track_id.track_id:app`
13
+ - Python version: >=3.9
14
+
15
+ ## Commands
16
+ - Install dependencies: `uv sync`
17
+ - Run the app: `uv run track-id`
18
+ - Run tests: `uv run pytest`
19
+ - Add dependency: `uv add <package>`
20
+ - Add dev dependency: `uv add --dev <package>`
21
+
22
+ ## Code Style
23
+ - Follow Python conventions
24
+ - Use type hints where appropriate
25
+ - Keep functions focused and testable
@@ -0,0 +1,34 @@
1
+ name: Package Validation
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ jobs:
10
+ validate-package:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install uv
22
+ uses: astral-sh/setup-uv@v5
23
+
24
+ - name: Install dependencies
25
+ run: uv sync --dev
26
+
27
+ - name: Run tests
28
+ run: uv run pytest
29
+
30
+ - name: Build distributions
31
+ run: uv build
32
+
33
+ - name: Validate distribution metadata
34
+ run: uvx twine check dist/*
@@ -0,0 +1,47 @@
1
+ name: publish-pypi
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ repository:
7
+ description: "Target repository (testpypi or pypi)"
8
+ required: true
9
+ default: testpypi
10
+ type: choice
11
+ options:
12
+ - testpypi
13
+ - pypi
14
+ push:
15
+ tags:
16
+ - "v*"
17
+
18
+ jobs:
19
+ publish:
20
+ runs-on: ubuntu-latest
21
+ environment:
22
+ name: pypi
23
+ url: https://pypi.org/p/track-id
24
+ permissions:
25
+ id-token: write
26
+ steps:
27
+ - name: Checkout
28
+ uses: actions/checkout@v4
29
+
30
+ - name: Set up Python
31
+ uses: actions/setup-python@v5
32
+ with:
33
+ python-version: "3.12"
34
+
35
+ - name: Install build dependencies
36
+ run: python -m pip install --upgrade pip build twine
37
+
38
+ - name: Build package
39
+ run: python -m build
40
+
41
+ - name: Check package metadata
42
+ run: twine check dist/*
43
+
44
+ - name: Publish to PyPI
45
+ uses: pypa/gh-action-pypi-publish@release/v1
46
+ with:
47
+ repository-url: ${{ inputs.repository == 'testpypi' && 'https://test.pypi.org/legacy/' || 'https://upload.pypi.org/legacy/' }}
@@ -0,0 +1,27 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Test files
13
+ .coverage
14
+
15
+ # MacOS files
16
+ .DS_Store
17
+
18
+ # Audio files
19
+ *.mp3
20
+ *.m4a
21
+ *.flac
22
+ *.wav
23
+ *.ogg
24
+ *.aac
25
+ *.m4b
26
+ *.m4p
27
+ *.m4a
@@ -0,0 +1 @@
1
+ 3.9
@@ -0,0 +1,72 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **Track-ID** is a Python CLI tool for music metadata enrichment and search. It searches tracks across multiple music data sources (Bandcamp, MusicBrainz), displays MP3 file info, and enriches MP3 files with metadata from external music databases.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ uv sync
14
+
15
+ # Run the CLI
16
+ uv run track-id search "Artist - Title"
17
+ uv run track-id info path/to/file.mp3
18
+ uv run track-id enrich path/to/file.mp3
19
+
20
+ # Run tests
21
+ uv run pytest
22
+ uv run pytest tests/test_bandcamp_api.py -v # single file
23
+ uv run pytest -m unit # unit tests only
24
+ uv run pytest -m integration # integration tests only
25
+ uv run pytest -m "not slow" # exclude slow tests
26
+ uv run pytest --cov=track_id --cov-report=term-missing
27
+
28
+ # Type checking
29
+ mypy track_id/
30
+ ```
31
+
32
+ ## Architecture
33
+
34
+ ### Data Source Plugin System
35
+
36
+ New music sources are added by subclassing `DataSource` in `data_sources.py` and registering with `DataSourceRegistry`. Each source must implement:
37
+ - `search(search_text)` — call external API, return raw response
38
+ - `find_matching_track(search_results, artist, title)` — select best match
39
+ - `extract_metadata(track_data)` — normalize to ID3 tag dict
40
+ - `enrich_mp3_file(file_path)` — orchestrates enrichment end-to-end
41
+
42
+ `unified_api.py` initializes all sources and aggregates results across them.
43
+
44
+ ### Data Flow
45
+
46
+ ```
47
+ CLI (track_id.py)
48
+ → unified_api.py # aggregates across sources
49
+ → DataSourceRegistry # dispatches to each source
50
+ → BandcampDataSource / MusicBrainzDataSource
51
+ → MP3File (mp3_utils.py) # reads/writes ID3 tags via mutagen
52
+ → display.py # Rich console output
53
+ ```
54
+
55
+ ### Key Files
56
+
57
+ | File | Role |
58
+ |------|------|
59
+ | `track_id/track_id.py` | CLI commands (Typer app) |
60
+ | `track_id/unified_api.py` | Orchestrates search/enrich across all sources |
61
+ | `track_id/data_sources.py` | Abstract base class + registry |
62
+ | `track_id/mp3_utils.py` | `MP3File` class — ID3 read/write, filename parsing |
63
+ | `track_id/display.py` | All Rich console output |
64
+ | `track_id/enrichment_handlers.py` | Shared logic reused by concrete data sources |
65
+
66
+ ### MP3File
67
+
68
+ `MP3File` in `mp3_utils.py` is the core data object. It wraps mutagen for ID3 tag access, parses `Artist - Title` filenames, caches metadata, and handles artwork download. Pass it between layers rather than raw file paths wherever possible.
69
+
70
+ ### ID3 Tags
71
+
72
+ `id3_tags.py` holds the canonical mapping of tag names used across the project. When adding new metadata fields, update this file first.
track_id-0.1.3/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 track-id contributors
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.
@@ -0,0 +1,184 @@
1
+ Metadata-Version: 2.4
2
+ Name: track-id
3
+ Version: 0.1.3
4
+ Summary: CLI for searching and enriching MP3 metadata from Bandcamp, MusicBrainz, and Discogs
5
+ Project-URL: Homepage, https://github.com/vtasca/track-id
6
+ Project-URL: Repository, https://github.com/vtasca/track-id
7
+ Project-URL: Issues, https://github.com/vtasca/track-id/issues
8
+ Author: track-id contributors
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 track-id contributors
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: bandcamp,cli,discogs,id3,metadata,mp3,music,musicbrainz
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: End Users/Desktop
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3 :: Only
38
+ Classifier: Programming Language :: Python :: 3.9
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Programming Language :: Python :: 3.13
43
+ Classifier: Topic :: Multimedia :: Sound/Audio
44
+ Classifier: Topic :: Utilities
45
+ Requires-Python: >=3.9
46
+ Requires-Dist: mutagen>=1.47.0
47
+ Requires-Dist: requests>=2.32.4
48
+ Requires-Dist: rich>=13.0.0
49
+ Requires-Dist: typer>=0.16.0
50
+ Requires-Dist: urllib3<2.0.0
51
+ Description-Content-Type: text/markdown
52
+
53
+ # track-id
54
+
55
+ A Python CLI tool for music metadata enrichment and search. Searches tracks across Bandcamp, MusicBrainz, and Discogs, displays MP3 file info, and enriches MP3 files with metadata from external music databases.
56
+
57
+ ## Features
58
+
59
+ - **Search**: Search for tracks across Bandcamp, MusicBrainz, and Discogs
60
+ - **Info**: Display detailed information about an MP3 file including all ID3 tags
61
+ - **Enrich**: Automatically populate an MP3 file's metadata (artist, album, genre, label, styles, track number, artwork, etc.) from Bandcamp, MusicBrainz, and Discogs
62
+
63
+ ## Installation
64
+
65
+ ### Using uv
66
+
67
+ Install from PyPI as a tool:
68
+ ```bash
69
+ uv tool install track-id
70
+ track-id --version
71
+ track-id search "Chaos In The CBD"
72
+ ```
73
+
74
+ ### Using pip
75
+
76
+ Install from PyPI with pip:
77
+ ```bash
78
+ pip install track-id
79
+ track-id --version
80
+ track-id search "Chaos In The CBD"
81
+ track-id info "path/to/your/file.mp3"
82
+ track-id enrich "path/to/your/file.mp3"
83
+ ```
84
+
85
+ ### Clone and install locally
86
+
87
+ Mainly for development purposes:
88
+ ```bash
89
+ # Clone the repository
90
+ git clone https://github.com/vtasca/track-id
91
+ cd track-id
92
+
93
+ # Install dependencies
94
+ uv sync
95
+ ```
96
+
97
+ ## Usage
98
+
99
+ ### Search for tracks
100
+
101
+ Search across Bandcamp, MusicBrainz, and Discogs simultaneously:
102
+
103
+ ```bash
104
+ track-id search "Chaos In The CBD"
105
+ track-id search "Burial - Archangel" --top 5
106
+ ```
107
+
108
+ The `--top` / `-t` flag controls how many results are shown per source (default: 3).
109
+
110
+ ### Display MP3 file information
111
+
112
+ ```bash
113
+ track-id info "path/to/your/file.mp3"
114
+ ```
115
+
116
+ ### Enrich an MP3 file with metadata
117
+
118
+ Queries Bandcamp, MusicBrainz, and Discogs for a matching track and writes the retrieved metadata directly into the file's ID3 tags:
119
+
120
+ ```bash
121
+ track-id enrich "path/to/your/file.mp3"
122
+ ```
123
+
124
+ The file must have either existing `Artist` and `Title` ID3 tags, or an `Artist - Title` filename so the tool knows what to search for. All three sources are tried and their results merged — existing tags are never overwritten.
125
+
126
+ Tags populated across sources include: `Title`, `Artist`, `Album Artist`, `Album`, `Year`, `Track Number`, `Genre`, `Publisher/Label`, `Style` (Discogs community tags), `Artwork`, and a `Discogs URL` reference.
127
+
128
+ ## Development
129
+
130
+ ### Setting up the development environment
131
+
132
+ ```bash
133
+ uv sync --dev
134
+ ```
135
+
136
+ ### Running tests
137
+
138
+ ```bash
139
+ # Run all tests
140
+ uv run pytest
141
+
142
+ # Run with coverage
143
+ uv run pytest --cov=track_id --cov-report=term-missing
144
+
145
+ # Run a specific file
146
+ uv run pytest tests/test_data_sources.py -v
147
+ ```
148
+
149
+ ## Project Structure
150
+
151
+ ```
152
+ track-id/
153
+ ├── track_id/
154
+ │ ├── track_id.py # CLI commands (Typer app)
155
+ │ ├── unified_api.py # Orchestrates search/enrich across all sources
156
+ │ ├── data_sources.py # Abstract base class + registry
157
+ │ ├── bandcamp_api.py # Bandcamp data source
158
+ │ ├── musicbrainz_api.py # MusicBrainz data source
159
+ │ ├── discogs_api.py # Discogs data source
160
+ │ ├── enrichment_handlers.py# Shared enrichment logic
161
+ │ ├── mp3_utils.py # MP3File class — ID3 read/write, filename parsing
162
+ │ ├── display.py # Rich console output
163
+ │ ├── id3_tags.py # Canonical ID3 tag name mapping
164
+ │ └── __init__.py
165
+ ├── tests/
166
+ │ ├── conftest.py
167
+ │ ├── test_data_sources.py
168
+ │ ├── test_bandcamp_api.py
169
+ │ ├── test_musicbrainz_api.py
170
+ │ ├── test_discogs_api.py
171
+ │ ├── test_artwork.py
172
+ │ ├── test_id3_tags.py
173
+ │ ├── test_track_id.py
174
+ │ └── test_integration.py
175
+ ├── pyproject.toml
176
+ └── README.md
177
+ ```
178
+
179
+ ## Contributing
180
+
181
+ 1. Write tests for new features
182
+ 2. Ensure all tests pass
183
+ 3. Follow the existing code style
184
+ 4. Update documentation as needed
@@ -0,0 +1,132 @@
1
+ # track-id
2
+
3
+ A Python CLI tool for music metadata enrichment and search. Searches tracks across Bandcamp, MusicBrainz, and Discogs, displays MP3 file info, and enriches MP3 files with metadata from external music databases.
4
+
5
+ ## Features
6
+
7
+ - **Search**: Search for tracks across Bandcamp, MusicBrainz, and Discogs
8
+ - **Info**: Display detailed information about an MP3 file including all ID3 tags
9
+ - **Enrich**: Automatically populate an MP3 file's metadata (artist, album, genre, label, styles, track number, artwork, etc.) from Bandcamp, MusicBrainz, and Discogs
10
+
11
+ ## Installation
12
+
13
+ ### Using uv
14
+
15
+ Install from PyPI as a tool:
16
+ ```bash
17
+ uv tool install track-id
18
+ track-id --version
19
+ track-id search "Chaos In The CBD"
20
+ ```
21
+
22
+ ### Using pip
23
+
24
+ Install from PyPI with pip:
25
+ ```bash
26
+ pip install track-id
27
+ track-id --version
28
+ track-id search "Chaos In The CBD"
29
+ track-id info "path/to/your/file.mp3"
30
+ track-id enrich "path/to/your/file.mp3"
31
+ ```
32
+
33
+ ### Clone and install locally
34
+
35
+ Mainly for development purposes:
36
+ ```bash
37
+ # Clone the repository
38
+ git clone https://github.com/vtasca/track-id
39
+ cd track-id
40
+
41
+ # Install dependencies
42
+ uv sync
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ ### Search for tracks
48
+
49
+ Search across Bandcamp, MusicBrainz, and Discogs simultaneously:
50
+
51
+ ```bash
52
+ track-id search "Chaos In The CBD"
53
+ track-id search "Burial - Archangel" --top 5
54
+ ```
55
+
56
+ The `--top` / `-t` flag controls how many results are shown per source (default: 3).
57
+
58
+ ### Display MP3 file information
59
+
60
+ ```bash
61
+ track-id info "path/to/your/file.mp3"
62
+ ```
63
+
64
+ ### Enrich an MP3 file with metadata
65
+
66
+ Queries Bandcamp, MusicBrainz, and Discogs for a matching track and writes the retrieved metadata directly into the file's ID3 tags:
67
+
68
+ ```bash
69
+ track-id enrich "path/to/your/file.mp3"
70
+ ```
71
+
72
+ The file must have either existing `Artist` and `Title` ID3 tags, or an `Artist - Title` filename so the tool knows what to search for. All three sources are tried and their results merged — existing tags are never overwritten.
73
+
74
+ Tags populated across sources include: `Title`, `Artist`, `Album Artist`, `Album`, `Year`, `Track Number`, `Genre`, `Publisher/Label`, `Style` (Discogs community tags), `Artwork`, and a `Discogs URL` reference.
75
+
76
+ ## Development
77
+
78
+ ### Setting up the development environment
79
+
80
+ ```bash
81
+ uv sync --dev
82
+ ```
83
+
84
+ ### Running tests
85
+
86
+ ```bash
87
+ # Run all tests
88
+ uv run pytest
89
+
90
+ # Run with coverage
91
+ uv run pytest --cov=track_id --cov-report=term-missing
92
+
93
+ # Run a specific file
94
+ uv run pytest tests/test_data_sources.py -v
95
+ ```
96
+
97
+ ## Project Structure
98
+
99
+ ```
100
+ track-id/
101
+ ├── track_id/
102
+ │ ├── track_id.py # CLI commands (Typer app)
103
+ │ ├── unified_api.py # Orchestrates search/enrich across all sources
104
+ │ ├── data_sources.py # Abstract base class + registry
105
+ │ ├── bandcamp_api.py # Bandcamp data source
106
+ │ ├── musicbrainz_api.py # MusicBrainz data source
107
+ │ ├── discogs_api.py # Discogs data source
108
+ │ ├── enrichment_handlers.py# Shared enrichment logic
109
+ │ ├── mp3_utils.py # MP3File class — ID3 read/write, filename parsing
110
+ │ ├── display.py # Rich console output
111
+ │ ├── id3_tags.py # Canonical ID3 tag name mapping
112
+ │ └── __init__.py
113
+ ├── tests/
114
+ │ ├── conftest.py
115
+ │ ├── test_data_sources.py
116
+ │ ├── test_bandcamp_api.py
117
+ │ ├── test_musicbrainz_api.py
118
+ │ ├── test_discogs_api.py
119
+ │ ├── test_artwork.py
120
+ │ ├── test_id3_tags.py
121
+ │ ├── test_track_id.py
122
+ │ └── test_integration.py
123
+ ├── pyproject.toml
124
+ └── README.md
125
+ ```
126
+
127
+ ## Contributing
128
+
129
+ 1. Write tests for new features
130
+ 2. Ensure all tests pass
131
+ 3. Follow the existing code style
132
+ 4. Update documentation as needed
@@ -0,0 +1,53 @@
1
+ # PyPI release guide for `track-id`
2
+
3
+ This guide documents the release path that is now wired into this repository.
4
+
5
+ ## One-time setup
6
+
7
+ 1. Create and verify accounts:
8
+ - https://pypi.org
9
+ - https://test.pypi.org
10
+ 2. In both PyPI and TestPyPI, configure a **Trusted Publisher** for this repo:
11
+ - Owner: `vtasca`
12
+ - Repository: `track-id`
13
+ - Workflow file: `publish-pypi.yml`
14
+ - Environment: leave empty unless you add environment protection rules
15
+ 3. Ensure you have permission to create GitHub releases in this repository.
16
+
17
+ ## What this repository now includes
18
+
19
+ - Package metadata in `pyproject.toml` ready for PyPI.
20
+ - CI package check workflow: `.github/workflows/package-validation.yml`.
21
+ - Publish workflow: `.github/workflows/publish-pypi.yml`.
22
+
23
+ ## Release checklist (every release)
24
+
25
+ 1. Update the version in `pyproject.toml` under `[project].version`.
26
+ 2. Commit and push the version change.
27
+ 3. Wait for package checks to pass in GitHub Actions.
28
+ 4. Publish to **TestPyPI** (recommended dry run):
29
+ - Run the `publish-pypi` workflow manually.
30
+ - Choose input `repository = testpypi`.
31
+ 5. Verify install from TestPyPI:
32
+ - `python -m venv /tmp/track-id-test && source /tmp/track-id-test/bin/activate`
33
+ - `pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ track-id==<version>`
34
+ - `track-id --version`
35
+ 6. Publish to **PyPI**:
36
+ - Preferred: create a GitHub Release (for example `v0.1.4`), which triggers publish to PyPI.
37
+ - Alternative: run workflow dispatch with `repository = pypi`.
38
+ 7. Verify public install:
39
+ - `python -m venv /tmp/track-id-prod && source /tmp/track-id-prod/bin/activate`
40
+ - `pip install track-id==<version>`
41
+ - `track-id --version`
42
+
43
+ ## Local preflight commands
44
+
45
+ Run these before making a release:
46
+
47
+ 1. `uv sync --dev`
48
+ 2. `uv run pytest`
49
+ 3. `rm -rf dist`
50
+ 4. `uv build`
51
+ 5. `uvx twine check dist/*`
52
+
53
+ If `twine check` passes and tests are green, the artifact is usually safe to publish.
@@ -0,0 +1,60 @@
1
+ [project]
2
+ name = "track-id"
3
+ version = "0.1.3"
4
+ description = "CLI for searching and enriching MP3 metadata from Bandcamp, MusicBrainz, and Discogs"
5
+ readme = "README.md"
6
+ requires-python = ">=3.9"
7
+ license = { file = "LICENSE" }
8
+ authors = [
9
+ { name = "track-id contributors" },
10
+ ]
11
+ keywords = ["mp3", "id3", "metadata", "music", "cli", "bandcamp", "musicbrainz", "discogs"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Environment :: Console",
15
+ "Intended Audience :: End Users/Desktop",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Programming Language :: Python :: 3.9",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Multimedia :: Sound/Audio",
25
+ "Topic :: Utilities",
26
+ ]
27
+ dependencies = [
28
+ "requests>=2.32.4",
29
+ "typer>=0.16.0",
30
+ "urllib3<2.0.0",
31
+ "mutagen>=1.47.0",
32
+ "rich>=13.0.0",
33
+ ]
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/vtasca/track-id"
37
+ Repository = "https://github.com/vtasca/track-id"
38
+ Issues = "https://github.com/vtasca/track-id/issues"
39
+
40
+ [project.scripts]
41
+ track-id = "track_id.track_id:app"
42
+
43
+ [build-system]
44
+ requires = ["hatchling"]
45
+ build-backend = "hatchling.build"
46
+
47
+ [tool.hatch.build.targets.wheel]
48
+ packages = ["track_id"]
49
+
50
+ [dependency-groups]
51
+ dev = [
52
+ "pytest>=7.0.0",
53
+ "pytest-cov>=4.0.0",
54
+ "mypy>=1.17.1",
55
+ "types-requests>=2.31.0.6",
56
+ ]
57
+
58
+ [tool.pytest.ini_options]
59
+ testpaths = ["tests"]
60
+ addopts = ["-v"]
@@ -0,0 +1 @@
1
+ # Tests package for track-id