Fix issues with ConfigEntry model (de)serializing
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Tue, 18 Feb 2025 12:18:50 +0000 (13:18 +0100)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Tue, 18 Feb 2025 12:18:50 +0000 (13:18 +0100)
54 files changed:
music_assistant/constants.py
music_assistant/controllers/cache.py
music_assistant/controllers/config.py
music_assistant/controllers/metadata.py
music_assistant/controllers/music.py
music_assistant/controllers/player_queues.py
music_assistant/controllers/streams.py
music_assistant/controllers/webserver.py
music_assistant/models/__init__.py
music_assistant/models/core_controller.py
music_assistant/models/player_provider.py
music_assistant/providers/_template_music_provider/__init__.py
music_assistant/providers/_template_player_provider/__init__.py
music_assistant/providers/_template_plugin_provider/__init__.py
music_assistant/providers/airplay/__init__.py
music_assistant/providers/apple_music/__init__.py
music_assistant/providers/audible/__init__.py
music_assistant/providers/audiobookshelf/__init__.py
music_assistant/providers/bluesound/__init__.py
music_assistant/providers/builtin/__init__.py
music_assistant/providers/chromecast/__init__.py
music_assistant/providers/deezer/__init__.py
music_assistant/providers/dlna/__init__.py
music_assistant/providers/fanarttv/__init__.py
music_assistant/providers/filesystem_local/__init__.py
music_assistant/providers/filesystem_local/constants.py
music_assistant/providers/filesystem_smb/__init__.py
music_assistant/providers/fully_kiosk/__init__.py
music_assistant/providers/hass/__init__.py
music_assistant/providers/hass_players/__init__.py
music_assistant/providers/ibroadcast/__init__.py
music_assistant/providers/jellyfin/__init__.py
music_assistant/providers/musicbrainz/__init__.py
music_assistant/providers/opensubsonic/__init__.py
music_assistant/providers/player_group/__init__.py
music_assistant/providers/plex/__init__.py
music_assistant/providers/podcastfeed/__init__.py
music_assistant/providers/qobuz/__init__.py
music_assistant/providers/radiobrowser/__init__.py
music_assistant/providers/siriusxm/__init__.py
music_assistant/providers/slimproto/__init__.py
music_assistant/providers/snapcast/__init__.py
music_assistant/providers/sonos/__init__.py
music_assistant/providers/sonos_s1/__init__.py
music_assistant/providers/soundcloud/__init__.py
music_assistant/providers/spotify/__init__.py
music_assistant/providers/spotify_connect/__init__.py
music_assistant/providers/test/__init__.py
music_assistant/providers/theaudiodb/__init__.py
music_assistant/providers/tidal/__init__.py
music_assistant/providers/tunein/__init__.py
music_assistant/providers/ytmusic/__init__.py
pyproject.toml
requirements_all.txt

index 8c4bee3b017546b76293e21e036e595c3acf0647..1132e07f1fe72e83ca69c80d928e0c2db519a060 100644 (file)
@@ -3,7 +3,11 @@
 import pathlib
 from typing import Final
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption
+from music_assistant_models.config_entries import (
+    ConfigEntry,
+    ConfigValueOption,
+    MultiValueConfigEntry,
+)
 from music_assistant_models.enums import ConfigEntryType, ContentType
 from music_assistant_models.media_items import AudioFormat
 
@@ -126,14 +130,14 @@ CONF_ENTRY_LOG_LEVEL = ConfigEntry(
     key=CONF_LOG_LEVEL,
     type=ConfigEntryType.STRING,
     label="Log level",
-    options=(
+    options=[
         ConfigValueOption("global", "GLOBAL"),
         ConfigValueOption("info", "INFO"),
         ConfigValueOption("warning", "WARNING"),
         ConfigValueOption("error", "ERROR"),
         ConfigValueOption("debug", "DEBUG"),
         ConfigValueOption("verbose", "VERBOSE"),
-    ),
+    ],
     default_value="GLOBAL",
     category="advanced",
 )
@@ -185,12 +189,12 @@ CONF_ENTRY_AUTO_PLAY = ConfigEntry(
 CONF_ENTRY_OUTPUT_CHANNELS = ConfigEntry(
     key=CONF_OUTPUT_CHANNELS,
     type=ConfigEntryType.STRING,
-    options=(
+    options=[
         ConfigValueOption("Stereo (both channels)", "stereo"),
         ConfigValueOption("Left channel", "left"),
         ConfigValueOption("Right channel", "right"),
         ConfigValueOption("Mono (both channels)", "mono"),
-    ),
+    ],
     default_value="stereo",
     label="Output Channel Mode",
     category="audio",
@@ -334,12 +338,12 @@ CONF_ENTRY_TTS_PRE_ANNOUNCE = ConfigEntry(
 CONF_ENTRY_ANNOUNCE_VOLUME_STRATEGY = ConfigEntry(
     key=CONF_ANNOUNCE_VOLUME_STRATEGY,
     type=ConfigEntryType.STRING,
-    options=(
+    options=[
         ConfigValueOption("Absolute volume", "absolute"),
         ConfigValueOption("Relative volume increase", "relative"),
         ConfigValueOption("Volume increase by fixed percentage", "percentual"),
         ConfigValueOption("Do not adjust volume", "none"),
-    ),
+    ],
     default_value="percentual",
     label="Volume strategy for Announcements",
     category="announcements",
@@ -404,10 +408,10 @@ CONF_ENTRY_PLAYER_ICON_GROUP = ConfigEntry.from_dict(
     {**CONF_ENTRY_PLAYER_ICON.to_dict(), "default_value": "mdi-speaker-multiple"}
 )
 
-CONF_ENTRY_SAMPLE_RATES = ConfigEntry(
+CONF_ENTRY_SAMPLE_RATES = MultiValueConfigEntry(
     key=CONF_SAMPLE_RATES,
     type=ConfigEntryType.INTEGER_TUPLE,
-    options=(
+    options=[
         ConfigValueOption("44.1kHz / 16 bits", (44100, 16)),
         ConfigValueOption("44.1kHz / 24 bits", (44100, 24)),
         ConfigValueOption("48kHz / 16 bits", (48000, 16)),
@@ -424,10 +428,9 @@ CONF_ENTRY_SAMPLE_RATES = ConfigEntry(
         ConfigValueOption("352.8kHz / 24 bits", (352800, 24)),
         ConfigValueOption("384kHz / 16 bits", (384000, 16)),
         ConfigValueOption("384kHz / 24 bits", (384000, 24)),
-    ),
+    ],
     default_value=[(44100, 16), (48000, 16)],
     required=True,
-    multi_value=True,
     label="Sample rates supported by this player",
     category="advanced",
     description="The sample rates (and bit depths) supported by this player.\n"
@@ -438,11 +441,11 @@ CONF_ENTRY_SAMPLE_RATES = ConfigEntry(
 CONF_ENTRY_HTTP_PROFILE = ConfigEntry(
     key=CONF_HTTP_PROFILE,
     type=ConfigEntryType.STRING,
-    options=(
+    options=[
         ConfigValueOption("Profile 1 - chunked", "chunked"),
         ConfigValueOption("Profile 2 - no content length", "no_content_length"),
         ConfigValueOption("Profile 3 - forced content length", "forced_content_length"),
-    ),
+    ],
     default_value="no_content_length",
     label="HTTP Profile used for sending audio",
     category="advanced",
@@ -465,11 +468,11 @@ CONF_ENTRY_HTTP_PROFILE_FORCED_2 = ConfigEntry.from_dict(
 CONF_ENTRY_ENABLE_ICY_METADATA = ConfigEntry(
     key=CONF_ENABLE_ICY_METADATA,
     type=ConfigEntryType.STRING,
-    options=(
+    options=[
         ConfigValueOption("Disabled - do not send ICY metadata", "disabled"),
         ConfigValueOption("Profile 1 - basic info", "basic"),
         ConfigValueOption("Profile 2 - full info (including image)", "full"),
-    ),
+    ],
     depends_on=CONF_FLOW_MODE,
     default_value="disabled",
     label="Try to ingest metadata into stream (ICY)",
@@ -496,10 +499,10 @@ def create_sample_rates_config_entry(
     safe_max_bit_depth: int = 16,
     hidden: bool = False,
     supported_sample_rates: list[int] | None = None,
-) -> ConfigEntry:
+) -> MultiValueConfigEntry:
     """Create sample rates config entry based on player specific helpers."""
     assert CONF_ENTRY_SAMPLE_RATES.options
-    conf_entry = ConfigEntry.from_dict(CONF_ENTRY_SAMPLE_RATES.to_dict())
+    conf_entry = MultiValueConfigEntry.from_dict(CONF_ENTRY_SAMPLE_RATES.to_dict())
     conf_entry.hidden = hidden
     options: list[ConfigValueOption] = []
     default_value: list[tuple[int, int]] = []
@@ -513,7 +516,7 @@ def create_sample_rates_config_entry(
             options.append(option)
         if sample_rate <= safe_max_sample_rate and bit_depth <= safe_max_bit_depth:
             default_value.append(option.value)
-    conf_entry.options = tuple(options)
+    conf_entry.options = options
     conf_entry.default_value = default_value
     return conf_entry
 
index 5103e6c6bb388d9d65144e241a07ed85937625af..59aeccba51d620624296be213a5d8f7e3929d1df 100644 (file)
@@ -11,7 +11,7 @@ from collections import OrderedDict
 from collections.abc import Callable, Iterator, MutableMapping
 from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import ConfigEntryType
 
 from music_assistant.constants import DB_TABLE_CACHE, DB_TABLE_SETTINGS, MASS_LOGGER_NAME
@@ -46,7 +46,7 @@ class CacheController(CoreController):
     async def get_config_entries(
         self,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """Return all Config Entries for this core module (if any)."""
         if action == CONF_CLEAR_CACHE:
@@ -75,7 +75,8 @@ class CacheController(CoreController):
 
     async def close(self) -> None:
         """Cleanup on exit."""
-        await self.database.close()
+        if self.database:
+            await self.database.close()
 
     async def get(
         self,
index 62df0b1033e68e65c2786c0816df7b67a5feaff2..88927b28bdd4a3dc42378103f03e239da07ec828 100644 (file)
@@ -16,7 +16,7 @@ from cryptography.fernet import Fernet, InvalidToken
 from music_assistant_models import config_entries
 from music_assistant_models.config_entries import (
     ConfigEntry,
-    ConfigValueType,
+    ConfigValueTypes,
     CoreConfig,
     PlayerConfig,
     ProviderConfig,
@@ -77,7 +77,7 @@ class ConfigController:
         self._data: dict[str, Any] = {}
         self.filename = os.path.join(self.mass.storage_path, "settings.json")
         self._timer_handle: asyncio.TimerHandle | None = None
-        self._value_cache: dict[str, ConfigValueType] = {}
+        self._value_cache: dict[str, ConfigValueTypes] = {}
 
     async def setup(self) -> None:
         """Async initialize of controller."""
@@ -208,7 +208,7 @@ class ConfigController:
         raise KeyError(msg)
 
     @api_command("config/providers/get_value")
-    async def get_provider_config_value(self, instance_id: str, key: str) -> ConfigValueType:
+    async def get_provider_config_value(self, instance_id: str, key: str) -> ConfigValueTypes:
         """Return single configentry value for a provider."""
         cache_key = f"prov_conf_value_{instance_id}.{key}"
         if (cached_value := self._value_cache.get(cache_key)) is not None:
@@ -229,7 +229,7 @@ class ConfigController:
         provider_domain: str,
         instance_id: str | None = None,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """
         Return Config entries to setup/configure a provider.
@@ -261,7 +261,7 @@ class ConfigController:
     async def save_provider_config(
         self,
         provider_domain: str,
-        values: dict[str, ConfigValueType],
+        values: dict[str, ConfigValueTypes],
         instance_id: str | None = None,
     ) -> ProviderConfig:
         """
@@ -356,7 +356,7 @@ class ConfigController:
         self,
         player_id: str,
         key: str,
-    ) -> ConfigValueType:
+    ) -> ConfigValueTypes:
         """Return single configentry value for a player."""
         conf = await self.get_player_config(player_id)
         return (
@@ -366,8 +366,8 @@ class ConfigController:
         )
 
     def get_raw_player_config_value(
-        self, player_id: str, key: str, default: ConfigValueType = None
-    ) -> ConfigValueType:
+        self, player_id: str, key: str, default: ConfigValueTypes = None
+    ) -> ConfigValueTypes:
         """
         Return (raw) single configentry value for a player.
 
@@ -380,7 +380,7 @@ class ConfigController:
 
     @api_command("config/players/save")
     async def save_player_config(
-        self, player_id: str, values: dict[str, ConfigValueType]
+        self, player_id: str, values: dict[str, ConfigValueTypes]
     ) -> PlayerConfig:
         """Save/update PlayerConfig."""
         config = await self.get_player_config(player_id)
@@ -513,7 +513,7 @@ class ConfigController:
         provider: str,
         name: str,
         enabled: bool,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> None:
         """
         Create default/empty PlayerConfig.
@@ -600,7 +600,7 @@ class ConfigController:
         return CoreConfig.parse(config_entries, raw_conf)
 
     @api_command("config/core/get_value")
-    async def get_core_config_value(self, domain: str, key: str) -> ConfigValueType:
+    async def get_core_config_value(self, domain: str, key: str) -> ConfigValueTypes:
         """Return single configentry value for a core controller."""
         conf = await self.get_core_config(domain)
         return (
@@ -614,7 +614,7 @@ class ConfigController:
         self,
         domain: str,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """
         Return Config entries to configure a core controller.
@@ -635,7 +635,7 @@ class ConfigController:
     async def save_core_config(
         self,
         domain: str,
-        values: dict[str, ConfigValueType],
+        values: dict[str, ConfigValueTypes],
     ) -> CoreConfig:
         """Save CoreController Config values."""
         config = await self.get_core_config(domain)
@@ -656,8 +656,8 @@ class ConfigController:
         return await self.get_core_config(domain)
 
     def get_raw_core_config_value(
-        self, core_module: str, key: str, default: ConfigValueType = None
-    ) -> ConfigValueType:
+        self, core_module: str, key: str, default: ConfigValueTypes = None
+    ) -> ConfigValueTypes:
         """
         Return (raw) single configentry value for a core controller.
 
@@ -669,8 +669,8 @@ class ConfigController:
         )
 
     def get_raw_provider_config_value(
-        self, provider_instance: str, key: str, default: ConfigValueType = None
-    ) -> ConfigValueType:
+        self, provider_instance: str, key: str, default: ConfigValueTypes = None
+    ) -> ConfigValueTypes:
         """
         Return (raw) single config(entry) value for a provider.
 
@@ -685,7 +685,7 @@ class ConfigController:
         self,
         provider_instance: str,
         key: str,
-        value: ConfigValueType,
+        value: ConfigValueTypes,
         encrypted: bool = False,
     ) -> None:
         """
@@ -707,7 +707,9 @@ class ConfigController:
         if prov := self.mass.get_provider(provider_instance, return_unavailable=True):
             prov.config.values[key].value = value
 
-    def set_raw_core_config_value(self, core_module: str, key: str, value: ConfigValueType) -> None:
+    def set_raw_core_config_value(
+        self, core_module: str, key: str, value: ConfigValueTypes
+    ) -> None:
         """
         Set (raw) single config(entry) value for a core controller.
 
@@ -718,7 +720,9 @@ class ConfigController:
             self.set(f"{CONF_CORE}/{core_module}", CoreConfig({}, core_module).to_raw())
         self.set(f"{CONF_CORE}/{core_module}/values/{key}", value)
 
-    def set_raw_player_config_value(self, player_id: str, key: str, value: ConfigValueType) -> None:
+    def set_raw_player_config_value(
+        self, player_id: str, key: str, value: ConfigValueTypes
+    ) -> None:
         """
         Set (raw) single config(entry) value for a player.
 
@@ -821,7 +825,7 @@ class ConfigController:
         await self.mass.load_provider_config(config)
 
     async def _update_provider_config(
-        self, instance_id: str, values: dict[str, ConfigValueType]
+        self, instance_id: str, values: dict[str, ConfigValueTypes]
     ) -> ProviderConfig:
         """Update ProviderConfig."""
         config = await self.get_provider_config(instance_id)
@@ -861,7 +865,7 @@ class ConfigController:
     async def _add_provider_config(
         self,
         provider_domain: str,
-        values: dict[str, ConfigValueType],
+        values: dict[str, ConfigValueTypes],
     ) -> list[ConfigEntry] | ProviderConfig:
         """
         Add new Provider (instance).
index 1d3efb882a178545f3f04395e74c892ce708ec0e..cd0a20a016ff2f7084fc7329abefc9dc131f7310 100644 (file)
@@ -16,7 +16,7 @@ from uuid import uuid4
 
 import aiofiles
 from aiohttp import web
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueTypes
 from music_assistant_models.enums import (
     AlbumType,
     ConfigEntryType,
@@ -131,7 +131,7 @@ class MetaDataController(CoreController):
     async def get_config_entries(
         self,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """Return all Config Entries for this core module (if any)."""
         return (
@@ -144,7 +144,7 @@ class MetaDataController(CoreController):
                 description="Preferred language for metadata.\n\n"
                 "Note that English will always be used as fallback when content "
                 "in your preferred language is not available.",
-                options=tuple(ConfigValueOption(value, key) for key, value in LOCALES.items()),
+                options=[ConfigValueOption(value, key) for key, value in LOCALES.items()],
             ),
             ConfigEntry(
                 key=CONF_ENABLE_ONLINE_METADATA,
index aa779b061419550816c5402b0ca8c2c5d092cf3a..edc8d9c7c8dff8d074fc383d4a3fac3cc84540c6 100644 (file)
@@ -11,7 +11,7 @@ from itertools import zip_longest
 from math import inf
 from typing import TYPE_CHECKING, Final, cast
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     CacheCategory,
     ConfigEntryType,
@@ -113,7 +113,7 @@ class MusicController(CoreController):
     async def get_config_entries(
         self,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """Return all Config Entries for this core module (if any)."""
         entries = (
index 002b9f189dea6a20186cb917bd837f1031b57771..8a2fcc730da9ec34a1288b12cffb026174a580fd 100644 (file)
@@ -19,7 +19,7 @@ import time
 from types import NoneType
 from typing import TYPE_CHECKING, Any, TypedDict, cast
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueTypes
 from music_assistant_models.enums import (
     CacheCategory,
     ConfigEntryType,
@@ -139,17 +139,17 @@ class PlayerQueuesController(CoreController):
     async def get_config_entries(
         self,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """Return all Config Entries for this core module (if any)."""
-        enqueue_options = tuple(ConfigValueOption(x.name, x.value) for x in QueueOption)
+        enqueue_options = [ConfigValueOption(x.name, x.value) for x in QueueOption]
         return (
             ConfigEntry(
                 key=CONF_DEFAULT_ENQUEUE_SELECT_ARTIST,
                 type=ConfigEntryType.STRING,
                 default_value=ENQUEUE_SELECT_ARTIST_DEFAULT_VALUE,
                 label="Items to select when you play a (in-library) artist.",
-                options=(
+                options=[
                     ConfigValueOption(
                         title="Only in-library tracks",
                         value="library_tracks",
@@ -166,14 +166,14 @@ class PlayerQueuesController(CoreController):
                         title="All tracks from all albums from (all) streaming provider(s)",
                         value="all_album_tracks",
                     ),
-                ),
+                ],
             ),
             ConfigEntry(
                 key=CONF_DEFAULT_ENQUEUE_SELECT_ALBUM,
                 type=ConfigEntryType.STRING,
                 default_value=ENQUEUE_SELECT_ALBUM_DEFAULT_VALUE,
                 label="Items to select when you play a (in-library) album.",
-                options=(
+                options=[
                     ConfigValueOption(
                         title="Only in-library tracks",
                         value="library_tracks",
@@ -182,7 +182,7 @@ class PlayerQueuesController(CoreController):
                         title="All tracks for album on (streaming) provider",
                         value="all_tracks",
                     ),
-                ),
+                ],
             ),
             ConfigEntry(
                 key=CONF_DEFAULT_ENQUEUE_OPTION_ARTIST,
index b2213731509ea58db88c439c8ddde6b5236f364c..2efb1d1664edb9dd78437ef0641a553b664dd1a8 100644 (file)
@@ -16,7 +16,7 @@ from typing import TYPE_CHECKING
 
 from aiofiles.os import wrap
 from aiohttp import web
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueTypes
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -115,7 +115,7 @@ class StreamsController(CoreController):
     async def get_config_entries(
         self,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """Return all Config Entries for this core module (if any)."""
         default_ip = await get_ip()
@@ -136,10 +136,10 @@ class StreamsController(CoreController):
                 type=ConfigEntryType.STRING,
                 default_value=VolumeNormalizationMode.FALLBACK_DYNAMIC,
                 label="Volume normalization method for radio streams",
-                options=(
+                options=[
                     ConfigValueOption(x.value.replace("_", " ").title(), x.value)
                     for x in VolumeNormalizationMode
-                ),
+                ],
                 category="audio",
             ),
             ConfigEntry(
@@ -147,10 +147,10 @@ class StreamsController(CoreController):
                 type=ConfigEntryType.STRING,
                 default_value=VolumeNormalizationMode.FALLBACK_DYNAMIC,
                 label="Volume normalization method for tracks",
-                options=(
+                options=[
                     ConfigValueOption(x.value.replace("_", " ").title(), x.value)
                     for x in VolumeNormalizationMode
-                ),
+                ],
                 category="audio",
             ),
             ConfigEntry(
@@ -187,7 +187,7 @@ class StreamsController(CoreController):
                 key=CONF_BIND_IP,
                 type=ConfigEntryType.STRING,
                 default_value="0.0.0.0",
-                options=(ConfigValueOption(x, x) for x in {"0.0.0.0", *all_ips}),
+                options=[ConfigValueOption(x, x) for x in {"0.0.0.0", *all_ips}],
                 label="Bind to IP/interface",
                 description="Start the stream server on this specific interface. \n"
                 "Use 0.0.0.0 to bind to all interfaces, which is the default. \n"
index 8ab15fbb7d1a7010b5adf0684bed4617d0d8bc24..44c32a12e1cb436fe6e1ee16a7a0713d2d9a5035 100644 (file)
@@ -39,7 +39,7 @@ from music_assistant.models.core_controller import CoreController
 if TYPE_CHECKING:
     from collections.abc import Awaitable
 
-    from music_assistant_models.config_entries import ConfigValueType, CoreConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, CoreConfig
     from music_assistant_models.event import MassEvent
 
 DEFAULT_SERVER_PORT = 8095
@@ -73,7 +73,7 @@ class WebserverController(CoreController):
     async def get_config_entries(
         self,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """Return all Config Entries for this core module (if any)."""
         default_publish_ip = await get_ip()
@@ -122,7 +122,7 @@ class WebserverController(CoreController):
                 key=CONF_BIND_IP,
                 type=ConfigEntryType.STRING,
                 default_value="0.0.0.0",
-                options=(ConfigValueOption(x, x) for x in {"0.0.0.0", *all_ips}),
+                options=[ConfigValueOption(x, x) for x in {"0.0.0.0", *all_ips}],
                 label="Bind to IP/interface",
                 description="Start the (web)server on this specific interface. \n"
                 "Use 0.0.0.0 to bind to all interfaces. \n"
index ce2bab18090b6a236e8065e48d11efb3548bc4ec..d9e8847296a12dc41758d925fee3f7affd3f40d3 100644 (file)
@@ -10,7 +10,7 @@ from .player_provider import PlayerProvider
 from .plugin import PluginProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant import MusicAssistant
@@ -33,7 +33,7 @@ class ProviderModuleType(Protocol):
         mass: MusicAssistant,
         instance_id: str | None = None,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """
         Return Config entries to setup this provider.
index 7f2532c32315b418e892308189ae9118ac70e251..f73ed6a5786dde86c09fa5735c18254679b03b48 100644 (file)
@@ -11,7 +11,7 @@ from music_assistant_models.provider import ProviderManifest
 from music_assistant.constants import CONF_LOG_LEVEL, MASS_LOGGER_NAME
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, CoreConfig
+    from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, CoreConfig
 
     from music_assistant import MusicAssistant
 
@@ -38,7 +38,7 @@ class CoreController:
     async def get_config_entries(
         self,
         action: str | None = None,
-        values: dict[str, ConfigValueType] | None = None,
+        values: dict[str, ConfigValueTypes] | None = None,
     ) -> tuple[ConfigEntry, ...]:
         """Return all Config Entries for this core module (if any)."""
         return ()
index 08d0b6118cab72d49ac1fd487ec00bd815345558..ae050dc68f3d6fd98d7bb6329bf25631122144a4 100644 (file)
@@ -315,10 +315,10 @@ class PlayerProvider(Provider):
                 label="Power Control",
                 default_value=PLAYER_CONTROL_NATIVE if supports_power else PLAYER_CONTROL_NONE,
                 required=True,
-                options=(
+                options=[
                     *base_power_options,
                     *(ConfigValueOption(x.name, x.id) for x in power_controls),
-                ),
+                ],
                 category="player_controls",
             ),
             # Volume control config entry
@@ -328,10 +328,10 @@ class PlayerProvider(Provider):
                 label="Volume Control",
                 default_value=PLAYER_CONTROL_NATIVE if supports_volume else PLAYER_CONTROL_NONE,
                 required=True,
-                options=(
+                options=[
                     *base_volume_options,
                     *(ConfigValueOption(x.name, x.id) for x in volume_controls),
-                ),
+                ],
                 category="player_controls",
             ),
             # Mute control config entry
@@ -341,10 +341,10 @@ class PlayerProvider(Provider):
                 label="Mute Control",
                 default_value=PLAYER_CONTROL_NATIVE if supports_mute else PLAYER_CONTROL_NONE,
                 required=True,
-                options=(
+                options=[
                     *base_mute_options,
-                    *(ConfigValueOption(x.name, x.id) for x in mute_controls),
-                ),
+                    *[ConfigValueOption(x.name, x.id) for x in mute_controls],
+                ],
                 category="player_controls",
             ),
         )
index b960057509957dde914ad8eedd780051296f8c19..3ecf27c1a5bf2177a0833d0ef925a1590997edab 100644 (file)
@@ -58,7 +58,7 @@ from music_assistant_models.streamdetails import StreamDetails
 from music_assistant.models.music_provider import MusicProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant.mass import MusicAssistant
@@ -79,7 +79,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -90,9 +90,9 @@ async def get_config_entries(
     """
     # ruff: noqa: ARG001
     # Config Entries are used to configure the Music Provider if needed.
-    # See the models of ConfigEntry and ConfigValueType for more information what is supported.
+    # See the models of ConfigEntry and ConfigValueTypes for more information what is supported.
     # The ConfigEntry is a dataclass that represents a single configuration entry.
-    # The ConfigValueType is an Enum that represents the type of value that
+    # The ConfigValueTypes is an Enum that represents the type of value that
     # can be stored in a ConfigEntry.
     # If your provider does not need any configuration, you can return an empty tuple.
 
index 33ff6dea531d61c9032f12312893787049fe5012..8bb1350c3acec73800cbb03c5ea9076ee1eff259 100644 (file)
@@ -43,7 +43,7 @@ from music_assistant.models.player_provider import PlayerProvider
 if TYPE_CHECKING:
     from music_assistant_models.config_entries import (
         ConfigEntry,
-        ConfigValueType,
+        ConfigValueTypes,
         PlayerConfig,
         ProviderConfig,
     )
@@ -68,7 +68,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -79,9 +79,9 @@ async def get_config_entries(
     """
     # ruff: noqa: ARG001
     # Config Entries are used to configure the Player Provider if needed.
-    # See the models of ConfigEntry and ConfigValueType for more information what is supported.
+    # See the models of ConfigEntry and ConfigValueTypes for more information what is supported.
     # The ConfigEntry is a dataclass that represents a single configuration entry.
-    # The ConfigValueType is an Enum that represents the type of value that
+    # The ConfigValueTypes is an Enum that represents the type of value that
     # can be stored in a ConfigEntry.
     # If your provider does not need any configuration, you can return an empty tuple.
     return ()
index fbed240056b8c48b05ad90b7121f694ff49997be..0ca1a61363308a2b319fe79e58b53009b2401687 100644 (file)
@@ -43,7 +43,7 @@ from music_assistant_models.media_items.audio_format import AudioFormat
 from music_assistant.models.plugin import PluginProvider, PluginSource
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
     from music_assistant_models.event import MassEvent
     from music_assistant_models.provider import ProviderManifest
 
@@ -65,7 +65,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -76,9 +76,9 @@ async def get_config_entries(
     """
     # ruff: noqa: ARG001
     # Config Entries are used to configure the Provider if needed.
-    # See the models of ConfigEntry and ConfigValueType for more information what is supported.
+    # See the models of ConfigEntry and ConfigValueTypes for more information what is supported.
     # The ConfigEntry is a dataclass that represents a single configuration entry.
-    # The ConfigValueType is an Enum that represents the type of value that
+    # The ConfigValueTypes is an Enum that represents the type of value that
     # can be stored in a ConfigEntry.
     # If your provider does not need any configuration, you can return an empty tuple.
     return ()
index ee3282cbf1cc840f362ea39bf89e93f41f644d81..67c2a0095e87de81b289e719f898ec67f38ee8b0 100644 (file)
@@ -2,9 +2,9 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, cast
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
 from music_assistant_models.enums import ConfigEntryType
 from music_assistant_models.provider import ProviderManifest
 
@@ -24,7 +24,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -38,7 +38,7 @@ async def get_config_entries(
         ConfigEntry(
             key=CONF_BIND_INTERFACE,
             type=ConfigEntryType.STRING,
-            default_value=mass.streams.publish_ip,
+            default_value=cast(str, mass.streams.publish_ip),
             label="Bind interface",
             description="Interface to bind to for Airplay streaming.",
             category="advanced",
index bfee2038c8615614142d59827f34d16ffb745a22..60d175e2a9397c20af3b296240027977d6560455 100644 (file)
@@ -8,7 +8,7 @@ import os
 from typing import TYPE_CHECKING, Any
 
 import aiofiles
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     AlbumType,
     ConfigEntryType,
@@ -82,7 +82,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 79da00ace905b056a34a60b5865ebaca677f38eb..167f205083fe736fdf36e0a0ee8817e27e47d917 100644 (file)
@@ -13,7 +13,7 @@ import audible
 from music_assistant_models.config_entries import (
     ConfigEntry,
     ConfigValueOption,
-    ConfigValueType,
+    ConfigValueTypes,
     ProviderConfig,
 )
 from music_assistant_models.enums import ConfigEntryType, EventType, MediaType, ProviderFeature
@@ -60,7 +60,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -139,7 +139,7 @@ async def get_config_entries(
             hidden=not auth_required,
             required=True,
             value=locale,
-            options=(
+            options=[
                 ConfigValueOption("US and all other countries not listed", "us"),
                 ConfigValueOption("Canada", "ca"),
                 ConfigValueOption("UK and Ireland", "uk"),
@@ -151,7 +151,7 @@ async def get_config_entries(
                 ConfigValueOption("India", "in"),
                 ConfigValueOption("Spain", "es"),
                 ConfigValueOption("Brazil", "br"),
-            ),
+            ],
             default_value="us",
         ),
         ConfigEntry(
@@ -166,7 +166,7 @@ async def get_config_entries(
             type=ConfigEntryType.STRING,
             label="Post Login Url",
             required=False,
-            value=values.get(CONF_POST_LOGIN_URL),
+            value=cast(str | None, values.get(CONF_POST_LOGIN_URL)),
             hidden=not auth_required,
         ),
         ConfigEntry(
@@ -183,7 +183,7 @@ async def get_config_entries(
             label="Code Verifier",
             hidden=True,
             required=False,
-            value=values.get(CONF_CODE_VERIFIER),
+            value=cast(str | None, values.get(CONF_CODE_VERIFIER)),
         ),
         ConfigEntry(
             key=CONF_SERIAL,
@@ -191,7 +191,7 @@ async def get_config_entries(
             label="Serial",
             hidden=True,
             required=False,
-            value=values.get(CONF_SERIAL),
+            value=cast(str | None, values.get(CONF_SERIAL)),
         ),
         ConfigEntry(
             key=CONF_LOGIN_URL,
@@ -199,7 +199,7 @@ async def get_config_entries(
             label="Login Url",
             hidden=True,
             required=False,
-            value=values.get(CONF_LOGIN_URL),
+            value=cast(str | None, values.get(CONF_LOGIN_URL)),
         ),
         ConfigEntry(
             key=CONF_AUTH_FILE,
@@ -207,7 +207,7 @@ async def get_config_entries(
             label="Authentication File",
             hidden=True,
             required=True,
-            value=values.get(CONF_AUTH_FILE),
+            value=cast(str | None, values.get(CONF_AUTH_FILE)),
         ),
     )
 
index 8131bedc72f9d8a20f749bc356c1cfb371b49b88..f47afa54d84d845eb0c80222e8dbd345224a6eae 100644 (file)
@@ -24,7 +24,7 @@ from aioaudiobookshelf.schema.library import (
 )
 from aioaudiobookshelf.schema.library import LibraryMediaType as AbsLibraryMediaType
 from mashumaro.mixins.dict import DataClassDictMixin
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -136,7 +136,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 08f03eb19b4092e0ccfb8baba3dcda83cc9c109d..32c488edfaf5862e1b26eeba1efa3b0b8d83b367 100644 (file)
@@ -28,7 +28,7 @@ from music_assistant.helpers.util import (
 from music_assistant.models.player_provider import PlayerProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
     from zeroconf.asyncio import AsyncServiceInfo
 
@@ -78,7 +78,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """Set up legacy BluOS devices."""
     # ruff: noqa: ARG001
index 9dacc398e8fb9ccab0c253508297fa1c26696a6b..047b4258b1b4151c592c6b2fe4a7d718cd171486 100644 (file)
@@ -45,7 +45,7 @@ from music_assistant.helpers.uri import parse_uri
 from music_assistant.models.music_provider import MusicProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant.mass import MusicAssistant
@@ -108,7 +108,7 @@ async def get_config_entries(
     mass: MusicAssistant,  # noqa: ARG001
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index f6957c2925c7f628321f31a6238657bad14961a9..586b2856a7f10f4242f137b37d3757be5c3d4ff2 100644 (file)
@@ -47,7 +47,7 @@ from music_assistant.models.player_provider import PlayerProvider
 from .helpers import CastStatusListener, ChromecastInfo
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
     from pychromecast.controllers.media import MediaStatus
     from pychromecast.controllers.receiver import CastStatus
@@ -101,7 +101,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index a7a5ae3ea578e92ab673c164ad859e90e9b87628..81c9c8524634d403ff123b37ce26494b8692b859 100644 (file)
@@ -11,7 +11,7 @@ import deezer
 from aiohttp import ClientSession, ClientTimeout
 from Crypto.Cipher import Blowfish
 from deezer import exceptions as deezer_exceptions
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
 from music_assistant_models.enums import (
     AlbumType,
     ConfigEntryType,
@@ -122,7 +122,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """Return Config entries to setup this provider."""
     # Action is to launch oauth flow
index 22836391745a130fa3718b0e80e0449260f5d3b0..d8b6322c647775b79f1bc2e42fcb1bbed2f1e06f 100644 (file)
@@ -22,7 +22,7 @@ from async_upnp_client.client_factory import UpnpFactory
 from async_upnp_client.exceptions import UpnpError, UpnpResponseError
 from async_upnp_client.profiles.dlna import DmrDevice, TransportState
 from async_upnp_client.search import async_search
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
 from music_assistant_models.errors import PlayerUnavailableError
 from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
@@ -88,7 +88,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 89a94c5bd413ffb5c42844c654e8d0163a454b1f..f641cc50096e8846d2c7488a5f3fb3a6a8f21352 100644 (file)
@@ -16,7 +16,7 @@ from music_assistant.helpers.throttle_retry import Throttler
 from music_assistant.models.metadata_provider import MetadataProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.media_items import Album, Artist
     from music_assistant_models.provider import ProviderManifest
 
@@ -51,7 +51,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index fcfc00544616f3e59837c9c95d79d97cfa9c75c7..affbdf1a9de055e76bf297536609b5abe8b73830 100644 (file)
@@ -90,7 +90,7 @@ from .helpers import (
 )
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant.mass import MusicAssistant
@@ -116,7 +116,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 81ba3304e6c53513166f32a1b88ff13fa9620d17..cb536700f3a6c7eb60b9d21c0ddf844e8eac0d0d 100644 (file)
@@ -15,11 +15,11 @@ CONF_ENTRY_MISSING_ALBUM_ARTIST = ConfigEntry(
     default_value="various_artists",
     help_link="https://music-assistant.io/music-providers/filesystem/#tagging-files",
     required=False,
-    options=(
+    options=[
         ConfigValueOption("Use Track artist(s)", "track_artist"),
         ConfigValueOption("Use Various Artists", "various_artists"),
         ConfigValueOption("Use Folder name (if possible)", "folder_name"),
-    ),
+    ],
     depends_on=CONF_CONTENT_TYPE,
     depends_on_value="music",
 )
@@ -39,11 +39,11 @@ CONF_ENTRY_CONTENT_TYPE = ConfigEntry(
     default_value="music",
     description="The type of content to expect in the media folder(s)",
     required=False,
-    options=(
+    options=[
         ConfigValueOption("Music", "music"),
         ConfigValueOption("Audiobooks", "audiobooks"),
         ConfigValueOption("Podcasts", "podcasts"),
-    ),
+    ],
 )
 CONF_ENTRY_CONTENT_TYPE_READ_ONLY = ConfigEntry.from_dict(
     {
index 72b2213e644b7bd455500baefffe128b6dbba247..de4ee2363efaa882c5dcf31aa7f83fa6d7fe95c3 100644 (file)
@@ -6,7 +6,7 @@ import os
 import platform
 from typing import TYPE_CHECKING
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import ConfigEntryType
 from music_assistant_models.errors import LoginFailed
 
@@ -56,7 +56,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index b096db65cec4a513d3f654538d9dfd800fdb9505..630a84557db92550f28e42f0b011a187cf76ca8c 100644 (file)
@@ -8,7 +8,7 @@ import time
 from typing import TYPE_CHECKING
 
 from fullykiosk import FullyKiosk
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
 from music_assistant_models.errors import PlayerUnavailableError, SetupFailedError
 from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
@@ -47,7 +47,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index c3c0a266216652098d9e2bf6df35452acd1515bd..ace6ee7f7c27d5c737ce6487e70b497057323196 100644 (file)
@@ -24,7 +24,12 @@ from hass_client.utils import (
     get_token,
     get_websocket_url,
 )
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import (
+    ConfigEntry,
+    ConfigValueOption,
+    ConfigValueTypes,
+    MultiValueConfigEntry,
+)
 from music_assistant_models.enums import ConfigEntryType
 from music_assistant_models.errors import LoginFailed, SetupFailedError
 from music_assistant_models.player_control import PlayerControl
@@ -65,7 +70,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -143,7 +148,7 @@ async def get_config_entries(
                 label="URL",
                 required=True,
                 description="URL to your Home Assistant instance (e.g. http://192.168.1.1:8123)",
-                value=values.get(CONF_URL) if values else None,
+                value=cast(str, values.get(CONF_URL)) if values else None,
             ),
             ConfigEntry(
                 key=CONF_ACTION_AUTH,
@@ -162,7 +167,7 @@ async def get_config_entries(
                 description="You can either paste a Long Lived Token here manually or use the "
                 "'authenticate' button to generate a token for you with logging in.",
                 depends_on=CONF_URL,
-                value=values.get(CONF_AUTH_TOKEN) if values else None,
+                value=cast(str, values.get(CONF_AUTH_TOKEN)) if values else None,
                 category="advanced",
             ),
             ConfigEntry(
@@ -183,26 +188,23 @@ async def get_config_entries(
 
     return (
         *base_entries,
-        ConfigEntry(
+        MultiValueConfigEntry(
             key=CONF_POWER_CONTROLS,
             type=ConfigEntryType.STRING,
             label=CONF_POWER_CONTROLS,
             default_value=[],
-            multi_value=True,
         ),
-        ConfigEntry(
+        MultiValueConfigEntry(
             key=CONF_VOLUME_CONTROLS,
             type=ConfigEntryType.STRING,
             label=CONF_VOLUME_CONTROLS,
             default_value=[],
-            multi_value=True,
         ),
-        ConfigEntry(
+        MultiValueConfigEntry(
             key=CONF_MUTE_CONTROLS,
             type=ConfigEntryType.STRING,
             label=CONF_MUTE_CONTROLS,
             default_value=[],
-            multi_value=True,
         ),
     )
 
@@ -252,37 +254,34 @@ async def _get_player_control_config_entries(hass: HomeAssistantClient) -> tuple
     all_mute_entities.sort(key=lambda x: x.title)
     all_volume_entities.sort(key=lambda x: x.title)
     return (
-        ConfigEntry(
+        MultiValueConfigEntry(
             key=CONF_POWER_CONTROLS,
             type=ConfigEntryType.STRING,
             label="Player Power Control entities",
             required=True,
-            options=tuple(all_power_entities),
-            multi_value=True,
+            options=all_power_entities,
             default_value=[],
             description="Specify which Home Assistant entities you "
             "like to import as player Power controls in Music Assistant.",
             category="player_controls",
         ),
-        ConfigEntry(
+        MultiValueConfigEntry(
             key=CONF_VOLUME_CONTROLS,
             type=ConfigEntryType.STRING,
             label="Player Volume Control entities",
             required=True,
-            options=tuple(all_volume_entities),
-            multi_value=True,
+            options=all_volume_entities,
             default_value=[],
             description="Specify which Home Assistant entities you "
             "like to import as player Volume controls in Music Assistant.",
             category="player_controls",
         ),
-        ConfigEntry(
+        MultiValueConfigEntry(
             key=CONF_MUTE_CONTROLS,
             type=ConfigEntryType.STRING,
             label="Player Mute Control entities",
             required=True,
-            options=tuple(all_mute_entities),
-            multi_value=True,
+            options=all_mute_entities,
             default_value=[],
             description="Specify which Home Assistant entities you "
             "like to import as player Mute controls in Music Assistant.",
index 63f253effbc4fab6146f45a16d8582768efbf39f..93a24a02f0ad6c53534e149531f42722376e5deb 100644 (file)
@@ -12,7 +12,12 @@ import time
 from typing import TYPE_CHECKING, Any
 
 from hass_client.exceptions import FailedCommand
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import (
+    ConfigEntry,
+    ConfigValueOption,
+    ConfigValueTypes,
+    MultiValueConfigEntry,
+)
 from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
 from music_assistant_models.errors import SetupFailedError
 from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
@@ -124,7 +129,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -140,13 +145,12 @@ async def get_config_entries(
             name = f"{state['attributes']['friendly_name']} ({state['entity_id']})"
             player_entities.append(ConfigValueOption(name, state["entity_id"]))
     return (
-        ConfigEntry(
+        MultiValueConfigEntry(
             key=CONF_PLAYERS,
             type=ConfigEntryType.STRING,
             label="Player entities",
             required=True,
-            options=tuple(player_entities),
-            multi_value=True,
+            options=player_entities,
             description="Specify which HA media_player entity id's you "
             "like to import as players in Music Assistant.",
         ),
index 2a3a11bc8fbeb60db8087673d43b9c4f5f0e2d72..397704889fd01ea5dc8df67c33b8bc1e763d6396 100644 (file)
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any
 
 from aiohttp import ClientSession
 from ibroadcastaio import IBroadcastClient
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     AlbumType,
     ConfigEntryType,
@@ -74,7 +74,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 9e698dcf8702c713398a524da5f5f97c96d3f75b..7480a7b26ab873481d89cc747d33068d9af7750f 100644 (file)
@@ -11,7 +11,7 @@ from typing import TYPE_CHECKING
 from aiojellyfin import MediaLibrary as JellyMediaLibrary
 from aiojellyfin import NotFound, authenticate_by_name
 from aiojellyfin.session import SessionConfiguration
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
 from music_assistant_models.enums import ConfigEntryType, MediaType, ProviderFeature, StreamType
 from music_assistant_models.errors import LoginFailed, MediaNotFoundError
 from music_assistant_models.media_items import (
@@ -71,7 +71,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index a7522994c4cd2b99a59d9315ad83110ff7b526c7..61daeee9fa583ea04dfc530cc4b2366699f18b27 100644 (file)
@@ -23,7 +23,7 @@ from music_assistant.helpers.util import parse_title_and_version
 from music_assistant.models.metadata_provider import MetadataProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
     from music_assistant_models.media_items import Album, Track
     from music_assistant_models.provider import ProviderManifest
 
@@ -47,7 +47,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 2505c386a9fb91f5c583bf79462d1a6ebfa2837b..eb070f41ddb29b0b27cd14eb056399cf1c5dc577 100644 (file)
@@ -4,7 +4,7 @@ from __future__ import annotations
 
 from typing import TYPE_CHECKING
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes, ProviderConfig
 from music_assistant_models.enums import ConfigEntryType
 
 from music_assistant.constants import CONF_PASSWORD, CONF_PATH, CONF_PORT, CONF_USERNAME
@@ -35,7 +35,7 @@ async def get_config_entries(
     mass: MusicAssistant,  # noqa: ARG001
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """Return Config entries to setup this provider."""
     return (
index c1b89b90c7b04c229ccd0592ccddaa88ec9b1eb4..259b193d29985048d0b875e892f1abd0b723a07b 100644 (file)
@@ -18,7 +18,8 @@ from aiohttp import web
 from music_assistant_models.config_entries import (
     ConfigEntry,
     ConfigValueOption,
-    ConfigValueType,
+    ConfigValueTypes,
+    MultiValueConfigEntry,
     PlayerConfig,
 )
 from music_assistant_models.constants import PLAYER_CONTROL_NATIVE, PLAYER_CONTROL_NONE
@@ -100,13 +101,12 @@ CONF_ENTRY_GROUP_TYPE = ConfigEntry(
     hidden=True,
     required=True,
 )
-CONF_ENTRY_GROUP_MEMBERS = ConfigEntry(
+CONF_ENTRY_GROUP_MEMBERS = MultiValueConfigEntry(
     key=CONF_GROUP_MEMBERS,
     type=ConfigEntryType.STRING,
     label="Group members",
     default_value=[],
     description="Select all players you want to be part of this group",
-    multi_value=True,
     required=False,  # otherwise dynamic members won't work (which allows empty members list)
 )
 CONF_ENTRY_SAMPLE_RATES_UGP = create_sample_rates_config_entry(44100, 16, 44100, 16, True)
@@ -143,7 +143,7 @@ async def get_config_entries(
     mass: MusicAssistant,  # noqa: ARG001
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index d4aa15a03faf5d914b02a04dac43c76d305d828e..62a521462bb581a2c40894a6889b62c17ceccd56 100644 (file)
@@ -14,7 +14,7 @@ import requests
 from music_assistant_models.config_entries import (
     ConfigEntry,
     ConfigValueOption,
-    ConfigValueType,
+    ConfigValueTypes,
     ProviderConfig,
 )
 from music_assistant_models.enums import (
@@ -105,7 +105,7 @@ async def get_config_entries(  # noqa: PLR0915
     mass: MusicAssistant,
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -182,7 +182,7 @@ async def get_config_entries(  # noqa: PLR0915
             label="Local server IP",
             description="The local server IP (e.g. 192.168.1.77)",
             required=True,
-            value=values.get(CONF_LOCAL_SERVER_IP) if values else None,
+            value=cast(str, values.get(CONF_LOCAL_SERVER_IP)) if values else None,
         ),
         ConfigEntry(
             key=CONF_LOCAL_SERVER_PORT,
@@ -191,7 +191,7 @@ async def get_config_entries(  # noqa: PLR0915
             description="The local server port (e.g. 32400)",
             required=True,
             default_value=32400,
-            value=values.get(CONF_LOCAL_SERVER_PORT) if values else None,
+            value=cast(int, values.get(CONF_LOCAL_SERVER_PORT)) if values else None,
         ),
         ConfigEntry(
             key=CONF_LOCAL_SERVER_SSL,
@@ -216,7 +216,7 @@ async def get_config_entries(  # noqa: PLR0915
             type=ConfigEntryType.SECURE_STRING,
             label=CONF_AUTH_TOKEN,
             action=CONF_AUTH_TOKEN,
-            value=values.get(CONF_AUTH_TOKEN) if values else None,
+            value=cast(str | None, values.get(CONF_AUTH_TOKEN)) if values else None,
             hidden=True,
         ),
     ]
@@ -257,7 +257,7 @@ async def get_config_entries(  # noqa: PLR0915
             ):
                 msg = "Unable to retrieve Servers and/or Music Libraries"
                 raise LoginFailed(msg)
-            conf_libraries.options = tuple(
+            conf_libraries.options = [
                 # use the same value for both the value and the title
                 # until we find out what plex uses as stable identifiers
                 ConfigValueOption(
@@ -265,7 +265,7 @@ async def get_config_entries(  # noqa: PLR0915
                     value=x,
                 )
                 for x in libraries
-            )
+            ]
             # select first library as (default) value
             conf_libraries.default_value = libraries[0]
             conf_libraries.value = libraries[0]
index 0e18cc7f04cb1117fa8b49faaba77d1a4e0ed714..bc69bfa733ad2efad4069846ebf2138420ababff 100644 (file)
@@ -14,7 +14,7 @@ from io import BytesIO
 from typing import TYPE_CHECKING
 
 import podcastparser
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -63,7 +63,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -76,7 +76,6 @@ async def get_config_entries(
         ConfigEntry(
             key=CONF_FEED_URL,
             type=ConfigEntryType.STRING,
-            default_value=[],
             label="RSS Feed URL",
             required=True,
         ),
index 0549e45412b22d191c4da96b1931bcb782128130..5b7f774fdc428a9654491284d5ff93e4b5f43f12 100644 (file)
@@ -9,7 +9,7 @@ from contextlib import suppress
 from typing import TYPE_CHECKING
 
 from aiohttp import client_exceptions
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     AlbumType,
     ConfigEntryType,
@@ -91,7 +91,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 1b85736b6ceb00c20a73ef13a980cc34ccf88806..3f6178131e6588cd439fbf87ab2237c15dc13747 100644 (file)
@@ -5,7 +5,7 @@ from __future__ import annotations
 from collections.abc import AsyncGenerator, Sequence
 from typing import TYPE_CHECKING, cast
 
-from music_assistant_models.config_entries import ConfigEntry
+from music_assistant_models.config_entries import ConfigEntry, MultiValueConfigEntry
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -44,7 +44,7 @@ SUPPORTED_FEATURES = {
 }
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant.mass import MusicAssistant
@@ -64,7 +64,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -74,7 +74,7 @@ async def get_config_entries(
     """
     # ruff: noqa: ARG001 D205
     return (
-        ConfigEntry(
+        MultiValueConfigEntry(
             # RadioBrowser doesn't support a library feature at all
             # but MA users like to favorite their radio stations and
             # have that included in backups so we store it in the config.
@@ -83,7 +83,6 @@ async def get_config_entries(
             label=CONF_STORED_RADIOS,
             default_value=[],
             required=False,
-            multi_value=True,
             hidden=True,
         ),
     )
index 45ddc7ae45b5bcffecfc2b9ba7640fa7422a72e3..cef972086a30dd2dce98786cb409ff72b651a013 100644 (file)
@@ -5,7 +5,7 @@ from __future__ import annotations
 from collections.abc import AsyncGenerator, Awaitable, Sequence
 from typing import TYPE_CHECKING, Any, cast
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueTypes
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -58,7 +58,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -85,10 +85,10 @@ async def get_config_entries(
             key=CONF_SXM_REGION,
             type=ConfigEntryType.STRING,
             default_value="US",
-            options=(
+            options=[
                 ConfigValueOption(title="United States", value="US"),
                 ConfigValueOption(title="Canada", value="CA"),
-            ),
+            ],
             label="Region",
             required=True,
         ),
index d8a75624e774abc16cb784b35026b5954a9f7652..153503e07e3f63c2cefc5fdc7f59da93dce00b44 100644 (file)
@@ -22,7 +22,7 @@ from aioslimproto.server import SlimServer
 from music_assistant_models.config_entries import (
     ConfigEntry,
     ConfigValueOption,
-    ConfigValueType,
+    ConfigValueTypes,
     PlayerConfig,
 )
 from music_assistant_models.enums import (
@@ -126,10 +126,10 @@ CONF_ENTRY_VISUALIZATION = ConfigEntry(
     key=CONF_VISUALIZATION,
     type=ConfigEntryType.STRING,
     default_value=DEFAULT_VISUALIZATION,
-    options=tuple(
+    options=[
         ConfigValueOption(title=x.name.replace("_", " ").title(), value=x.value)
         for x in SlimVisualisationType
-    ),
+    ],
     required=False,
     label="Visualization type",
     description="The type of visualization to show on the display "
@@ -150,7 +150,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 1cae193f4ef6d79ac83e3666f528ffd3cc68ae61..f2d8d5b616d6ab54499f71c033dbb6cac30cfcfa 100644 (file)
@@ -13,7 +13,7 @@ from contextlib import suppress
 from typing import TYPE_CHECKING, Final, cast
 
 from bidict import bidict
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueTypes
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -114,7 +114,7 @@ async def get_config_entries(
     mass: MusicAssistant,  # noqa: ARG001
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -176,7 +176,7 @@ async def get_config_entries(
         ConfigEntry(
             key=CONF_SERVER_TRANSPORT_CODEC,
             type=ConfigEntryType.STRING,
-            options=(
+            options=[
                 ConfigValueOption(
                     title="FLAC",
                     value="flac",
@@ -193,7 +193,7 @@ async def get_config_entries(
                     title="PCM",
                     value="pcm",
                 ),
-            ),
+            ],
             default_value="flac",
             label="Snapserver default transport codec",
             required=False,
index 0ccfa50c1d0be7850750d952dc0c238eb6fff6a2..95c95a1db4380f5d8485daa6be6f12c94cbef386 100644 (file)
@@ -17,7 +17,7 @@ from music_assistant.constants import VERBOSE_LOG_LEVEL
 from .provider import CONF_IPS, SonosPlayerProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant import MusicAssistant
@@ -41,7 +41,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 23c0474b4c66e9819d916c28858bb53b7f99f9a8..e50683234e7eec8a66e797e46275720a2b046617 100644 (file)
@@ -15,7 +15,7 @@ from collections import OrderedDict
 from dataclasses import dataclass, field
 from typing import TYPE_CHECKING, cast
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     ConfigEntryType,
     PlayerFeature,
@@ -89,7 +89,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index e0363ed9918608f0954e6db3e17eadafc3c665fc..88c43496db7e95aa683581e7ac6c272764da7faa 100644 (file)
@@ -5,7 +5,7 @@ from __future__ import annotations
 import time
 from typing import TYPE_CHECKING, Any
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -69,7 +69,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 804ac419651655b0db3584c21004dff0f3d4b90d..c3112413d941b97abb3aadeaf7d905ca89ff790c 100644 (file)
@@ -10,7 +10,7 @@ import time
 from typing import TYPE_CHECKING, Any, cast
 from urllib.parse import urlencode
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     AlbumType,
     ConfigEntryType,
@@ -125,7 +125,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 7c96224d5c6fc09ef6273ae0f76a476254918dd5..4b404a9632411b5b4af00f8d4acd2a0b9ff66e46 100644 (file)
@@ -35,7 +35,7 @@ from music_assistant.providers.spotify.helpers import get_librespot_binary
 
 if TYPE_CHECKING:
     from aiohttp.web import Request
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.event import MassEvent
     from music_assistant_models.provider import ProviderManifest
 
@@ -60,7 +60,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -77,10 +77,10 @@ async def get_config_entries(
             label="Connected Music Assistant Player",
             description="Select the player for which you want to enable Spotify Connect.",
             multi_value=False,
-            options=tuple(
+            options=[
                 ConfigValueOption(x.display_name, x.player_id)
                 for x in mass.players.all(False, False)
-            ),
+            ],
             required=True,
         ),
         # ConfigEntry(
index d645ad526476db4c893042566ecd77f70ab49a8e..e3d3d2bf5b4ce6309eb93a2c10ed9bc65031a4ac 100644 (file)
@@ -35,7 +35,7 @@ from music_assistant.constants import MASS_LOGO, SILENCE_FILE_LONG, VARIOUS_ARTI
 from music_assistant.models.music_provider import MusicProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant.mass import MusicAssistant
@@ -74,7 +74,7 @@ async def get_config_entries(
     mass: MusicAssistant,  # noqa: ARG001
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index ded4f5598e1b86dd5ce4290610376682b015ebac..c732284d5bf040a5e53ccaba96685ec576479fa5 100644 (file)
@@ -32,7 +32,7 @@ from music_assistant.helpers.throttle_retry import Throttler
 from music_assistant.models.metadata_provider import MetadataProvider
 
 if TYPE_CHECKING:
-    from music_assistant_models.config_entries import ConfigValueType, ProviderConfig
+    from music_assistant_models.config_entries import ConfigValueTypes, ProviderConfig
     from music_assistant_models.provider import ProviderManifest
 
     from music_assistant.mass import MusicAssistant
@@ -94,7 +94,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index b9c3026f968a42896e0d95659e581b2f4f8344eb..146645515ab333de65adb1a7ef9bb23b56ff5eb5 100644 (file)
@@ -11,7 +11,7 @@ from datetime import datetime, timedelta
 from enum import StrEnum
 from typing import TYPE_CHECKING, ParamSpec, TypeVar, cast
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueTypes
 from music_assistant_models.enums import (
     AlbumType,
     CacheCategory,
@@ -165,7 +165,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
@@ -226,8 +226,8 @@ async def get_config_entries(
                 label=CONF_QUALITY,
                 required=True,
                 hidden=True,
-                default_value=values.get(CONF_QUALITY, TidalQualityEnum.HI_RES.value),
-                value=values.get(CONF_QUALITY),
+                value=cast(str, values.get(CONF_QUALITY) or TidalQualityEnum.HI_RES.value),
+                default_value=cast(str, values.get(CONF_QUALITY) or TidalQualityEnum.HI_RES.value),
             ),
         )
     else:
@@ -238,9 +238,9 @@ async def get_config_entries(
                 label="Quality setting for Tidal:",
                 required=True,
                 description="HIGH_LOSSLESS = 16bit 44.1kHz, HI_RES = Up to 24bit 192kHz",
-                options=tuple(ConfigValueOption(x.value, x.name) for x in TidalQualityEnum),
+                options=[ConfigValueOption(x.value, x.name) for x in TidalQualityEnum],
                 default_value=TidalQualityEnum.HI_RES.value,
-                value=values.get(CONF_QUALITY) if values else None,
+                value=cast(str, values.get(CONF_QUALITY)) if values else None,
             ),
             ConfigEntry(
                 key=LABEL_START_PKCE_LOGIN,
@@ -261,7 +261,7 @@ async def get_config_entries(
                 action=CONF_ACTION_START_PKCE_LOGIN,
                 depends_on=CONF_QUALITY,
                 action_label="Starts the auth process via PKCE on Tidal.com",
-                value=values.get(CONF_TEMP_SESSION) if values else None,
+                value=cast(str, values.get(CONF_TEMP_SESSION)) if values else None,
                 hidden=action == CONF_ACTION_START_PKCE_LOGIN,
             ),
             ConfigEntry(
@@ -270,7 +270,7 @@ async def get_config_entries(
                 label="Temporary session for Tidal",
                 hidden=True,
                 required=False,
-                value=values.get(CONF_TEMP_SESSION) if values else None,
+                value=cast(str, values.get(CONF_TEMP_SESSION)) if values else None,
             ),
             ConfigEntry(
                 key=LABEL_OOPS_URL,
@@ -287,7 +287,7 @@ async def get_config_entries(
                 " Tidal.com and being redirected to a page that prominently displays"
                 " 'Oops' at the top.",
                 depends_on=CONF_ACTION_START_PKCE_LOGIN,
-                value=values.get(CONF_OOPS_URL) if values else None,
+                value=cast(str, values.get(CONF_OOPS_URL)) if values else None,
                 hidden=action != CONF_ACTION_START_PKCE_LOGIN,
             ),
             ConfigEntry(
@@ -320,7 +320,7 @@ async def get_config_entries(
             label="Authentication token for Tidal",
             description="You need to link Music Assistant to your Tidal account.",
             hidden=True,
-            value=values.get(CONF_AUTH_TOKEN) if values else None,
+            value=cast(str, values.get(CONF_AUTH_TOKEN)) if values else None,
         ),
         ConfigEntry(
             key=CONF_REFRESH_TOKEN,
@@ -328,14 +328,14 @@ async def get_config_entries(
             label="Refresh token for Tidal",
             description="You need to link Music Assistant to your Tidal account.",
             hidden=True,
-            value=values.get(CONF_REFRESH_TOKEN) if values else None,
+            value=cast(str, values.get(CONF_REFRESH_TOKEN)) if values else None,
         ),
         ConfigEntry(
             key=CONF_EXPIRY_TIME,
             type=ConfigEntryType.STRING,
             label="Expiry time of auth token for Tidal",
             hidden=True,
-            value=values.get(CONF_EXPIRY_TIME) if values else None,
+            value=cast(str, values.get(CONF_EXPIRY_TIME)) if values else None,
         ),
         ConfigEntry(
             key=CONF_USER_ID,
@@ -343,7 +343,7 @@ async def get_config_entries(
             label="Your Tidal User ID",
             description="This is your unique Tidal user ID.",
             hidden=True,
-            value=values.get(CONF_USER_ID) if values else None,
+            value=cast(str, values.get(CONF_USER_ID)) if values else None,
         ),
     )
 
index c03a2ddfc33e4e6e5baa623cdb1f2744a7ad1adf..b459515537959bfd32136303066bd6a8776c55c8 100644 (file)
@@ -4,7 +4,7 @@ from __future__ import annotations
 
 from typing import TYPE_CHECKING
 
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     ConfigEntryType,
     ContentType,
@@ -56,7 +56,7 @@ async def get_config_entries(
     mass: MusicAssistant,
     instance_id: str | None = None,
     action: str | None = None,
-    values: dict[str, ConfigValueType] | None = None,
+    values: dict[str, ConfigValueTypes] | None = None,
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 4e39a0cf352002f297456e3519cf3243dc97aea1..101b3d3297e3ce20bbee8e90459a046323c8ed81 100644 (file)
@@ -11,7 +11,7 @@ from urllib.parse import unquote
 
 import yt_dlp
 from duration_parser import parse as parse_str_duration
-from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueTypes
 from music_assistant_models.enums import (
     AlbumType,
     ConfigEntryType,
@@ -136,7 +136,7 @@ async def get_config_entries(
     mass: MusicAssistant,  # noqa: ARG001
     instance_id: str | None = None,  # noqa: ARG001
     action: str | None = None,  # noqa: ARG001
-    values: dict[str, ConfigValueType] | None = None,  # noqa: ARG001
+    values: dict[str, ConfigValueTypes] | None = None,  # noqa: ARG001
 ) -> tuple[ConfigEntry, ...]:
     """
     Return Config entries to setup this provider.
index 4dc657ad6e242e8be08594600b80dadce8fc2f85..a5cb57d91c9962e3a13f06b6ceeff17313af6cd5 100644 (file)
@@ -24,7 +24,7 @@ dependencies = [
   "mashumaro==3.15",
   "memory-tempfile==2.2.3",
   "music-assistant-frontend==2.11.5",
-  "music-assistant-models==1.1.27",
+  "music-assistant-models==1.1.28",
   "mutagen==1.47.0",
   "orjson==3.10.12",
   "pillow==11.1.0",
index d85cd3241a60856a0e18fc7ef8f77ca54153bb10..642e0aeffbb65918d5ab4cd7cb2d5ed6724cd94d 100644 (file)
@@ -26,7 +26,7 @@ ifaddr==0.2.0
 mashumaro==3.15
 memory-tempfile==2.2.3
 music-assistant-frontend==2.11.5
-music-assistant-models==1.1.27
+music-assistant-models==1.1.28
 mutagen==1.47.0
 orjson==3.10.12
 pillow==11.1.0