revert(purchases): remove mock FastAPI server from repository

cx
This commit is contained in:
vicrodh committed 2026-02-17 19:36:22 -06:00
1 parent 415a9d93f3
commit 861a9e0311
3 files changed
-727

No files matched your search

-593
View File
@@ -1,593 +0,0 @@
"""Mock purchase data — Qobuz-shaped responses for UI prototyping."""
MOCK_ALBUMS = [
{
"id": "album-001",
"title": "Wish You Were Here",
"artist": {"id": 36819, "name": "Pink Floyd"},
"image": {
"small": "https://via.placeholder.com/150?text=WYWH",
"large": "https://via.placeholder.com/600?text=WYWH",
"thumbnail": "https://via.placeholder.com/50?text=WYWH",
},
"release_date_original": "1975-09-12",
"label": {"id": 1, "name": "Harvest"},
"genre": {"id": 10, "name": "Rock"},
"tracks_count": 5,
"duration": 2580,
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"downloadable": True,
"downloaded": True,
"purchased_at": "2026-01-15T10:30:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 5,
"items": [
{
"id": 101,
"title": "Shine On You Crazy Diamond (Parts I-V)",
"track_number": 1,
"media_number": 1,
"duration": 810,
"performer": {"id": 36819, "name": "Pink Floyd"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"streamable": True,
},
{
"id": 102,
"title": "Welcome to the Machine",
"track_number": 2,
"media_number": 1,
"duration": 447,
"performer": {"id": 36819, "name": "Pink Floyd"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"streamable": True,
},
{
"id": 103,
"title": "Have a Cigar",
"track_number": 3,
"media_number": 1,
"duration": 308,
"performer": {"id": 36819, "name": "Pink Floyd"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"streamable": True,
},
{
"id": 104,
"title": "Wish You Were Here",
"track_number": 4,
"media_number": 1,
"duration": 334,
"performer": {"id": 36819, "name": "Pink Floyd"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"streamable": True,
},
{
"id": 105,
"title": "Shine On You Crazy Diamond (Parts VI-IX)",
"track_number": 5,
"media_number": 1,
"duration": 751,
"performer": {"id": 36819, "name": "Pink Floyd"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"streamable": True,
},
],
},
},
{
"id": "album-002",
"title": "Kind of Blue",
"artist": {"id": 26577, "name": "Miles Davis"},
"image": {
"small": "https://via.placeholder.com/150?text=KoB",
"large": "https://via.placeholder.com/600?text=KoB",
"thumbnail": "https://via.placeholder.com/50?text=KoB",
},
"release_date_original": "1959-08-17",
"label": {"id": 2, "name": "Columbia"},
"genre": {"id": 20, "name": "Jazz"},
"tracks_count": 5,
"duration": 2760,
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"downloadable": True,
"downloaded": True,
"purchased_at": "2026-01-20T14:00:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 5,
"items": [
{
"id": 201,
"title": "So What",
"track_number": 1,
"media_number": 1,
"duration": 562,
"performer": {"id": 26577, "name": "Miles Davis"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 202,
"title": "Freddie Freeloader",
"track_number": 2,
"media_number": 1,
"duration": 586,
"performer": {"id": 26577, "name": "Miles Davis"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 203,
"title": "Blue in Green",
"track_number": 3,
"media_number": 1,
"duration": 327,
"performer": {"id": 26577, "name": "Miles Davis"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 204,
"title": "All Blues",
"track_number": 4,
"media_number": 1,
"duration": 695,
"performer": {"id": 26577, "name": "Miles Davis"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 205,
"title": "Flamenco Sketches",
"track_number": 5,
"media_number": 1,
"duration": 566,
"performer": {"id": 26577, "name": "Miles Davis"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
],
},
},
{
"id": "album-003",
"title": "In the Court of the Crimson King",
"artist": {"id": 18290, "name": "King Crimson"},
"image": {
"small": "https://via.placeholder.com/150?text=ITCOTCK",
"large": "https://via.placeholder.com/600?text=ITCOTCK",
"thumbnail": "https://via.placeholder.com/50?text=ITCOTCK",
},
"release_date_original": "1969-10-10",
"label": {"id": 3, "name": "Island"},
"genre": {"id": 11, "name": "Progressive Rock"},
"tracks_count": 5,
"duration": 2630,
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"downloadable": True,
"purchased_at": "2026-02-01T08:15:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 5,
"items": [
{
"id": 301,
"title": "21st Century Schizoid Man",
"track_number": 1,
"media_number": 1,
"duration": 442,
"performer": {"id": 18290, "name": "King Crimson"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 302,
"title": "I Talk to the Wind",
"track_number": 2,
"media_number": 1,
"duration": 363,
"performer": {"id": 18290, "name": "King Crimson"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 303,
"title": "Epitaph",
"track_number": 3,
"media_number": 1,
"duration": 527,
"performer": {"id": 18290, "name": "King Crimson"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 304,
"title": "Moonchild",
"track_number": 4,
"media_number": 1,
"duration": 732,
"performer": {"id": 18290, "name": "King Crimson"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
{
"id": 305,
"title": "The Court of the Crimson King",
"track_number": 5,
"media_number": 1,
"duration": 566,
"performer": {"id": 18290, "name": "King Crimson"},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
},
],
},
},
{
"id": "album-004",
"title": "OK Computer",
"artist": {"id": 12345, "name": "Radiohead"},
"image": {
"small": "https://via.placeholder.com/150?text=OKC",
"large": "https://via.placeholder.com/600?text=OKC",
"thumbnail": "https://via.placeholder.com/50?text=OKC",
},
"release_date_original": "1997-06-16",
"label": {"id": 4, "name": "Parlophone"},
"genre": {"id": 12, "name": "Alternative Rock"},
"tracks_count": 12,
"duration": 3218,
"hires": False,
"maximum_bit_depth": 16,
"maximum_sampling_rate": 44.1,
"downloadable": True,
"purchased_at": "2025-12-25T09:00:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 12,
"items": [
{"id": 401, "title": "Airbag", "track_number": 1, "media_number": 1, "duration": 278, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 402, "title": "Paranoid Android", "track_number": 2, "media_number": 1, "duration": 384, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 403, "title": "Subterranean Homesick Alien", "track_number": 3, "media_number": 1, "duration": 264, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 404, "title": "Exit Music (For a Film)", "track_number": 4, "media_number": 1, "duration": 261, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 405, "title": "Let Down", "track_number": 5, "media_number": 1, "duration": 294, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 406, "title": "Karma Police", "track_number": 6, "media_number": 1, "duration": 264, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 407, "title": "Fitter Happier", "track_number": 7, "media_number": 1, "duration": 117, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 408, "title": "Electioneering", "track_number": 8, "media_number": 1, "duration": 234, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 409, "title": "Climbing Up the Walls", "track_number": 9, "media_number": 1, "duration": 282, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 410, "title": "No Surprises", "track_number": 10, "media_number": 1, "duration": 229, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 411, "title": "Lucky", "track_number": 11, "media_number": 1, "duration": 261, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
{"id": 412, "title": "The Tourist", "track_number": 12, "media_number": 1, "duration": 324, "performer": {"id": 12345, "name": "Radiohead"}, "hires": False, "maximum_bit_depth": 16, "maximum_sampling_rate": 44.1, "streamable": True},
],
},
},
{
"id": "album-005",
"title": "A Love Supreme",
"artist": {"id": 44321, "name": "John Coltrane"},
"image": {
"small": "https://via.placeholder.com/150?text=ALS",
"large": "https://via.placeholder.com/600?text=ALS",
"thumbnail": "https://via.placeholder.com/50?text=ALS",
},
"release_date_original": "1965-02-01",
"label": {"id": 5, "name": "Impulse!"},
"genre": {"id": 20, "name": "Jazz"},
"tracks_count": 4,
"duration": 1980,
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"downloadable": True,
"purchased_at": "2026-02-10T16:45:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 4,
"items": [
{"id": 501, "title": "Acknowledgement", "track_number": 1, "media_number": 1, "duration": 480, "performer": {"id": 44321, "name": "John Coltrane"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 502, "title": "Resolution", "track_number": 2, "media_number": 1, "duration": 442, "performer": {"id": 44321, "name": "John Coltrane"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 503, "title": "Pursuance", "track_number": 3, "media_number": 1, "duration": 617, "performer": {"id": 44321, "name": "John Coltrane"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 504, "title": "Psalm", "track_number": 4, "media_number": 1, "duration": 441, "performer": {"id": 44321, "name": "John Coltrane"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
],
},
},
{
"id": "album-006",
"title": "Buena Vista Social Club",
"artist": {"id": 55432, "name": "Buena Vista Social Club"},
"image": {
"small": "https://via.placeholder.com/150?text=BVSC",
"large": "https://via.placeholder.com/600?text=BVSC",
"thumbnail": "https://via.placeholder.com/50?text=BVSC",
},
"release_date_original": "1997-09-16",
"label": {"id": 6, "name": "World Circuit"},
"genre": {"id": 30, "name": "Latin"},
"tracks_count": 14,
"duration": 3600,
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"downloadable": True,
"purchased_at": "2026-02-14T12:00:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 14,
"items": [
{"id": 601, "title": "Chan Chan", "track_number": 1, "media_number": 1, "duration": 274, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 602, "title": "De Camino a la Vereda", "track_number": 2, "media_number": 1, "duration": 227, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 603, "title": "El Cuarto de Tula", "track_number": 3, "media_number": 1, "duration": 444, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 604, "title": "Pueblo Nuevo", "track_number": 4, "media_number": 1, "duration": 207, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 605, "title": "Dos Gardenias", "track_number": 5, "media_number": 1, "duration": 205, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 606, "title": "Y Tu Que Has Hecho?", "track_number": 6, "media_number": 1, "duration": 195, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 607, "title": "Veinte Anos", "track_number": 7, "media_number": 1, "duration": 194, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 608, "title": "El Carretero", "track_number": 8, "media_number": 1, "duration": 207, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 609, "title": "Candela", "track_number": 9, "media_number": 1, "duration": 306, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 610, "title": "Amor de Loca Juventud", "track_number": 10, "media_number": 1, "duration": 178, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 611, "title": "Orgullecida", "track_number": 11, "media_number": 1, "duration": 179, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 612, "title": "Murmullo", "track_number": 12, "media_number": 1, "duration": 144, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 613, "title": "Buena Vista Social Club", "track_number": 13, "media_number": 1, "duration": 297, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 614, "title": "La Bayamesa", "track_number": 14, "media_number": 1, "duration": 343, "performer": {"id": 55432, "name": "Buena Vista Social Club"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
],
},
},
{
"id": "album-007",
"title": "The Wall",
"artist": {"id": 36819, "name": "Pink Floyd"},
"image": {
"small": "https://via.placeholder.com/150?text=Wall",
"large": "https://via.placeholder.com/600?text=Wall",
"thumbnail": "https://via.placeholder.com/50?text=Wall",
},
"release_date_original": "1979-11-30",
"label": {"id": 1, "name": "Harvest"},
"genre": {"id": 10, "name": "Rock"},
"tracks_count": 26,
"duration": 4860,
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"downloadable": False, # Unavailable — for gray-out test
"purchased_at": "2025-11-01T18:00:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 26,
"items": [
{"id": 701, "title": "In the Flesh?", "track_number": 1, "media_number": 1, "duration": 199, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 702, "title": "The Thin Ice", "track_number": 2, "media_number": 1, "duration": 146, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 703, "title": "Another Brick in the Wall, Pt. 1", "track_number": 3, "media_number": 1, "duration": 200, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 704, "title": "The Happiest Days of Our Lives", "track_number": 4, "media_number": 1, "duration": 106, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 705, "title": "Another Brick in the Wall, Pt. 2", "track_number": 5, "media_number": 1, "duration": 238, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 706, "title": "Mother", "track_number": 6, "media_number": 1, "duration": 323, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 707, "title": "Goodbye Blue Sky", "track_number": 7, "media_number": 1, "duration": 170, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 708, "title": "Empty Spaces", "track_number": 8, "media_number": 1, "duration": 129, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 709, "title": "Young Lust", "track_number": 9, "media_number": 1, "duration": 198, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 710, "title": "One of My Turns", "track_number": 10, "media_number": 1, "duration": 213, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 711, "title": "Don't Leave Me Now", "track_number": 11, "media_number": 1, "duration": 254, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 712, "title": "Another Brick in the Wall, Pt. 3", "track_number": 12, "media_number": 1, "duration": 74, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 713, "title": "Goodbye Cruel World", "track_number": 13, "media_number": 1, "duration": 67, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
# Disc 2
{"id": 714, "title": "Hey You", "track_number": 1, "media_number": 2, "duration": 282, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 715, "title": "Is There Anybody Out There?", "track_number": 2, "media_number": 2, "duration": 161, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 716, "title": "Nobody Home", "track_number": 3, "media_number": 2, "duration": 202, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 717, "title": "Vera", "track_number": 4, "media_number": 2, "duration": 95, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 718, "title": "Bring the Boys Back Home", "track_number": 5, "media_number": 2, "duration": 86, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 719, "title": "Comfortably Numb", "track_number": 6, "media_number": 2, "duration": 382, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 720, "title": "The Show Must Go On", "track_number": 7, "media_number": 2, "duration": 97, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 721, "title": "In the Flesh", "track_number": 8, "media_number": 2, "duration": 256, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 722, "title": "Run Like Hell", "track_number": 9, "media_number": 2, "duration": 252, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 723, "title": "Waiting for the Worms", "track_number": 10, "media_number": 2, "duration": 240, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 724, "title": "Stop", "track_number": 11, "media_number": 2, "duration": 30, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 725, "title": "The Trial", "track_number": 12, "media_number": 2, "duration": 311, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
{"id": 726, "title": "Outside the Wall", "track_number": 13, "media_number": 2, "duration": 105, "performer": {"id": 36819, "name": "Pink Floyd"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 192.0, "streamable": True},
],
},
},
{
"id": "album-008",
"title": "Mezzanine",
"artist": {"id": 66789, "name": "Massive Attack"},
"image": {
"small": "https://via.placeholder.com/150?text=Mezz",
"large": "https://via.placeholder.com/600?text=Mezz",
"thumbnail": "https://via.placeholder.com/50?text=Mezz",
},
"release_date_original": "1998-04-20",
"label": {"id": 7, "name": "Virgin"},
"genre": {"id": 13, "name": "Electronic"},
"tracks_count": 11,
"duration": 3780,
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"downloadable": True,
"purchased_at": "2026-02-16T20:00:00Z",
"tracks": {
"offset": 0,
"limit": 50,
"total": 11,
"items": [
{"id": 801, "title": "Angel", "track_number": 1, "media_number": 1, "duration": 379, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 802, "title": "Risingson", "track_number": 2, "media_number": 1, "duration": 298, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 803, "title": "Teardrop", "track_number": 3, "media_number": 1, "duration": 328, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 804, "title": "Inertia Creeps", "track_number": 4, "media_number": 1, "duration": 368, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 805, "title": "Exchange", "track_number": 5, "media_number": 1, "duration": 246, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 806, "title": "Dissolved Girl", "track_number": 6, "media_number": 1, "duration": 340, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 807, "title": "Man Next Door", "track_number": 7, "media_number": 1, "duration": 363, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 808, "title": "Black Milk", "track_number": 8, "media_number": 1, "duration": 376, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 809, "title": "Mezzanine", "track_number": 9, "media_number": 1, "duration": 359, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 810, "title": "Group Four", "track_number": 10, "media_number": 1, "duration": 489, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
{"id": 811, "title": "(Exchange)", "track_number": 11, "media_number": 1, "duration": 234, "performer": {"id": 66789, "name": "Massive Attack"}, "hires": True, "maximum_bit_depth": 24, "maximum_sampling_rate": 96.0, "streamable": True},
],
},
},
]
# Individual tracks purchased outside of albums
MOCK_INDIVIDUAL_TRACKS = [
{
"id": 9001,
"title": "Comfortably Numb",
"track_number": 6,
"media_number": 2,
"duration": 382,
"performer": {"id": 36819, "name": "Pink Floyd"},
"album": {
"id": "album-007",
"title": "The Wall",
"image": {
"small": "https://via.placeholder.com/150?text=Wall",
"large": "https://via.placeholder.com/600?text=Wall",
"thumbnail": "https://via.placeholder.com/50?text=Wall",
},
},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"streamable": True,
"purchased_at": "2026-02-15T11:00:00Z",
},
{
"id": 9002,
"title": "Money",
"track_number": 6,
"media_number": 1,
"duration": 382,
"performer": {"id": 36819, "name": "Pink Floyd"},
"album": {
"id": "album-dsotm",
"title": "The Dark Side of the Moon",
"image": {
"small": "https://via.placeholder.com/150?text=DSotM",
"large": "https://via.placeholder.com/600?text=DSotM",
"thumbnail": "https://via.placeholder.com/50?text=DSotM",
},
},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 192.0,
"streamable": True,
"downloaded": True,
"purchased_at": "2026-02-12T09:30:00Z",
},
{
"id": 9003,
"title": "Starless",
"track_number": 8,
"media_number": 1,
"duration": 726,
"performer": {"id": 18290, "name": "King Crimson"},
"album": {
"id": "album-rtta",
"title": "Red",
"image": {
"small": "https://via.placeholder.com/150?text=Red",
"large": "https://via.placeholder.com/600?text=Red",
"thumbnail": "https://via.placeholder.com/50?text=Red",
},
},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
"purchased_at": "2026-02-08T14:20:00Z",
},
{
"id": 9004,
"title": "Teardrop",
"track_number": 3,
"media_number": 1,
"duration": 328,
"performer": {"id": 66789, "name": "Massive Attack"},
"album": {
"id": "album-008",
"title": "Mezzanine",
"image": {
"small": "https://via.placeholder.com/150?text=Mezz",
"large": "https://via.placeholder.com/600?text=Mezz",
"thumbnail": "https://via.placeholder.com/50?text=Mezz",
},
},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
"downloaded": True,
"purchased_at": "2026-01-28T17:45:00Z",
},
{
"id": 9005,
"title": "Chan Chan",
"track_number": 1,
"media_number": 1,
"duration": 274,
"performer": {"id": 55432, "name": "Buena Vista Social Club"},
"album": {
"id": "album-006",
"title": "Buena Vista Social Club",
"image": {
"small": "https://via.placeholder.com/150?text=BVSC",
"large": "https://via.placeholder.com/600?text=BVSC",
"thumbnail": "https://via.placeholder.com/50?text=BVSC",
},
},
"hires": True,
"maximum_bit_depth": 24,
"maximum_sampling_rate": 96.0,
"streamable": True,
"purchased_at": "2026-01-05T08:00:00Z",
},
]
MOCK_FORMATS = [
{"id": 27, "label": "FLAC Hi-Res 24-bit / 192 kHz", "bit_depth": 24, "sampling_rate": 192.0},
{"id": 7, "label": "FLAC Hi-Res 24-bit / 96 kHz", "bit_depth": 24, "sampling_rate": 96.0},
{"id": 6, "label": "FLAC CD 16-bit / 44.1 kHz", "bit_depth": 16, "sampling_rate": 44.1},
{"id": 5, "label": "MP3 320 kbps", "bit_depth": None, "sampling_rate": None},
]
-131
View File
@@ -1,131 +0,0 @@
"""Mock Purchases API — Qobuz-shaped responses for UI prototyping."""
import asyncio
import json
import time
from fastapi import FastAPI, Query
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from data import MOCK_ALBUMS, MOCK_INDIVIDUAL_TRACKS, MOCK_FORMATS
app = FastAPI(title="QBZ Mock Purchases API")
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:1420", "http://localhost:1421"],
allow_methods=["*"],
allow_headers=["*"],
)
ALBUMS_BY_ID = {a["id"]: a for a in MOCK_ALBUMS}
def paginate(items: list, limit: int, offset: int) -> dict:
return {
"offset": offset,
"limit": limit,
"total": len(items),
"items": items[offset : offset + limit],
}
@app.get("/purchases")
def get_purchases(limit: int = Query(50, ge=1, le=500), offset: int = Query(0, ge=0)):
return {
"albums": paginate(MOCK_ALBUMS, limit, offset),
"tracks": paginate(MOCK_INDIVIDUAL_TRACKS, limit, offset),
}
@app.get("/purchases/search")
def search_purchases(q: str = Query("", min_length=0)):
query = q.lower()
if not query:
return {
"albums": paginate(MOCK_ALBUMS, 50, 0),
"tracks": paginate(MOCK_INDIVIDUAL_TRACKS, 50, 0),
}
matched_albums = [
a
for a in MOCK_ALBUMS
if query in a["title"].lower() or query in a["artist"]["name"].lower()
]
matched_tracks = [
t
for t in MOCK_INDIVIDUAL_TRACKS
if query in t["title"].lower() or query in t["performer"]["name"].lower()
]
return {
"albums": paginate(matched_albums, 50, 0),
"tracks": paginate(matched_tracks, 50, 0),
}
@app.get("/purchases/album/{album_id}")
def get_album_detail(album_id: str):
album = ALBUMS_BY_ID.get(album_id)
if not album:
return {"error": "Album not found"}, 404
return album
@app.get("/purchases/formats/{album_id}")
def get_formats(album_id: str):
album = ALBUMS_BY_ID.get(album_id)
if not album:
return MOCK_FORMATS
max_depth = album.get("maximum_bit_depth", 16)
max_rate = album.get("maximum_sampling_rate", 44.1)
return [
f
for f in MOCK_FORMATS
if (f["bit_depth"] is None)
or (f["bit_depth"] <= max_depth and f["sampling_rate"] <= max_rate)
]
async def _download_progress_generator(total_tracks: int, entity_id: str, is_album: bool):
"""SSE stream simulating download progress."""
for idx in range(total_tracks):
total_bytes = 50_000_000 + idx * 10_000_000
# Simulate progress in 4 steps per track
for step in range(4):
progress = {
"albumId" if is_album else "trackId": entity_id,
"trackIndex": idx,
"totalTracks": total_tracks,
"bytesDownloaded": int(total_bytes * (step + 1) / 4),
"totalBytes": total_bytes,
"status": "downloading" if step < 3 else "complete",
}
yield f"data: {json.dumps(progress)}\n\n"
await asyncio.sleep(0.3)
# Final event
yield f"data: {json.dumps({'status': 'complete', 'totalTracks': total_tracks})}\n\n"
@app.post("/purchases/download/album/{album_id}")
async def download_album(album_id: str):
album = ALBUMS_BY_ID.get(album_id)
if not album:
return {"error": "Album not found"}, 404
if not album.get("downloadable", True):
return {"error": "Album not available for download"}, 403
total = album.get("tracks_count", 1)
return StreamingResponse(
_download_progress_generator(total, album_id, is_album=True),
media_type="text/event-stream",
)
@app.post("/purchases/download/track/{track_id}")
async def download_track(track_id: int):
return StreamingResponse(
_download_progress_generator(1, str(track_id), is_album=False),
media_type="text/event-stream",
)
@@ -1,3 +0,0 @@
fastapi>=0.110.0
uvicorn>=0.29.0
sse-starlette>=2.0.0