# 🎵 Jellyfin Auto-Tagging Script A Python CLI tool for tagging Jellyfin artists and albums recursively using the Jellyfin API. ## 📋 Table of Contents - [Overview](#-overview) - [Features](#-features) - [Requirements](#-requirements) - [Installation](#-installation) - [Usage](#-usage) - [Examples](#-examples) - [Technical Details](#-technical-details) - [Troubleshooting](#-troubleshooting) - [License](#-license) - [Authors](#-authors) ## 🎯 Overview This script automates the process of adding tags to Jellyfin music artists and their albums. It's designed to be simple, efficient, and safe, with a dry-run mode to preview changes before applying them. ## ✨ Features - **Recursive Tagging**: Tags an artist and all their albums with a single command - **Dry Run Mode**: Preview changes without making modifications - **Tag Preservation**: Merges new tags with existing ones (no duplicates) - **Username/Password Auth**: Uses Jellyfin credentials (no API key required) - **Comprehensive Error Handling**: Clear success/failure reporting - **Minimal Dependencies**: Only requires Python and `requests` library ## 📦 Requirements - Python 3.6+ - `requests` library (`pip install requests`) - Jellyfin Server 10.11.5+ - User account with write permissions ## 🔧 Installation ### 1. Clone or Download ```bash # Clone the repository (if available) git clone https://github.com/your-repo/jellyfin-autotag.git cd jellyfin-autotag # Or download just the script wget https://raw.githubusercontent.com/your-repo/jellyfin-autotag/main/tag_artist.py chmod +x tag_artist.py ``` ### 2. Install Dependencies ```bash pip install requests ``` ### 3. Make Executable ```bash chmod +x tag_artist.py ``` ## 🚀 Usage ```bash ./tag_artist.py --server SERVER_URL --username USERNAME --password PASSWORD \ --artist-id ARTIST_ID --tag TAG_NAME [--dry-run] ``` ### Command Line Arguments | Argument | Required | Description | Example | |----------|----------|-------------|---------| | `--server` | ✅ Yes | Jellyfin server URL | `http://localhost:8096` | | `--username` | ✅ Yes | Jellyfin username | `username` | | `--password` | ✅ Yes | Jellyfin password | `password123` | | `--artist-id` | ✅ Yes | Artist ID to tag | `artistidxxxxxxxxxxxxxxxxxx` | | `--tag` | ✅ Yes | Tag to apply | `yourtag` | | `--dry-run` | ❌ No | Dry run mode (no changes) | (flag only) | ## 📚 Examples ### 1. Dry Run (Safe Preview) ```bash ./tag_artist.py --server http://10.11.12.13:8096 \ --username admin \ --password hBBOmvfsRYvgn0DIfd34 \ --artist-id b32224387e37aae08d962f71f7272c6c \ --tag "electronic-favorite" \ --dry-run ``` **Output:** ``` 🎯 Jellyfin Artist Tagger 📡 Server: http://10.11.12.13:8096 👤 Artist ID: b32224387e37aae08d962f71f7272c6c 🏷️ Tag: electronic-favorite 🔄 DRY RUN MODE - No changes will be made 🎵 Fetching artist information... 🎤 Artist: Goldfrapp 🏷️ Tagging artist... [DRY RUN] Would tag artist 'Goldfrapp' with 'electronic-favorite' 💿 Fetching albums... 📚 Found 10 albums: [DRY RUN] Would tag album 'Silver Eye' with 'electronic-favorite' [DRY RUN] Would tag album 'Seventh Tree' with 'electronic-favorite' ... 🎉 Dry run completed! Would tag artist and 10 albums with 'electronic-favorite' ``` ### 2. Actual Tagging ```bash ./tag_artist.py --server http://your.jellyfin.url \ --username yourusername \ --password yourpassword \ --artist-id artistidxxxxxxxxxxxxxx \ --tag "yourtag" ``` **Output:** ``` 🎯 Jellyfin Artist Tagger 📡 Server: http://your.jellyfin.url 👤 Artist ID: artistidxxxxxxxxxxxxxx 🏷️ Tag: yourtag ⚠️ LIVE MODE - Changes will be made 🎵 Fetching artist information... 🎤 Artist: Artist name 🏷️ Tagging artist... ✅ Tagged artist 'Goldfrapp' with 'yourtag' 💿 Fetching albums... 📚 Found 10 albums: ✅ Tagged album 'Album name' with 'yourtag' ✅ Tagged album 'Album name 2' with 'yourtag' ... 🎉 Completed! Tagged artist and 10/10 albums with 'yourtag' ``` ## 🔍 Technical Details ### Authentication The script uses Jellyfin's username/password authentication to obtain an access token: ```python # Authentication flow 1. POST to /Users/AuthenticateByName with username/password 2. Receive access token and user ID 3. Use token for all subsequent API calls ``` ### API Endpoints Used - `POST /Users/AuthenticateByName` - Authentication - `GET /Items/{id}` - Fetch artist/album details - `POST /Items/{id}` - Update tags ### Data Format The script sends complete artist/album objects matching the Jellyfin UI format: ```json { "Id": "artist-id", "Name": "Artist Name", "Tags": ["tag1", "tag2"], "Genres": ["Genre1", "Genre2"], "ProviderIds": {}, "DateCreated": "2019-01-08T09:19:41.000Z", "LockData": false, "LockedFields": [] // ... all other metadata fields } ``` ### Tag Merging Logic ```python # Preserve existing tags and add new ones existing_tags = set(current_item.get('Tags', [])) new_tags = set(tags) merged_tags = list(existing_tags.union(new_tags)) ``` ## 🐛 Troubleshooting ### Common Issues #### 1. Authentication Failed **Error:** `❌ Authentication failed: 401 Unauthorized` **Solution:** - Verify username and password - Check if user has API access permissions - Ensure server URL is correct #### 2. Artist Not Found **Error:** `❌ Could not fetch artist information` **Solution:** - Verify artist ID is correct - Check if artist exists in your library - Use dry run to test connectivity #### 3. Tagging Failed **Error:** `❌ Failed to tag artist/album` **Solution:** - Check Jellyfin server logs for details - Ensure user has write permissions - Verify Jellyfin version compatibility ### Debugging Tips 1. **Use dry run first**: Always test with `--dry-run` before making changes 2. **Check server logs**: Look for detailed error information 3. **Test with different artists**: Rule out data-specific issues 4. **Verify network connectivity**: Ensure script can reach the server ## 📜 License This project is open-source and available under the **MIT License**. ## 👥 Authors **Bach** - Initial development and implementation **Mistral AI** - Assistance and optimization ## 🎉 Success Story This script was developed to automate the tedious process of manually tagging artists and albums in Jellyfin. What started as a simple Python CLI tool evolved into a robust solution that: - ✅ Successfully tags artists and albums recursively - ✅ Preserves all existing metadata - ✅ Provides safe dry-run functionality - ✅ Handles errors gracefully - ✅ Matches Jellyfin UI behavior exactly **Result:** A production-ready tool that saves hours of manual tagging work! 🎊 ## 📬 Contact For questions, issues, or contributions, please open an issue on the GitHub repository. ## 🙏 Acknowledgments - Jellyfin team for creating an amazing media server - Python community for the excellent `requests` library - All open-source contributors who make tools like this possible --- **Last Updated:** February 13, 2026 **Version:** 1.0.0