0
# Models and Data Structures
1
2
Mopidy's immutable data models represent music metadata and provide the foundation for all music-related operations. These models are designed to be immutable, validated, and serializable, ensuring data consistency throughout the system.
3
4
## Capabilities
5
6
### Base Model Classes
7
8
Foundation classes for all Mopidy models providing immutability, validation, and serialization capabilities.
9
10
```python { .api }
11
class ImmutableObject:
12
"""Base class for immutable objects with keyword-only construction."""
13
def __init__(self, **kwargs): ...
14
def replace(self, **kwargs): ...
15
16
class ValidatedImmutableObject(ImmutableObject):
17
"""Base class with field validation and type checking."""
18
def __init__(self, **kwargs): ...
19
```
20
21
### Reference Objects
22
23
Lightweight URI references with human-friendly names and type information, used for browsing and navigation without full metadata.
24
25
```python { .api }
26
class Ref(ValidatedImmutableObject):
27
"""
28
Model to represent URI references with a human friendly name and type.
29
30
Parameters:
31
- uri (str): Object URI
32
- name (str): Human-readable name
33
- type (str): Object type ('artist', 'album', 'track', 'playlist', 'directory')
34
"""
35
uri: str
36
name: str
37
type: str
38
39
# Type constants
40
ALBUM = "album"
41
ARTIST = "artist"
42
DIRECTORY = "directory"
43
PLAYLIST = "playlist"
44
TRACK = "track"
45
46
@classmethod
47
def album(cls, **kwargs): ...
48
49
@classmethod
50
def artist(cls, **kwargs): ...
51
52
@classmethod
53
def directory(cls, **kwargs): ...
54
55
@classmethod
56
def playlist(cls, **kwargs): ...
57
58
@classmethod
59
def track(cls, **kwargs): ...
60
```
61
62
Usage example:
63
```python
64
# Create references using factory methods
65
artist_ref = Ref.artist(uri="spotify:artist:123", name="The Beatles")
66
album_ref = Ref.album(uri="spotify:album:456", name="Abbey Road")
67
track_ref = Ref.track(uri="spotify:track:789", name="Come Together")
68
```
69
70
### Artist Metadata
71
72
Artist information including identifiers, names, and metadata for music organization and display.
73
74
```python { .api }
75
class Artist(ValidatedImmutableObject):
76
"""
77
Artist metadata model.
78
79
Parameters:
80
- uri (str): Artist URI
81
- name (str): Artist name
82
- sortname (str, optional): Artist name for sorting (e.g., without articles)
83
- musicbrainz_id (str, optional): MusicBrainz identifier
84
"""
85
uri: str
86
name: str
87
sortname: str
88
musicbrainz_id: str
89
```
90
91
Usage example:
92
```python
93
artist = Artist(
94
uri="local:artist:the-beatles",
95
name="The Beatles",
96
sortname="Beatles, The",
97
musicbrainz_id="b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"
98
)
99
```
100
101
### Album Metadata
102
103
Album information including tracks, release details, and associated artists.
104
105
```python { .api }
106
class Album(ValidatedImmutableObject):
107
"""
108
Album metadata model.
109
110
Parameters:
111
- uri (str): Album URI
112
- name (str): Album name
113
- artists (frozenset[Artist]): Album artists
114
- num_tracks (int, optional): Number of tracks in album
115
- num_discs (int, optional): Number of discs in album
116
- date (str, optional): Release date (YYYY or YYYY-MM-DD)
117
- musicbrainz_id (str, optional): MusicBrainz identifier
118
"""
119
uri: str
120
name: str
121
artists: frozenset[Artist]
122
num_tracks: int
123
num_discs: int
124
date: str
125
musicbrainz_id: str
126
```
127
128
Usage example:
129
```python
130
album = Album(
131
uri="local:album:abbey-road",
132
name="Abbey Road",
133
artists=frozenset([artist]),
134
num_tracks=17,
135
date="1969-09-26",
136
musicbrainz_id="7fb57fde-258e-4430-b23c-14dac0f8bb0b"
137
)
138
```
139
140
### Track Metadata
141
142
Complete track information including audio metadata, relationships, and technical details.
143
144
```python { .api }
145
class Track(ValidatedImmutableObject):
146
"""
147
Track metadata model.
148
149
Parameters:
150
- uri (str): Track URI
151
- name (str): Track name
152
- artists (frozenset[Artist], optional): Track artists
153
- album (Album, optional): Track album
154
- composers (frozenset[Artist], optional): Track composers
155
- performers (frozenset[Artist], optional): Track performers
156
- genre (str, optional): Track genre
157
- track_no (int, optional): Track number in album
158
- disc_no (int, optional): Disc number in album
159
- date (str, optional): Track release date (YYYY or YYYY-MM-DD)
160
- length (int, optional): Track length in milliseconds
161
- bitrate (int, optional): Bitrate in kbit/s
162
- comment (str, optional): Track comment
163
- musicbrainz_id (str, optional): MusicBrainz identifier
164
- last_modified (int, optional): Last modification time (Unix epoch ms)
165
"""
166
uri: str
167
name: str
168
artists: frozenset[Artist]
169
album: Album
170
composers: frozenset[Artist]
171
performers: frozenset[Artist]
172
genre: str
173
track_no: int
174
disc_no: int
175
date: str
176
length: int
177
bitrate: int
178
comment: str
179
musicbrainz_id: str
180
last_modified: int
181
```
182
183
Usage example:
184
```python
185
track = Track(
186
uri="local:track:come-together.mp3",
187
name="Come Together",
188
artists=frozenset([artist]),
189
album=album,
190
track_no=1,
191
length=259000, # 4:19 in milliseconds
192
bitrate=320
193
)
194
```
195
196
### Tracklist Tracks
197
198
Tracklist-specific track wrappers that allow the same track to appear multiple times with unique identifiers.
199
200
```python { .api }
201
class TlTrack(ValidatedImmutableObject):
202
"""
203
A tracklist track wrapping a regular track with a tracklist ID.
204
205
Parameters:
206
- tlid (int): Tracklist ID
207
- track (Track): The track object
208
"""
209
tlid: int
210
track: Track
211
212
def __init__(self, *args, **kwargs):
213
"""Supports positional arguments: TlTrack(tlid, track)"""
214
...
215
216
def __iter__(self):
217
"""Supports iteration: tlid, track = tl_track"""
218
...
219
```
220
221
Usage example:
222
```python
223
tl_track = TlTrack(tlid=1, track=track)
224
# Or using positional arguments
225
tl_track = TlTrack(1, track)
226
# Or using iteration
227
tlid, track_obj = tl_track
228
```
229
230
### Playlist Metadata
231
232
Playlist information including tracks, modification times, and metadata.
233
234
```python { .api }
235
class Playlist(ValidatedImmutableObject):
236
"""
237
Playlist metadata model.
238
239
Parameters:
240
- uri (str): Playlist URI
241
- name (str): Playlist name
242
- tracks (tuple[Track]): Playlist tracks
243
- last_modified (int, optional): Modification time (Unix epoch ms)
244
"""
245
uri: str
246
name: str
247
tracks: tuple[Track]
248
last_modified: int
249
250
@property
251
def length(self) -> int:
252
"""The number of tracks in the playlist."""
253
...
254
```
255
256
Usage example:
257
```python
258
playlist = Playlist(
259
uri="m3u:playlist:favorites.m3u",
260
name="My Favorites",
261
tracks=(track1, track2, track3),
262
last_modified=1640995200000
263
)
264
print(f"Playlist has {playlist.length} tracks")
265
```
266
267
### Search Results
268
269
Container for search results across different media types with organized results by category.
270
271
```python { .api }
272
class SearchResult(ValidatedImmutableObject):
273
"""
274
Search result container organizing matches by type.
275
276
Parameters:
277
- uri (str, optional): Search result URI
278
- tracks (tuple[Track], optional): Matching tracks
279
- artists (tuple[Artist], optional): Matching artists
280
- albums (tuple[Album], optional): Matching albums
281
"""
282
uri: str
283
tracks: tuple[Track]
284
artists: tuple[Artist]
285
albums: tuple[Album]
286
```
287
288
Usage example:
289
```python
290
search_result = SearchResult(
291
uri="spotify:search:beatles",
292
tracks=(track1, track2),
293
artists=(artist,),
294
albums=(album1, album2)
295
)
296
```
297
298
### Image Metadata
299
300
Image information for album art, artist photos, and other visual content.
301
302
```python { .api }
303
class Image(ValidatedImmutableObject):
304
"""
305
Image metadata model.
306
307
Parameters:
308
- uri (str): Image URI
309
- width (int, optional): Image width in pixels
310
- height (int, optional): Image height in pixels
311
"""
312
uri: str
313
width: int
314
height: int
315
```
316
317
Usage example:
318
```python
319
image = Image(
320
uri="https://example.com/album-art.jpg",
321
width=600,
322
height=600
323
)
324
```
325
326
### JSON Serialization
327
328
Utilities for converting models to and from JSON representations for storage and transmission.
329
330
```python { .api }
331
class ModelJSONEncoder(json.JSONEncoder):
332
"""JSON encoder for Mopidy model objects."""
333
def default(self, obj): ...
334
335
def model_json_decoder(dct):
336
"""
337
JSON decoder for reconstructing Mopidy model objects.
338
339
Parameters:
340
- dct (dict): Dictionary from JSON parsing
341
342
Returns:
343
- Model object or original dict
344
"""
345
...
346
```
347
348
Usage example:
349
```python
350
import json
351
352
# Serialize models to JSON
353
encoder = ModelJSONEncoder()
354
json_data = encoder.encode(track)
355
356
# Deserialize models from JSON
357
track_obj = json.loads(json_data, object_hook=model_json_decoder)
358
```
359
360
## Types
361
362
```python { .api }
363
# Type definitions used throughout models
364
Uri = str
365
UriScheme = str
366
QueryValue = Union[str, int]
367
Query = Dict[str, List[QueryValue]]
368
```