Compare commits
36
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d46c50a2db | ||
|
|
964006ec6d | ||
|
|
0c82da7a1d | ||
|
|
93a4f808bf | ||
|
|
7a58f37d9f | ||
|
|
b727284ef3 | ||
|
|
396848e898 | ||
|
|
55926b8dc4 | ||
|
|
ee6a1b88c5 | ||
|
|
1a7519becd | ||
|
|
a534b1b70b | ||
|
|
8fdd21f8a2 | ||
|
|
c561330bd0 | ||
|
|
64c62eb394 | ||
|
|
0d3cd69a0f | ||
|
|
81975b72e4 | ||
|
|
1b21471845 | ||
|
|
15f207ffc6 | ||
|
|
93aa06703b | ||
|
|
8fdd25f569 | ||
|
|
00b5c208ec | ||
|
|
c81bfcf51d | ||
|
|
942a74c86c | ||
|
|
1f95f0231d | ||
|
|
ae0e9d0a08 | ||
|
|
6a91bc73eb | ||
|
|
e15c988bf4 | ||
|
|
f36a30411d | ||
|
|
5d5e4fac50 | ||
|
|
e9027472f4 | ||
|
|
e0eb343ce0 | ||
|
|
8d223177cd | ||
|
|
f9ab79f0c2 | ||
|
|
b68393ab01 | ||
|
|
12ace6f45a | ||
|
|
9a42b463a3 |
@@ -5,17 +5,28 @@
|
||||
- LLM analysis runs via Python scripts calling the Anthropic
|
||||
Messages API: model `claude-sonnet-4-6`, `temperature=0`,
|
||||
thinking disabled, Batch API where possible.
|
||||
- Prompt definition files live in `prompts/<task>_v<N>.md` and
|
||||
are passed verbatim as the system prompt.
|
||||
- Every LLM step runs the same definition file twice, then a
|
||||
separate arbitration step reconciles the two outputs
|
||||
("2 runs + 1 arbitration"). If arbitration output is
|
||||
unexpected, revise the definition file and repeat the whole
|
||||
- Prompt definition files live in
|
||||
`prompts/<track>-<step>-<task>.md` (e.g. 01-01-tag.md; no
|
||||
version suffix -- versions live in git history) and are
|
||||
passed verbatim as the system prompt.
|
||||
- Per-song LLM judgments (coding, screening) run the same
|
||||
definition file twice, then a separate arbitration step
|
||||
settles only the script-computed disagreements
|
||||
("2 runs + 1 arbitration"). Free-generation steps run
|
||||
twice and both outputs are pooled, unarbitrated.
|
||||
Vocabulary-building steps (convergence) run once as a
|
||||
recorded pass. If an arbitration or validation outcome is
|
||||
unexpected, revise the definition file and repeat that
|
||||
cycle; never patch results by hand.
|
||||
- Every execution is archived self-contained under
|
||||
`runs/<phase>/<date>-<prompt-version>/`: prompt snapshot,
|
||||
raw outputs of both runs, arbitration output, and `meta.json`
|
||||
(model ID, parameters, timestamps, batch IDs).
|
||||
- Each run of a step is archived self-contained under the
|
||||
destination directory given explicitly on the `run-llm`
|
||||
command line (by convention `runs/<definition-file>/run<N>/`):
|
||||
prompt snapshot, raw output, and `meta.json` (model ID,
|
||||
parameters, timestamps, batch ID). The two runs of a step
|
||||
are two separate invocations of `run-llm`. An arbitration
|
||||
pass is a step of its own with its own archive. Replacing
|
||||
an existing run archive requires an explicit flag;
|
||||
superseded runs live in git history.
|
||||
- Scripts read the API key from the `ANTHROPIC_API_KEY`
|
||||
environment variable (`.env`, gitignored).
|
||||
|
||||
@@ -36,4 +47,4 @@
|
||||
cites); `runs/` holds raw audit records. The paper cites
|
||||
`results/` only.
|
||||
- Any change to a definition file, the codebook, or the plan is
|
||||
recorded in `docs/decision_log.md` with date and reason.
|
||||
recorded in `docs/decision-log.md` with date and reason.
|
||||
|
||||
@@ -7,10 +7,10 @@ Hot 100(2016–2025)為例的內容分析。
|
||||
|
||||
## 目錄結構
|
||||
|
||||
見 `docs/project_structure.md`。研究步驟規劃見
|
||||
`docs/research_plan.md`;方法細節見 `docs/methodology.md`;
|
||||
見 `docs/project-structure.md`。研究步驟規劃見
|
||||
`docs/research-plan.md`;方法細節見 `docs/methodology.md`;
|
||||
人工編碼手冊見 `docs/codebook.md`;決策日誌見
|
||||
`docs/decision_log.md`。
|
||||
`docs/decision-log.md`。
|
||||
|
||||
## 重現方式
|
||||
|
||||
@@ -18,7 +18,7 @@ Hot 100(2016–2025)為例的內容分析。
|
||||
`pip install -e tools/`。
|
||||
2. 自 `tools/.env.example` 建立 `tools/.env`,寫入
|
||||
Anthropic API 金鑰。
|
||||
3. 依 `docs/research_plan.md` 的階段順序,於 `tools/` 目錄下
|
||||
3. 依 `docs/research-plan.md` 的階段順序,於 `tools/` 目錄下
|
||||
執行子命令,必要輸入以位置引數、選擇性輸入以選項給定(如
|
||||
`pop-fem-audit-tools build-db
|
||||
../data/source/yearend_hot100_2016_2025.csv
|
||||
@@ -26,8 +26,9 @@ Hot 100(2016–2025)為例的內容分析。
|
||||
--lyrics-dir ../data/captures/lyrics
|
||||
--wikidata-csv ../data/captures/artists-wikidata.csv`)。
|
||||
LLM 步驟使用 `claude-sonnet-4-6`、temperature=0、
|
||||
thinking 關閉;每步驟獨立執行兩次後由仲裁步驟合併
|
||||
(「2+1」協定)。
|
||||
thinking 關閉;輸出可逐項比對的步驟獨立執行兩次,由
|
||||
比對程式算出分歧、仲裁步驟裁決(「2+1」協定),自由
|
||||
生成步驟兩次執行進池不仲裁。
|
||||
4. 每次執行的完整紀錄(定義檔快照、原始輸出、參數)存於
|
||||
`runs/`,可逐筆稽核。論文引用的最終資料表在 `results/`。
|
||||
|
||||
|
||||
+470
-470
@@ -1,470 +1,470 @@
|
||||
name,qid,gender,type,genre,country,note
|
||||
070 Shake,Q54861040,female,solo,hip-hop; cloud rap; alternative hip-hop,United States,American rapper and singer
|
||||
2 Chainz,Q129668,male,solo,Southern hip-hop; trap music; gangsta rap; dirty south; Atlanta hip-hop; hardcore hip-hop,United States,American rapper
|
||||
21 Savage,Q25095399,male,solo,hip-hop; trap music,United Kingdom,British-born rapper (born 1992)
|
||||
24kGoldn,Q83751918,male,solo,pop rap,United States,American rapper
|
||||
42 Dugg,Q95694810,male,solo,Michigan rap; Midwest hip-hop; trap music; gangsta rap,United States,American rapper
|
||||
4batz,Q124313062,male,solo,contemporary R&B,United States,American singer (born 2003)
|
||||
5 Seconds of Summer,Q4641147,,group,pop rock; pop-punk,Australia,Australian pop rock band
|
||||
50 Cent,Q6060,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop,United States,American rapper (born 1975)
|
||||
6ix9ine,Q44479972,male,solo,hip-hop; East Coast hip-hop; gangsta rap; trap metal; hardcore hip-hop; SoundCloud rap; punk rap; drill; trap music; urbano music; reggaeton; Brooklyn drill,United States,American rapper from New York (born 1996)
|
||||
6LACK,Q27886640,male,solo,alternative R&B; contemporary R&B; trap music; cloud rap; industrial music; soul; hip-hop soul,United States,American singer-songwriter and rapper (born 1992)
|
||||
A Boogie wit da Hoodie,Q27927826,male,solo,hip-hop; trap music,United States,American rapper (born 1995)
|
||||
A$AP Ferg,Q15648254,male,solo,East Coast hip-hop; trap music,United States,American rapper (born 1988)
|
||||
A$AP Rocky,Q129910,male,solo,East Coast hip-hop; psychedelic rap; experimental hip-hop; alternative hip-hop; cloud rap; trap music,United States,American rapper (born 1988)
|
||||
Adassa,Q576181,female,solo,reggaeton; urban contemporary; pop music,United States,American singer-songwriter
|
||||
Adele,Q23215,female,solo,pop music; blue-eyed soul; rhythm and blues; soul; jazz; rock music,United Kingdom,English singer-songwriter (born 1988)
|
||||
AJR,Q16154058,,group,indie pop; alternative pop; electropop,United States,American indie pop band
|
||||
Alessia Cara,Q20090091,female,solo,contemporary R&B; indie pop; pop music; soul; alternative R&B,Italy,"Italian-Canadian singer, songwriter and actress"
|
||||
Alex Warren,Q121842162,male,solo,pop music,United States,"American singer, songwriter, YouTuber, and influencer"
|
||||
Aminé,Q27830860,male,solo,West Coast hip-hop; alternative hip-hop; trap music; contemporary R&B,United States,"American rapper, singer, and songwriter"
|
||||
Anderson .Paak,Q20810369,male,solo,contemporary R&B; hip-hop; soul; funk; pop music,United States,"American singer, rapper, drummer, and record producer (born 1986)"
|
||||
Andrew Choi,Q15229870,male,solo,K-pop; pop music; contemporary R&B,South Korea,South Korean singer and songwriter
|
||||
Anne-Marie,Q25396976,female,solo,pop music; contemporary R&B,United Kingdom,British singer (born 1990)
|
||||
Aqua,Q213388,,group,pop music; bubblegum music; Eurodance,Denmark,Danish-Norwegian music group
|
||||
Ariana Grande,Q151892,female,solo,pop music; contemporary R&B; electronic dance music,United States,"American singer, songwriter, and actress (born 1993)"
|
||||
Arizona Zervas,Q75124792,male,solo,hip-hop; contemporary R&B; pop music,United States,American singer and rapper (born 1995)
|
||||
Artemas,Q125176874,male,solo,alternative pop,United Kingdom,British singer-songwriter and record producer
|
||||
ATR Son Son,Q140814072,male,solo,hip-hop,United States,American rapper
|
||||
Audrey Nuna,Q105538243,female,solo,K-pop; pop music; hip-hop; contemporary R&B; trap music,United States,South Korean-American singer and rapper
|
||||
Ava Max,Q56755505,female,solo,dance-pop,United States,American singer and songwriter (born 1994)
|
||||
Avery Anna,Q131401753,female,solo,pop rock; country music,United States,American singer
|
||||
Ayo,Q55860029,male,solo,hip-hop,United States,American singer and dancer
|
||||
AzChike,Q131417489,male,solo,hip-hop,United States,American rapper
|
||||
Bad Bunny,Q44333953,male,solo,Latin trap; reggaeton,Puerto Rico,"Puerto Rican rapper, singer, and record producer (born 1994)"
|
||||
Bailey Zimmerman,Q112581616,male,solo,country music,United States,American singer
|
||||
Bastille,Q689,,group,synth-pop,United Kingdom,English indie pop band
|
||||
Bazzi,Q48720231,male,solo,pop music,United States,American-born Lebanese singer-songwriter (born 1997)
|
||||
beabadoobee,Q66817366,female,solo,indie rock; space rock; alternative rock; slacker rock; indie pop; folk-pop; bedroom pop,Philippines,Filipino singer
|
||||
Bebe Rexha,Q16185856,female,solo,pop music; contemporary R&B,United States,American singer
|
||||
Becky G,Q1393997,female,solo,pop music; hip-hop; Latin music; Latin pop; reggaeton,United States,American singer and actress (born 1997)
|
||||
BENEE,Q61749159,female,solo,alternative pop; soul,New Zealand,New Zealand singer-songwriter
|
||||
benny blanco,Q818048,male,solo,pop music,United States,American pop music producer (born 1988)
|
||||
Benson Boone,Q110008128,male,solo,pop music; pop rock,United States,American singer
|
||||
Beyoncé,Q36153,female,solo,pop music; contemporary R&B; country music,United States,"American singer, songwriter, record producer, and dancer (born 1981)"
|
||||
Big Sean,Q367634,male,solo,hip-hop; Midwest hip-hop; Michigan rap; pop rap,United States,American rapper (born 1988)
|
||||
BigXthaPlug,Q124750337,male,solo,rapping; hip-hop,United States,American rapper
|
||||
Billie Eilish,Q29564107,female,solo,electropop; indie pop; alternative pop,United States,American singer-songwriter (born 2001)
|
||||
Billy Ray Cyrus,Q231259,male,solo,country music; country pop; country rock; country blues,United States,American country singer and actor
|
||||
Bipolar Sunshine,Q16727521,male,solo,pop music,United Kingdom,British musician
|
||||
Bizarrap,Q99937928,male,solo,Latin trap; reggaeton,Argentina,Argentine DJ and producer (born 1998)
|
||||
Black Eyed Peas,Q134541,,group,alternative hip-hop; pop rap; hip-hop; pop music; Latin hip-hop,United States,American hip hop group from California
|
||||
blackbear,Q22974007,male,solo,pop music; emo; contemporary R&B; hip-hop,United States,"American singer, songwriter, and record producer (born 1990)"
|
||||
Blake Shelton,Q94831,male,solo,country music,United States,American country music singer and television personality
|
||||
Blanco Brown,Q64736729,male,solo,country rap; trap music; hip-hop,United States,American rapper and singer
|
||||
BlocBoy JB,Q49481016,male,solo,hip-hop; trap music,United States,American rapper from Tennessee
|
||||
Blueface,Q60463134,male,solo,hip-hop; trap music; West Coast hip-hop; gangsta rap,United States,American rapper (born 1997)
|
||||
Bobby Helms,Q888554,male,solo,country music,United States,American male singer (1933–1997)
|
||||
Bomba Estéreo,Q887911,,group,cumbia,Colombia,Colombian band
|
||||
Bradley Cooper,Q205707,male,solo,,United States,American actor (born 1975)
|
||||
Brandon Lake,Q100314823,male,solo,contemporary Christian music; Christian rock,United States,American Christian musician
|
||||
Brenda Lee,Q230925,female,solo,rock and roll; country music; pop music; rockabilly,United States,American singer and recording artist (born 1944)
|
||||
Brendon Urie,Q1047474,male,solo,pop rock; alternative rock,United States,American singer and musician
|
||||
Brett Young,Q25189679,male,solo,country music,United States,American country musician
|
||||
BRS Kash,Q105409004,male,solo,hip-hop,United States,American rapper
|
||||
Bruno Mars,Q1450,male,solo,pop music; contemporary R&B; hip-hop; new wave; reggae; funk,United States,American singer-songwriter and record producer (born 1985)
|
||||
Bryson Tiller,Q21066641,male,solo,contemporary R&B; hip-hop; trap music; soul,United States,American singer and rapper (born 1993)
|
||||
BTS,Q13580495,,group,K-pop; dance-pop; Korean hip-hop,South Korea,South Korean musical group; boy band
|
||||
Burl Ives,Q315723,male,solo,folk music,United States,American musician (1909–1995)
|
||||
Calboy,Q66085272,male,solo,hip-hop,United States,American rapper (born 1999)
|
||||
Calvin Harris,Q81637,male,solo,electronic dance music; electronic pop; acid house,United Kingdom,Scottish electronic music producer and DJ (born 1984)
|
||||
Camila Cabello,Q18810940,female,solo,pop music; contemporary R&B; Latin pop; Gothic pop,Cuba,Cuban-Mexican-American singer
|
||||
Cardi B,Q29033668,female,solo,hip-hop; pop music; pop rap,United States,American rapper (born 1992)
|
||||
Carly Pearce,Q29913337,female,solo,country music,United States,American country music singer-songwriter
|
||||
Carolina Gaitán,Q5753201,female,solo,,Colombia,Colombian actress and singer
|
||||
Carrie Underwood,Q215546,female,solo,pop music; country music; country pop; country rock,United States,American singer and actor (born 1983)
|
||||
Cash Cobain,Q125989634,male,solo,hip-hop; drill; Jersey drill; pop rap; East Coast hip-hop; trap music,United States,American rapper and record producer
|
||||
Casper Mágico,Q60333702,male,solo,Latin trap; reggaeton,United States,Puerto Rican rapper
|
||||
Chance the Rapper,Q12470060,male,solo,hip-hop; alternative hip-hop; contemporary R&B; conscious hip-hop; alternative R&B; gospel music,United States,"American rapper, singer and record producer (born 1993)"
|
||||
Chappell Roan,Q110281146,female,solo,synth-pop; pop music; electronic music,United States,American singer (born 1998)
|
||||
Charlie Puth,Q19810390,male,solo,pop music; contemporary R&B,United States,"American singer, songwriter, and record producer"
|
||||
Chase Rice,Q5087189,male,solo,country music,United States,American singer-songwriter and football player
|
||||
Cheat Codes,Q23978754,,group,electronic music; electronic dance music; tropical house; dancehall,United States,electronic music DJ trio
|
||||
Chencho Corleone,Q113625582,male,solo,reggaeton,United States,Puerto Rican singer (born 1979)
|
||||
Childish Gambino,Q1239933,male,solo,hip-hop; funk; contemporary R&B; soul; psychedelic music; indie pop; comedy hip-hop,United States,"American actor, comedian, musician, and filmmaker (born 1983)"
|
||||
Chris Brown,Q155700,male,solo,contemporary R&B; pop music; hip-hop,United States,American singer and rapper (born 1989)
|
||||
Chris Stapleton,Q5108148,male,solo,country music,United States,American country musician
|
||||
Chris Young,Q952176,male,solo,country music,United States,American country music artist
|
||||
City Girls,Q60658858,,group,hip-hop,United States,American musical duo
|
||||
CJ,Q103868817,male,solo,drill; trap music; East Coast hip-hop; hip-hop,United States,American rapper
|
||||
CKay,Q98312451,male,solo,Afrobeats,Nigeria,Nigerian singer-songwriter
|
||||
Clean Bandit,Q11838808,,group,electropop,United Kingdom,English electronic music group
|
||||
Cody Johnson,Q17916913,male,solo,country music; country rock,United States,American country singer and songwriter
|
||||
Coi Leray,Q106376206,female,solo,hip-hop; pop music,United States,American rapper and singer
|
||||
Coldplay,Q45188,,group,alternative rock; pop music,United Kingdom,British rock band
|
||||
Cole Swindell,Q15101510,male,solo,country music,United States,American singer-songwriter
|
||||
Corey Kent,Q113452679,male,solo,country music,United States,American singer
|
||||
Cris MJ,Q111425015,male,solo,reggaeton,Chile,Chilean singer-songwriter
|
||||
D.R.A.M.,Q25138504,male,solo,Southern hip-hop; contemporary R&B; trap music,United States,American rapper and singer (born 1988)
|
||||
DaBaby,Q62107457,male,solo,hip-hop; trap music; pop rap; Southern hip-hop,United States,American rapper (born 1991)
|
||||
Daddy Yankee,Q272591,male,solo,reggaeton; Latin hip-hop,United States,Puerto Rican rapper and actor (born 1976)
|
||||
Daft Punk,Q185828,,group,house music; electronic music; French house; synth-pop; electronic rock; electronica; nu-disco; dance music; leftfield house,France,French electronic music band
|
||||
Dan Smyers,Q57630595,male,solo,country music,United States,songwriter and member of the duo Dan + Shay
|
||||
Daniel Caesar,Q29589083,male,solo,contemporary R&B; soul; neo soul,Canada,Canadian R&B singer
|
||||
Danny Chung,Q140814119,male,solo,hip-hop; K-pop,United States,"Korean-American rapper, singer and songwriter"
|
||||
Darell,Q56467651,male,solo,reggaeton; Latin trap,United States,Puerto Rican rapper and singer
|
||||
Dasha,Q125157260,female,solo,country pop,United States,American country singer-songwriter
|
||||
David Guetta,Q8298,male,solo,electronic dance music; house music; electroclash; electro house,France,French DJ and electronic music producer (born 1967)
|
||||
David Kushner,Q117745879,male,solo,,United States,American male singer-songwriter
|
||||
Daya,Q21005558,female,solo,pop music,United States,American singer
|
||||
dazy,Q140814120,male,solo,pop music,,Los Angeles-based record producer and musician
|
||||
Dean Lewis,Q29905254,male,solo,pop music,Australia,Australian singer-songwriter (born 1987)
|
||||
Demi Lovato,Q41173,genderfluid,solo,pop rock; pop music; contemporary R&B; power pop; dance-pop; teen pop; electropop; soul; pop-punk; nu metal,United States,"American singer, songwriter, and actress (born 1992)"
|
||||
Desiigner,Q23091498,male,solo,hip-hop; East Coast hip-hop; trap music; mumble rap; hardcore hip-hop,United States,American rapper and singer (born 1997)
|
||||
Diane Guerrero,Q17166318,female,solo,,United States,American actress
|
||||
Diplo,Q533781,male,solo,electronic dance music; trap music; hip-hop; pop music; moombahton; electropop; house music; EDM trap music,United States,American record producer (born 1978)
|
||||
DJ Khaled,Q80805,male,solo,hip-hop; pop rap,United States,American DJ and rapper (born 1975)
|
||||
DJ Snake,Q16728588,male,solo,electronic dance music; EDM trap music,France,French record producer (born 1986)
|
||||
Djo,Q27064031,male,solo,synth-pop,United States,American actor and musician (born 1992)
|
||||
DNCE,Q21648421,,group,pop rock,United States,American pop band
|
||||
Doechii,Q106629186,female,solo,hip-hop; contemporary R&B; pop music; alternative hip-hop; pop rap,United States,American rapper and singer
|
||||
Doja Cat,Q51120673,female,solo,contemporary R&B; pop music; electronic music; indie pop; hip-hop,United States,American singer and rapper (born 1995)
|
||||
Don Toliver,Q56513383,male,solo,hip-hop; trap music; contemporary R&B,United States,American singer and rapper (born 1994)
|
||||
Dove Cameron,Q13560423,female,solo,pop music; alternative pop; soul,United States,American actress and singer
|
||||
Drake,Q33240,male,solo,hip-hop; contemporary R&B; pop music; trap music,Canada,Canadian-American rapper and singer
|
||||
Dua Lipa,Q21914464,female,solo,pop music; post-disco; house music; funktronica; indie pop; dream pop; synth-pop,United Kingdom,British singer-songwriter (born 1995)
|
||||
Duncan Laurence,Q60758679,male,solo,pop music,Kingdom of the Netherlands,Dutch singer
|
||||
Dustin Lynch,Q5317118,male,solo,country music,United States,American singer
|
||||
Ed Sheeran,Q47447,male,solo,pop music; folk music; hip-hop; dance music; soul; rock music,United Kingdom,English singer-songwriter and guitarist (born 1991)
|
||||
EJAE,Q135108208,female,solo,K-pop; pop music; contemporary R&B,South Korea,South Korean-American singer and songwriter (born 1991)
|
||||
Ella Langley,Q127559972,female,solo,country music,United States,American country singer
|
||||
Ella Mai,Q29033458,female,solo,contemporary R&B,United Kingdom,British singer
|
||||
Elle King,Q5364665,female,solo,country music; Americana; blues rock; alternative country,United States,"American singer, songwriter, and actress"
|
||||
Ellie Goulding,Q31164,female,solo,synth-pop; electropop; indie pop; folktronica; alternative rock; alternative music; dream pop; indietronica,United Kingdom,English singer and songwriter (born 1986)
|
||||
Elton John,Q2808,male,solo,rock music; pop rock; glam rock; soft rock; rhythm and blues,United Kingdom,"British singer, songwriter and musician (born 1947)"
|
||||
Em Beihold,Q111333139,female,solo,pop music,United States,American singer-songwriter
|
||||
Emilee,Q98635221,female,solo,pop music,United States,"American singer, star of TikTok and influencer"
|
||||
Eminem,Q5608,male,solo,hip-hop; horrorcore; hardcore hip-hop; comedy hip-hop; Midwest hip-hop; rap rock,United States,"American rapper, record producer and actor"
|
||||
Encanto Cast,Q140814124,,,,United States,ensemble cast credited on songs from the 2021 Disney animated film Encanto
|
||||
Eric Church,Q975911,male,solo,country music,United States,American country singer
|
||||
ERNEST,Q110442717,male,solo,country music,United States,American hip hop and country musician
|
||||
Eslabón Armado,Q112702265,,group,regional Mexican,United States,American hispanic radio music group
|
||||
Fat Joe,Q309888,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop; boom bap; mafioso rap,United States,American rapper
|
||||
Fetty Wap,Q19361511,male,solo,hip-hop; trap music; pop rap,United States,American rapper and singer (born 1991)
|
||||
Fifth Harmony,Q3087893,,group,pop music,United States,American girl group
|
||||
Fifty Fifty,Q116731010,,group,K-pop; J-pop,South Korea,South Korean girl group
|
||||
Flipp Dinero,Q57584556,male,solo,hip-hop,United States,American rapper
|
||||
Flo Milli,Q89352069,female,solo,hip-hop,United States,American rapper
|
||||
Flo Rida,Q213538,male,solo,hip-hop; pop music; dance music; electronic dance music; Southern hip-hop; contemporary R&B; house music; electro hop; electro house; electropop; electro; EDM trap music; trap music; bass music; crunk; pop rap; dirty south; dance-pop; hip house; Miami bass; electronic music; techno; trance,United States,American rapper and singer (born 1979)
|
||||
Florida Georgia Line,Q3644642,,group,country music,United States,American country music duo
|
||||
FloyyMenor,Q125819969,male,solo,reggaeton,Chile,Chilean singer-songwriter
|
||||
Flume,Q4038837,male,solo,electronica; trip hop; future bass,Australia,Australian music producer
|
||||
Frank Ocean,Q357645,male,solo,alternative R&B; psychedelic soul; progressive soul; contemporary R&B; pop music; soul; hip-hop; avant-pop,United States,"American singer, songwriter, and rapper"
|
||||
French Montana,Q1455261,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop,Morocco,Moroccan and American rapper
|
||||
Fuerza Regida,Q118466501,,group,regional Mexican; banda music; corrido; corridos tumbados; sierreña; norteño,United States,regional Mexican group
|
||||
Future,Q3445057,male,solo,Southern hip-hop; trap music; mumble rap; contemporary R&B,United States,American rapper (born 1983)
|
||||
G-Eazy,Q5511893,male,solo,hip-hop,United States,American rapper
|
||||
Gabby Barrett,Q53912835,female,solo,country pop,United States,American country singer
|
||||
GAYLE,Q109768702,female,solo,pop-punk; pop rock; power pop; emo pop; alternative pop; alternative rock,United States,American singer-songwriter
|
||||
Gigi Perez,Q130235359,female,solo,indie folk,United States,American singer-songwriter
|
||||
Giveon,Q96418479,male,solo,contemporary R&B,United States,American R&B singer
|
||||
Glass Animals,Q16839267,,group,indie rock; psychedelic pop; indietronica; alternative pop; electronic rock; psychedelic rock,United Kingdom,English indie rock band
|
||||
GloRilla,Q114132368,female,solo,hip-hop; trap music; crunk; Memphis rap; Southern hip-hop,United States,American rapper
|
||||
gnash,Q23978226,male,solo,pop music; hip-hop; alternative R&B; indie folk,United States,American musician
|
||||
Gracie Abrams,Q106301562,female,solo,bedroom pop; pop music,United States,American singer-songwriter (born 1999)
|
||||
Grey,Q28451953,,group,electronic music; pop music; future bass,United States,American electronic music group consisting of brothers Kyle and Michael Trewartha
|
||||
Grupo Frontera,Q118141487,,group,regional Mexican; norteño; cumbia norteña mexicana,United States,Mexican-American musical band
|
||||
Gucci Mane,Q206032,male,solo,Southern hip-hop; trap music; gangsta rap; hardcore hip-hop; dirty south; Atlanta hip-hop; dirty rap,United States,American rapper and music executive (born 1980)
|
||||
Gunna,Q55613105,male,solo,hip-hop; trap music; Southern hip-hop; contemporary R&B,United States,American rapper (born 1993)
|
||||
Gus Dapperton,Q51858412,male,solo,pop music,United States,American singer-songwriter
|
||||
Gwen Stefani,Q483379,female,solo,pop music; contemporary R&B; ska; electronica; new wave; rock music,United States,American singer
|
||||
H.E.R.,Q30639849,female,solo,contemporary R&B,United States,American R&B singer
|
||||
Hailee Steinfeld,Q231726,female,solo,pop music; dance-pop,United States,American actress and singer-songwriter (born 1996)
|
||||
Halsey,Q18534249,female,solo,pop music; electropop; synth-pop; art pop; alternative pop; alternative rock; alternative R&B; indie pop; contemporary R&B,United States,American singer-songwriter (born 1994)
|
||||
HARDY,Q63341424,male,solo,country music,United States,American country singer
|
||||
Harry Styles,Q3626966,male,solo,soft rock; pop music; rock music; Britpop; traditional folk music,United Kingdom,"English singer, songwriter and actor"
|
||||
Hozier,Q16233232,male,solo,blues; blues rock; rhythm and blues; traditional folk music; soul; indie rock,Ireland,Irish musician and singer
|
||||
Hudson Westbrook,Q134125831,male,solo,country music,United States,American singer
|
||||
iann dior,Q65631841,male,solo,emo rap; pop rap; rap rock; pop rock,United States,American rapper and singer
|
||||
Ice Spice,Q114114977,female,solo,Bronx drill; hip-hop; East Coast hip-hop; Jersey club; pop rap,United States,American rapper (born 2000)
|
||||
Imagine Dragons,Q391348,,group,pop rock; electropop; alternative rock; new wave,United States,American pop rock band
|
||||
Infared,Q140814135,male,solo,hip-hop,,hip-hop songwriter and rapper featured on the 2016 single All the Way Up
|
||||
Internet Money,Q99691610,,,hip-hop,United States,American record label and record producer collective
|
||||
J Balvin,Q966845,male,solo,reggaeton; Latin pop; Latin trap,Colombia,Colombian singer
|
||||
J. Cole,Q204018,male,solo,hip-hop; Southern hip-hop; pop rap; East Coast hip-hop; conscious hip-hop,United States,American rapper and record producer (born 1985)
|
||||
Jack Harlow,Q59727812,male,solo,hip-hop; pop rap,United States,American rapper and singer (born 1998)
|
||||
Jake Scott,Q140814152,male,solo,pop music,United States,American singer-songwriter
|
||||
James Arthur,Q717626,male,solo,pop music,United Kingdom,British singer (born 1988)
|
||||
James Bay,Q17811637,male,solo,rock music; pop music; soul; Americana,United Kingdom,British singer-songwriter
|
||||
James Blake,Q350362,male,solo,pop music; electronica; post-dubstep; electronic dance music,United Kingdom,English singer-songwriter (born 1988)
|
||||
Jason Aldean,Q195439,male,solo,country music,United States,American country singer
|
||||
Jason Derulo,Q243639,male,solo,pop music; rhythm and blues; contemporary R&B; hip-hop,United States,American singer-songwriter
|
||||
Jawsh 685,Q96472235,male,solo,pop music,New Zealand,New Zealand music producer
|
||||
Jay Rock,Q152632,male,solo,West Coast hip-hop,United States,American rapper (born 1985)
|
||||
Jay Z,Q62766,male,solo,East Coast hip-hop; mafioso rap; gangsta rap; hardcore hip-hop,United States,"American rapper, record producer, and entrepreneur"
|
||||
Jelly Roll,Q6176881,male,solo,Southern hip-hop; country rap; country music; hardcore hip-hop,United States,American rapper (born 1984)
|
||||
Jeremih,Q472891,male,solo,contemporary R&B,United States,American R&B singer (born 1987)
|
||||
Jessica Darrow,Q109718598,non-binary,solo,,United States,American actor and singer
|
||||
Jessie Murph,Q122157373,female,solo,country rock; country pop; pop music,United States,American singer
|
||||
Jhay Cortez,Q75997191,male,solo,Latin trap; reggaeton; Latin R&B,United States,Puerto Rican singer
|
||||
Jhené Aiko,Q15929781,female,solo,hip-hop; pop music; rhythm and blues; soul; alternative R&B; neo soul; contemporary R&B,United States,American R&B singer (born 1988)
|
||||
JID,Q29588830,male,solo,hip-hop,United States,"American rapper, singer, and songwriter from Georgia"
|
||||
Jimin,Q20947093,male,solo,K-pop,South Korea,South Korean singer and dancer (BTS)
|
||||
JNR CHOI,Q111507858,male,solo,hip-hop; trap music; world music,United Kingdom,Gambian-British rapper and singer
|
||||
John Legend,Q44857,male,solo,soul; pop music; contemporary R&B,United States,American singer-songwriter
|
||||
Joji,Q23826617,male,solo,contemporary R&B; alternative R&B; trip hop; lo-fi music; surreal humour; satirical music; satire; comedy hip-hop; black comedy; alternative rock; comedy music,Japan,Japanese-Australian entertainer (born 1992)
|
||||
Jon Bellion,Q18044284,male,solo,pop music; contemporary R&B; hip-hop; indie rock; pop rap; alternative hip-hop; indie pop; alternative rock; dance-pop; soul,United States,"American singer, rapper, songwriter, and record producer"
|
||||
Jon Pardi,Q6271354,male,solo,country music,United States,American country singer
|
||||
Jonas Brothers,Q134233,,group,pop music; pop rock,United States,American pop rock band
|
||||
Jordan Davis,Q44274417,male,solo,country pop; country music; pop music,United States,American country music singer and songwriter
|
||||
JP Saxe,Q86009464,male,solo,pop music,Canada,Canadian singer and musician
|
||||
Juice WRLD,Q52151598,male,solo,hip-hop; emo rap; alternative rock; trap music; pop rap; SoundCloud rap; contemporary R&B; alternative hip-hop; mumble rap,United States,American rapper and singer (1998–2019)
|
||||
Juicy J,Q602779,male,solo,Southern hip-hop; gangsta rap; trap music; dirty rap; Memphis rap; dirty south; horrorcore; hardcore hip-hop; crunk,United States,American record producer and rapper (born 1975)
|
||||
Julia Michaels,Q20051697,female,solo,pop music; electronic dance music,United States,American singer and songwriter (born 1993)
|
||||
Jung Kook,Q22338877,male,solo,K-pop,South Korea,South Korean singer
|
||||
Justin Bieber,Q34086,male,solo,pop music; contemporary R&B; tropical house; reggaeton; contemporary country,Canada,Canadian singer-songwriter (born 1994)
|
||||
Justin Timberlake,Q43432,male,solo,pop music; contemporary R&B,United States,American singer and actor (born 1981)
|
||||
JVKE,Q114865231,male,solo,pop music,United States,American singer and producer
|
||||
Kacey Musgraves,Q2783855,female,solo,country music; folk music,United States,American singer (born 1988)
|
||||
Kai,Q6347342,female,solo,pop music,Canada,Canadian singer and songwriter
|
||||
Kali Uchis,Q19004484,female,solo,contemporary R&B,United States,American singer and songwriter (born 1994)
|
||||
Kaliii,Q115633164,female,solo,hip-hop; trap music; Southern hip-hop,United States,American rapper
|
||||
Kane Brown,Q21620939,male,solo,country music,United States,American country music singer
|
||||
Kanye West,Q15935,male,solo,hip-hop; pop music; electro; soul; gospel music; progressive rap; art pop; pop rap; hip-hop soul; chipmunk soul; contemporary R&B,United States,American rapper and record producer
|
||||
Karol G,Q22001324,female,solo,reggaeton; Latin pop; Latin R&B,Colombia,Colombian singer and songwriter
|
||||
Kate Bush,Q636,female,solo,art pop; progressive pop; singer-songwriter music; baroque pop; experimental pop; art rock; pop rock,United Kingdom,"English singer, pianist and songwriter (born 1958)"
|
||||
Katelyn Brown,Q140814175,female,solo,pop music,United States,American singer
|
||||
Katy Perry,Q42493,female,solo,pop music; rock music; pop rock; dance music; synth-pop; electropop; gospel music,United States,American singer
|
||||
Kehlani,Q20657541,non-binary,solo,contemporary R&B; pop music; neo soul; hip-hop,United States,American singer-songwriter (born 1995)
|
||||
Keith Urban,Q315547,male,solo,country music,Australia,Australian-American musician
|
||||
Kendrick Lamar,Q130798,male,solo,West Coast hip-hop; progressive rap; alternative hip-hop; jazz rap; conscious hip-hop; gangsta rap; hardcore hip-hop; jazz; pop music,United States,American rapper (born 1987)
|
||||
Kenny Chesney,Q467526,male,solo,country music,United States,American country musician
|
||||
Kent Jones,Q25190082,male,solo,pop rap; contemporary R&B; pop music,United States,American singer and rapper (born 1993)
|
||||
Kesha,Q33605,female,solo,electropop; dance-pop; synth-pop; pop rock; pop rap; rock music; dance music; country music,United States,American singer and songwriter (born 1987)
|
||||
Kevin Gates,Q6396353,male,solo,hip-hop; gangsta rap; hardcore hip-hop; dirty south; Southern hip-hop,United States,American rapper
|
||||
Kevin Woo,Q6397789,male,solo,K-pop,United States,Korean-American singer
|
||||
Khalid,Q28816483,male,solo,contemporary R&B,United States,American singer (born 1998)
|
||||
Kid Cudi,Q299138,male,solo,Midwest hip-hop; contemporary R&B; alternative hip-hop; pop rap; alternative rock; trip hop; neo-psychedelia; punk rock; grunge; emo rap; psychedelic rap; psychedelic hip-hop,United States,"American rapper, singer, record producer and actor (born 1984)"
|
||||
Kiiara,Q23042767,female,solo,pop music; electropop; alternative R&B; experimental pop,United States,American singer and songwriter
|
||||
Kim Petras,Q60964,trans woman,solo,pop music,Germany,German singer
|
||||
Kodak Black,Q22005867,male,solo,hip-hop; trap music; SoundCloud rap; gangsta rap; Southern hip-hop; mumble rap,United States,American rapper (born. 1997)
|
||||
Koe Wetzel,Q107434048,male,solo,country music; rock music,United States,American musician
|
||||
Kygo,Q16845512,male,solo,tropical house; deep house; downtempo; progressive house; house music; electronic dance music,Norway,Norwegian DJ and music producer
|
||||
Kyla,Q25190133,female,solo,UK funky,United Kingdom,British singer
|
||||
KYLE,Q28606665,male,solo,West Coast hip-hop; pop rap,United States,American rapper and singer
|
||||
Lady Gaga,Q19848,female,solo,electropop; dance-pop; electronic dance music; art pop; pop music; synth-pop,United States,"American singer, songwriter, and actress (born 1986)"
|
||||
Lainey Wilson,Q106378786,female,solo,country music; folk music,United States,American singer-songwriter
|
||||
Latto,Q65029930,female,solo,hip-hop; trap music; pop music; pop rap,United States,American rapper (born 1998)
|
||||
Lauren Alaina,Q271796,female,solo,country music; folk music,United States,American singer & songwriter (born 1994)
|
||||
Lauren Daigle,Q18685595,female,solo,contemporary Christian music,United States,American singer and songwriter (born 1991)
|
||||
Lauren Spencer-Smith,Q110630787,female,solo,pop music,Canada,Canadian singer and songwriter
|
||||
Lauv,Q30122224,male,solo,electronic music; pop music,United States,American musician
|
||||
Lee Brice,Q1811729,male,solo,country music,United States,American country singer
|
||||
Lefty Gunplay,Q131374668,male,solo,hip-hop; West Coast hip-hop; gangsta rap,United States,American rapper
|
||||
Leon Thomas,Q714375,male,solo,contemporary R&B; pop music; soul; hip-hop,United States,"American actor, singer, songwriter and producer"
|
||||
Lewis Capaldi,Q42315001,male,solo,blue-eyed soul; pop music; pop rock; alternative rock; soft rock,United Kingdom,Scottish singer-songwriter (born 1996)
|
||||
Liam Payne,Q2756349,male,solo,pop music; contemporary R&B,United Kingdom,English singer and songwriter (1993–2024)
|
||||
Lil Baby,Q50527563,male,solo,hip-hop; trap music; Southern hip-hop,United States,American rapper (born 1994)
|
||||
Lil Dicky,Q16876006,male,solo,hip-hop; pop rap; comedy hip-hop,United States,American rapper and comedian (born 1988)
|
||||
Lil Durk,Q2899818,male,solo,Midwest hip-hop; trap music; drill; gangsta rap; hardcore hip-hop; Chicago hip-hop; Chicago drill,United States,American rapper
|
||||
Lil Mosey,Q55819454,male,solo,hip-hop; pop rap; trap music,United States,American rapper and singer-songwriter
|
||||
Lil Nas X,Q62591281,male,solo,hip-hop; pop rap; country rap; trap music; pop music; rock music; pop rock; country music; Southern hip-hop,United States,"American rapper, singer and songwriter (born 1999)"
|
||||
Lil Pump,Q38002101,male,solo,hip-hop; trap music; SoundCloud rap; punk rap; Southern hip-hop,United States,American rapper
|
||||
Lil Tecca,Q65054660,male,solo,hip-hop; trap music,United States,American rapper and singer-songwriter
|
||||
Lil Tjay,Q61670761,male,solo,hip-hop,United States,American rapper
|
||||
Lil Uzi Vert,Q23771950,non-binary,solo,hip-hop; emo rap; trap music; SoundCloud rap; punk rap; psychedelic rap; rage; cloud rap; psychedelic hip-hop; East Coast hip-hop,United States,American rapper
|
||||
Lil Wayne,Q15615,male,solo,Southern hip-hop; bounce music; gangsta rap; trap music; pop rap; dirty south; hardcore hip-hop,United States,American rapper and singer
|
||||
Lil Yachty,Q23772141,male,solo,hip-hop; trap music; pop rap; mumble rap; cloud rap; Southern hip-hop,United States,American rapper and singer
|
||||
Lizzo,Q16232225,female,solo,hip-hop; soul; contemporary R&B; gospel music,United States,American singer and rapper (born 1988)
|
||||
Logic,Q6667429,male,solo,hip-hop; pop rap; conscious hip-hop; East Coast hip-hop,United States,American rapper from Maryland
|
||||
Lola Young,Q115869427,female,solo,pop music; soul; contemporary R&B,United Kingdom,British singer-songwriter (born 2001)
|
||||
Luis Fonsi,Q1387726,male,solo,pop music; Latin pop; ballad; reggaeton,United States,Puerto Rican singer
|
||||
Lukas Graham,Q300935,,group,soul; pop music; pop rock; funk,Denmark,Danish band
|
||||
Luke Bryan,Q166197,male,solo,country music,United States,American country music singer
|
||||
Luke Combs,Q23884740,male,solo,country music,United States,American country singer
|
||||
Machine Gun Kelly,Q1354843,male,solo,hip-hop; pop rap; rap rock; pop-punk; alternative rock; alternative hip-hop,United States,American musician (born 1990)
|
||||
Maddie,Q54607228,female,solo,country music,United States,"Singer, part of Maddie & Tae"
|
||||
Mae Muller,Q83696883,female,solo,pop music; rhythm and blues,United Kingdom,British singer
|
||||
Major Lazer,Q2604214,,group,dancehall; moombahton; reggae fusion; trap music; electronic dance music; hip-hop; electro house; rocksteady,United States,Jamaican-American electronic music band
|
||||
Maren Morris,Q21622122,female,solo,country music; country pop; folk rock; folk music,United States,American country singer
|
||||
Mariah Carey,Q41076,female,solo,contemporary R&B; pop music; adult contemporary music; dance-pop; hip-hop,United States,American singer (born 1969)
|
||||
Mariah the Scientist,Q84356665,female,solo,alternative R&B,United States,American singer (born 1997)
|
||||
Marian Hill,Q20858093,,group,electronic music,United States,American musical duo
|
||||
Maroon 5,Q182223,,group,alternative rock; funk rock; pop rock; pop music,United States,American pop rock band
|
||||
Marshmello,Q26334949,male,solo,electronic dance music,United States,American DJ and electronic music producer (born 1992)
|
||||
Masked Wolf,Q105490126,male,solo,hip-hop,Australia,Australian rapper
|
||||
Mauro Castillo,Q16605580,male,solo,salsa,Colombia,"Colombian singer, composer, and actor"
|
||||
MAX,Q1190160,male,solo,pop music,United States,American singer
|
||||
Meek Mill,Q1897911,male,solo,East Coast hip-hop; hardcore hip-hop; gangsta rap; trap music; hip-hop,United States,American rapper
|
||||
Megan Moroney,Q116786312,female,solo,country music; folk music,United States,American country music singer
|
||||
Megan Thee Stallion,Q59268408,female,solo,hip-hop; trap music; dirty rap; pop rap; pop music,United States,"American rapper, singer and songwriter"
|
||||
Meghan Trainor,Q17403494,female,solo,pop music; contemporary R&B; dance-pop; soul; doo-wop,United States,American singer-songwriter (born 1993)
|
||||
Metro Boomin,Q16235273,male,solo,hip-hop; trap music,United States,American record producer (born 1993)
|
||||
Migos,Q15777045,,group,Southern hip-hop; trap music; mumble rap,United States,American hip hop group
|
||||
Miguel,Q73463,male,solo,contemporary R&B; alternative R&B; hip-hop; pop music; soul,United States,American R&B singer
|
||||
Mike Posner,Q268284,male,solo,pop music,United States,American musician
|
||||
Miley Cyrus,Q4235,genderfluid,solo,pop music; country music; pop rock; dance-pop; electropop; rock music; hip-hop; teen pop; country pop,United States,"American singer, actress, and television personality (born 1992)"
|
||||
Miranda Lambert,Q231233,female,solo,country music; folk music,United States,American country singer
|
||||
MNEK,Q6716905,male,solo,pop music,United Kingdom,British singer
|
||||
Moneybagg Yo,Q38459032,male,solo,hip-hop; trap music; gangsta rap; Memphis rap; Southern hip-hop,United States,American rapper from Tennessee
|
||||
Mooski,Q113554625,male,solo,hip-hop,United States,Musical artist
|
||||
Morgan Wallen,Q29561472,male,solo,country music; country pop; bro-country; country rap,United States,American country singer
|
||||
Muni Long,Q7245622,female,solo,contemporary R&B; pop music,United States,American singer
|
||||
Murda Beatz,Q27970613,male,solo,hip-hop,Canada,Canadian record producer (born 1994)
|
||||
Mustard,Q15941115,male,solo,hip-hop; ratchet music; West Coast hip-hop; contemporary R&B,United States,American record producer
|
||||
Myles Smith,Q126076580,male,solo,folk-pop; folk music; pop music; folk rock,United Kingdom,British singer
|
||||
Måneskin,Q56884561,,group,pop rock; glam rock,Italy,Italian rock band
|
||||
MØ,Q10670047,female,solo,indie pop; electronic music,Kingdom of Denmark,Danish singer and songwriter
|
||||
N*E*R*D,Q941293,,group,funk rock; bossa nova; orchestral pop; hip-hop; skate punk,United States,American rock and hip-hop band
|
||||
Natanael Cano,Q104904549,male,solo,corridos tumbados; regional Mexican,Mexico,Mexican rapper and singer
|
||||
Nate Smith,Q110707312,male,solo,country music; country rock,United States,"American country music singer, musician and songwriter"
|
||||
NAV,Q28831246,male,solo,hip-hop; cloud rap; trap music; contemporary R&B,Canada,"Canadian rapper, singer, and record producer (born 1989)"
|
||||
Neckwav,Q140814188,male,solo,contemporary R&B,South Korea,South Korean R&B singer
|
||||
NEIKED,Q26703294,,group,,Sweden,Swedish artist collective
|
||||
Nelly,Q218992,male,solo,Midwest hip-hop; pop rap; contemporary R&B; pop music; country rap; country music,United States,"American rapper, singer and actor (born 1974)"
|
||||
Netón Vega,Q129208676,male,solo,regional Mexican; corridos tumbados,Mexico,Mexican singer-songwriter
|
||||
NF,Q19571648,male,solo,hip-hop,United States,American rapper from Michigan
|
||||
Niall Horan,Q775231,male,solo,pop music; pop rock; folk-pop,Ireland,Irish singer-songwriter
|
||||
Nick Jonas,Q201656,male,solo,pop music; rock music; contemporary R&B,United States,"American singer, actor and musician"
|
||||
Nicki Minaj,Q162202,female,solo,hip-hop; pop music; contemporary R&B; trap music; dance music,Trinidad and Tobago,Trinidadian rapper (born 1982)
|
||||
Nicky Jam,Q1374560,male,solo,reggaeton; Latin trap,United States,American singer
|
||||
Nicky Youre,Q112666811,male,solo,indie pop,United States,American singer-songwriter
|
||||
Niko Moon,Q67399825,male,solo,country music,United States,musical artist
|
||||
Nio García,Q107358694,male,solo,Latin trap; reggaeton,United States,Puerto Rican singer
|
||||
NLE Choppa,Q64009351,male,solo,trap music; hip-hop; drill; Memphis rap; gangsta rap; Southern hip-hop,United States,American rapper from Tennessee (born 2002)
|
||||
Noah Kahan,Q53832755,male,solo,folk-pop,United States,American singer-songwriter (born 1997)
|
||||
Normani,Q28148022,female,solo,pop music; contemporary R&B,United States,American singer and dancer
|
||||
O.T. Genasis,Q18623749,male,solo,hip-hop; trap music,United States,American rapper
|
||||
Offset,Q30612480,male,solo,hip-hop; trap music; Southern hip-hop,United States,American rapper
|
||||
Old Dominion,Q20685018,,group,country pop,United States,American country pop music group (2007–)
|
||||
Oliver Anthony Music,Q121391237,male,solo,country music; folk music,United States,American singer-songwriter
|
||||
Olivia O'Brien,Q23978275,female,solo,dance-pop; pop music,United States,American singer
|
||||
Olivia Rodrigo,Q63243883,female,solo,indie pop; pop music; rock music,United States,American singer and actress (born 2003)
|
||||
One Direction,Q146027,,group,dance-pop; teen pop; pop rock,United Kingdom,English-Irish musical group; boy band
|
||||
OneRepublic,Q1438730,,group,pop rock; alternative rock; cello rock,United States,American pop rock band
|
||||
Ozuna,Q28739901,male,solo,reggaeton; Latin trap; Latin pop; dancehall,United States,Puerto Rican singer
|
||||
P!nk,Q160009,female,solo,pop music; pop rock; contemporary R&B,United States,"American singer, songwriter, and actress (born 1979)"
|
||||
Panic! At The Disco,Q277551,,group,pop rock; synth-pop; pop-punk; baroque pop; emo pop; alternative rock,United States,American musical group; rock solo project band
|
||||
Parker McCollum,Q20684755,male,solo,Americana; country music,United States,American musician
|
||||
Parmalee,Q7139162,,group,country music,United States,American country music band
|
||||
PARTYNEXTDOOR,Q15929398,male,solo,Canadian hip-hop; alternative R&B,Canada,Canadian singer (born 1993)
|
||||
Paul Russell,Q122932071,male,solo,hip-hop; contemporary R&B; pop rap,United States,American singer
|
||||
Peso Pluma,Q117242724,male,solo,regional Mexican; corridos tumbados; reggaeton; Latin trap; cumbia norteña mexicana,Mexico,Mexican singer (born 1999)
|
||||
Pharrell Williams,Q14313,male,solo,contemporary R&B; hip-hop; pop music; funk; rock music; pop rap,United States,American record producer and songwriter
|
||||
Pinkfong,Q55735607,,,children's music,South Korea,Korean children's entertainment brand
|
||||
PinkPantheress,Q107570416,female,solo,pop music; bedroom pop; dance music; alternative pop; drum and bass; 2-step garage; jungle; hyperpop,United Kingdom,British singer-songwriter
|
||||
Playboi Carti,Q27671080,male,solo,Southern hip-hop; trap music; mumble rap; cloud rap; rage; punk rap; alternative hip-hop; plugg music; lo-fi music; SoundCloud rap,United States,American rapper
|
||||
PnB Rock,Q28155029,male,solo,hip-hop; contemporary R&B; trap music; pop music; pop rap,United States,American rapper (1991–2022)
|
||||
Polo G,Q62953486,male,solo,hip-hop; drill; trap music; conscious hip-hop; Midwest hip-hop; Chicago hip-hop,United States,American rapper
|
||||
Pooh Shiesty,Q105105274,male,solo,trap music; Southern hip-hop; drill; hardcore hip-hop; gangsta rap; Memphis rap,United States,American rapper from Tennessee (born. 1999)
|
||||
Pop Smoke,Q81698554,male,solo,East Coast hip-hop; Brooklyn drill; trap music; gangsta rap; drill; hip-hop,United States,American rapper (1999–2020)
|
||||
Portugal. The Man,Q606879,,group,pop music; indie rock,United States,American rock band
|
||||
Post Malone,Q21621919,male,solo,hip-hop; pop music; country music,United States,American musician (born 1995)
|
||||
Powfu,Q89069821,male,solo,hip-hop; lo-fi music; power pop; rock music,Canada,Canadian rapper and singer
|
||||
Project Pat,Q593741,male,solo,Memphis rap; gangsta rap; hardcore hip-hop; Southern hip-hop; crunk; dirty south; trap music; horrorcore,United States,American rapper
|
||||
Quavo,Q30072039,male,solo,hip-hop; trap music,United States,American rapper
|
||||
Rae Sremmurd,Q18123226,,group,hip-hop; trap music; pop music; pop rap,United States,American hip hop duo
|
||||
Rauw Alejandro,Q61586861,male,solo,contemporary R&B; urban contemporary; Latin R&B; reggaeton; Latin trap; Latin pop; salsa,United States,Puerto Rican singer and songwriter
|
||||
Ravyn Lenae,Q28962463,female,solo,contemporary R&B; alternative R&B; neo soul,United States,American singer
|
||||
RAYE,Q28071144,female,solo,contemporary R&B,United Kingdom,British singer-songwriter
|
||||
REI AMI,Q104842557,female,solo,K-pop; pop music; hip-hop; contemporary R&B,South Korea,South Korean singer and rapper
|
||||
Rema,Q65071082,male,solo,Afrobeats,Nigeria,Nigerian singer-songwriter and rapper (2000–)
|
||||
Remy Boyz,Q63405888,,group,hip-hop,United States,musical group
|
||||
Remy Ma,Q275437,female,solo,East Coast hip-hop,United States,American rapper
|
||||
Rhenzy Feliz,Q34344805,male,solo,,United States,American actor
|
||||
Rich The Kid,Q18637908,male,solo,hip-hop; trap music; mumble rap; plugg music; Southern hip-hop,United States,American rapper
|
||||
Rick Ross,Q297831,male,solo,Southern hip-hop; gangsta rap; mafioso rap; trap music; hardcore hip-hop; dirty south,United States,American rapper and record executive
|
||||
Rihanna,Q36844,female,solo,pop music; dancehall; contemporary R&B; electronic dance music; adult contemporary music,Barbados,Barbadian singer (born 1988)
|
||||
Riley Green,Q57418818,male,solo,country music,United States,American singer/songwriter
|
||||
Ritt Momney,Q105105308,male,solo,folk music; indie pop; synth-pop,United States,American singer-songwriter from Utah
|
||||
Rod Wave,Q78754352,male,solo,hip-hop; contemporary R&B; soul; trap music,United States,American rapper and singer-songwriter (born 1998)
|
||||
Roddy Ricch,Q59209423,male,solo,West Coast hip-hop; trap music; pop rap; gangsta rap; hardcore hip-hop; hip-hop,United States,American rapper (born 1998)
|
||||
ROSÉ,Q27655344,female,solo,K-pop; dance-pop; hip-hop; electronic dance music,New Zealand,South Korean-New Zealand singer (born 1997)
|
||||
Rozes,Q22955580,female,solo,pop music; dance music; electronic dance music,United States,American singer
|
||||
Russell Dickerson,Q24572267,male,solo,country music,United States,American country singer-songwriter
|
||||
Ruth B,Q22056665,female,solo,pop music,Canada,Canadian singer-songwriter
|
||||
Ryan Hurd,Q42224127,male,solo,country music,United States,American country singer
|
||||
Sabrina Carpenter,Q7396400,female,solo,pop music; teen pop; dance-pop; contemporary R&B; electropop; country pop,United States,American singer-songwriter and actress (born 1999)
|
||||
SAINt JHN,Q52274581,male,solo,hip-hop; trap music; contemporary R&B,United States,Guyanese-American rapper and singer
|
||||
Sam Barber,Q124428137,male,solo,country music,United States,American singer-songwriter
|
||||
Sam Hunt,Q16223171,male,solo,country music,United States,American singer and songwriter
|
||||
Sam Smith,Q15123969,non-binary,solo,soul; contemporary R&B; pop music; rhythm and blues,United Kingdom,British singer-songwriter
|
||||
Sam Tompkins,Q112155955,male,solo,pop music,United Kingdom,British singer-songwriter
|
||||
samUIL Lee,Q140814222,male,solo,J-pop,South Korea,"South Korean singer, songwriter and record producer"
|
||||
Saweetie,Q50486592,female,solo,hip-hop,United States,American rapper (born 1993)
|
||||
Scotty McCreery,Q255969,male,solo,country music,United States,American country music singer
|
||||
Sean Paul,Q200577,male,solo,dancehall; pop music,Jamaica,Jamaican dancehall singer and rapper (born 1973)
|
||||
Selena Gomez,Q83287,female,solo,pop music; dance-pop; electropop; pop rock; contemporary R&B; alternative R&B,United States,American singer and actress (born 1992)
|
||||
Sexyy Red,Q119842023,female,solo,hip-hop; trap music; dirty rap; Midwest hip-hop,United States,American rapper (born 1998)
|
||||
Shaboozey,Q125295750,male,solo,alternative country; country music; hip-hop; Americana,United States,American singer (born 1995)
|
||||
SHAED,Q60643444,,group,electropop; indie pop,United States,American musical group
|
||||
Shakira,Q34424,female,solo,pop music; Latin pop; pop rock; Latin rock; dance music; folk music; world music; contemporary R&B; rock music,Spain,"Colombian singer, songwriter, and actress"
|
||||
Shawn Mendes,Q17198340,male,solo,folk-pop; pop music; pop rock,Canada,Canadian singer
|
||||
Shay Mooney,Q116536996,male,solo,country music,United States,"American musician and songwriter, part of Dan + Shay"
|
||||
Sheck Wes,Q56513324,male,solo,East Coast hip-hop; trap music,United States,American rapper (born 1998)
|
||||
Sia,Q181484,female,solo,electropop; indie pop,Australia,Australian singer and songwriter (born 1975)
|
||||
Silentó,Q20354248,male,solo,hip-hop; pop rap; trap music; comedy hip-hop; snap music; pop music,United States,American rapper and singer (born 1998)
|
||||
Skip Marley,Q21621948,male,solo,reggae; pop music; hip-hop; rock music,Jamaica,Jamaican singer and songwriter
|
||||
Snow,Q94708,male,solo,dancehall; reggae; hip-hop; reggae fusion,Canada,Canadian dancehall rapper (born 1969)
|
||||
Social House,Q65117469,,group,pop music,United States,American pop duo
|
||||
sombr,Q133444448,male,solo,alternative pop; bedroom pop,United States,American singer-songwriter
|
||||
SpotemGottem,Q105105325,male,solo,mumble rap; trap music; drill; Southern hip-hop,United States,American rapper
|
||||
StaySolidRocky,Q95918251,male,solo,hip-hop,United States,American rapper
|
||||
Stephanie Beatriz,Q16832110,female,solo,,United States,Argentine-American actress
|
||||
Stephen Sanchez,Q113023532,male,solo,pop music,United States,American singer-songwriter
|
||||
Steve Lacy,Q56733980,male,solo,alternative R&B,United States,"American singer, songwriter, guitarist, and record producer (born 1998)"
|
||||
Summer Walker,Q61959478,female,solo,contemporary R&B,United States,American R&B singer
|
||||
Surf Mesa,Q93771412,male,solo,tropical house,United States,American record producer and multi-instrumentalist
|
||||
Surfaces,Q76330429,,group,pop music,United States,American musical duo
|
||||
Swae Lee,Q30103025,male,solo,hip-hop; trap music,United States,American rapper and singer-songwriter (born 1993)
|
||||
SZA,Q16210722,female,solo,contemporary R&B; alternative R&B; neo soul; pop music; hip-hop,United States,American singer
|
||||
Tae,Q54607285,female,solo,country music,United States,"Singer, part of Maddie & Tae"
|
||||
Tate McRae,Q95129121,female,solo,pop music; alternative pop; dance-pop,Canada,"Canadian singer, songwriter, and dancer"
|
||||
Taylor Swift,Q26876,female,solo,pop music; country music,United States,American singer-songwriter (born 1989)
|
||||
Teddy Swims,Q105542333,male,solo,country music; pop music; rhythm and blues; soul,United States,American singer-songwriter
|
||||
Tems,Q72759173,female,solo,alternative R&B; Afrobeats,Nigeria,Nigerian singer-songwriter (born 1995)
|
||||
Teo,Q55860035,male,solo,hip-hop,United States,American singer and dancer
|
||||
The Chainsmokers,Q7721993,,group,electronic dance music,United States,American electronic music duo
|
||||
The Kid LAROI,Q82890761,male,solo,Australian hip-hop; contemporary R&B; pop music; emo rap,Australia,Australian rapper and singer (born 2003)
|
||||
The Marías,Q85807852,,group,indie pop; psychedelic soul; dream pop; synth-pop,United States,American band
|
||||
The Weeknd,Q2121062,male,solo,alternative R&B; pop music; electropop,Canada,Canadian singer and songwriter (born 1990)
|
||||
Thomas Rhett,Q7793491,male,solo,country music,United States,American country singer
|
||||
Tim McGraw,Q356487,male,solo,country music,United States,American country singer and actor (born 1967)
|
||||
Tommy Richman,Q125778611,male,solo,pop rap; contemporary R&B,United States,American singer
|
||||
Tones And I,Q62887629,female,solo,indie pop; electronic dance music; pop music,Australia,"Australian singer, songwriter and record producer"
|
||||
Toosii,Q106725126,male,solo,hip-hop,United States,American rapper from New York
|
||||
Tory Lanez,Q18353558,male,solo,hip-hop; contemporary R&B,Canada,Canadian rapper and singer (born 1992)
|
||||
Tove Lo,Q15948790,female,solo,pop music; indie pop; synth-pop; electropop,Sweden,Swedish singer
|
||||
Travis Scott,Q13605596,male,solo,hip-hop; trap music; pop rap; psychedelic rap; rock music; Southern hip-hop; contemporary R&B; psychedelic music; pop rock; alternative rock; alternative hip-hop; alternative R&B; psychedelic rock; psychedelic hip-hop,United States,"American rapper, singer and record producer"
|
||||
Trevor Daniel,Q81738417,male,solo,contemporary R&B; pop music,United States,American singer-songwriter
|
||||
Tucker Wetmore,Q124754909,male,solo,country music,United States,American country music artist
|
||||
twenty one pilots,Q7857806,,group,reggae; alternative rock; electropop; alternative hip-hop; rap rock; indie pop; pop rock,United States,American musical duo
|
||||
Ty Dolla $ign,Q7859785,male,solo,contemporary R&B; West Coast hip-hop; trap music; hip-hop,United States,American singer and rapper (born 1982)
|
||||
Tyga,Q358087,male,solo,West Coast hip-hop; pop rap,United States,American rapper
|
||||
Tyla,Q118105408,female,solo,contemporary R&B; pop music; Amapiano; new jack swing,South Africa,South African singer-songwriter
|
||||
Tyler Cole,Q140814245,male,solo,,United States,"American singer, songwriter and record producer"
|
||||
Tyler Hubbard,Q20740966,male,solo,country music,United States,American singer
|
||||
"Tyler, The Creator",Q167635,male,solo,alternative hip-hop; neo soul; West Coast hip-hop; jazz rap; hardcore hip-hop; horrorcore,United States,American rapper and record producer (born 1991)
|
||||
Usher,Q165911,male,solo,contemporary R&B; pop music; soul; hip-hop; dance music; dance-pop; crunk,United States,American R&B singer (born 1978)
|
||||
Victoria Monét,Q19864989,female,solo,pop music; contemporary R&B; hip-hop,United States,American singer and songwriter (born 1989)
|
||||
Walker Hayes,Q7962267,male,solo,country music,United States,American musician
|
||||
Warren Zeiders,Q120986980,male,solo,country music,United States,American country musician
|
||||
Wham!,Q744087,,group,pop music; new wave; blue-eyed soul,United Kingdom,British pop band
|
||||
WILLOW,Q298209,female,solo,indie pop; alternative R&B; experimental pop; neo soul; hip-hop; electronic dance music; pop music; dream pop; contemporary R&B; rock music; indie rock; progressive rock; pop-punk; alternative rock; alternative pop; jazz,United States,American singer and actress (born 2000)
|
||||
Willy William,Q17016749,male,solo,house music; reggaeton; zouk,France,"French DJ, record producer, and singer (born 1981)"
|
||||
Wiz Khalifa,Q117139,male,solo,East Coast hip-hop; pop rap,United States,"American rapper, singer and actor (born 1987)"
|
||||
Wizkid,Q16233663,male,solo,Afrobeats; dancehall; rhythm and blues,Nigeria,Nigerian singer and songwriter (born 1990)
|
||||
X Ambassadors,Q15963313,,group,alternative rock,United States,"American rock band from Ithaca, New York"
|
||||
Xavi,Q124219723,male,solo,regional Mexican; corridos tumbados,United States,American singer
|
||||
XXXTENTACION,Q28561969,male,solo,hip-hop; emo rap; SoundCloud rap; rap rock; lo-fi music; hardcore hip-hop; alternative rock; lofi hip-hop; indie rock; nu metal; cloud rap; trap music; hardcore punk; trap metal; punk rock; rock music; rap metal; alternative R&B; contemporary R&B; punk rap; heavy metal music,United States,American rapper (1998–2018)
|
||||
Yeat,Q108761978,male,solo,experimental hip-hop; rage; trap music,United States,"American rapper, singer-songwriter, and record producer (born 2000)"
|
||||
YFN Lucci,Q28000403,male,solo,hip-hop,United States,American rapper (born 1991)
|
||||
YG,Q3076050,male,solo,West Coast hip-hop; gangsta rap; dirty rap; hardcore hip-hop,United States,American rapper and actor
|
||||
YK Osiris,Q66095815,male,solo,contemporary R&B; hip-hop,United States,"American rapper, singer, and songwriter"
|
||||
Yng Lvcas,Q117834547,male,solo,reggaeton,Mexico,Mexican singer and rapper
|
||||
YNW Melly,Q56276347,male,solo,Southern hip-hop; trap music; contemporary R&B; gangsta rap; drill; hardcore hip-hop,United States,American rapper
|
||||
Yo Gotti,Q586919,male,solo,Southern hip-hop; trap music; dirty south; hardcore hip-hop; gangsta rap; Memphis rap,United States,American rapper
|
||||
Young Dolph,Q23541285,male,solo,Southern hip-hop; gangsta rap; trap music; Memphis rap; dirty south; hardcore hip-hop,United States,American rapper (1985–2021)
|
||||
Young Nudy,Q62036530,male,solo,hip-hop,United States,American rapper (born 1992)
|
||||
Young Thug,Q15637814,male,solo,Southern hip-hop; trap music; mumble rap; progressive rap; SoundCloud rap,United States,American rapper and singer
|
||||
YoungBoy Never Broke Again,Q36490532,male,solo,hip-hop; Southern hip-hop; gangsta rap; trap music,United States,American rapper (born 1999)
|
||||
Yung Bleu,Q105105248,male,solo,contemporary R&B; hip-hop,United States,American rapper and singer
|
||||
Zacari,Q68593407,male,solo,contemporary R&B; hip-hop; alternative hip-hop; alternative R&B,United States,"American singer, songwriter, and multi-instrumentalist (born 1994)"
|
||||
Zach Bryan,Q106770023,male,solo,alternative country; red dirt; country music,United States,American country musician
|
||||
Zach Top,Q126414316,male,solo,country music,United States,American singer/songwriter
|
||||
Zara Larsson,Q4177928,female,solo,dance-pop; pop music; electropop,Sweden,Swedish singer and songwriter (born 1997)
|
||||
Zay Hilfigerrr,Q55859289,male,solo,hip-hop,United States,American rapper
|
||||
Zayion McCall,Q55859293,male,solo,hip-hop,United States,
|
||||
Zayn,Q3626950,male,solo,pop music; contemporary R&B; dance-pop; alternative R&B,United Kingdom,English singer
|
||||
Zedd,Q21088,male,solo,electronic dance music; house music; electro house,Russia,German electronic music producer (born 1989)
|
||||
Óscar Maydon,Q130241052,male,solo,corridos tumbados,Mexico,Mexican singer
|
||||
name,qid,gender,type,genre,country,note
|
||||
070 Shake,Q54861040,female,solo,hip-hop; cloud rap; alternative hip-hop,United States,American rapper and singer
|
||||
2 Chainz,Q129668,male,solo,Southern hip-hop; trap music; gangsta rap; dirty south; Atlanta hip-hop; hardcore hip-hop,United States,American rapper
|
||||
21 Savage,Q25095399,male,solo,hip-hop; trap music,United Kingdom,British-born rapper (born 1992)
|
||||
24kGoldn,Q83751918,male,solo,pop rap,United States,American rapper
|
||||
42 Dugg,Q95694810,male,solo,Michigan rap; Midwest hip-hop; trap music; gangsta rap,United States,American rapper
|
||||
4batz,Q124313062,male,solo,contemporary R&B,United States,American singer (born 2003)
|
||||
5 Seconds of Summer,Q4641147,,group,pop rock; pop-punk,Australia,Australian pop rock band
|
||||
50 Cent,Q6060,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop,United States,American rapper (born 1975)
|
||||
6ix9ine,Q44479972,male,solo,hip-hop; East Coast hip-hop; gangsta rap; trap metal; hardcore hip-hop; SoundCloud rap; punk rap; drill; trap music; urbano music; reggaeton; Brooklyn drill,United States,American rapper from New York (born 1996)
|
||||
6LACK,Q27886640,male,solo,alternative R&B; contemporary R&B; trap music; cloud rap; industrial music; soul; hip-hop soul,United States,American singer-songwriter and rapper (born 1992)
|
||||
A Boogie wit da Hoodie,Q27927826,male,solo,hip-hop; trap music,United States,American rapper (born 1995)
|
||||
A$AP Ferg,Q15648254,male,solo,East Coast hip-hop; trap music,United States,American rapper (born 1988)
|
||||
A$AP Rocky,Q129910,male,solo,East Coast hip-hop; psychedelic rap; experimental hip-hop; alternative hip-hop; cloud rap; trap music,United States,American rapper (born 1988)
|
||||
Adassa,Q576181,female,solo,reggaeton; urban contemporary; pop music,United States,American singer-songwriter
|
||||
Adele,Q23215,female,solo,pop music; blue-eyed soul; rhythm and blues; soul; jazz; rock music,United Kingdom,English singer-songwriter (born 1988)
|
||||
AJR,Q16154058,,group,indie pop; alternative pop; electropop,United States,American indie pop band
|
||||
Alessia Cara,Q20090091,female,solo,contemporary R&B; indie pop; pop music; soul; alternative R&B,Italy,"Italian-Canadian singer, songwriter and actress"
|
||||
Alex Warren,Q121842162,male,solo,pop music,United States,"American singer, songwriter, YouTuber, and influencer"
|
||||
Aminé,Q27830860,male,solo,West Coast hip-hop; alternative hip-hop; trap music; contemporary R&B,United States,"American rapper, singer, and songwriter"
|
||||
Anderson .Paak,Q20810369,male,solo,contemporary R&B; hip-hop; soul; funk; pop music,United States,"American singer, rapper, drummer, and record producer (born 1986)"
|
||||
Andrew Choi,Q15229870,male,solo,K-pop; pop music; contemporary R&B,South Korea,South Korean singer and songwriter
|
||||
Anne-Marie,Q25396976,female,solo,pop music; contemporary R&B,United Kingdom,British singer (born 1990)
|
||||
Aqua,Q213388,,group,pop music; bubblegum music; Eurodance,Denmark,Danish-Norwegian music group
|
||||
Ariana Grande,Q151892,female,solo,pop music; contemporary R&B; electronic dance music,United States,"American singer, songwriter, and actress (born 1993)"
|
||||
Arizona Zervas,Q75124792,male,solo,hip-hop; contemporary R&B; pop music,United States,American singer and rapper (born 1995)
|
||||
Artemas,Q125176874,male,solo,alternative pop,United Kingdom,British singer-songwriter and record producer
|
||||
ATR Son Son,Q140814072,male,solo,hip-hop,United States,American rapper
|
||||
Audrey Nuna,Q105538243,female,solo,K-pop; pop music; hip-hop; contemporary R&B; trap music,United States,South Korean-American singer and rapper
|
||||
Ava Max,Q56755505,female,solo,dance-pop,United States,American singer and songwriter (born 1994)
|
||||
Avery Anna,Q131401753,female,solo,pop rock; country music,United States,American singer
|
||||
Ayo,Q55860029,male,solo,hip-hop,United States,American singer and dancer
|
||||
AzChike,Q131417489,male,solo,hip-hop,United States,American rapper
|
||||
Bad Bunny,Q44333953,male,solo,Latin trap; reggaeton,Puerto Rico,"Puerto Rican rapper, singer, and record producer (born 1994)"
|
||||
Bailey Zimmerman,Q112581616,male,solo,country music,United States,American singer
|
||||
Bastille,Q689,,group,synth-pop,United Kingdom,English indie pop band
|
||||
Bazzi,Q48720231,male,solo,pop music,United States,American-born Lebanese singer-songwriter (born 1997)
|
||||
beabadoobee,Q66817366,female,solo,indie rock; space rock; alternative rock; slacker rock; indie pop; folk-pop; bedroom pop,Philippines,Filipino singer
|
||||
Bebe Rexha,Q16185856,female,solo,pop music; contemporary R&B,United States,American singer
|
||||
Becky G,Q1393997,female,solo,pop music; hip-hop; Latin music; Latin pop; reggaeton,United States,American singer and actress (born 1997)
|
||||
BENEE,Q61749159,female,solo,alternative pop; soul,New Zealand,New Zealand singer-songwriter
|
||||
benny blanco,Q818048,male,solo,pop music,United States,American pop music producer (born 1988)
|
||||
Benson Boone,Q110008128,male,solo,pop music; pop rock,United States,American singer
|
||||
Beyoncé,Q36153,female,solo,pop music; contemporary R&B; country music,United States,"American singer, songwriter, record producer, and dancer (born 1981)"
|
||||
Big Sean,Q367634,male,solo,hip-hop; Midwest hip-hop; Michigan rap; pop rap,United States,American rapper (born 1988)
|
||||
BigXthaPlug,Q124750337,male,solo,rapping; hip-hop,United States,American rapper
|
||||
Billie Eilish,Q29564107,female,solo,electropop; indie pop; alternative pop,United States,American singer-songwriter (born 2001)
|
||||
Billy Ray Cyrus,Q231259,male,solo,country music; country pop; country rock; country blues,United States,American country singer and actor
|
||||
Bipolar Sunshine,Q16727521,male,solo,pop music,United Kingdom,British musician
|
||||
Bizarrap,Q99937928,male,solo,Latin trap; reggaeton,Argentina,Argentine DJ and producer (born 1998)
|
||||
Black Eyed Peas,Q134541,,group,alternative hip-hop; pop rap; hip-hop; pop music; Latin hip-hop,United States,American hip hop group from California
|
||||
blackbear,Q22974007,male,solo,pop music; emo; contemporary R&B; hip-hop,United States,"American singer, songwriter, and record producer (born 1990)"
|
||||
Blake Shelton,Q94831,male,solo,country music,United States,American country music singer and television personality
|
||||
Blanco Brown,Q64736729,male,solo,country rap; trap music; hip-hop,United States,American rapper and singer
|
||||
BlocBoy JB,Q49481016,male,solo,hip-hop; trap music,United States,American rapper from Tennessee
|
||||
Blueface,Q60463134,male,solo,hip-hop; trap music; West Coast hip-hop; gangsta rap,United States,American rapper (born 1997)
|
||||
Bobby Helms,Q888554,male,solo,country music,United States,American male singer (1933–1997)
|
||||
Bomba Estéreo,Q887911,,group,cumbia,Colombia,Colombian band
|
||||
Bradley Cooper,Q205707,male,solo,,United States,American actor (born 1975)
|
||||
Brandon Lake,Q100314823,male,solo,contemporary Christian music; Christian rock,United States,American Christian musician
|
||||
Brenda Lee,Q230925,female,solo,rock and roll; country music; pop music; rockabilly,United States,American singer and recording artist (born 1944)
|
||||
Brendon Urie,Q1047474,male,solo,pop rock; alternative rock,United States,American singer and musician
|
||||
Brett Young,Q25189679,male,solo,country music,United States,American country musician
|
||||
BRS Kash,Q105409004,male,solo,hip-hop,United States,American rapper
|
||||
Bruno Mars,Q1450,male,solo,pop music; contemporary R&B; hip-hop; new wave; reggae; funk,United States,American singer-songwriter and record producer (born 1985)
|
||||
Bryson Tiller,Q21066641,male,solo,contemporary R&B; hip-hop; trap music; soul,United States,American singer and rapper (born 1993)
|
||||
BTS,Q13580495,,group,K-pop; dance-pop; Korean hip-hop,South Korea,South Korean musical group; boy band
|
||||
Burl Ives,Q315723,male,solo,folk music,United States,American musician (1909–1995)
|
||||
Calboy,Q66085272,male,solo,hip-hop,United States,American rapper (born 1999)
|
||||
Calvin Harris,Q81637,male,solo,electronic dance music; electronic pop; acid house,United Kingdom,Scottish electronic music producer and DJ (born 1984)
|
||||
Camila Cabello,Q18810940,female,solo,pop music; contemporary R&B; Latin pop; Gothic pop,Cuba,Cuban-Mexican-American singer
|
||||
Cardi B,Q29033668,female,solo,hip-hop; pop music; pop rap,United States,American rapper (born 1992)
|
||||
Carly Pearce,Q29913337,female,solo,country music,United States,American country music singer-songwriter
|
||||
Carolina Gaitán,Q5753201,female,solo,,Colombia,Colombian actress and singer
|
||||
Carrie Underwood,Q215546,female,solo,pop music; country music; country pop; country rock,United States,American singer and actor (born 1983)
|
||||
Cash Cobain,Q125989634,male,solo,hip-hop; drill; Jersey drill; pop rap; East Coast hip-hop; trap music,United States,American rapper and record producer
|
||||
Casper Mágico,Q60333702,male,solo,Latin trap; reggaeton,United States,Puerto Rican rapper
|
||||
Chance the Rapper,Q12470060,male,solo,hip-hop; alternative hip-hop; contemporary R&B; conscious hip-hop; alternative R&B; gospel music,United States,"American rapper, singer and record producer (born 1993)"
|
||||
Chappell Roan,Q110281146,female,solo,synth-pop; pop music; electronic music,United States,American singer (born 1998)
|
||||
Charlie Puth,Q19810390,male,solo,pop music; contemporary R&B,United States,"American singer, songwriter, and record producer"
|
||||
Chase Rice,Q5087189,male,solo,country music,United States,American singer-songwriter and football player
|
||||
Cheat Codes,Q23978754,,group,electronic music; electronic dance music; tropical house; dancehall,United States,electronic music DJ trio
|
||||
Chencho Corleone,Q113625582,male,solo,reggaeton,United States,Puerto Rican singer (born 1979)
|
||||
Childish Gambino,Q1239933,male,solo,hip-hop; funk; contemporary R&B; soul; psychedelic music; indie pop; comedy hip-hop,United States,"American actor, comedian, musician, and filmmaker (born 1983)"
|
||||
Chris Brown,Q155700,male,solo,contemporary R&B; pop music; hip-hop,United States,American singer and rapper (born 1989)
|
||||
Chris Stapleton,Q5108148,male,solo,country music,United States,American country musician
|
||||
Chris Young,Q952176,male,solo,country music,United States,American country music artist
|
||||
City Girls,Q60658858,,group,hip-hop,United States,American musical duo
|
||||
CJ,Q103868817,male,solo,drill; trap music; East Coast hip-hop; hip-hop,United States,American rapper
|
||||
CKay,Q98312451,male,solo,Afrobeats,Nigeria,Nigerian singer-songwriter
|
||||
Clean Bandit,Q11838808,,group,electropop,United Kingdom,English electronic music group
|
||||
Cody Johnson,Q17916913,male,solo,country music; country rock,United States,American country singer and songwriter
|
||||
Coi Leray,Q106376206,female,solo,hip-hop; pop music,United States,American rapper and singer
|
||||
Coldplay,Q45188,,group,alternative rock; pop music,United Kingdom,British rock band
|
||||
Cole Swindell,Q15101510,male,solo,country music,United States,American singer-songwriter
|
||||
Corey Kent,Q113452679,male,solo,country music,United States,American singer
|
||||
Cris MJ,Q111425015,male,solo,reggaeton,Chile,Chilean singer-songwriter
|
||||
D.R.A.M.,Q25138504,male,solo,Southern hip-hop; contemporary R&B; trap music,United States,American rapper and singer (born 1988)
|
||||
DaBaby,Q62107457,male,solo,hip-hop; trap music; pop rap; Southern hip-hop,United States,American rapper (born 1991)
|
||||
Daddy Yankee,Q272591,male,solo,reggaeton; Latin hip-hop,United States,Puerto Rican rapper and actor (born 1976)
|
||||
Daft Punk,Q185828,,group,house music; electronic music; French house; synth-pop; electronic rock; electronica; nu-disco; dance music; leftfield house,France,French electronic music band
|
||||
Dan Smyers,Q57630595,male,solo,country music,United States,songwriter and member of the duo Dan + Shay
|
||||
Daniel Caesar,Q29589083,male,solo,contemporary R&B; soul; neo soul,Canada,Canadian R&B singer
|
||||
Danny Chung,Q140814119,male,solo,hip-hop; K-pop,United States,"Korean-American rapper, singer and songwriter"
|
||||
Darell,Q56467651,male,solo,reggaeton; Latin trap,United States,Puerto Rican rapper and singer
|
||||
Dasha,Q125157260,female,solo,country pop,United States,American country singer-songwriter
|
||||
David Guetta,Q8298,male,solo,electronic dance music; house music; electroclash; electro house,France,French DJ and electronic music producer (born 1967)
|
||||
David Kushner,Q117745879,male,solo,,United States,American male singer-songwriter
|
||||
Daya,Q21005558,female,solo,pop music,United States,American singer
|
||||
dazy,Q140814120,male,solo,pop music,,Los Angeles-based record producer and musician
|
||||
Dean Lewis,Q29905254,male,solo,pop music,Australia,Australian singer-songwriter (born 1987)
|
||||
Demi Lovato,Q41173,genderfluid,solo,pop rock; pop music; contemporary R&B; power pop; dance-pop; teen pop; electropop; soul; pop-punk; nu metal,United States,"American singer, songwriter, and actress (born 1992)"
|
||||
Desiigner,Q23091498,male,solo,hip-hop; East Coast hip-hop; trap music; mumble rap; hardcore hip-hop,United States,American rapper and singer (born 1997)
|
||||
Diane Guerrero,Q17166318,female,solo,,United States,American actress
|
||||
Diplo,Q533781,male,solo,electronic dance music; trap music; hip-hop; pop music; moombahton; electropop; house music; EDM trap music,United States,American record producer (born 1978)
|
||||
DJ Khaled,Q80805,male,solo,hip-hop; pop rap,United States,American DJ and rapper (born 1975)
|
||||
DJ Snake,Q16728588,male,solo,electronic dance music; EDM trap music,France,French record producer (born 1986)
|
||||
Djo,Q27064031,male,solo,synth-pop,United States,American actor and musician (born 1992)
|
||||
DNCE,Q21648421,,group,pop rock,United States,American pop band
|
||||
Doechii,Q106629186,female,solo,hip-hop; contemporary R&B; pop music; alternative hip-hop; pop rap,United States,American rapper and singer
|
||||
Doja Cat,Q51120673,female,solo,contemporary R&B; pop music; electronic music; indie pop; hip-hop,United States,American singer and rapper (born 1995)
|
||||
Don Toliver,Q56513383,male,solo,hip-hop; trap music; contemporary R&B,United States,American singer and rapper (born 1994)
|
||||
Dove Cameron,Q13560423,female,solo,pop music; alternative pop; soul,United States,American actress and singer
|
||||
Drake,Q33240,male,solo,hip-hop; contemporary R&B; pop music; trap music,Canada,Canadian-American rapper and singer
|
||||
Dua Lipa,Q21914464,female,solo,pop music; post-disco; house music; funktronica; indie pop; dream pop; synth-pop,United Kingdom,British singer-songwriter (born 1995)
|
||||
Duncan Laurence,Q60758679,male,solo,pop music,Kingdom of the Netherlands,Dutch singer
|
||||
Dustin Lynch,Q5317118,male,solo,country music,United States,American singer
|
||||
Ed Sheeran,Q47447,male,solo,pop music; folk music; hip-hop; dance music; soul; rock music,United Kingdom,English singer-songwriter and guitarist (born 1991)
|
||||
EJAE,Q135108208,female,solo,K-pop; pop music; contemporary R&B,South Korea,South Korean-American singer and songwriter (born 1991)
|
||||
Ella Langley,Q127559972,female,solo,country music,United States,American country singer
|
||||
Ella Mai,Q29033458,female,solo,contemporary R&B,United Kingdom,British singer
|
||||
Elle King,Q5364665,female,solo,country music; Americana; blues rock; alternative country,United States,"American singer, songwriter, and actress"
|
||||
Ellie Goulding,Q31164,female,solo,synth-pop; electropop; indie pop; folktronica; alternative rock; alternative music; dream pop; indietronica,United Kingdom,English singer and songwriter (born 1986)
|
||||
Elton John,Q2808,male,solo,rock music; pop rock; glam rock; soft rock; rhythm and blues,United Kingdom,"British singer, songwriter and musician (born 1947)"
|
||||
Em Beihold,Q111333139,female,solo,pop music,United States,American singer-songwriter
|
||||
Emilee,Q98635221,female,solo,pop music,United States,"American singer, star of TikTok and influencer"
|
||||
Eminem,Q5608,male,solo,hip-hop; horrorcore; hardcore hip-hop; comedy hip-hop; Midwest hip-hop; rap rock,United States,"American rapper, record producer and actor"
|
||||
Encanto Cast,Q140814124,,,,United States,ensemble cast credited on songs from the 2021 Disney animated film Encanto
|
||||
Eric Church,Q975911,male,solo,country music,United States,American country singer
|
||||
ERNEST,Q110442717,male,solo,country music,United States,American hip hop and country musician
|
||||
Eslabón Armado,Q112702265,,group,regional Mexican,United States,American hispanic radio music group
|
||||
Fat Joe,Q309888,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop; boom bap; mafioso rap,United States,American rapper
|
||||
Fetty Wap,Q19361511,male,solo,hip-hop; trap music; pop rap,United States,American rapper and singer (born 1991)
|
||||
Fifth Harmony,Q3087893,,group,pop music,United States,American girl group
|
||||
Fifty Fifty,Q116731010,,group,K-pop; J-pop,South Korea,South Korean girl group
|
||||
Flipp Dinero,Q57584556,male,solo,hip-hop,United States,American rapper
|
||||
Flo Milli,Q89352069,female,solo,hip-hop,United States,American rapper
|
||||
Flo Rida,Q213538,male,solo,hip-hop; pop music; dance music; electronic dance music; Southern hip-hop; contemporary R&B; house music; electro hop; electro house; electropop; electro; EDM trap music; trap music; bass music; crunk; pop rap; dirty south; dance-pop; hip house; Miami bass; electronic music; techno; trance,United States,American rapper and singer (born 1979)
|
||||
Florida Georgia Line,Q3644642,,group,country music,United States,American country music duo
|
||||
FloyyMenor,Q125819969,male,solo,reggaeton,Chile,Chilean singer-songwriter
|
||||
Flume,Q4038837,male,solo,electronica; trip hop; future bass,Australia,Australian music producer
|
||||
Frank Ocean,Q357645,male,solo,alternative R&B; psychedelic soul; progressive soul; contemporary R&B; pop music; soul; hip-hop; avant-pop,United States,"American singer, songwriter, and rapper"
|
||||
French Montana,Q1455261,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop,Morocco,Moroccan and American rapper
|
||||
Fuerza Regida,Q118466501,,group,regional Mexican; banda music; corrido; corridos tumbados; sierreña; norteño,United States,regional Mexican group
|
||||
Future,Q3445057,male,solo,Southern hip-hop; trap music; mumble rap; contemporary R&B,United States,American rapper (born 1983)
|
||||
G-Eazy,Q5511893,male,solo,hip-hop,United States,American rapper
|
||||
Gabby Barrett,Q53912835,female,solo,country pop,United States,American country singer
|
||||
GAYLE,Q109768702,female,solo,pop-punk; pop rock; power pop; emo pop; alternative pop; alternative rock,United States,American singer-songwriter
|
||||
Gigi Perez,Q130235359,female,solo,indie folk,United States,American singer-songwriter
|
||||
Giveon,Q96418479,male,solo,contemporary R&B,United States,American R&B singer
|
||||
Glass Animals,Q16839267,,group,indie rock; psychedelic pop; indietronica; alternative pop; electronic rock; psychedelic rock,United Kingdom,English indie rock band
|
||||
GloRilla,Q114132368,female,solo,hip-hop; trap music; crunk; Memphis rap; Southern hip-hop,United States,American rapper
|
||||
gnash,Q23978226,male,solo,pop music; hip-hop; alternative R&B; indie folk,United States,American musician
|
||||
Gracie Abrams,Q106301562,female,solo,bedroom pop; pop music,United States,American singer-songwriter (born 1999)
|
||||
Grey,Q28451953,,group,electronic music; pop music; future bass,United States,American electronic music group consisting of brothers Kyle and Michael Trewartha
|
||||
Grupo Frontera,Q118141487,,group,regional Mexican; norteño; cumbia norteña mexicana,United States,Mexican-American musical band
|
||||
Gucci Mane,Q206032,male,solo,Southern hip-hop; trap music; gangsta rap; hardcore hip-hop; dirty south; Atlanta hip-hop; dirty rap,United States,American rapper and music executive (born 1980)
|
||||
Gunna,Q55613105,male,solo,hip-hop; trap music; Southern hip-hop; contemporary R&B,United States,American rapper (born 1993)
|
||||
Gus Dapperton,Q51858412,male,solo,pop music,United States,American singer-songwriter
|
||||
Gwen Stefani,Q483379,female,solo,pop music; contemporary R&B; ska; electronica; new wave; rock music,United States,American singer
|
||||
H.E.R.,Q30639849,female,solo,contemporary R&B,United States,American R&B singer
|
||||
Hailee Steinfeld,Q231726,female,solo,pop music; dance-pop,United States,American actress and singer-songwriter (born 1996)
|
||||
Halsey,Q18534249,female,solo,pop music; electropop; synth-pop; art pop; alternative pop; alternative rock; alternative R&B; indie pop; contemporary R&B,United States,American singer-songwriter (born 1994)
|
||||
HARDY,Q63341424,male,solo,country music,United States,American country singer
|
||||
Harry Styles,Q3626966,male,solo,soft rock; pop music; rock music; Britpop; traditional folk music,United Kingdom,"English singer, songwriter and actor"
|
||||
Hozier,Q16233232,male,solo,blues; blues rock; rhythm and blues; traditional folk music; soul; indie rock,Ireland,Irish musician and singer
|
||||
Hudson Westbrook,Q134125831,male,solo,country music,United States,American singer
|
||||
iann dior,Q65631841,male,solo,emo rap; pop rap; rap rock; pop rock,United States,American rapper and singer
|
||||
Ice Spice,Q114114977,female,solo,Bronx drill; hip-hop; East Coast hip-hop; Jersey club; pop rap,United States,American rapper (born 2000)
|
||||
Imagine Dragons,Q391348,,group,pop rock; electropop; alternative rock; new wave,United States,American pop rock band
|
||||
Infared,Q140814135,male,solo,hip-hop,,hip-hop songwriter and rapper featured on the 2016 single All the Way Up
|
||||
Internet Money,Q99691610,,,hip-hop,United States,American record label and record producer collective
|
||||
J Balvin,Q966845,male,solo,reggaeton; Latin pop; Latin trap,Colombia,Colombian singer
|
||||
J. Cole,Q204018,male,solo,hip-hop; Southern hip-hop; pop rap; East Coast hip-hop; conscious hip-hop,United States,American rapper and record producer (born 1985)
|
||||
Jack Harlow,Q59727812,male,solo,hip-hop; pop rap,United States,American rapper and singer (born 1998)
|
||||
Jake Scott,Q140814152,male,solo,pop music,United States,American singer-songwriter
|
||||
James Arthur,Q717626,male,solo,pop music,United Kingdom,British singer (born 1988)
|
||||
James Bay,Q17811637,male,solo,rock music; pop music; soul; Americana,United Kingdom,British singer-songwriter
|
||||
James Blake,Q350362,male,solo,pop music; electronica; post-dubstep; electronic dance music,United Kingdom,English singer-songwriter (born 1988)
|
||||
Jason Aldean,Q195439,male,solo,country music,United States,American country singer
|
||||
Jason Derulo,Q243639,male,solo,pop music; rhythm and blues; contemporary R&B; hip-hop,United States,American singer-songwriter
|
||||
Jawsh 685,Q96472235,male,solo,pop music,New Zealand,New Zealand music producer
|
||||
Jay Rock,Q152632,male,solo,West Coast hip-hop,United States,American rapper (born 1985)
|
||||
Jay Z,Q62766,male,solo,East Coast hip-hop; mafioso rap; gangsta rap; hardcore hip-hop,United States,"American rapper, record producer, and entrepreneur"
|
||||
Jelly Roll,Q6176881,male,solo,Southern hip-hop; country rap; country music; hardcore hip-hop,United States,American rapper (born 1984)
|
||||
Jeremih,Q472891,male,solo,contemporary R&B,United States,American R&B singer (born 1987)
|
||||
Jessica Darrow,Q109718598,non-binary,solo,,United States,American actor and singer
|
||||
Jessie Murph,Q122157373,female,solo,country rock; country pop; pop music,United States,American singer
|
||||
Jhay Cortez,Q75997191,male,solo,Latin trap; reggaeton; Latin R&B,United States,Puerto Rican singer
|
||||
Jhené Aiko,Q15929781,female,solo,hip-hop; pop music; rhythm and blues; soul; alternative R&B; neo soul; contemporary R&B,United States,American R&B singer (born 1988)
|
||||
JID,Q29588830,male,solo,hip-hop,United States,"American rapper, singer, and songwriter from Georgia"
|
||||
Jimin,Q20947093,male,solo,K-pop,South Korea,South Korean singer and dancer (BTS)
|
||||
JNR CHOI,Q111507858,male,solo,hip-hop; trap music; world music,United Kingdom,Gambian-British rapper and singer
|
||||
John Legend,Q44857,male,solo,soul; pop music; contemporary R&B,United States,American singer-songwriter
|
||||
Joji,Q23826617,male,solo,contemporary R&B; alternative R&B; trip hop; lo-fi music; surreal humour; satirical music; satire; comedy hip-hop; black comedy; alternative rock; comedy music,Japan,Japanese-Australian entertainer (born 1992)
|
||||
Jon Bellion,Q18044284,male,solo,pop music; contemporary R&B; hip-hop; indie rock; pop rap; alternative hip-hop; indie pop; alternative rock; dance-pop; soul,United States,"American singer, rapper, songwriter, and record producer"
|
||||
Jon Pardi,Q6271354,male,solo,country music,United States,American country singer
|
||||
Jonas Brothers,Q134233,,group,pop music; pop rock,United States,American pop rock band
|
||||
Jordan Davis,Q44274417,male,solo,country pop; country music; pop music,United States,American country music singer and songwriter
|
||||
JP Saxe,Q86009464,male,solo,pop music,Canada,Canadian singer and musician
|
||||
Juice WRLD,Q52151598,male,solo,hip-hop; emo rap; alternative rock; trap music; pop rap; SoundCloud rap; contemporary R&B; alternative hip-hop; mumble rap,United States,American rapper and singer (1998–2019)
|
||||
Juicy J,Q602779,male,solo,Southern hip-hop; gangsta rap; trap music; dirty rap; Memphis rap; dirty south; horrorcore; hardcore hip-hop; crunk,United States,American record producer and rapper (born 1975)
|
||||
Julia Michaels,Q20051697,female,solo,pop music; electronic dance music,United States,American singer and songwriter (born 1993)
|
||||
Jung Kook,Q22338877,male,solo,K-pop,South Korea,South Korean singer
|
||||
Justin Bieber,Q34086,male,solo,pop music; contemporary R&B; tropical house; reggaeton; contemporary country,Canada,Canadian singer-songwriter (born 1994)
|
||||
Justin Timberlake,Q43432,male,solo,pop music; contemporary R&B,United States,American singer and actor (born 1981)
|
||||
JVKE,Q114865231,male,solo,pop music,United States,American singer and producer
|
||||
Kacey Musgraves,Q2783855,female,solo,country music; folk music,United States,American singer (born 1988)
|
||||
Kai,Q6347342,female,solo,pop music,Canada,Canadian singer and songwriter
|
||||
Kali Uchis,Q19004484,female,solo,contemporary R&B,United States,American singer and songwriter (born 1994)
|
||||
Kaliii,Q115633164,female,solo,hip-hop; trap music; Southern hip-hop,United States,American rapper
|
||||
Kane Brown,Q21620939,male,solo,country music,United States,American country music singer
|
||||
Kanye West,Q15935,male,solo,hip-hop; pop music; electro; soul; gospel music; progressive rap; art pop; pop rap; hip-hop soul; chipmunk soul; contemporary R&B,United States,American rapper and record producer
|
||||
Karol G,Q22001324,female,solo,reggaeton; Latin pop; Latin R&B,Colombia,Colombian singer and songwriter
|
||||
Kate Bush,Q636,female,solo,art pop; progressive pop; singer-songwriter music; baroque pop; experimental pop; art rock; pop rock,United Kingdom,"English singer, pianist and songwriter (born 1958)"
|
||||
Katelyn Brown,Q140814175,female,solo,pop music,United States,American singer
|
||||
Katy Perry,Q42493,female,solo,pop music; rock music; pop rock; dance music; synth-pop; electropop; gospel music,United States,American singer
|
||||
Kehlani,Q20657541,non-binary,solo,contemporary R&B; pop music; neo soul; hip-hop,United States,American singer-songwriter (born 1995)
|
||||
Keith Urban,Q315547,male,solo,country music,Australia,Australian-American musician
|
||||
Kendrick Lamar,Q130798,male,solo,West Coast hip-hop; progressive rap; alternative hip-hop; jazz rap; conscious hip-hop; gangsta rap; hardcore hip-hop; jazz; pop music,United States,American rapper (born 1987)
|
||||
Kenny Chesney,Q467526,male,solo,country music,United States,American country musician
|
||||
Kent Jones,Q25190082,male,solo,pop rap; contemporary R&B; pop music,United States,American singer and rapper (born 1993)
|
||||
Kesha,Q33605,female,solo,electropop; dance-pop; synth-pop; pop rock; pop rap; rock music; dance music; country music,United States,American singer and songwriter (born 1987)
|
||||
Kevin Gates,Q6396353,male,solo,hip-hop; gangsta rap; hardcore hip-hop; dirty south; Southern hip-hop,United States,American rapper
|
||||
Kevin Woo,Q6397789,male,solo,K-pop,United States,Korean-American singer
|
||||
Khalid,Q28816483,male,solo,contemporary R&B,United States,American singer (born 1998)
|
||||
Kid Cudi,Q299138,male,solo,Midwest hip-hop; contemporary R&B; alternative hip-hop; pop rap; alternative rock; trip hop; neo-psychedelia; punk rock; grunge; emo rap; psychedelic rap; psychedelic hip-hop,United States,"American rapper, singer, record producer and actor (born 1984)"
|
||||
Kiiara,Q23042767,female,solo,pop music; electropop; alternative R&B; experimental pop,United States,American singer and songwriter
|
||||
Kim Petras,Q60964,trans woman,solo,pop music,Germany,German singer
|
||||
Kodak Black,Q22005867,male,solo,hip-hop; trap music; SoundCloud rap; gangsta rap; Southern hip-hop; mumble rap,United States,American rapper (born. 1997)
|
||||
Koe Wetzel,Q107434048,male,solo,country music; rock music,United States,American musician
|
||||
Kygo,Q16845512,male,solo,tropical house; deep house; downtempo; progressive house; house music; electronic dance music,Norway,Norwegian DJ and music producer
|
||||
Kyla,Q25190133,female,solo,UK funky,United Kingdom,British singer
|
||||
KYLE,Q28606665,male,solo,West Coast hip-hop; pop rap,United States,American rapper and singer
|
||||
Lady Gaga,Q19848,female,solo,electropop; dance-pop; electronic dance music; art pop; pop music; synth-pop,United States,"American singer, songwriter, and actress (born 1986)"
|
||||
Lainey Wilson,Q106378786,female,solo,country music; folk music,United States,American singer-songwriter
|
||||
Latto,Q65029930,female,solo,hip-hop; trap music; pop music; pop rap,United States,American rapper (born 1998)
|
||||
Lauren Alaina,Q271796,female,solo,country music; folk music,United States,American singer & songwriter (born 1994)
|
||||
Lauren Daigle,Q18685595,female,solo,contemporary Christian music,United States,American singer and songwriter (born 1991)
|
||||
Lauren Spencer-Smith,Q110630787,female,solo,pop music,Canada,Canadian singer and songwriter
|
||||
Lauv,Q30122224,male,solo,electronic music; pop music,United States,American musician
|
||||
Lee Brice,Q1811729,male,solo,country music,United States,American country singer
|
||||
Lefty Gunplay,Q131374668,male,solo,hip-hop; West Coast hip-hop; gangsta rap,United States,American rapper
|
||||
Leon Thomas,Q714375,male,solo,contemporary R&B; pop music; soul; hip-hop,United States,"American actor, singer, songwriter and producer"
|
||||
Lewis Capaldi,Q42315001,male,solo,blue-eyed soul; pop music; pop rock; alternative rock; soft rock,United Kingdom,Scottish singer-songwriter (born 1996)
|
||||
Liam Payne,Q2756349,male,solo,pop music; contemporary R&B,United Kingdom,English singer and songwriter (1993–2024)
|
||||
Lil Baby,Q50527563,male,solo,hip-hop; trap music; Southern hip-hop,United States,American rapper (born 1994)
|
||||
Lil Dicky,Q16876006,male,solo,hip-hop; pop rap; comedy hip-hop,United States,American rapper and comedian (born 1988)
|
||||
Lil Durk,Q2899818,male,solo,Midwest hip-hop; trap music; drill; gangsta rap; hardcore hip-hop; Chicago hip-hop; Chicago drill,United States,American rapper
|
||||
Lil Mosey,Q55819454,male,solo,hip-hop; pop rap; trap music,United States,American rapper and singer-songwriter
|
||||
Lil Nas X,Q62591281,male,solo,hip-hop; pop rap; country rap; trap music; pop music; rock music; pop rock; country music; Southern hip-hop,United States,"American rapper, singer and songwriter (born 1999)"
|
||||
Lil Pump,Q38002101,male,solo,hip-hop; trap music; SoundCloud rap; punk rap; Southern hip-hop,United States,American rapper
|
||||
Lil Tecca,Q65054660,male,solo,hip-hop; trap music,United States,American rapper and singer-songwriter
|
||||
Lil Tjay,Q61670761,male,solo,hip-hop,United States,American rapper
|
||||
Lil Uzi Vert,Q23771950,non-binary,solo,hip-hop; emo rap; trap music; SoundCloud rap; punk rap; psychedelic rap; rage; cloud rap; psychedelic hip-hop; East Coast hip-hop,United States,American rapper
|
||||
Lil Wayne,Q15615,male,solo,Southern hip-hop; bounce music; gangsta rap; trap music; pop rap; dirty south; hardcore hip-hop,United States,American rapper and singer
|
||||
Lil Yachty,Q23772141,male,solo,hip-hop; trap music; pop rap; mumble rap; cloud rap; Southern hip-hop,United States,American rapper and singer
|
||||
Lizzo,Q16232225,female,solo,hip-hop; soul; contemporary R&B; gospel music,United States,American singer and rapper (born 1988)
|
||||
Logic,Q6667429,male,solo,hip-hop; pop rap; conscious hip-hop; East Coast hip-hop,United States,American rapper from Maryland
|
||||
Lola Young,Q115869427,female,solo,pop music; soul; contemporary R&B,United Kingdom,British singer-songwriter (born 2001)
|
||||
Luis Fonsi,Q1387726,male,solo,pop music; Latin pop; ballad; reggaeton,United States,Puerto Rican singer
|
||||
Lukas Graham,Q300935,,group,soul; pop music; pop rock; funk,Denmark,Danish band
|
||||
Luke Bryan,Q166197,male,solo,country music,United States,American country music singer
|
||||
Luke Combs,Q23884740,male,solo,country music,United States,American country singer
|
||||
Machine Gun Kelly,Q1354843,male,solo,hip-hop; pop rap; rap rock; pop-punk; alternative rock; alternative hip-hop,United States,American musician (born 1990)
|
||||
Maddie,Q54607228,female,solo,country music,United States,"Singer, part of Maddie & Tae"
|
||||
Mae Muller,Q83696883,female,solo,pop music; rhythm and blues,United Kingdom,British singer
|
||||
Major Lazer,Q2604214,,group,dancehall; moombahton; reggae fusion; trap music; electronic dance music; hip-hop; electro house; rocksteady,United States,Jamaican-American electronic music band
|
||||
Maren Morris,Q21622122,female,solo,country music; country pop; folk rock; folk music,United States,American country singer
|
||||
Mariah Carey,Q41076,female,solo,contemporary R&B; pop music; adult contemporary music; dance-pop; hip-hop,United States,American singer (born 1969)
|
||||
Mariah the Scientist,Q84356665,female,solo,alternative R&B,United States,American singer (born 1997)
|
||||
Marian Hill,Q20858093,,group,electronic music,United States,American musical duo
|
||||
Maroon 5,Q182223,,group,alternative rock; funk rock; pop rock; pop music,United States,American pop rock band
|
||||
Marshmello,Q26334949,male,solo,electronic dance music,United States,American DJ and electronic music producer (born 1992)
|
||||
Masked Wolf,Q105490126,male,solo,hip-hop,Australia,Australian rapper
|
||||
Mauro Castillo,Q16605580,male,solo,salsa,Colombia,"Colombian singer, composer, and actor"
|
||||
MAX,Q1190160,male,solo,pop music,United States,American singer
|
||||
Meek Mill,Q1897911,male,solo,East Coast hip-hop; hardcore hip-hop; gangsta rap; trap music; hip-hop,United States,American rapper
|
||||
Megan Moroney,Q116786312,female,solo,country music; folk music,United States,American country music singer
|
||||
Megan Thee Stallion,Q59268408,female,solo,hip-hop; trap music; dirty rap; pop rap; pop music,United States,"American rapper, singer and songwriter"
|
||||
Meghan Trainor,Q17403494,female,solo,pop music; contemporary R&B; dance-pop; soul; doo-wop,United States,American singer-songwriter (born 1993)
|
||||
Metro Boomin,Q16235273,male,solo,hip-hop; trap music,United States,American record producer (born 1993)
|
||||
Migos,Q15777045,,group,Southern hip-hop; trap music; mumble rap,United States,American hip hop group
|
||||
Miguel,Q73463,male,solo,contemporary R&B; alternative R&B; hip-hop; pop music; soul,United States,American R&B singer
|
||||
Mike Posner,Q268284,male,solo,pop music,United States,American musician
|
||||
Miley Cyrus,Q4235,genderfluid,solo,pop music; country music; pop rock; dance-pop; electropop; rock music; hip-hop; teen pop; country pop,United States,"American singer, actress, and television personality (born 1992)"
|
||||
Miranda Lambert,Q231233,female,solo,country music; folk music,United States,American country singer
|
||||
MNEK,Q6716905,male,solo,pop music,United Kingdom,British singer
|
||||
Moneybagg Yo,Q38459032,male,solo,hip-hop; trap music; gangsta rap; Memphis rap; Southern hip-hop,United States,American rapper from Tennessee
|
||||
Mooski,Q113554625,male,solo,hip-hop,United States,Musical artist
|
||||
Morgan Wallen,Q29561472,male,solo,country music; country pop; bro-country; country rap,United States,American country singer
|
||||
Muni Long,Q7245622,female,solo,contemporary R&B; pop music,United States,American singer
|
||||
Murda Beatz,Q27970613,male,solo,hip-hop,Canada,Canadian record producer (born 1994)
|
||||
Mustard,Q15941115,male,solo,hip-hop; ratchet music; West Coast hip-hop; contemporary R&B,United States,American record producer
|
||||
Myles Smith,Q126076580,male,solo,folk-pop; folk music; pop music; folk rock,United Kingdom,British singer
|
||||
Måneskin,Q56884561,,group,pop rock; glam rock,Italy,Italian rock band
|
||||
MØ,Q10670047,female,solo,indie pop; electronic music,Kingdom of Denmark,Danish singer and songwriter
|
||||
N*E*R*D,Q941293,,group,funk rock; bossa nova; orchestral pop; hip-hop; skate punk,United States,American rock and hip-hop band
|
||||
Natanael Cano,Q104904549,male,solo,corridos tumbados; regional Mexican,Mexico,Mexican rapper and singer
|
||||
Nate Smith,Q110707312,male,solo,country music; country rock,United States,"American country music singer, musician and songwriter"
|
||||
NAV,Q28831246,male,solo,hip-hop; cloud rap; trap music; contemporary R&B,Canada,"Canadian rapper, singer, and record producer (born 1989)"
|
||||
Neckwav,Q140814188,male,solo,contemporary R&B,South Korea,South Korean R&B singer
|
||||
NEIKED,Q26703294,,group,,Sweden,Swedish artist collective
|
||||
Nelly,Q218992,male,solo,Midwest hip-hop; pop rap; contemporary R&B; pop music; country rap; country music,United States,"American rapper, singer and actor (born 1974)"
|
||||
Netón Vega,Q129208676,male,solo,regional Mexican; corridos tumbados,Mexico,Mexican singer-songwriter
|
||||
NF,Q19571648,male,solo,hip-hop,United States,American rapper from Michigan
|
||||
Niall Horan,Q775231,male,solo,pop music; pop rock; folk-pop,Ireland,Irish singer-songwriter
|
||||
Nick Jonas,Q201656,male,solo,pop music; rock music; contemporary R&B,United States,"American singer, actor and musician"
|
||||
Nicki Minaj,Q162202,female,solo,hip-hop; pop music; contemporary R&B; trap music; dance music,Trinidad and Tobago,Trinidadian rapper (born 1982)
|
||||
Nicky Jam,Q1374560,male,solo,reggaeton; Latin trap,United States,American singer
|
||||
Nicky Youre,Q112666811,male,solo,indie pop,United States,American singer-songwriter
|
||||
Niko Moon,Q67399825,male,solo,country music,United States,musical artist
|
||||
Nio García,Q107358694,male,solo,Latin trap; reggaeton,United States,Puerto Rican singer
|
||||
NLE Choppa,Q64009351,male,solo,trap music; hip-hop; drill; Memphis rap; gangsta rap; Southern hip-hop,United States,American rapper from Tennessee (born 2002)
|
||||
Noah Kahan,Q53832755,male,solo,folk-pop,United States,American singer-songwriter (born 1997)
|
||||
Normani,Q28148022,female,solo,pop music; contemporary R&B,United States,American singer and dancer
|
||||
O.T. Genasis,Q18623749,male,solo,hip-hop; trap music,United States,American rapper
|
||||
Offset,Q30612480,male,solo,hip-hop; trap music; Southern hip-hop,United States,American rapper
|
||||
Old Dominion,Q20685018,,group,country pop,United States,American country pop music group (2007–)
|
||||
Oliver Anthony Music,Q121391237,male,solo,country music; folk music,United States,American singer-songwriter
|
||||
Olivia O'Brien,Q23978275,female,solo,dance-pop; pop music,United States,American singer
|
||||
Olivia Rodrigo,Q63243883,female,solo,indie pop; pop music; rock music,United States,American singer and actress (born 2003)
|
||||
One Direction,Q146027,,group,dance-pop; teen pop; pop rock,United Kingdom,English-Irish musical group; boy band
|
||||
OneRepublic,Q1438730,,group,pop rock; alternative rock; cello rock,United States,American pop rock band
|
||||
Ozuna,Q28739901,male,solo,reggaeton; Latin trap; Latin pop; dancehall,United States,Puerto Rican singer
|
||||
P!nk,Q160009,female,solo,pop music; pop rock; contemporary R&B,United States,"American singer, songwriter, and actress (born 1979)"
|
||||
Panic! At The Disco,Q277551,,group,pop rock; synth-pop; pop-punk; baroque pop; emo pop; alternative rock,United States,American musical group; rock solo project band
|
||||
Parker McCollum,Q20684755,male,solo,Americana; country music,United States,American musician
|
||||
Parmalee,Q7139162,,group,country music,United States,American country music band
|
||||
PARTYNEXTDOOR,Q15929398,male,solo,Canadian hip-hop; alternative R&B,Canada,Canadian singer (born 1993)
|
||||
Paul Russell,Q122932071,male,solo,hip-hop; contemporary R&B; pop rap,United States,American singer
|
||||
Peso Pluma,Q117242724,male,solo,regional Mexican; corridos tumbados; reggaeton; Latin trap; cumbia norteña mexicana,Mexico,Mexican singer (born 1999)
|
||||
Pharrell Williams,Q14313,male,solo,contemporary R&B; hip-hop; pop music; funk; rock music; pop rap,United States,American record producer and songwriter
|
||||
Pinkfong,Q55735607,,,children's music,South Korea,Korean children's entertainment brand
|
||||
PinkPantheress,Q107570416,female,solo,pop music; bedroom pop; dance music; alternative pop; drum and bass; 2-step garage; jungle; hyperpop,United Kingdom,British singer-songwriter
|
||||
Playboi Carti,Q27671080,male,solo,Southern hip-hop; trap music; mumble rap; cloud rap; rage; punk rap; alternative hip-hop; plugg music; lo-fi music; SoundCloud rap,United States,American rapper
|
||||
PnB Rock,Q28155029,male,solo,hip-hop; contemporary R&B; trap music; pop music; pop rap,United States,American rapper (1991–2022)
|
||||
Polo G,Q62953486,male,solo,hip-hop; drill; trap music; conscious hip-hop; Midwest hip-hop; Chicago hip-hop,United States,American rapper
|
||||
Pooh Shiesty,Q105105274,male,solo,trap music; Southern hip-hop; drill; hardcore hip-hop; gangsta rap; Memphis rap,United States,American rapper from Tennessee (born. 1999)
|
||||
Pop Smoke,Q81698554,male,solo,East Coast hip-hop; Brooklyn drill; trap music; gangsta rap; drill; hip-hop,United States,American rapper (1999–2020)
|
||||
Portugal. The Man,Q606879,,group,pop music; indie rock,United States,American rock band
|
||||
Post Malone,Q21621919,male,solo,hip-hop; pop music; country music,United States,American musician (born 1995)
|
||||
Powfu,Q89069821,male,solo,hip-hop; lo-fi music; power pop; rock music,Canada,Canadian rapper and singer
|
||||
Project Pat,Q593741,male,solo,Memphis rap; gangsta rap; hardcore hip-hop; Southern hip-hop; crunk; dirty south; trap music; horrorcore,United States,American rapper
|
||||
Quavo,Q30072039,male,solo,hip-hop; trap music,United States,American rapper
|
||||
Rae Sremmurd,Q18123226,,group,hip-hop; trap music; pop music; pop rap,United States,American hip hop duo
|
||||
Rauw Alejandro,Q61586861,male,solo,contemporary R&B; urban contemporary; Latin R&B; reggaeton; Latin trap; Latin pop; salsa,United States,Puerto Rican singer and songwriter
|
||||
Ravyn Lenae,Q28962463,female,solo,contemporary R&B; alternative R&B; neo soul,United States,American singer
|
||||
RAYE,Q28071144,female,solo,contemporary R&B,United Kingdom,British singer-songwriter
|
||||
REI AMI,Q104842557,female,solo,K-pop; pop music; hip-hop; contemporary R&B,South Korea,South Korean singer and rapper
|
||||
Rema,Q65071082,male,solo,Afrobeats,Nigeria,Nigerian singer-songwriter and rapper (2000–)
|
||||
Remy Boyz,Q63405888,,group,hip-hop,United States,musical group
|
||||
Remy Ma,Q275437,female,solo,East Coast hip-hop,United States,American rapper
|
||||
Rhenzy Feliz,Q34344805,male,solo,,United States,American actor
|
||||
Rich The Kid,Q18637908,male,solo,hip-hop; trap music; mumble rap; plugg music; Southern hip-hop,United States,American rapper
|
||||
Rick Ross,Q297831,male,solo,Southern hip-hop; gangsta rap; mafioso rap; trap music; hardcore hip-hop; dirty south,United States,American rapper and record executive
|
||||
Rihanna,Q36844,female,solo,pop music; dancehall; contemporary R&B; electronic dance music; adult contemporary music,Barbados,Barbadian singer (born 1988)
|
||||
Riley Green,Q57418818,male,solo,country music,United States,American singer/songwriter
|
||||
Ritt Momney,Q105105308,male,solo,folk music; indie pop; synth-pop,United States,American singer-songwriter from Utah
|
||||
Rod Wave,Q78754352,male,solo,hip-hop; contemporary R&B; soul; trap music,United States,American rapper and singer-songwriter (born 1998)
|
||||
Roddy Ricch,Q59209423,male,solo,West Coast hip-hop; trap music; pop rap; gangsta rap; hardcore hip-hop; hip-hop,United States,American rapper (born 1998)
|
||||
ROSÉ,Q27655344,female,solo,K-pop; dance-pop; hip-hop; electronic dance music,New Zealand,South Korean-New Zealand singer (born 1997)
|
||||
Rozes,Q22955580,female,solo,pop music; dance music; electronic dance music,United States,American singer
|
||||
Russell Dickerson,Q24572267,male,solo,country music,United States,American country singer-songwriter
|
||||
Ruth B,Q22056665,female,solo,pop music,Canada,Canadian singer-songwriter
|
||||
Ryan Hurd,Q42224127,male,solo,country music,United States,American country singer
|
||||
Sabrina Carpenter,Q7396400,female,solo,pop music; teen pop; dance-pop; contemporary R&B; electropop; country pop,United States,American singer-songwriter and actress (born 1999)
|
||||
SAINt JHN,Q52274581,male,solo,hip-hop; trap music; contemporary R&B,United States,Guyanese-American rapper and singer
|
||||
Sam Barber,Q124428137,male,solo,country music,United States,American singer-songwriter
|
||||
Sam Hunt,Q16223171,male,solo,country music,United States,American singer and songwriter
|
||||
Sam Smith,Q15123969,non-binary,solo,soul; contemporary R&B; pop music; rhythm and blues,United Kingdom,British singer-songwriter
|
||||
Sam Tompkins,Q112155955,male,solo,pop music,United Kingdom,British singer-songwriter
|
||||
samUIL Lee,Q140814222,male,solo,J-pop,South Korea,"South Korean singer, songwriter and record producer"
|
||||
Saweetie,Q50486592,female,solo,hip-hop,United States,American rapper (born 1993)
|
||||
Scotty McCreery,Q255969,male,solo,country music,United States,American country music singer
|
||||
Sean Paul,Q200577,male,solo,dancehall; pop music,Jamaica,Jamaican dancehall singer and rapper (born 1973)
|
||||
Selena Gomez,Q83287,female,solo,pop music; dance-pop; electropop; pop rock; contemporary R&B; alternative R&B,United States,American singer and actress (born 1992)
|
||||
Sexyy Red,Q119842023,female,solo,hip-hop; trap music; dirty rap; Midwest hip-hop,United States,American rapper (born 1998)
|
||||
Shaboozey,Q125295750,male,solo,alternative country; country music; hip-hop; Americana,United States,American singer (born 1995)
|
||||
SHAED,Q60643444,,group,electropop; indie pop,United States,American musical group
|
||||
Shakira,Q34424,female,solo,pop music; Latin pop; pop rock; Latin rock; dance music; folk music; world music; contemporary R&B; rock music,Spain,"Colombian singer, songwriter, and actress"
|
||||
Shawn Mendes,Q17198340,male,solo,folk-pop; pop music; pop rock,Canada,Canadian singer
|
||||
Shay Mooney,Q116536996,male,solo,country music,United States,"American musician and songwriter, part of Dan + Shay"
|
||||
Sheck Wes,Q56513324,male,solo,East Coast hip-hop; trap music,United States,American rapper (born 1998)
|
||||
Sia,Q181484,female,solo,electropop; indie pop,Australia,Australian singer and songwriter (born 1975)
|
||||
Silentó,Q20354248,male,solo,hip-hop; pop rap; trap music; comedy hip-hop; snap music; pop music,United States,American rapper and singer (born 1998)
|
||||
Skip Marley,Q21621948,male,solo,reggae; pop music; hip-hop; rock music,Jamaica,Jamaican singer and songwriter
|
||||
Snow,Q94708,male,solo,dancehall; reggae; hip-hop; reggae fusion,Canada,Canadian dancehall rapper (born 1969)
|
||||
Social House,Q65117469,,group,pop music,United States,American pop duo
|
||||
sombr,Q133444448,male,solo,alternative pop; bedroom pop,United States,American singer-songwriter
|
||||
SpotemGottem,Q105105325,male,solo,mumble rap; trap music; drill; Southern hip-hop,United States,American rapper
|
||||
StaySolidRocky,Q95918251,male,solo,hip-hop,United States,American rapper
|
||||
Stephanie Beatriz,Q16832110,female,solo,,United States,Argentine-American actress
|
||||
Stephen Sanchez,Q113023532,male,solo,pop music,United States,American singer-songwriter
|
||||
Steve Lacy,Q56733980,male,solo,alternative R&B,United States,"American singer, songwriter, guitarist, and record producer (born 1998)"
|
||||
Summer Walker,Q61959478,female,solo,contemporary R&B,United States,American R&B singer
|
||||
Surf Mesa,Q93771412,male,solo,tropical house,United States,American record producer and multi-instrumentalist
|
||||
Surfaces,Q76330429,,group,pop music,United States,American musical duo
|
||||
Swae Lee,Q30103025,male,solo,hip-hop; trap music,United States,American rapper and singer-songwriter (born 1993)
|
||||
SZA,Q16210722,female,solo,contemporary R&B; alternative R&B; neo soul; pop music; hip-hop,United States,American singer
|
||||
Tae,Q54607285,female,solo,country music,United States,"Singer, part of Maddie & Tae"
|
||||
Tate McRae,Q95129121,female,solo,pop music; alternative pop; dance-pop,Canada,"Canadian singer, songwriter, and dancer"
|
||||
Taylor Swift,Q26876,female,solo,pop music; country music,United States,American singer-songwriter (born 1989)
|
||||
Teddy Swims,Q105542333,male,solo,country music; pop music; rhythm and blues; soul,United States,American singer-songwriter
|
||||
Tems,Q72759173,female,solo,alternative R&B; Afrobeats,Nigeria,Nigerian singer-songwriter (born 1995)
|
||||
Teo,Q55860035,male,solo,hip-hop,United States,American singer and dancer
|
||||
The Chainsmokers,Q7721993,,group,electronic dance music,United States,American electronic music duo
|
||||
The Kid LAROI,Q82890761,male,solo,Australian hip-hop; contemporary R&B; pop music; emo rap,Australia,Australian rapper and singer (born 2003)
|
||||
The Marías,Q85807852,,group,indie pop; psychedelic soul; dream pop; synth-pop,United States,American band
|
||||
The Weeknd,Q2121062,male,solo,alternative R&B; pop music; electropop,Canada,Canadian singer and songwriter (born 1990)
|
||||
Thomas Rhett,Q7793491,male,solo,country music,United States,American country singer
|
||||
Tim McGraw,Q356487,male,solo,country music,United States,American country singer and actor (born 1967)
|
||||
Tommy Richman,Q125778611,male,solo,pop rap; contemporary R&B,United States,American singer
|
||||
Tones And I,Q62887629,female,solo,indie pop; electronic dance music; pop music,Australia,"Australian singer, songwriter and record producer"
|
||||
Toosii,Q106725126,male,solo,hip-hop,United States,American rapper from New York
|
||||
Tory Lanez,Q18353558,male,solo,hip-hop; contemporary R&B,Canada,Canadian rapper and singer (born 1992)
|
||||
Tove Lo,Q15948790,female,solo,pop music; indie pop; synth-pop; electropop,Sweden,Swedish singer
|
||||
Travis Scott,Q13605596,male,solo,hip-hop; trap music; pop rap; psychedelic rap; rock music; Southern hip-hop; contemporary R&B; psychedelic music; pop rock; alternative rock; alternative hip-hop; alternative R&B; psychedelic rock; psychedelic hip-hop,United States,"American rapper, singer and record producer"
|
||||
Trevor Daniel,Q81738417,male,solo,contemporary R&B; pop music,United States,American singer-songwriter
|
||||
Tucker Wetmore,Q124754909,male,solo,country music,United States,American country music artist
|
||||
twenty one pilots,Q7857806,,group,reggae; alternative rock; electropop; alternative hip-hop; rap rock; indie pop; pop rock,United States,American musical duo
|
||||
Ty Dolla $ign,Q7859785,male,solo,contemporary R&B; West Coast hip-hop; trap music; hip-hop,United States,American singer and rapper (born 1982)
|
||||
Tyga,Q358087,male,solo,West Coast hip-hop; pop rap,United States,American rapper
|
||||
Tyla,Q118105408,female,solo,contemporary R&B; pop music; Amapiano; new jack swing,South Africa,South African singer-songwriter
|
||||
Tyler Cole,Q140814245,male,solo,,United States,"American singer, songwriter and record producer"
|
||||
Tyler Hubbard,Q20740966,male,solo,country music,United States,American singer
|
||||
"Tyler, The Creator",Q167635,male,solo,alternative hip-hop; neo soul; West Coast hip-hop; jazz rap; hardcore hip-hop; horrorcore,United States,American rapper and record producer (born 1991)
|
||||
Usher,Q165911,male,solo,contemporary R&B; pop music; soul; hip-hop; dance music; dance-pop; crunk,United States,American R&B singer (born 1978)
|
||||
Victoria Monét,Q19864989,female,solo,pop music; contemporary R&B; hip-hop,United States,American singer and songwriter (born 1989)
|
||||
Walker Hayes,Q7962267,male,solo,country music,United States,American musician
|
||||
Warren Zeiders,Q120986980,male,solo,country music,United States,American country musician
|
||||
Wham!,Q744087,,group,pop music; new wave; blue-eyed soul,United Kingdom,British pop band
|
||||
WILLOW,Q298209,female,solo,indie pop; alternative R&B; experimental pop; neo soul; hip-hop; electronic dance music; pop music; dream pop; contemporary R&B; rock music; indie rock; progressive rock; pop-punk; alternative rock; alternative pop; jazz,United States,American singer and actress (born 2000)
|
||||
Willy William,Q17016749,male,solo,house music; reggaeton; zouk,France,"French DJ, record producer, and singer (born 1981)"
|
||||
Wiz Khalifa,Q117139,male,solo,East Coast hip-hop; pop rap,United States,"American rapper, singer and actor (born 1987)"
|
||||
Wizkid,Q16233663,male,solo,Afrobeats; dancehall; rhythm and blues,Nigeria,Nigerian singer and songwriter (born 1990)
|
||||
X Ambassadors,Q15963313,,group,alternative rock,United States,"American rock band from Ithaca, New York"
|
||||
Xavi,Q124219723,male,solo,regional Mexican; corridos tumbados,United States,American singer
|
||||
XXXTENTACION,Q28561969,male,solo,hip-hop; emo rap; SoundCloud rap; rap rock; lo-fi music; hardcore hip-hop; alternative rock; lofi hip-hop; indie rock; nu metal; cloud rap; trap music; hardcore punk; trap metal; punk rock; rock music; rap metal; alternative R&B; contemporary R&B; punk rap; heavy metal music,United States,American rapper (1998–2018)
|
||||
Yeat,Q108761978,male,solo,experimental hip-hop; rage; trap music,United States,"American rapper, singer-songwriter, and record producer (born 2000)"
|
||||
YFN Lucci,Q28000403,male,solo,hip-hop,United States,American rapper (born 1991)
|
||||
YG,Q3076050,male,solo,West Coast hip-hop; gangsta rap; dirty rap; hardcore hip-hop,United States,American rapper and actor
|
||||
YK Osiris,Q66095815,male,solo,contemporary R&B; hip-hop,United States,"American rapper, singer, and songwriter"
|
||||
Yng Lvcas,Q117834547,male,solo,reggaeton,Mexico,Mexican singer and rapper
|
||||
YNW Melly,Q56276347,male,solo,Southern hip-hop; trap music; contemporary R&B; gangsta rap; drill; hardcore hip-hop,United States,American rapper
|
||||
Yo Gotti,Q586919,male,solo,Southern hip-hop; trap music; dirty south; hardcore hip-hop; gangsta rap; Memphis rap,United States,American rapper
|
||||
Young Dolph,Q23541285,male,solo,Southern hip-hop; gangsta rap; trap music; Memphis rap; dirty south; hardcore hip-hop,United States,American rapper (1985–2021)
|
||||
Young Nudy,Q62036530,male,solo,hip-hop,United States,American rapper (born 1992)
|
||||
Young Thug,Q15637814,male,solo,Southern hip-hop; trap music; mumble rap; progressive rap; SoundCloud rap,United States,American rapper and singer
|
||||
YoungBoy Never Broke Again,Q36490532,male,solo,hip-hop; Southern hip-hop; gangsta rap; trap music,United States,American rapper (born 1999)
|
||||
Yung Bleu,Q105105248,male,solo,contemporary R&B; hip-hop,United States,American rapper and singer
|
||||
Zacari,Q68593407,male,solo,contemporary R&B; hip-hop; alternative hip-hop; alternative R&B,United States,"American singer, songwriter, and multi-instrumentalist (born 1994)"
|
||||
Zach Bryan,Q106770023,male,solo,alternative country; red dirt; country music,United States,American country musician
|
||||
Zach Top,Q126414316,male,solo,country music,United States,American singer/songwriter
|
||||
Zara Larsson,Q4177928,female,solo,dance-pop; pop music; electropop,Sweden,Swedish singer and songwriter (born 1997)
|
||||
Zay Hilfigerrr,Q55859289,male,solo,hip-hop,United States,American rapper
|
||||
Zayion McCall,Q55859293,male,solo,hip-hop,United States,
|
||||
Zayn,Q3626950,male,solo,pop music; contemporary R&B; dance-pop; alternative R&B,United Kingdom,English singer
|
||||
Zedd,Q21088,male,solo,electronic dance music; house music; electro house,Russia,German electronic music producer (born 1989)
|
||||
Óscar Maydon,Q130241052,male,solo,corridos tumbados,Mexico,Mexican singer
|
||||
|
||||
|
@@ -0,0 +1,884 @@
|
||||
song_id,source,method,acquired_at,note
|
||||
192,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
193,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
194,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
187,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
151,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
195,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
196,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
197,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
198,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
199,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
200,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
201,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
202,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
203,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
204,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
205,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
206,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
207,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
208,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
209,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
146,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
212,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
214,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
215,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
224,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
228,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
245,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
247,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
143,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
251,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
252,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
263,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
267,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
272,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
275,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
277,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
145,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
278,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
279,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
280,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
281,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
261,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
283,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
285,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
286,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
287,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
288,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
289,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
290,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
291,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
293,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
296,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
300,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
302,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
303,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
223,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
307,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
310,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
314,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
315,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
317,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
320,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
323,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
328,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
330,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
331,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
333,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
335,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
337,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
341,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
342,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
344,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
347,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
348,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
353,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
354,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
356,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
220,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
360,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
361,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
362,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
364,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
367,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
332,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
368,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
369,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
370,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
371,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
372,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
373,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
374,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
375,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
376,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
377,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
378,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
379,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
380,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
381,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
382,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
383,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
384,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
385,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
386,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
387,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
388,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
389,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
390,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
391,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
392,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
393,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
394,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
395,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
396,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
397,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
398,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
399,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
295,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
400,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
401,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
402,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
403,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
404,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
405,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
406,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
407,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
408,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
409,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
410,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
411,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
412,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
413,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
339,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
414,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
415,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
416,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
417,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
418,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
419,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
420,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
421,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
422,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
423,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
424,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
425,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
426,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
427,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
428,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
429,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
311,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
430,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
431,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
432,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
433,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
434,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
435,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
436,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
437,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
438,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
439,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
440,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
441,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
442,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
443,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
444,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
445,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
446,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
447,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
448,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
449,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
450,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
451,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
452,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
453,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
454,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
455,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
456,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
457,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
458,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
459,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
460,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
461,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
462,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
463,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
464,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
465,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
466,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
467,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
468,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
469,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
470,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
471,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
472,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
473,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
474,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
475,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
476,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
477,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
478,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
479,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
480,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
481,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
482,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
483,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
484,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
485,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
486,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
487,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
488,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
489,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
490,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
491,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
492,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
493,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
494,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
495,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
496,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
497,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
498,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
499,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
500,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
501,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
502,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
503,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
504,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
505,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
506,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
507,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
508,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
509,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
510,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
511,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
512,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
513,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
514,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
515,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
516,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
517,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
518,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
519,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
520,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
521,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
522,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
523,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
524,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
525,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
526,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
527,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
528,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
529,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
530,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
531,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
532,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
533,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
534,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
535,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
536,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
537,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
538,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
539,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
540,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
541,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
542,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
543,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
544,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
545,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
546,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
547,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
548,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
549,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
550,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
551,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
552,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
553,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
554,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
555,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
556,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
557,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
558,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
559,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
560,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
561,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
562,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
563,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
564,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
565,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
566,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
567,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
568,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
569,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
570,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
571,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
572,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
573,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
574,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
575,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
576,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
577,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
578,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
579,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
580,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
581,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
582,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
583,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
584,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
585,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
586,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
587,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
588,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
589,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
590,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
591,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
592,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
593,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
594,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
595,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
596,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
597,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
598,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
599,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
600,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
601,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
602,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
603,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
604,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
605,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
606,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
607,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
608,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
609,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
610,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
611,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
612,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
613,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
614,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
615,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
616,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
617,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
618,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
619,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
620,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
621,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
622,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
623,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
624,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
625,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
626,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
627,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
628,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
629,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
630,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
631,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
632,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
633,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
634,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
635,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
636,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
637,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
638,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
639,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
640,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
641,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
642,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
643,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
644,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
645,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
646,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
647,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
648,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
649,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
650,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
651,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
652,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
653,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
654,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
655,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
656,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
657,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
658,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
659,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
660,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
661,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
662,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
663,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
664,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
665,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
666,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
667,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
668,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
669,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
670,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
671,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
672,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
673,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
674,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
675,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
676,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
677,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
678,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
679,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
680,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
681,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
682,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
683,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
684,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
685,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
686,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
687,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
688,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
689,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
690,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
691,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
692,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
693,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
694,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
695,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
696,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
697,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
698,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
699,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
700,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
701,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
702,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
703,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
704,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
705,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
706,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
707,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
708,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
709,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
710,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
711,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
712,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
713,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
714,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
715,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
716,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
717,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
718,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
719,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
720,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
721,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
722,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
723,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
724,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
725,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
726,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
727,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
728,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
729,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
730,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
731,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
732,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
733,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
734,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
735,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
736,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
737,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
738,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
739,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
740,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
741,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
742,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
743,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
744,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
745,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
746,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
747,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
748,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
749,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
750,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
751,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
752,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
753,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
754,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
755,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
756,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
757,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
758,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
759,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
760,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
761,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
762,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
763,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
764,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
765,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
766,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
767,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
768,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
769,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
770,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
771,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
772,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
773,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
774,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
775,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
776,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
777,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
778,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
779,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
780,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
781,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
782,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
783,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
784,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
785,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
786,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
787,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
788,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
789,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
790,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
791,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
792,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
793,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
794,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
795,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
796,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
797,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
798,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
799,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
800,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
801,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
802,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
803,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
804,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
805,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
806,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
807,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
808,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
809,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
810,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
811,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
812,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
813,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
814,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
815,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
816,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
817,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
818,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
819,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
820,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
821,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
822,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
823,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
824,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
825,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
826,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
827,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
828,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
829,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
830,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
831,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
832,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
833,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
834,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
835,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
836,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
837,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
838,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
839,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
840,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
841,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
842,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
843,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
844,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
845,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
846,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
847,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
848,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
849,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
850,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
851,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
852,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
853,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
854,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
855,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
856,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
857,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
858,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
859,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
860,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
861,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
862,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
863,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
864,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
865,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
866,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
867,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
868,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
869,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
870,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
871,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
872,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
873,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
874,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
875,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
876,lrclib,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
877,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
878,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
879,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
880,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
881,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
882,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
883,lyrics.ovh,pilot-import,2026-08-04,fetched by the pilot study before 2026-04
|
||||
1,lyrics.ovh,api-fetch,2026-08-04,
|
||||
2,lyrics.ovh,api-fetch,2026-08-04,
|
||||
3,lyrics.ovh,api-fetch,2026-08-04,
|
||||
4,lyrics.ovh,api-fetch,2026-08-04,
|
||||
5,lyrics.ovh,api-fetch,2026-08-04,
|
||||
6,lyrics.ovh,api-fetch,2026-08-04,
|
||||
7,lyrics.ovh,api-fetch,2026-08-04,
|
||||
8,lrclib,api-fetch,2026-08-04,
|
||||
9,lrclib,api-fetch,2026-08-04,
|
||||
10,lyrics.ovh,api-fetch,2026-08-04,
|
||||
11,lyrics.ovh,api-fetch,2026-08-04,
|
||||
12,lyrics.ovh,api-fetch,2026-08-04,
|
||||
13,lyrics.ovh,api-fetch,2026-08-04,
|
||||
14,lyrics.ovh,api-fetch,2026-08-04,
|
||||
15,lyrics.ovh,api-fetch,2026-08-04,
|
||||
16,lyrics.ovh,api-fetch,2026-08-04,
|
||||
17,lyrics.ovh,api-fetch,2026-08-04,
|
||||
18,lyrics.ovh,api-fetch,2026-08-04,
|
||||
19,lrclib,api-fetch,2026-08-04,
|
||||
20,lyrics.ovh,api-fetch,2026-08-04,
|
||||
21,lyrics.ovh,api-fetch,2026-08-04,
|
||||
22,lrclib,api-fetch,2026-08-04,
|
||||
23,lyrics.ovh,api-fetch,2026-08-04,
|
||||
24,lyrics.ovh,api-fetch,2026-08-04,
|
||||
25,lyrics.ovh,api-fetch,2026-08-04,
|
||||
26,lyrics.ovh,api-fetch,2026-08-04,
|
||||
27,lyrics.ovh,api-fetch,2026-08-04,
|
||||
28,lyrics.ovh,api-fetch,2026-08-04,
|
||||
29,lyrics.ovh,api-fetch,2026-08-04,
|
||||
30,lyrics.ovh,api-fetch,2026-08-04,
|
||||
31,lyrics.ovh,api-fetch,2026-08-04,
|
||||
32,lyrics.ovh,api-fetch,2026-08-04,
|
||||
33,lrclib,api-fetch,2026-08-04,
|
||||
34,lrclib,api-fetch,2026-08-04,
|
||||
35,lrclib,api-fetch,2026-08-04,
|
||||
36,lyrics.ovh,api-fetch,2026-08-04,
|
||||
37,lyrics.ovh,api-fetch,2026-08-04,
|
||||
38,lyrics.ovh,api-fetch,2026-08-04,
|
||||
39,lyrics.ovh,api-fetch,2026-08-04,
|
||||
40,lyrics.ovh,api-fetch,2026-08-04,
|
||||
41,lyrics.ovh,api-fetch,2026-08-04,
|
||||
42,lrclib,api-fetch,2026-08-04,
|
||||
43,lyrics.ovh,api-fetch,2026-08-04,
|
||||
44,lyrics.ovh,api-fetch,2026-08-04,
|
||||
45,lyrics.ovh,api-fetch,2026-08-04,
|
||||
46,lyrics.ovh,api-fetch,2026-08-04,
|
||||
47,lyrics.ovh,api-fetch,2026-08-04,
|
||||
48,lrclib,api-fetch,2026-08-04,
|
||||
49,lrclib,api-fetch,2026-08-04,
|
||||
50,lrclib,api-fetch,2026-08-04,
|
||||
51,lyrics.ovh,api-fetch,2026-08-04,
|
||||
52,lyrics.ovh,api-fetch,2026-08-04,
|
||||
53,lyrics.ovh,api-fetch,2026-08-04,
|
||||
54,lyrics.ovh,api-fetch,2026-08-04,
|
||||
55,lyrics.ovh,api-fetch,2026-08-04,
|
||||
56,lyrics.ovh,api-fetch,2026-08-04,
|
||||
57,lyrics.ovh,api-fetch,2026-08-04,
|
||||
58,lyrics.ovh,api-fetch,2026-08-04,
|
||||
59,lyrics.ovh,api-fetch,2026-08-04,
|
||||
60,lyrics.ovh,api-fetch,2026-08-04,
|
||||
61,lyrics.ovh,api-fetch,2026-08-04,
|
||||
62,lyrics.ovh,api-fetch,2026-08-04,
|
||||
63,lrclib,api-fetch,2026-08-04,
|
||||
64,lrclib,api-fetch,2026-08-04,
|
||||
65,lyrics.ovh,api-fetch,2026-08-04,
|
||||
66,lyrics.ovh,api-fetch,2026-08-04,
|
||||
67,lyrics.ovh,api-fetch,2026-08-04,
|
||||
68,lyrics.ovh,api-fetch,2026-08-04,
|
||||
69,lyrics.ovh,api-fetch,2026-08-04,
|
||||
70,lyrics.ovh,api-fetch,2026-08-04,
|
||||
71,lyrics.ovh,api-fetch,2026-08-04,
|
||||
72,lrclib,api-fetch,2026-08-04,
|
||||
73,lyrics.ovh,api-fetch,2026-08-04,
|
||||
74,lyrics.ovh,api-fetch,2026-08-04,
|
||||
75,lyrics.ovh,api-fetch,2026-08-04,
|
||||
76,lyrics.ovh,api-fetch,2026-08-04,
|
||||
77,lyrics.ovh,api-fetch,2026-08-04,
|
||||
78,lyrics.ovh,api-fetch,2026-08-04,
|
||||
79,lyrics.ovh,api-fetch,2026-08-04,
|
||||
80,lyrics.ovh,api-fetch,2026-08-04,
|
||||
81,lyrics.ovh,api-fetch,2026-08-04,
|
||||
82,lyrics.ovh,api-fetch,2026-08-04,
|
||||
83,lyrics.ovh,api-fetch,2026-08-04,
|
||||
84,lyrics.ovh,api-fetch,2026-08-04,
|
||||
85,lyrics.ovh,api-fetch,2026-08-04,
|
||||
86,lyrics.ovh,api-fetch,2026-08-04,
|
||||
87,lyrics.ovh,api-fetch,2026-08-04,
|
||||
88,lrclib,api-fetch,2026-08-04,
|
||||
89,lyrics.ovh,api-fetch,2026-08-04,
|
||||
90,lyrics.ovh,api-fetch,2026-08-04,
|
||||
91,lrclib,api-fetch,2026-08-04,
|
||||
92,lyrics.ovh,api-fetch,2026-08-04,
|
||||
93,lyrics.ovh,api-fetch,2026-08-04,
|
||||
94,lyrics.ovh,api-fetch,2026-08-04,
|
||||
95,lyrics.ovh,api-fetch,2026-08-04,
|
||||
96,lyrics.ovh,api-fetch,2026-08-04,
|
||||
97,lyrics.ovh,api-fetch,2026-08-04,
|
||||
98,lyrics.ovh,api-fetch,2026-08-04,
|
||||
99,lyrics.ovh,api-fetch,2026-08-04,
|
||||
100,lyrics.ovh,api-fetch,2026-08-04,
|
||||
101,lyrics.ovh,api-fetch,2026-08-04,
|
||||
102,lyrics.ovh,api-fetch,2026-08-04,
|
||||
103,lrclib,api-fetch,2026-08-04,
|
||||
104,lyrics.ovh,api-fetch,2026-08-04,
|
||||
105,lyrics.ovh,api-fetch,2026-08-04,
|
||||
106,lyrics.ovh,api-fetch,2026-08-04,
|
||||
107,lyrics.ovh,api-fetch,2026-08-04,
|
||||
108,lyrics.ovh,api-fetch,2026-08-04,
|
||||
109,lyrics.ovh,api-fetch,2026-08-04,
|
||||
110,lrclib,api-fetch,2026-08-04,
|
||||
111,lrclib,api-fetch,2026-08-04,
|
||||
112,lyrics.ovh,api-fetch,2026-08-04,
|
||||
113,lyrics.ovh,api-fetch,2026-08-04,
|
||||
114,lyrics.ovh,api-fetch,2026-08-04,
|
||||
115,lyrics.ovh,api-fetch,2026-08-04,
|
||||
116,lyrics.ovh,api-fetch,2026-08-04,
|
||||
117,lyrics.ovh,api-fetch,2026-08-04,
|
||||
118,lyrics.ovh,api-fetch,2026-08-04,
|
||||
119,lyrics.ovh,api-fetch,2026-08-04,
|
||||
120,lyrics.ovh,api-fetch,2026-08-04,
|
||||
121,lrclib,api-fetch,2026-08-04,
|
||||
122,lyrics.ovh,api-fetch,2026-08-04,
|
||||
123,lyrics.ovh,api-fetch,2026-08-04,
|
||||
124,lrclib,api-fetch,2026-08-04,
|
||||
125,lrclib,api-fetch,2026-08-04,
|
||||
126,lyrics.ovh,api-fetch,2026-08-04,
|
||||
127,lyrics.ovh,api-fetch,2026-08-04,
|
||||
128,lyrics.ovh,api-fetch,2026-08-04,
|
||||
129,lrclib,api-fetch,2026-08-04,
|
||||
130,lyrics.ovh,api-fetch,2026-08-04,
|
||||
131,lyrics.ovh,api-fetch,2026-08-04,
|
||||
132,lyrics.ovh,api-fetch,2026-08-04,
|
||||
133,lyrics.ovh,api-fetch,2026-08-04,
|
||||
134,lyrics.ovh,api-fetch,2026-08-04,
|
||||
135,lyrics.ovh,api-fetch,2026-08-04,
|
||||
136,lrclib,api-fetch,2026-08-04,
|
||||
137,lyrics.ovh,api-fetch,2026-08-04,
|
||||
138,lyrics.ovh,api-fetch,2026-08-04,
|
||||
139,lyrics.ovh,api-fetch,2026-08-04,
|
||||
140,lyrics.ovh,api-fetch,2026-08-04,
|
||||
141,lyrics.ovh,api-fetch,2026-08-04,
|
||||
142,lyrics.ovh,api-fetch,2026-08-04,
|
||||
144,lyrics.ovh,api-fetch,2026-08-04,
|
||||
147,lyrics.ovh,api-fetch,2026-08-04,
|
||||
148,lyrics.ovh,api-fetch,2026-08-04,
|
||||
149,lyrics.ovh,api-fetch,2026-08-04,
|
||||
150,lyrics.ovh,api-fetch,2026-08-04,
|
||||
152,lrclib,api-fetch,2026-08-04,
|
||||
153,lyrics.ovh,api-fetch,2026-08-04,
|
||||
154,lyrics.ovh,api-fetch,2026-08-04,
|
||||
155,lrclib,api-fetch,2026-08-04,
|
||||
156,lyrics.ovh,api-fetch,2026-08-04,
|
||||
157,lyrics.ovh,api-fetch,2026-08-04,
|
||||
158,lyrics.ovh,api-fetch,2026-08-04,
|
||||
159,lyrics.ovh,api-fetch,2026-08-04,
|
||||
160,lyrics.ovh,api-fetch,2026-08-04,
|
||||
161,lyrics.ovh,api-fetch,2026-08-04,
|
||||
162,lyrics.ovh,api-fetch,2026-08-04,
|
||||
163,lyrics.ovh,api-fetch,2026-08-04,
|
||||
164,lyrics.ovh,api-fetch,2026-08-04,
|
||||
165,lyrics.ovh,api-fetch,2026-08-04,
|
||||
166,lyrics.ovh,api-fetch,2026-08-04,
|
||||
167,lyrics.ovh,api-fetch,2026-08-04,
|
||||
168,lyrics.ovh,api-fetch,2026-08-04,
|
||||
169,lyrics.ovh,api-fetch,2026-08-04,
|
||||
170,lyrics.ovh,api-fetch,2026-08-04,
|
||||
171,lrclib,api-fetch,2026-08-04,
|
||||
172,lyrics.ovh,api-fetch,2026-08-04,
|
||||
173,lyrics.ovh,api-fetch,2026-08-04,
|
||||
174,lyrics.ovh,api-fetch,2026-08-04,
|
||||
175,lyrics.ovh,api-fetch,2026-08-04,
|
||||
176,lrclib,api-fetch,2026-08-04,
|
||||
177,lyrics.ovh,api-fetch,2026-08-04,
|
||||
178,lyrics.ovh,api-fetch,2026-08-04,
|
||||
179,lyrics.ovh,api-fetch,2026-08-04,
|
||||
180,lyrics.ovh,api-fetch,2026-08-04,
|
||||
181,lyrics.ovh,api-fetch,2026-08-04,
|
||||
182,lyrics.ovh,api-fetch,2026-08-04,
|
||||
183,lyrics.ovh,api-fetch,2026-08-04,
|
||||
184,lyrics.ovh,api-fetch,2026-08-04,
|
||||
185,lyrics.ovh,api-fetch,2026-08-04,
|
||||
186,lyrics.ovh,api-fetch,2026-08-04,
|
||||
188,lyrics.ovh,api-fetch,2026-08-04,
|
||||
189,lyrics.ovh,api-fetch,2026-08-04,
|
||||
190,lyrics.ovh,api-fetch,2026-08-04,
|
||||
191,lyrics.ovh,api-fetch,2026-08-04,
|
||||
210,lyrics.ovh,api-fetch,2026-08-04,
|
||||
211,lyrics.ovh,api-fetch,2026-08-04,
|
||||
213,lyrics.ovh,api-fetch,2026-08-04,
|
||||
216,lyrics.ovh,api-fetch,2026-08-04,
|
||||
217,lyrics.ovh,api-fetch,2026-08-04,
|
||||
218,lyrics.ovh,api-fetch,2026-08-04,
|
||||
219,lyrics.ovh,api-fetch,2026-08-04,
|
||||
221,lrclib,api-fetch,2026-08-04,
|
||||
222,lyrics.ovh,api-fetch,2026-08-04,
|
||||
225,lyrics.ovh,api-fetch,2026-08-04,
|
||||
226,lyrics.ovh,api-fetch,2026-08-04,
|
||||
227,lrclib,api-fetch,2026-08-04,
|
||||
229,lyrics.ovh,api-fetch,2026-08-04,
|
||||
230,lrclib,api-fetch,2026-08-04,
|
||||
231,lyrics.ovh,api-fetch,2026-08-04,
|
||||
232,lrclib,api-fetch,2026-08-04,
|
||||
233,lyrics.ovh,api-fetch,2026-08-04,
|
||||
234,lyrics.ovh,api-fetch,2026-08-04,
|
||||
235,lyrics.ovh,api-fetch,2026-08-04,
|
||||
236,lyrics.ovh,api-fetch,2026-08-04,
|
||||
237,lyrics.ovh,api-fetch,2026-08-04,
|
||||
238,lyrics.ovh,api-fetch,2026-08-04,
|
||||
239,lyrics.ovh,api-fetch,2026-08-04,
|
||||
240,lyrics.ovh,api-fetch,2026-08-04,
|
||||
241,lyrics.ovh,api-fetch,2026-08-04,
|
||||
242,lyrics.ovh,api-fetch,2026-08-04,
|
||||
243,lyrics.ovh,api-fetch,2026-08-04,
|
||||
244,lyrics.ovh,api-fetch,2026-08-04,
|
||||
246,lyrics.ovh,api-fetch,2026-08-04,
|
||||
248,lyrics.ovh,api-fetch,2026-08-04,
|
||||
249,lyrics.ovh,api-fetch,2026-08-04,
|
||||
250,lyrics.ovh,api-fetch,2026-08-04,
|
||||
253,lyrics.ovh,api-fetch,2026-08-04,
|
||||
254,lyrics.ovh,api-fetch,2026-08-04,
|
||||
255,lrclib,api-fetch,2026-08-04,
|
||||
256,lyrics.ovh,api-fetch,2026-08-04,
|
||||
257,lrclib,api-fetch,2026-08-04,
|
||||
258,lyrics.ovh,api-fetch,2026-08-04,
|
||||
259,lyrics.ovh,api-fetch,2026-08-04,
|
||||
260,lrclib,api-fetch,2026-08-04,
|
||||
262,lyrics.ovh,api-fetch,2026-08-04,
|
||||
264,lrclib,api-fetch,2026-08-04,
|
||||
265,lyrics.ovh,api-fetch,2026-08-04,
|
||||
266,lrclib,api-fetch,2026-08-04,
|
||||
268,lyrics.ovh,api-fetch,2026-08-04,
|
||||
269,lrclib,api-fetch,2026-08-04,
|
||||
270,lyrics.ovh,api-fetch,2026-08-04,
|
||||
271,lyrics.ovh,api-fetch,2026-08-04,
|
||||
273,lyrics.ovh,api-fetch,2026-08-04,
|
||||
274,lyrics.ovh,api-fetch,2026-08-04,
|
||||
276,lyrics.ovh,api-fetch,2026-08-04,
|
||||
282,lyrics.ovh,api-fetch,2026-08-04,
|
||||
284,lyrics.ovh,api-fetch,2026-08-04,
|
||||
292,lrclib,api-fetch,2026-08-04,
|
||||
294,lyrics.ovh,api-fetch,2026-08-04,
|
||||
297,lyrics.ovh,api-fetch,2026-08-04,
|
||||
298,lyrics.ovh,api-fetch,2026-08-04,
|
||||
299,lyrics.ovh,api-fetch,2026-08-04,
|
||||
301,lrclib,api-fetch,2026-08-04,
|
||||
304,lyrics.ovh,api-fetch,2026-08-04,
|
||||
305,lyrics.ovh,api-fetch,2026-08-04,
|
||||
308,lyrics.ovh,api-fetch,2026-08-04,
|
||||
309,lyrics.ovh,api-fetch,2026-08-04,
|
||||
312,lyrics.ovh,api-fetch,2026-08-04,
|
||||
313,lyrics.ovh,api-fetch,2026-08-04,
|
||||
316,lyrics.ovh,api-fetch,2026-08-04,
|
||||
318,lyrics.ovh,api-fetch,2026-08-04,
|
||||
319,lyrics.ovh,api-fetch,2026-08-04,
|
||||
321,lyrics.ovh,api-fetch,2026-08-04,
|
||||
322,lyrics.ovh,api-fetch,2026-08-04,
|
||||
324,lyrics.ovh,api-fetch,2026-08-04,
|
||||
325,lyrics.ovh,api-fetch,2026-08-04,
|
||||
326,lyrics.ovh,api-fetch,2026-08-04,
|
||||
327,lyrics.ovh,api-fetch,2026-08-04,
|
||||
329,lyrics.ovh,api-fetch,2026-08-04,
|
||||
334,lyrics.ovh,api-fetch,2026-08-04,
|
||||
336,lyrics.ovh,api-fetch,2026-08-04,
|
||||
338,lyrics.ovh,api-fetch,2026-08-04,
|
||||
340,lyrics.ovh,api-fetch,2026-08-04,
|
||||
343,lyrics.ovh,api-fetch,2026-08-04,
|
||||
345,lyrics.ovh,api-fetch,2026-08-04,
|
||||
346,lyrics.ovh,api-fetch,2026-08-04,
|
||||
349,lyrics.ovh,api-fetch,2026-08-04,
|
||||
350,lyrics.ovh,api-fetch,2026-08-04,
|
||||
351,lyrics.ovh,api-fetch,2026-08-04,
|
||||
355,lyrics.ovh,api-fetch,2026-08-04,
|
||||
357,lyrics.ovh,api-fetch,2026-08-04,
|
||||
358,lyrics.ovh,api-fetch,2026-08-04,
|
||||
359,lyrics.ovh,api-fetch,2026-08-04,
|
||||
365,lrclib,api-fetch,2026-08-04,
|
||||
366,lyrics.ovh,api-fetch,2026-08-04,
|
||||
306,lyrics.ovh,api-fetch,2026-08-04,
|
||||
352,lrclib,api-fetch,2026-08-04,
|
||||
363,lyrics.ovh,api-fetch,2026-08-04,
|
||||
|
+470
-470
@@ -1,470 +1,470 @@
|
||||
Name,Wikidata QID,Gender,Type,Genre,Country,Songs
|
||||
070 Shake,,,,,,Escapism (2023#48)
|
||||
2 Chainz,,,,,,Big Bank (2018#63)
|
||||
21 Savage,,,,,,A Lot (2019#42)|Bank Account (2017#48)|Bartier Cardi (2018#61)|Creepin' (2023#5)|Good Good (2024#79)|Jimmy Cooks (2022#33)|Knife Talk (2021#86/2022#60)|Peaches & Eggplants (2023#94)|Redrum (2024#42)|Rich Flex (2023#14)|Rockstar (2017#56/2018#5)|Spin Bout U (2023#43)
|
||||
24kGoldn,,,,,,Mood (2020#47/2021#4)
|
||||
42 Dugg,,,,,,We Paid (2020#57)
|
||||
4batz,,,,,,Act II: Date @ 8 (2024#80)
|
||||
5 Seconds of Summer,,,,,,Youngblood (2018#36/2019#33)
|
||||
50 Cent,,,,,,The Woo (2020#78)
|
||||
6ix9ine,,,,,,FEFE (2018#31)|Gummo (2018#56)|Swervin (2019#82)
|
||||
6LACK,,,,,,Calling My Phone (2021#33)
|
||||
A Boogie wit da Hoodie,,,,,,Drowning (2017#81)|Look Back At It (2019#41)|Swervin (2019#82)
|
||||
A$AP Ferg,,,,,,Plain Jane (2018#74)
|
||||
A$AP Rocky,,,,,,No Limit (2018#30)
|
||||
Adassa,,,,,,We Don't Talk About Bruno (2022#24)
|
||||
Adele,,,,,,Easy On Me (2022#4)|Hello (2016#7)|Oh My God (2022#72)|Send My Love (To Your New Lover) (2016#26)|Water Under The Bridge (2017#88)|When We Were Young (2016#83)
|
||||
AJR,,,,,,Bang! (2021#56)
|
||||
Alessia Cara,,,,,,1-800-273-8255 (2017#31/2018#84)|Here (2016#39)|Scars To Your Beautiful (2017#30)|Stay (2017#17)
|
||||
Alex Warren,,,,,,Ordinary (2025#7)
|
||||
Aminé,,,,,,Caroline (2017#60)
|
||||
Anderson .Paak,,,,,,Leave The Door Open (2021#7)|Smokin Out The Window (2022#41)
|
||||
Andrew Choi,,,,,,Free (2025#92)|Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Anne-Marie,,,,,,Friends (2018#26)|Rockabye (2017#44)
|
||||
Aqua,,,,,,Barbie World (2023#46)
|
||||
Ariana Grande,,,,,,"34+35 (2021#21)|7 Rings (2019#7)|Boyfriend (2019#98)|Break Up With Your Girlfriend, I'm Bored (2019#36)|Breathin (2019#72)|Dangerous Woman (2016#36)|Die For You (2023#7)|God Is A Woman (2018#62)|Into You (2016#51)|No Tears Left To Cry (2018#20)|Positions (2021#14)|pov (2021#87)|Rain On Me (2020#48)|Save Your Tears (2021#2/2022#40)|Side To Side (2016#77/2017#43)|Stuck With U (2020#80)|Thank U, Next (2019#12)|We Can't Be Friends (Wait For Your Love) (2024#26)|Yes, And? (2024#92)"
|
||||
Arizona Zervas,,,,,,Roxanne (2020#16)
|
||||
Artemas,,,,,,I Like The Way You Kiss Me (2024#63)
|
||||
ATR Son Son,,,,,,Rags2Riches (2020#90)
|
||||
Audrey Nuna,,,,,,Golden (2025#25)|How It's Done (2025#68)|Takedown (2025#93)|What It Sounds Like (2025#83)
|
||||
Ava Max,,,,,,Kings & Queens (2021#73)|Sweet But Psycho (2019#23)
|
||||
Avery Anna,,,,,,Indigo (2025#49)
|
||||
Ayo,,,,,,Rolex (2017#61)
|
||||
AzChike,,,,,,Peekaboo (2025#53)
|
||||
Bad Bunny,,,,,,Baile Inolvidable (2025#70)|Dakiti (2021#28)|Despues de La Playa (2022#78)|DTMF (2025#51)|Efecto (2022#69)|EOO (2025#77)|I Like It (2018#7/2019#69)|Me Porto Bonito (2022#20)|MIA (2019#44)|Monaco (2024#82)|Moscow Mule (2022#44)|Nuevayol (2025#89)|Ojitos Lindos (2022#87)|Party (2022#77)|Te Bote (2018#81)|Titi Me Pregunto (2022#22)|Un x100to (2023#49)|Where She Goes (2023#72)|Yonaguni (2021#83)
|
||||
Bailey Zimmerman,,,,,,All The Way (2025#33)|Backup Plan (2025#80)|Fall In Love (2022#54)|Religiously (2023#42)|Rock And A Hard Place (2022#70/2023#16)|Where It Ends (2024#87)
|
||||
Bastille,,,,,,Happier (2018#80/2019#6)
|
||||
Bazzi,,,,,,Beautiful (2019#95)|Mine (2018#21)
|
||||
beabadoobee,,,,,,Death Bed (2020#43)
|
||||
Bebe Rexha,,,,,,"I'm Good (Blue) (2023#10)|Me, Myself & I (2016#19)|Meant To Be (2018#3)"
|
||||
Becky G,,,,,,MAMIII (2022#59)
|
||||
BENEE,,,,,,Supalonely (2020#84)
|
||||
benny blanco,,,,,,Eastside (2018#77/2019#17)|Lonely (2021#65)
|
||||
Benson Boone,,,,,,Beautiful Things (2024#3/2025#6)|Mystical Magical (2025#47)|Slow It Down (2024#41)|Sorry I'm Here For Someone Else (2025#37)
|
||||
Beyoncé,,,,,,Break My Soul (2022#38)|Cuff It (2023#29)|Mi Gente (2017#50/2018#99)|Sorry (2016#71)|Texas Hold 'Em (2024#32)
|
||||
Big Sean,,,,,,Big Bank (2018#63)|Bounce Back (2017#35)|Feels (2017#74)
|
||||
BigXthaPlug,,,,,,All The Way (2025#33)
|
||||
Billie Eilish,,,,,,Bad Guy (2019#4/2020#46)|Birds Of A Feather (2024#15/2025#5)|Bury A Friend (2019#73)|Everything I Wanted (2020#18)|Happier Than Ever (2021#94)|Lunch (2024#48)|Therefore I Am (2021#25)|What Was I Made For? (2023#81/2024#46)|When The Party's Over (2019#67)|Wildflower (2024#89/2025#26)
|
||||
Billy Ray Cyrus,,,,,,Old Town Road (2019#1)
|
||||
Bipolar Sunshine,,,,,,Middle (2016#80)
|
||||
Bizarrap,,,,,,"Bzrp Music Sessions, Vol. 53 (2023#96)"
|
||||
Black Eyed Peas,,,,,,RITMO (Bad Boys For Life) (2020#50)
|
||||
blackbear,,,,,,Do Re Mi (2017#98)|Hot Girl Bummer (2020#26)|My Ex's Best Friend (2021#23)
|
||||
Blake Shelton,,,,,,God's Country (2019#53)|Nobody But You (2020#52)|Pour Me A Drink (2024#76)
|
||||
Blanco Brown,,,,,,Just The Way (2021#88)|The Git Up (2019#56)
|
||||
BlocBoy JB,,,,,,Look Alive (2018#23)
|
||||
Blueface,,,,,,Thotiana (2019#47)
|
||||
Bobby Helms,,,,,,Jingle Bell Rock (2022#86/2023#68/2024#68/2025#81)
|
||||
Bomba Estéreo,,,,,,Ojitos Lindos (2022#87)
|
||||
Bradley Cooper,,,,,,Shallow (2019#19)
|
||||
Brandon Lake,,,,,,Hard Fought Hallelujah (2025#84)
|
||||
Brenda Lee,,,,,,Rockin' Around The Christmas Tree (2021#92/2022#80/2023#60/2024#59/2025#67)
|
||||
Brendon Urie,,,,,,ME! (2019#43)
|
||||
Brett Young,,,,,,In Case You Didn't Know (2017#57)|Mercy (2018#95)
|
||||
BRS Kash,,,,,,Throat Baby (Go Baby) (2021#97)
|
||||
Bruno Mars,,,,,,24K Magic (2017#16)|APT. (2025#9)|Die With A Smile (2024#62/2025#1)|Finesse (2018#14)|Leave The Door Open (2021#7)|Please Me (2019#37)|Smokin Out The Window (2022#41)|That's What I Like (2017#3)|Wake Up In The Sky (2019#51)
|
||||
Bryson Tiller,,,,,,Don't (2016#35)|Exchange (2016#53)|Whatever She Wants (2024#58)|Wild Thoughts (2017#18)
|
||||
BTS,,,,,,Butter (2021#11)|Dynamite (2020#38/2021#41)
|
||||
Burl Ives,,,,,,A Holly Jolly Christmas (2022#89/2023#71/2024#94)
|
||||
Calboy,,,,,,Envy Me (2019#59)
|
||||
Calvin Harris,,,,,,Feels (2017#74)|One Kiss (2018#68)|Slide (2017#71)|This Is What You Came For (2016#17)
|
||||
Camila Cabello,,,,,,Bad Things (2017#41)|Bam Bam (2022#66)|Beautiful (2019#95)|Havana (2017#96/2018#4)|I Know What You Did Last Summer (2016#86)|My Oh My (2020#37)|Never Be The Same (2018#18)|Senorita (2019#15/2020#44)
|
||||
Cardi B,,,,,,Bartier Cardi (2018#61)|Be Careful (2018#59)|Bodak Yellow (Money Moves) (2017#24/2018#54)|Clout (2019#87)|Finesse (2018#14)|Girls Like You (2018#10/2019#22)|I Like It (2018#7/2019#69)|Money (2019#38)|MotorSport (2018#34)|No Limit (2018#30)|Please Me (2019#37)|Put It On Da Floor Again (2023#98)|Taki Taki (2019#57)|Tomorrow 2 (2023#70)|Up (2021#26)|WAP (2020#24)
|
||||
Carly Pearce,,,,,,I Hope You're Happy Now (2020#73)
|
||||
Carolina Gaitán,,,,,,We Don't Talk About Bruno (2022#24)
|
||||
Carrie Underwood,,,,,,I'm Gonna Love You (2025#78)|If I Didn't Love You (2021#85)|The Fighter (2017#100)
|
||||
Cash Cobain,,,,,,Somebody Loves Me (2025#85)
|
||||
Casper Mágico,,,,,,Te Bote (2018#81)
|
||||
Chance the Rapper,,,,,,Holy (2021#35)|I'm The One (2017#12)|No Brainer (2018#73)
|
||||
Chappell Roan,,,,,,"Good Luck, Babe! (2024#18/2025#31)|Hot To Go! (2024#53)|Pink Pony Club (2025#10)"
|
||||
Charlie Puth,,,,,,Attention (2017#22)|How Long (2018#65)|I Hope (2020#12/2021#40)|One Call Away (2016#43)|See You Again (2016#99)|We Don't Talk Anymore (2016#50)
|
||||
Chase Rice,,,,,,Drinkin' Beer. Talkin' God. Amen. (2021#99)|Eyes On You (2019#96)
|
||||
Cheat Codes,,,,,,No Promises (2017#91)
|
||||
Chencho Corleone,,,,,,Me Porto Bonito (2022#20)
|
||||
Childish Gambino,,,,,,Redbone (2017#25)|This Is America (2018#51)
|
||||
Chris Brown,,,,,,Back To Sleep (2016#89)|Freaky Friday (2018#55)|Go Crazy (2020#39/2021#19)|No Guidance (2019#21/2020#36)|Residuals (2025#63)|Superhero (Heroes & Villains) (2023#38)|Under The Influence (2023#17)
|
||||
Chris Stapleton,,,,,,Say Something (2018#85)|Starting Over (2021#53)|White Horse (2024#77)|You Should Probably Leave (2022#79)
|
||||
Chris Young,,,,,,Famous Friends (2021#69)
|
||||
City Girls,,,,,,Act Up (2019#68)
|
||||
CJ,,,,,,Whoopty (2021#50)
|
||||
CKay,,,,,,Love Nwantiti (Ah Ah Ah) (2022#55)
|
||||
Clean Bandit,,,,,,Rockabye (2017#44)
|
||||
Cody Johnson,,,,,,'Til You Can't (2022#34)|I'm Gonna Love You (2025#78)|The Painter (2024#98)
|
||||
Coi Leray,,,,,,No More Parties (2021#79)|Players (2023#33)
|
||||
Coldplay,,,,,,Adventure Of A Lifetime (2016#95)|Hymn For The Weekend (2016#73)|Something Just Like This (2017#5)
|
||||
Cole Swindell,,,,,,Never Say Never (2022#92)|She Had Me At Heads Carolina (2022#46)|Single Saturday Night (2021#95)
|
||||
Corey Kent,,,,,,Wild As Her (2023#93)
|
||||
Cris MJ,,,,,,Gata Only (2024#52)
|
||||
D.R.A.M.,,,,,,Broccoli (2016#34/2017#70)
|
||||
DaBaby,,,,,,Baby (2019#84)|Beat Box (2021#44)|BOP (2020#29)|Cash Shit (2019#90)|Cry Baby (2021#77)|For The Night (2020#49/2021#32)|My Oh My (2020#37)|Rockstar (2020#5)|Suge (2019#24)|Whats Poppin (2020#13)
|
||||
Daddy Yankee,,,,,,Con Calma (2019#65)|Despacito (2017#2)|Dura (2018#93)
|
||||
Daft Punk,,,,,,I Feel It Coming (2017#34)|Starboy (2016#58/2017#20)
|
||||
Dan Smyers,,,,,,"10,000 Hours (2020#23)|All To Myself (2019#97)|Glad You Exist (2021#64)|Speechless (2019#35)|Tequila (2018#32/2019#91)"
|
||||
Daniel Caesar,,,,,,Peaches (2021#10)
|
||||
Danny Chung,,,,,,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Darell,,,,,,Te Bote (2018#81)
|
||||
Dasha,,,,,,Austin (2024#27)
|
||||
David Guetta,,,,,,I'm Good (Blue) (2023#10)
|
||||
David Kushner,,,,,,Daylight (2023#62)
|
||||
Daya,,,,,,"Don't Let Me Down (2016#8)|Hide Away (2016#84)|Sit Still, Look Pretty (2016#78)"
|
||||
dazy,,,,,,Sunroof (2022#29)
|
||||
Dean Lewis,,,,,,Be Alright (2019#54)
|
||||
Demi Lovato,,,,,,No Promises (2017#91)|Sorry Not Sorry (2017#47/2018#64)
|
||||
Desiigner,,,,,,Panda (2016#6)|Tiimmy Turner (2016#98)
|
||||
Diane Guerrero,,,,,,We Don't Talk About Bruno (2022#24)
|
||||
Diplo,,,,,,Close To Me (2019#58)
|
||||
DJ Khaled,,,,,,Every Chance I Get (2021#59)|For Free (2016#59)|I'm The One (2017#12)|No Brainer (2018#73)|Popstar (2020#66)|Wild Thoughts (2017#18)
|
||||
DJ Snake,,,,,,Lean On (2016#85)|Let Me Love You (2016#47/2017#46)|Middle (2016#80)|Taki Taki (2019#57)
|
||||
Djo,,,,,,End Of Beginning (2024#47)
|
||||
DNCE,,,,,,Cake By The Ocean (2016#18)
|
||||
Doechii,,,,,,Anxiety (2025#39)|Denial Is A River (2025#75)|What It Is (Block Boy) (2023#76)
|
||||
Doja Cat,,,,,,34+35 (2021#21)|Agora Hills (2024#17)|Best Friend (2021#29)|Get Into It (Yuh) (2022#68)|I Like You (A Happier Song) (2022#26/2023#75)|Juicy (2020#87)|Kiss Me More (2021#6/2022#90)|Need To Know (2021#46/2022#18)|Paint The Town Red (2023#52/2024#21)|Say So (2020#11)|Streets (2021#67)|Vegas (2022#47)|Woman (2022#21)|You Right (2021#43/2022#45)
|
||||
Don Toliver,,,,,,Lemonade (2021#51)|No Pole (2025#97)
|
||||
Dove Cameron,,,,,,Boyfriend (2022#51)
|
||||
Drake,,,,,,Act II: Date @ 8 (2024#80)|Both (2017#83)|Controlla (2016#41)|Fake Love (2017#37)|First Person Shooter (2024#61)|For Free (2016#59)|God's Plan (2018#1)|Going Bad (2019#18)|Hotline Bling (2016#24)|I'm Upset (2018#86)|IDGAF (2024#83)|In My Feelings (2018#9)|Jimmy Cooks (2022#33)|Jumpman (2016#37)|Knife Talk (2021#86/2022#60)|Laugh Now Cry Later (2020#41/2021#45)|Life Is Good (2020#7)|Look Alive (2018#23)|Meltdown (2023#97)|MIA (2019#44)|Money In The Grave (2019#34)|Nice For What (2018#11)|No Guidance (2019#21/2020#36)|Nokia (2025#24)|Nonstop (2018#52)|One Dance (2016#3)|Passionfruit (2017#65)|Pop Style (2016#82)|Popstar (2020#66)|Rich Baby Daddy (2024#45)|Rich Flex (2023#14)|Search & Rescue (2023#45)|Somebody Loves Me (2025#85)|Spin Bout U (2023#43)|Too Good (2016#29)|Toosie Slide (2020#32)|Wait For U (2022#11/2023#83)|Walk It Talk It (2018#43)|Wants And Needs (2021#47)|Way 2 Sexy (2021#48)|What's Next (2021#68)|Work (2016#4)|Yes Indeed (2018#25)|You're Mines Still (2021#58)
|
||||
Dua Lipa,,,,,,Break My Heart (2020#33)|Cold Heart (PNAU Remix) (2022#10)|Dance The Night (2023#35/2024#100)|Don't Start Now (2020#4)|Houdini (2024#43)|IDGAF (2018#98)|Levitating (2021#1/2022#42)|New Rules (2018#16)|One Kiss (2018#68)|Sweetest Pie (2022#62)|We're Good (2021#90)
|
||||
Duncan Laurence,,,,,,Arcade (2021#82)
|
||||
Dustin Lynch,,,,,,Small Town Boy (2017#94)
|
||||
Ed Sheeran,,,,,,Bad Habits (2021#15/2022#13)|Bam Bam (2022#66)|Beautiful People (2019#50)|Castle On The Hill (2017#40)|Eyes Closed (2023#64)|I Don't Care (2019#16)|Perfect (2018#2)|Shape Of You (2017#1/2018#71)|Shivers (2022#5)
|
||||
EJAE,,,,,,Free (2025#92)|Golden (2025#25)|How It's Done (2025#68)|Takedown (2025#93)|What It Sounds Like (2025#83)
|
||||
Ella Langley,,,,,,Weren't For The Wind (2025#71)
|
||||
Ella Mai,,,,,,Boo'd Up (2018#15)|Trip (2018#92/2019#80)
|
||||
Elle King,,,,,,Ex's & Oh's (2016#63)
|
||||
Ellie Goulding,,,,,,Close To Me (2019#58)|On My Mind (2016#81)
|
||||
Elton John,,,,,,Cold Heart (PNAU Remix) (2022#10)
|
||||
Em Beihold,,,,,,Numb Little Bug (2022#32)
|
||||
Emilee,,,,,,ily (2020#95)
|
||||
Eminem,,,,,,Godzilla (2020#62)|Houdini (2024#39)
|
||||
Encanto Cast,,,,,,We Don't Talk About Bruno (2022#24)
|
||||
Eric Church,,,,,,Does To Me (2020#93)|Hell Of A View (2021#91)
|
||||
ERNEST,,,,,,Cowgirls (2024#29)|Flower Shops (2022#96)
|
||||
Eslabón Armado,,,,,,Ella Baila Sola (2023#26)
|
||||
Fat Joe,,,,,,All The Way Up (2016#87)
|
||||
Fetty Wap,,,,,,679 (2016#54)|All In My Head (Flex) (2016#93)
|
||||
Fifth Harmony,,,,,,All In My Head (Flex) (2016#93)|Work From Home (2016#16)
|
||||
Fifty Fifty,,,,,,Cupid (2023#44)
|
||||
Flipp Dinero,,,,,,Leave Me Alone (2019#71)
|
||||
Flo Milli,,,,,,Never Lose Me (2024#49)
|
||||
Flo Rida,,,,,,My House (2016#14)
|
||||
Florida Georgia Line,,,,,,Drinkin' Beer. Talkin' God. Amen. (2021#99)|H.O.L.Y. (2016#49)|Lil Bit (2021#70)|Meant To Be (2018#3)|Simple (2018#82)|Talk You Out Of It (2019#94)
|
||||
FloyyMenor,,,,,,Gata Only (2024#52)
|
||||
Flume,,,,,,Never Be Like You (2016#60)
|
||||
Frank Ocean,,,,,,Slide (2017#71)
|
||||
French Montana,,,,,,All The Way Up (2016#87)|Unforgettable (2017#15)
|
||||
Fuerza Regida,,,,,,Bebe Dame (2023#73)|Tu Boda (2025#87)
|
||||
Future,,,,,,Cold (2017#69)|Jumpman (2016#37)|King's Dead (2018#79)|Life Is Good (2020#7)|Like That (2024#14)|Low Life (2016#30)|Mask Off (2017#14)|Puffin On Zootiez (2022#84)|Pushin P (2022#48)|Superhero (Heroes & Villains) (2023#38)|Type Shit (2024#51)|Wait For U (2022#11/2023#83)|Way 2 Sexy (2021#48)|Wicked (2016#97)
|
||||
G-Eazy,,,,,,"Him & I (2018#45)|Me, Myself & I (2016#19)|No Limit (2018#30)"
|
||||
Gabby Barrett,,,,,,I Hope (2020#12/2021#40)|The Good Ones (2021#62)
|
||||
GAYLE,,,,,,abcdefu (2022#17)
|
||||
Gigi Perez,,,,,,Sailor Song (2025#36)
|
||||
Giveon,,,,,,Heartbreak Anniversary (2021#31)|Peaches (2021#10)
|
||||
Glass Animals,,,,,,Heat Waves (2021#16/2022#1)
|
||||
GloRilla,,,,,,Sticky (2025#41)|Tomorrow 2 (2023#70)|Wanna Be (2024#40)|Whatchu Kno About Me (2025#48)|Yeah Glo! (2024#44)
|
||||
gnash,,,,,,I Hate U I Love U (2016#38)|Lights Down Low (2018#66)
|
||||
Gracie Abrams,,,,,,That's So True (2025#14)
|
||||
Grey,,,,,,Starving (2016#94/2017#82)|The Middle (2018#8)
|
||||
Grupo Frontera,,,,,,Bebe Dame (2023#73)|Un x100to (2023#49)
|
||||
Gucci Mane,,,,,,Black Beatles (2017#19)|Both (2017#83)|I Get The Bag (2017#93/2018#72)|Slippery (2017#86)|Wake Up In The Sky (2019#51)
|
||||
Gunna,,,,,,Drip Too Hard (2019#26)|Fukumean (2023#31/2024#85)|Hot (2020#72)|Lemonade (2021#51)|Pushin P (2022#48)|What Happened To Virgil (2022#83)
|
||||
Gus Dapperton,,,,,,Supalonely (2020#84)
|
||||
Gwen Stefani,,,,,,Nobody But You (2020#52)
|
||||
H.E.R.,,,,,,Slide (2020#99)
|
||||
Hailee Steinfeld,,,,,,Starving (2016#94/2017#82)
|
||||
Halsey,,,,,,Bad At Love (2018#27)|Closer (2016#10/2017#7)|Eastside (2018#77/2019#17)|Him & I (2018#45)|Now Or Never (2017#59)|Without Me (2019#3)|You Should Be Sad (2020#82)
|
||||
HARDY,,,,,,Truck Bed (2024#67)|Wait In The Truck (2023#54)
|
||||
Harry Styles,,,,,,Adore You (2020#6)|As It Was (2022#2/2023#15)|Late Night Talking (2022#25)|Sign Of The Times (2017#87)|Watermelon Sugar (2020#20)
|
||||
Hozier,,,,,,Too Sweet (2024#10/2025#34)
|
||||
Hudson Westbrook,,,,,,House Again (2025#95)
|
||||
iann dior,,,,,,Mood (2020#47/2021#4)
|
||||
Ice Spice,,,,,,"Barbie World (2023#46)|Boy's A Liar, Pt. 2 (2023#20)|Karma (2023#27)|Princess Diana (2023#69)"
|
||||
Imagine Dragons,,,,,,Believer (2017#9/2018#100)|Enemy (2022#15)|Natural (2018#69)|Sucker For Pain (2016#68)|Thunder (2017#51/2018#22)|Whatever It Takes (2018#37)
|
||||
Infared,,,,,,All The Way Up (2016#87)
|
||||
Internet Money,,,,,,Lemonade (2021#51)
|
||||
J Balvin,,,,,,I Like It (2018#7/2019#69)|Mi Gente (2017#50/2018#99)|RITMO (Bad Boys For Life) (2020#50)|X (2018#90)
|
||||
J. Cole,,,,,,All My Life (2023#25)|First Person Shooter (2024#61)|Middle Child (2019#25)|The London (2019#64)
|
||||
Jack Harlow,,,,,,First Class (2022#6)|Industry Baby (2021#24/2022#16)|Lovin On Me (2024#5)|Whats Poppin (2020#13)
|
||||
Jake Scott,,,,,,She Likes It (2022#91)
|
||||
James Arthur,,,,,,Say You Won't Let Go (2017#11)
|
||||
James Bay,,,,,,Let It Go (2016#44)
|
||||
James Blake,,,,,,King's Dead (2018#79)
|
||||
Jason Aldean,,,,,,Got What I Got (2020#60)|If I Didn't Love You (2021#85)|Trouble With A Heartbreak (2022#88)|Try That In A Small Town (2023#66)|You Make It Easy (2018#70)
|
||||
Jason Derulo,,,,,,Savage Love (Laxed - Siren Beat) (2020#35)|Swalla (2017#85)
|
||||
Jawsh 685,,,,,,Savage Love (Laxed - Siren Beat) (2020#35)
|
||||
Jay Rock,,,,,,King's Dead (2018#79)
|
||||
Jay Z,,,,,,All The Way Up (2016#87)|Pop Style (2016#82)
|
||||
Jelly Roll,,,,,,Hard Fought Hallelujah (2025#84)|I Am Not Okay (2024#75/2025#79)|Liar (2025#86)|Need A Favor (2023#34/2024#64)|Save Me (2024#65)|Wild Ones (2024#36)
|
||||
Jeremih,,,,,,Oui (2016#55)
|
||||
Jessica Darrow,,,,,,Surface Pressure (2022#53)
|
||||
Jessie Murph,,,,,,Blue Strips (2025#52)|High Road (2024#81/2025#55)|Wild Ones (2024#36)
|
||||
Jhay Cortez,,,,,,Dakiti (2021#28)
|
||||
Jhené Aiko,,,,,,P*$$y Fairy (OTW) (2020#94)
|
||||
JID,,,,,,Enemy (2022#15)
|
||||
Jimin,,,,,,Who (2025#57)
|
||||
JNR CHOI,,,,,,To The Moon! (2022#97)
|
||||
John Legend,,,,,,Like I'm Gonna Lose You (2016#42)
|
||||
Joji,,,,,,Glimpse Of Us (2022#52)
|
||||
Jon Bellion,,,,,,All Time Low (2017#75)
|
||||
Jon Pardi,,,,,,Last Night Lonely (2022#95)
|
||||
Jonas Brothers,,,,,,Leave Before You Love Me (2021#63)|Only Human (2019#78/2020#77)|Sucker (2019#10)
|
||||
Jordan Davis,,,,,,Buy Dirt (2022#49)|Next Thing You Know (2023#47)|What My World Spins Around (2023#91)
|
||||
JP Saxe,,,,,,If The World Was Ending (2020#56)
|
||||
Juice WRLD,,,,,,Bandit (2020#63)|Come & Go (2020#54)|Godzilla (2020#62)|Lucid Dreams (2018#12/2019#48)|Robbery (2019#100)|Suicidal (2020#75)|Wishing Well (2020#92)
|
||||
Juicy J,,,,,,Powerglide (2018#97)
|
||||
Julia Michaels,,,,,,If The World Was Ending (2020#56)|Issues (2017#29)
|
||||
Jung Kook,,,,,,Seven (2023#82)
|
||||
Justin Bieber,,,,,,"10,000 Hours (2020#23)|Anyone (2021#74)|Cold Water (2016#25)|Daisies (2025#60)|Despacito (2017#2)|Essence (2021#60/2022#64)|Ghost (2022#8)|Holy (2021#35)|I Don't Care (2019#16)|I'm The One (2017#12)|Intentions (2020#17)|Let Me Love You (2016#47/2017#46)|Lonely (2021#65)|Love Yourself (2016#1)|No Brainer (2018#73)|Peaches (2021#10)|Sorry (2016#2)|Stay (2021#12/2022#3)|Stuck With U (2020#80)|What Do You Mean? (2016#31)|Yummy (2020#58)"
|
||||
Justin Timberlake,,,,,,Can't Stop The Feeling! (2016#9/2017#49)|Say Something (2018#85)
|
||||
JVKE,,,,,,Golden Hour (2023#41)
|
||||
Kacey Musgraves,,,,,,I Remember Everything (2023#74/2024#9)
|
||||
Kai,,,,,,Never Be Like You (2016#60)
|
||||
Kali Uchis,,,,,,Telepatia (2021#49)
|
||||
Kaliii,,,,,,Area Codes (2023#88)
|
||||
Kane Brown,,,,,,Be Like That (2020#88)|Bury Me In Georgia (2023#89)|Famous Friends (2021#69)|Good As You (2019#86)|Heaven (2018#53)|Homesick (2020#89)|Like I Love Country Music (2022#85)|Miles On It (2024#34)|One Mississippi (2022#99)|One Thing Right (2019#89)|Thank God (2023#23)|What Ifs (2017#72)
|
||||
Kanye West,,,,,,Carnival (2024#38)|Pop Style (2016#82)
|
||||
Karol G,,,,,,MAMIII (2022#59)|Provenza (2022#63)|TQG (2023#65)
|
||||
Kate Bush,,,,,,Running Up That Hill (A Deal With God) (2022#23)
|
||||
Katelyn Brown,,,,,,Thank God (2023#23)
|
||||
Katy Perry,,,,,,Chained To The Rhythm (2017#73)|Con Calma (2019#65)|Feels (2017#74)
|
||||
Kehlani,,,,,,Folded (2025#98)
|
||||
Keith Urban,,,,,,One Too Many (2021#81)|The Fighter (2017#100)
|
||||
Kendrick Lamar,,,,,,30 For 30 (2025#21)|All The Stars (2018#47)|DNA. (2017#62)|Don't Wanna Know (2017#38)|Euphoria (2024#66)|Humble. (2017#4)|King's Dead (2018#79)|Like That (2024#14)|Love. (2018#50)|Loyalty. (2017#66)|Luther (2025#2)|Not Like Us (2024#6/2025#17)|Peekaboo (2025#53)|Pray For Me (2018#40)|Squabble Up (2025#20)|TV Off (2025#15)
|
||||
Kenny Chesney,,,,,,Get Along (2018#87)
|
||||
Kent Jones,,,,,,Don't Mind (2016#48)
|
||||
Kesha,,,,,,Praying (2017#67)
|
||||
Kevin Gates,,,,,,2 Phones (2016#57)|Really Really (2016#92)
|
||||
Kevin Woo,,,,,,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Khalid,,,,,,1-800-273-8255 (2017#31/2018#84)|Be Like That (2020#88)|Beautiful People (2019#50)|Better (2019#20)|Eastside (2018#77/2019#17)|Location (2017#21)|Love Lies (2018#19/2019#88)|Talk (2019#8)|Young Dumb & Broke (2017#78/2018#67)
|
||||
Kid Cudi,,,,,,The Scotts (2020#86)
|
||||
Kiiara,,,,,,Gold (2016#52)
|
||||
Kim Petras,,,,,,Unholy (2022#98/2023#11)
|
||||
Kodak Black,,,,,,Drowning (2017#81)|Super Gremlin (2022#9)|Tunnel Vision (2017#55)|Wake Up In The Sky (2019#51)|What It Is (Block Boy) (2023#76)|ZEZE (2019#31)
|
||||
Koe Wetzel,,,,,,High Road (2024#81/2025#55)
|
||||
Kygo,,,,,,It Ain't Me (2017#27)
|
||||
Kyla,,,,,,One Dance (2016#3)
|
||||
KYLE,,,,,,iSpy (2017#28)
|
||||
Lady Gaga,,,,,,Abracadabra (2025#56)|Bloody Mary (2023#99)|Die With A Smile (2024#62/2025#1)|Rain On Me (2020#48)|Shallow (2019#19)
|
||||
Lainey Wilson,,,,,,Heart Like A Truck (2023#58)|Never Say Never (2022#92)|Save Me (2024#65)|Things A Man Oughta Know (2021#96)|Wait In The Truck (2023#54)|Watermelon Moonshine (2023#100)
|
||||
Latto,,,,,,Big Energy (2022#7)|Put It On Da Floor Again (2023#98)|Seven (2023#82)
|
||||
Lauren Alaina,,,,,,What Ifs (2017#72)
|
||||
Lauren Daigle,,,,,,You Say (2019#60)
|
||||
Lauren Spencer-Smith,,,,,,Fingers Crossed (2022#75)
|
||||
Lauv,,,,,,I Like Me Better (2018#35)
|
||||
Lee Brice,,,,,,I Hope You're Happy Now (2020#73)|One Of Them Girls (2020#68)|Rumor (2019#81)
|
||||
Lefty Gunplay,,,,,,TV Off (2025#15)
|
||||
Leon Thomas,,,,,,Mutt (2025#22)
|
||||
Lewis Capaldi,,,,,,Before You Go (2020#21)|Someone You Loved (2019#27/2020#10)
|
||||
Liam Payne,,,,,,Strip That Down (2017#36)
|
||||
Lil Baby,,,,,,Baby (2019#84)|Close Friends (2019#74)|Drip Too Hard (2019#26)|Emotionally Scarred (2020#74)|Every Chance I Get (2021#59)|For The Night (2020#49/2021#32)|In A Minute (2022#43)|On Me (2021#36)|Sum 2 Prove (2020#79)|The Bigger Picture (2020#76)|Wants And Needs (2021#47)|We Paid (2020#57)|Woah (2020#42)|Yes Indeed (2018#25)
|
||||
Lil Dicky,,,,,,Freaky Friday (2018#55)
|
||||
Lil Durk,,,,,,All My Life (2023#25)|Back In Blood (2021#39)|Broadway Girls (2022#81)|Every Chance I Get (2021#59)|Laugh Now Cry Later (2020#41/2021#45)|No More Parties (2021#79)|What Happened To Virgil (2022#83)
|
||||
Lil Mosey,,,,,,Blueberry Faygo (2020#27)
|
||||
Lil Nas X,,,,,,Industry Baby (2021#24/2022#16)|Montero (Call Me By Your Name) (2021#9)|Old Town Road (2019#1)|Panini (2019#40/2020#71)|Thats What I Want (2022#14)
|
||||
Lil Pump,,,,,,Gucci Gang (2018#44)
|
||||
Lil Tecca,,,,,,Dark Thoughts (2025#96)|Ran$om (2019#28)
|
||||
Lil Tjay,,,,,,Calling My Phone (2021#33)|Mood Swings (2020#81)|Pop Out (2019#45)
|
||||
Lil Uzi Vert,,,,,,Bad And Boujee (2017#6)|Everybody (2024#71)|Just Wanna Rock (2023#28)|XO TOUR Llif3 (2017#13)
|
||||
Lil Wayne,,,,,,I'm The One (2017#12)|Sticky (2025#41)|Sucker For Pain (2016#68)|Whats Poppin (2020#13)
|
||||
Lil Yachty,,,,,,Broccoli (2016#34/2017#70)|iSpy (2017#28)
|
||||
Lizzo,,,,,,About Damn Time (2022#12)|Good As Hell (2020#31)|Truth Hurts (2019#13/2020#55)
|
||||
Logic,,,,,,1-800-273-8255 (2017#31/2018#84)|Sucker For Pain (2016#68)
|
||||
Lola Young,,,,,,Like Him (2025#62)|Messy (2025#28)
|
||||
Luis Fonsi,,,,,,Despacito (2017#2)
|
||||
Lukas Graham,,,,,,7 Years (2016#12)
|
||||
Luke Bryan,,,,,,Buy Dirt (2022#49)|Knockin' Boots (2019#79)|One Margarita (2020#70)
|
||||
Luke Combs,,,,,,"Ain't No Love In Oklahoma (2024#37)|Backup Plan (2025#80)|Beautiful Crazy (2019#46)|Beer Never Broke My Heart (2019#63)|Better Together (2021#57)|Does To Me (2020#93)|Doin' This (2022#71)|Even Though I'm Leaving (2020#85)|Fast Car (2023#8/2024#23)|Forever After All (2021#18)|Going, Going, Gone (2023#59)|Hurricane (2017#76)|Love You Anyway (2023#36)|Lovin' On You (2020#97)|One Number Away (2018#96)|The Kind Of Love We Make (2022#36)|Where The Wild Things Are (2024#70)"
|
||||
Machine Gun Kelly,,,,,,Bad Things (2017#41)|My Ex's Best Friend (2021#23)
|
||||
Maddie,,,,,,Die From A Broken Heart (2020#65)
|
||||
Mae Muller,,,,,,Better Days (2022#73)
|
||||
Major Lazer,,,,,,Cold Water (2016#25)|Lean On (2016#85)
|
||||
Maren Morris,,,,,,Chasing After You (2021#61)|Circles Around This Town (2022#100)|The Bones (2020#9)|The Middle (2018#8)
|
||||
Mariah Carey,,,,,,All I Want For Christmas Is You (2020#67/2021#78/2022#65/2023#55/2024#54/2025#59)
|
||||
Mariah the Scientist,,,,,,Burning Blue (2025#58)
|
||||
Marian Hill,,,,,,Down (2017#90)
|
||||
Maroon 5,,,,,,Beautiful Mistakes (2021#34)|Cold (2017#69)|Don't Wanna Know (2017#38)|Girls Like You (2018#10/2019#22)|Memories (2020#8)|Wait (2018#58)|What Lovers Do (2017#97/2018#89)
|
||||
Marshmello,,,,,,Come & Go (2020#54)|Friends (2018#26)|Happier (2018#80/2019#6)|Leave Before You Love Me (2021#63)|Miles On It (2024#34)|One Thing Right (2019#89)|Wolves (2018#60)
|
||||
Masked Wolf,,,,,,Astronaut In The Ocean (2021#20)
|
||||
Mauro Castillo,,,,,,We Don't Talk About Bruno (2022#24)
|
||||
MAX,,,,,,Lights Down Low (2018#66)
|
||||
Meek Mill,,,,,,Going Bad (2019#18)
|
||||
Megan Moroney,,,,,,Am I Okay? (2025#66)|Tennessee Orange (2023#67)
|
||||
Megan Thee Stallion,,,,,,34+35 (2021#21)|Beautiful Mistakes (2021#34)|Body (2021#54)|Cash Shit (2019#90)|Cry Baby (2021#77)|Hot Girl Summer (2019#93)|Savage (2020#15)|Sweetest Pie (2022#62)|Thot Shit (2021#71)|Wanna Be (2024#40)|WAP (2020#24)
|
||||
Meghan Trainor,,,,,,Like I'm Gonna Lose You (2016#42)|Made You Look (2023#53)|Me Too (2016#62)|No (2016#45)
|
||||
Metro Boomin,,,,,,Creepin' (2023#5)|Like That (2024#14)|Ric Flair Drip (2018#38)|Superhero (Heroes & Villains) (2023#38)|Type Shit (2024#51)
|
||||
Migos,,,,,,Bad And Boujee (2017#6)|I Get The Bag (2017#93/2018#72)|MotorSport (2018#34)|Pure Water (2019#55)|Slide (2017#71)|Slippery (2017#86)|Stir Fry (2018#48)|T-Shirt (2017#52)|Walk It Talk It (2018#43)
|
||||
Miguel,,,,,,Sky Walker (2018#75)|Sure Thing (2023#24)
|
||||
Mike Posner,,,,,,I Took A Pill In Ibiza (2016#15)
|
||||
Miley Cyrus,,,,,,Flowers (2023#2/2024#69)|Malibu (2017#89)
|
||||
Miranda Lambert,,,,,,Bluebird (2020#91)
|
||||
MNEK,,,,,,Never Forget You (2016#46)
|
||||
Moneybagg Yo,,,,,,Said Sum (2020#98)|Time Today (2021#76)|Wockesha (2021#42)
|
||||
Mooski,,,,,,Track Star (2021#75)
|
||||
Morgan Wallen,,,,,,20 Cigarettes (2025#90)|Ain't That Some (2023#92)|Broadway Girls (2022#81)|Chasin' You (2020#34)|Cowgirls (2024#29)|Everything I Love (2023#56)|Flower Shops (2022#96)|I Ain't Coming Back (2025#72)|I Got Better (2025#40)|I Had Some Help (2024#4/2025#8)|I Wrote The Book (2023#95)|I'm The Problem (2025#13)|Just In Case (2025#18)|Last Night (2023#1/2024#28)|Lies Lies Lies (2024#50)|Love Somebody (2025#11)|More Than My Hometown (2020#96)|One Thing At A Time (2023#37)|Sand In My Boots (2022#58)|Smile (2025#64)|Superman (2025#99)|Thinkin' Bout Me (2023#19/2024#31)|Thought You Should Know (2023#22)|Wasted On You (2022#19)|What I Want (2025#27)|Whiskey Glasses (2019#52)|You Proof (2022#27/2023#12)
|
||||
Muni Long,,,,,,Hrs And Hrs (2022#57)|Made For Me (2024#56)
|
||||
Murda Beatz,,,,,,FEFE (2018#31)
|
||||
Mustard,,,,,,Ballin' (2020#25)|High Fashion (2020#40)|Pure Water (2019#55)
|
||||
Myles Smith,,,,,,Stargazing (2024#73/2025#29)
|
||||
Måneskin,,,,,,Beggin' (2021#66)
|
||||
MØ,,,,,,Cold Water (2016#25)|Lean On (2016#85)
|
||||
N*E*R*D,,,,,,Lemon (2018#83)
|
||||
Natanael Cano,,,,,,PRC (2023#90)
|
||||
Nate Smith,,,,,,Bulletproof (2024#96)|World On Fire (2024#90)
|
||||
NAV,,,,,,Lemonade (2021#51)
|
||||
Neckwav,,,,,,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
NEIKED,,,,,,Better Days (2022#73)
|
||||
Nelly,,,,,,Lil Bit (2021#70)
|
||||
Netón Vega,,,,,,Loco (2025#100)
|
||||
NF,,,,,,Let You Down (2018#29)
|
||||
Niall Horan,,,,,,Slow Hands (2017#32)
|
||||
Nick Jonas,,,,,,Close (2016#66)
|
||||
Nicki Minaj,,,,,,Barbie World (2023#46)|Big Bank (2018#63)|Down In The DM (2016#69)|Everybody (2024#71)|FEFE (2018#31)|FTCU (2024#88)|Hot Girl Summer (2019#93)|MotorSport (2018#34)|Plain Jane (2018#74)|Princess Diana (2023#69)|Rake It Up (2017#53)|Side To Side (2016#77/2017#43)|Super Freaky Girl (2022#56/2023#79)|Swalla (2017#85)
|
||||
Nicky Jam,,,,,,Te Bote (2018#81)|X (2018#90)
|
||||
Nicky Youre,,,,,,Sunroof (2022#29)
|
||||
Niko Moon,,,,,,Good Time (2021#84)
|
||||
Nio García,,,,,,Te Bote (2018#81)
|
||||
NLE Choppa,,,,,,Shotta Flow (2019#92)|Walk Em Down (2020#100)
|
||||
Noah Kahan,,,,,,Dial Drunk (2023#80)|Stick Season (2024#11)
|
||||
Normani,,,,,,Dancing With A Stranger (2019#14)|Love Lies (2018#19/2019#88)
|
||||
O.T. Genasis,,,,,,Cut It (2016#91)
|
||||
Offset,,,,,,Clout (2019#87)|Ric Flair Drip (2018#38)|Taste (2018#28)|ZEZE (2019#31)
|
||||
Old Dominion,,,,,,Memory Lane (2023#87)|One Man Band (2020#59)
|
||||
Oliver Anthony Music,,,,,,Rich Men North Of Richmond (2023#78)
|
||||
Olivia O'Brien,,,,,,I Hate U I Love U (2016#38)
|
||||
Olivia Rodrigo,,,,,,Deja Vu (2021#13)|Drivers License (2021#8)|Good 4 U (2021#5/2022#31)|Traitor (2021#38)|Vampire (2023#30/2024#57)
|
||||
One Direction,,,,,,Perfect (2016#100)
|
||||
OneRepublic,,,,,,I Ain't Worried (2022#37)
|
||||
Ozuna,,,,,,Taki Taki (2019#57)|Te Bote (2018#81)
|
||||
P!nk,,,,,,Just Like Fire (2016#33)|One Too Many (2021#81)|Walk Me Home (2019#99)|What About Us (2017#84)
|
||||
Panic! At The Disco,,,,,,"Hey Look Ma, I Made It (2019#61)|High Hopes (2019#11)"
|
||||
Parker McCollum,,,,,,Burn It Down (2024#84)|Handle On You (2023#85)
|
||||
Parmalee,,,,,,Just The Way (2021#88)|Take My Name (2022#82)
|
||||
PARTYNEXTDOOR,,,,,,Somebody Loves Me (2025#85)
|
||||
Paul Russell,,,,,,Lil Boo Thang (2024#78)
|
||||
Peso Pluma,,,,,,Ella Baila Sola (2023#26)|La Bebe (2023#40)|Por Las Noches (2023#86)|PRC (2023#90)
|
||||
Pharrell Williams,,,,,,Feels (2017#74)
|
||||
Pinkfong,,,,,,Baby Shark (2019#75)
|
||||
PinkPantheress,,,,,,"Boy's A Liar, Pt. 2 (2023#20)"
|
||||
Playboi Carti,,,,,,Carnival (2024#38)|FE!N (2024#97)|Magnolia (2017#79)|Rather Lie (2025#91)|Timeless (2025#16)|Type Shit (2024#51)
|
||||
PnB Rock,,,,,,Everyday We Lit (2017#95)
|
||||
Polo G,,,,,,Better Days (2022#73)|Pop Out (2019#45)|Rapstar (2021#30)
|
||||
Pooh Shiesty,,,,,,Back In Blood (2021#39)|Beat Box (2021#44)
|
||||
Pop Smoke,,,,,,Dior (2020#83)|For The Night (2020#49/2021#32)|Mood Swings (2020#81)|The Woo (2020#78)|What You Know Bout Love (2021#22)
|
||||
Portugal. The Man,,,,,,Feel It Still (2017#45/2018#33)
|
||||
Post Malone,,,,,,Better Now (2018#13/2019#32)|Chemical (2023#57)|Circles (2019#62/2020#2)|Congratulations (2017#10)|Dial Drunk (2023#80)|Fortnight (2024#22)|Goodbyes (2019#30)|I Ain't Coming Back (2025#72)|I Fall Apart (2018#39)|I Had Some Help (2024#4/2025#8)|I Like You (A Happier Song) (2022#26/2023#75)|One Right Now (2022#30)|Pour Me A Drink (2024#76)|Psycho (2018#6)|Rockstar (2017#56/2018#5)|Sunflower (Spider-Man: Into The Spider-Verse) (2019#2)|White Iverson (2016#65)|Wow. (2019#5)
|
||||
Powfu,,,,,,Death Bed (2020#43)
|
||||
Project Pat,,,,,,Knife Talk (2021#86/2022#60)
|
||||
Quavo,,,,,,Congratulations (2017#10)|I'm The One (2017#12)|Intentions (2020#17)|No Brainer (2018#73)|Strip That Down (2017#36)
|
||||
Rae Sremmurd,,,,,,Black Beatles (2017#19)|Powerglide (2018#97)|Swang (2017#64)
|
||||
Rauw Alejandro,,,,,,Party (2022#77)|Todo de Ti (2021#100)
|
||||
Ravyn Lenae,,,,,,Love Me Not (2025#30)
|
||||
RAYE,,,,,,Escapism (2023#48)
|
||||
REI AMI,,,,,,Golden (2025#25)|How It's Done (2025#68)|Takedown (2025#93)|What It Sounds Like (2025#83)
|
||||
Rema,,,,,,Calm Down (2023#6)
|
||||
Remy Boyz,,,,,,679 (2016#54)
|
||||
Remy Ma,,,,,,All The Way Up (2016#87)
|
||||
Rhenzy Feliz,,,,,,We Don't Talk About Bruno (2022#24)
|
||||
Rich The Kid,,,,,,Carnival (2024#38)|Plug Walk (2018#57)
|
||||
Rick Ross,,,,,,Money In The Grave (2019#34)
|
||||
Rihanna,,,,,,Lemon (2018#83)|Lift Me Up (2023#63)|Love On The Brain (2017#33)|Loyalty. (2017#66)|Needed Me (2016#13)|This Is What You Came For (2016#17)|Too Good (2016#29)|Wild Thoughts (2017#18)|Work (2016#4)
|
||||
Riley Green,,,,,,Worst Way (2025#35)
|
||||
Ritt Momney,,,,,,Put Your Records On (2021#93)
|
||||
Rod Wave,,,,,,Heart On Ice (2020#51)|Rags2Riches (2020#90)|Tombstone (2021#98)
|
||||
Roddy Ricch,,,,,,Ballin' (2020#25)|High Fashion (2020#40)|Late At Night (2021#72)|Rockstar (2020#5)|The Box (2020#3)|The Woo (2020#78)|Walk Em Down (2020#100)
|
||||
ROSÉ,,,,,,APT. (2025#9)
|
||||
Rozes,,,,,,Roses (2016#27)
|
||||
Russell Dickerson,,,,,,Happen To Me (2025#69)|She Likes It (2022#91)
|
||||
Ruth B,,,,,,Lost Boy (2016#76)
|
||||
Ryan Hurd,,,,,,Chasing After You (2021#61)
|
||||
Sabrina Carpenter,,,,,,Bed Chem (2025#45)|Espresso (2024#7/2025#12)|Feather (2024#25)|Manchild (2025#38)|Please Please Please (2024#16/2025#50)|Taste (2024#86/2025#19)
|
||||
SAINt JHN,,,,,,Roses (2020#19)
|
||||
Sam Barber,,,,,,Indigo (2025#49)
|
||||
Sam Hunt,,,,,,Body Like A Back Road (2017#8)|Hard To Forget (2020#69)
|
||||
Sam Smith,,,,,,Dancing With A Stranger (2019#14)|How Do You Sleep? (2019#83)|Too Good At Goodbyes (2017#77/2018#49)|Unholy (2022#98/2023#11)
|
||||
Sam Tompkins,,,,,,To The Moon! (2022#97)
|
||||
samUIL Lee,,,,,,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Saweetie,,,,,,Best Friend (2021#29)|My Type (2019#76)
|
||||
Scotty McCreery,,,,,,Damn Strait (2022#93)
|
||||
Sean Paul,,,,,,Cheap Thrills (2016#11)|Rockabye (2017#44)
|
||||
Selena Gomez,,,,,,Back To You (2018#41)|Calm Down (2023#6)|Hands To Myself (2016#56)|It Ain't Me (2017#27)|Lose You To Love Me (2020#30)|Same Old Love (2016#40)|Taki Taki (2019#57)|We Don't Talk Anymore (2016#50)|Wolves (2018#60)
|
||||
Sexyy Red,,,,,,Get It Sexyy (2024#55)|Rich Baby Daddy (2024#45)|Sticky (2025#41)|Whatchu Kno About Me (2025#48)
|
||||
Shaboozey,,,,,,A Bar Song (Tipsy) (2024#2/2025#3)|Good News (2025#23)
|
||||
SHAED,,,,,,Trampoline (2019#70/2020#53)
|
||||
Shakira,,,,,,"Bzrp Music Sessions, Vol. 53 (2023#96)|TQG (2023#65)"
|
||||
Shawn Mendes,,,,,,I Know What You Did Last Summer (2016#86)|If I Can't Have You (2019#29)|In My Blood (2018#46)|Mercy (2017#54)|Senorita (2019#15/2020#44)|Stitches (2016#23)|There's Nothing Holdin' Me Back (2017#23)|Treat You Better (2016#28/2017#92)
|
||||
Shay Mooney,,,,,,"10,000 Hours (2020#23)|All To Myself (2019#97)|Glad You Exist (2021#64)|Speechless (2019#35)|Tequila (2018#32/2019#91)"
|
||||
Sheck Wes,,,,,,Mo Bamba (2019#49)
|
||||
Sia,,,,,,Cheap Thrills (2016#11)
|
||||
Silentó,,,,,,Watch Me (2016#88)
|
||||
Skip Marley,,,,,,Chained To The Rhythm (2017#73)
|
||||
Snow,,,,,,Con Calma (2019#65)
|
||||
Social House,,,,,,Boyfriend (2019#98)
|
||||
sombr,,,,,,Back To Friends (2025#44)|Undressed (2025#42)
|
||||
SpotemGottem,,,,,,Beat Box (2021#44)
|
||||
StaySolidRocky,,,,,,Party Girl (2020#64)
|
||||
Stephanie Beatriz,,,,,,We Don't Talk About Bruno (2022#24)
|
||||
Stephen Sanchez,,,,,,Until I Found You (2023#50)
|
||||
Steve Lacy,,,,,,Bad Habit (2022#28/2023#39)
|
||||
Summer Walker,,,,,,Good Good (2024#79)|Heart Of A Woman (2025#94)
|
||||
Surf Mesa,,,,,,ily (2020#95)
|
||||
Surfaces,,,,,,Sunday Best (2020#61)
|
||||
Swae Lee,,,,,,Be Like That (2020#88)|Close To Me (2019#58)|Sunflower (Spider-Man: Into The Spider-Verse) (2019#2)|Unforgettable (2017#15)
|
||||
SZA,,,,,,30 For 30 (2025#21)|All The Stars (2018#47)|BMF (2025#76)|Good Days (2021#52)|I Hate U (2022#50)|Kill Bill (2023#3)|Kiss Me More (2021#6/2022#90)|Love Galore (2017#80)|Luther (2025#2)|Nobody Gets Me (2023#77)|Rich Baby Daddy (2024#45)|Saturn (2024#19)|Shirt (2023#51)|Snooze (2023#9/2024#20)|What Lovers Do (2017#97/2018#89)
|
||||
Tae,,,,,,Die From A Broken Heart (2020#65)
|
||||
Tate McRae,,,,,,Exes (2024#93)|Greedy (2024#13)|Revolving Door (2025#82)|She's All I Wanna Be (2022#94)|Sports Car (2025#46)|What I Want (2025#27)|You Broke Me First. (2021#37)
|
||||
Taylor Swift,,,,,,All Too Well (Taylor's Version) (2022#76)|Anti-Hero (2023#4)|Cruel Summer (2023#18/2024#12)|Delicate (2018#24)|Down Bad (2024#99)|Fortnight (2024#22)|I Can Do It With A Broken Heart (2024#35)|I Don't Wanna Live Forever (Fifty Shades Darker) (2017#26)|Is It Over Now? (Taylor's Version) [From The Vault] (2024#33)|Karma (2023#27)|Lavender Haze (2023#32)|Look What You Made Me Do (2017#39)|ME! (2019#43)|Wildest Dreams (2016#79)|Willow (2021#55)|You Need To Calm Down (2019#39)
|
||||
Teddy Swims,,,,,,Bad Dreams (2025#74)|Lose Control (2024#1/2025#4)
|
||||
Tems,,,,,,Essence (2021#60/2022#64)|Wait For U (2022#11/2023#83)
|
||||
Teo,,,,,,Rolex (2017#61)
|
||||
The Chainsmokers,,,,,,Closer (2016#10/2017#7)|Don't Let Me Down (2016#8)|Paris (2017#42)|Roses (2016#27)|Something Just Like This (2017#5)
|
||||
The Kid LAROI,,,,,,Stay (2021#12/2022#3)|Without You (2021#17)
|
||||
The Marías,,,,,,No One Noticed (2025#32)
|
||||
The Weeknd,,,,,,Blinding Lights (2020#1/2021#3)|Call Out My Name (2018#78)|Can't Feel My Face (2016#72)|Creepin' (2023#5)|Cry For Me (2025#73)|Die For You (2023#7)|Heartless (2020#28)|I Feel It Coming (2017#34)|In The Night (2016#61)|Low Life (2016#30)|One Right Now (2022#30)|Pray For Me (2018#40)|Rather Lie (2025#91)|Save Your Tears (2021#2/2022#40)|Starboy (2016#58/2017#20)|Take My Breath (2021#89)|The Hills (2016#32)|Timeless (2025#16)|You Right (2021#43/2022#45)
|
||||
Thomas Rhett,,,,,,After All The Bars Are Closed (2025#88)|Die A Happy Man (2016#64)|Look What God Gave Her (2019#85)|Marry Me (2018#76)|What's Your Country Song (2021#80)
|
||||
Tim McGraw,,,,,,Humble And Kind (2016#96)
|
||||
Tommy Richman,,,,,,Million Dollar Baby (2024#8)
|
||||
Tones And I,,,,,,Dance Monkey (2020#14)
|
||||
Toosii,,,,,,Favorite Song (2023#21)
|
||||
Tory Lanez,,,,,,Luv (2016#70)|Say It (2016#74)|Whats Poppin (2020#13)
|
||||
Tove Lo,,,,,,Close (2016#66)
|
||||
Travis Scott,,,,,,Antidote (2016#75)|FE!N (2024#97)|Goosebumps (2017#68)|HIGHEST IN THE ROOM (2020#45)|Love Galore (2017#80)|Meltdown (2023#97)|Sicko Mode (2018#42/2019#9)|Sky Walker (2018#75)|The London (2019#64)|The Scotts (2020#86)|Type Shit (2024#51)|ZEZE (2019#31)
|
||||
Trevor Daniel,,,,,,Falling (2020#22)
|
||||
Tucker Wetmore,,,,,,Wind Up Missin' You (2024#95)
|
||||
twenty one pilots,,,,,,Heathens (2016#21/2017#58)|Ride (2016#20)|Stressed Out (2016#5)
|
||||
Ty Dolla $ign,,,,,,Carnival (2024#38)|Hot Girl Summer (2019#93)|Psycho (2018#6)|Sucker For Pain (2016#68)|Swalla (2017#85)|Work From Home (2016#16)
|
||||
Tyga,,,,,,Juicy (2020#87)|Taste (2018#28)
|
||||
Tyla,,,,,,Water (2024#24)
|
||||
Tyler Cole,,,,,,Meet Me At Our Spot (2022#74)
|
||||
Tyler Hubbard,,,,,,5 Foot 9 (2022#67)|Dancin' In The Country (2023#61)
|
||||
"Tyler, The Creator",,,,,,Like Him (2025#62)|Sticky (2025#41)
|
||||
Usher,,,,,,Good Good (2024#79)|No Limit (2016#90)
|
||||
Victoria Monét,,,,,,On My Mama (2024#91)
|
||||
Walker Hayes,,,,,,AA (2022#61)|Fancy Like (2021#27/2022#35)
|
||||
Warren Zeiders,,,,,,Pretty Little Poison (2024#60)
|
||||
Wham!,,,,,,Last Christmas (2023#84/2024#74/2025#65)
|
||||
WILLOW,,,,,,Meet Me At Our Spot (2022#74)
|
||||
Willy William,,,,,,Mi Gente (2017#50/2018#99)
|
||||
Wiz Khalifa,,,,,,See You Again (2016#99)|Sucker For Pain (2016#68)
|
||||
Wizkid,,,,,,Essence (2021#60/2022#64)|One Dance (2016#3)
|
||||
X Ambassadors,,,,,,Sucker For Pain (2016#68)|Unsteady (2016#67)
|
||||
Xavi,,,,,,La Diabla (2024#72)
|
||||
XXXTENTACION,,,,,,Changes (2018#94)|Look At Me! (2017#99)|Moonlight (2018#88)|Sad! (2018#17)
|
||||
Yeat,,,,,,IDGAF (2024#83)
|
||||
YFN Lucci,,,,,,Everyday We Lit (2017#95)
|
||||
YG,,,,,,Big Bank (2018#63)|Slide (2020#99)
|
||||
YK Osiris,,,,,,Worth It (2019#77)
|
||||
Yng Lvcas,,,,,,La Bebe (2023#40)
|
||||
YNW Melly,,,,,,Murder On My Mind (2019#66)|Suicidal (2020#75)
|
||||
Yo Gotti,,,,,,Down In The DM (2016#69)|Rake It Up (2017#53)
|
||||
Young Dolph,,,,,,Cut It (2016#91)
|
||||
Young Nudy,,,,,,Peaches & Eggplants (2023#94)
|
||||
Young Thug,,,,,,Go Crazy (2020#39/2021#19)|Goodbyes (2019#30)|Havana (2017#96/2018#4)|Hot (2020#72)|No Limit (2016#90)|Pushin P (2022#48)|The London (2019#64)|Way 2 Sexy (2021#48)
|
||||
YoungBoy Never Broke Again,,,,,,Bandit (2020#63)|Outside Today (2018#91)
|
||||
Yung Bleu,,,,,,You're Mines Still (2021#58)
|
||||
Zacari,,,,,,Love. (2018#50)
|
||||
Zach Bryan,,,,,,I Remember Everything (2023#74/2024#9)|Pink Skies (2024#30)|Something In The Orange (2022#39/2023#13)
|
||||
Zach Top,,,,,,I Never Lie (2025#43)
|
||||
Zara Larsson,,,,,,Never Forget You (2016#46)
|
||||
Zay Hilfigerrr,,,,,,Juju On That Beat (TZ Anthem) (2017#63)
|
||||
Zayion McCall,,,,,,Juju On That Beat (TZ Anthem) (2017#63)
|
||||
Zayn,,,,,,I Don't Wanna Live Forever (Fifty Shades Darker) (2017#26)|Pillowtalk (2016#22)
|
||||
Zedd,,,,,,Starving (2016#94/2017#82)|Stay (2017#17)|The Middle (2018#8)
|
||||
Óscar Maydon,,,,,,Tu Boda (2025#87)
|
||||
Name,Wikidata QID,Gender,Type,Genre,Country,Songs
|
||||
070 Shake,Q54861040,female,solo,hip-hop; cloud rap; alternative hip-hop,United States,Escapism (2023#48)
|
||||
2 Chainz,Q129668,male,solo,Southern hip-hop; trap music; gangsta rap; dirty south; Atlanta hip-hop; hardcore hip-hop,United States,Big Bank (2018#63)
|
||||
21 Savage,Q25095399,male,solo,hip-hop; trap music,United Kingdom,A Lot (2019#42)|Bank Account (2017#48)|Bartier Cardi (2018#61)|Creepin' (2023#5)|Good Good (2024#79)|Jimmy Cooks (2022#33)|Knife Talk (2021#86/2022#60)|Peaches & Eggplants (2023#94)|Redrum (2024#42)|Rich Flex (2023#14)|Rockstar (2017#56/2018#5)|Spin Bout U (2023#43)
|
||||
24kGoldn,Q83751918,male,solo,pop rap,United States,Mood (2020#47/2021#4)
|
||||
42 Dugg,Q95694810,male,solo,Michigan rap; Midwest hip-hop; trap music; gangsta rap,United States,We Paid (2020#57)
|
||||
4batz,Q124313062,male,solo,contemporary R&B,United States,Act II: Date @ 8 (2024#80)
|
||||
5 Seconds of Summer,Q4641147,,group,pop rock; pop-punk,Australia,Youngblood (2018#36/2019#33)
|
||||
50 Cent,Q6060,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop,United States,The Woo (2020#78)
|
||||
6ix9ine,Q44479972,male,solo,hip-hop; East Coast hip-hop; gangsta rap; trap metal; hardcore hip-hop; SoundCloud rap; punk rap; drill; trap music; urbano music; reggaeton; Brooklyn drill,United States,FEFE (2018#31)|Gummo (2018#56)|Swervin (2019#82)
|
||||
6LACK,Q27886640,male,solo,alternative R&B; contemporary R&B; trap music; cloud rap; industrial music; soul; hip-hop soul,United States,Calling My Phone (2021#33)
|
||||
A Boogie wit da Hoodie,Q27927826,male,solo,hip-hop; trap music,United States,Drowning (2017#81)|Look Back At It (2019#41)|Swervin (2019#82)
|
||||
A$AP Ferg,Q15648254,male,solo,East Coast hip-hop; trap music,United States,Plain Jane (2018#74)
|
||||
A$AP Rocky,Q129910,male,solo,East Coast hip-hop; psychedelic rap; experimental hip-hop; alternative hip-hop; cloud rap; trap music,United States,No Limit (2018#30)
|
||||
Adassa,Q576181,female,solo,reggaeton; urban contemporary; pop music,United States,We Don't Talk About Bruno (2022#24)
|
||||
Adele,Q23215,female,solo,pop music; blue-eyed soul; rhythm and blues; soul; jazz; rock music,United Kingdom,Easy On Me (2022#4)|Hello (2016#7)|Oh My God (2022#72)|Send My Love (To Your New Lover) (2016#26)|Water Under The Bridge (2017#88)|When We Were Young (2016#83)
|
||||
AJR,Q16154058,,group,indie pop; alternative pop; electropop,United States,Bang! (2021#56)
|
||||
Alessia Cara,Q20090091,female,solo,contemporary R&B; indie pop; pop music; soul; alternative R&B,Italy,1-800-273-8255 (2017#31/2018#84)|Here (2016#39)|Scars To Your Beautiful (2017#30)|Stay (2017#17)
|
||||
Alex Warren,Q121842162,male,solo,pop music,United States,Ordinary (2025#7)
|
||||
Aminé,Q27830860,male,solo,West Coast hip-hop; alternative hip-hop; trap music; contemporary R&B,United States,Caroline (2017#60)
|
||||
Anderson .Paak,Q20810369,male,solo,contemporary R&B; hip-hop; soul; funk; pop music,United States,Leave The Door Open (2021#7)|Smokin Out The Window (2022#41)
|
||||
Andrew Choi,Q15229870,male,solo,K-pop; pop music; contemporary R&B,South Korea,Free (2025#92)|Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Anne-Marie,Q25396976,female,solo,pop music; contemporary R&B,United Kingdom,Friends (2018#26)|Rockabye (2017#44)
|
||||
Aqua,Q213388,,group,pop music; bubblegum music; Eurodance,Denmark,Barbie World (2023#46)
|
||||
Ariana Grande,Q151892,female,solo,pop music; contemporary R&B; electronic dance music,United States,"34+35 (2021#21)|7 Rings (2019#7)|Boyfriend (2019#98)|Break Up With Your Girlfriend, I'm Bored (2019#36)|Breathin (2019#72)|Dangerous Woman (2016#36)|Die For You (2023#7)|God Is A Woman (2018#62)|Into You (2016#51)|No Tears Left To Cry (2018#20)|Positions (2021#14)|pov (2021#87)|Rain On Me (2020#48)|Save Your Tears (2021#2/2022#40)|Side To Side (2016#77/2017#43)|Stuck With U (2020#80)|Thank U, Next (2019#12)|We Can't Be Friends (Wait For Your Love) (2024#26)|Yes, And? (2024#92)"
|
||||
Arizona Zervas,Q75124792,male,solo,hip-hop; contemporary R&B; pop music,United States,Roxanne (2020#16)
|
||||
Artemas,Q125176874,male,solo,alternative pop,United Kingdom,I Like The Way You Kiss Me (2024#63)
|
||||
ATR Son Son,Q140814072,male,solo,hip-hop,United States,Rags2Riches (2020#90)
|
||||
Audrey Nuna,Q105538243,female,solo,K-pop; pop music; hip-hop; contemporary R&B; trap music,United States,Golden (2025#25)|How It's Done (2025#68)|Takedown (2025#93)|What It Sounds Like (2025#83)
|
||||
Ava Max,Q56755505,female,solo,dance-pop,United States,Kings & Queens (2021#73)|Sweet But Psycho (2019#23)
|
||||
Avery Anna,Q131401753,female,solo,pop rock; country music,United States,Indigo (2025#49)
|
||||
Ayo,Q55860029,male,solo,hip-hop,United States,Rolex (2017#61)
|
||||
AzChike,Q131417489,male,solo,hip-hop,United States,Peekaboo (2025#53)
|
||||
Bad Bunny,Q44333953,male,solo,Latin trap; reggaeton,Puerto Rico,Baile Inolvidable (2025#70)|Dakiti (2021#28)|Despues de La Playa (2022#78)|DTMF (2025#51)|Efecto (2022#69)|EOO (2025#77)|I Like It (2018#7/2019#69)|Me Porto Bonito (2022#20)|MIA (2019#44)|Monaco (2024#82)|Moscow Mule (2022#44)|Nuevayol (2025#89)|Ojitos Lindos (2022#87)|Party (2022#77)|Te Bote (2018#81)|Titi Me Pregunto (2022#22)|Un x100to (2023#49)|Where She Goes (2023#72)|Yonaguni (2021#83)
|
||||
Bailey Zimmerman,Q112581616,male,solo,country music,United States,All The Way (2025#33)|Backup Plan (2025#80)|Fall In Love (2022#54)|Religiously (2023#42)|Rock And A Hard Place (2022#70/2023#16)|Where It Ends (2024#87)
|
||||
Bastille,Q689,,group,synth-pop,United Kingdom,Happier (2018#80/2019#6)
|
||||
Bazzi,Q48720231,male,solo,pop music,United States,Beautiful (2019#95)|Mine (2018#21)
|
||||
beabadoobee,Q66817366,female,solo,indie rock; space rock; alternative rock; slacker rock; indie pop; folk-pop; bedroom pop,Philippines,Death Bed (2020#43)
|
||||
Bebe Rexha,Q16185856,female,solo,pop music; contemporary R&B,United States,"I'm Good (Blue) (2023#10)|Me, Myself & I (2016#19)|Meant To Be (2018#3)"
|
||||
Becky G,Q1393997,female,solo,pop music; hip-hop; Latin music; Latin pop; reggaeton,United States,MAMIII (2022#59)
|
||||
BENEE,Q61749159,female,solo,alternative pop; soul,New Zealand,Supalonely (2020#84)
|
||||
benny blanco,Q818048,male,solo,pop music,United States,Eastside (2018#77/2019#17)|Lonely (2021#65)
|
||||
Benson Boone,Q110008128,male,solo,pop music; pop rock,United States,Beautiful Things (2024#3/2025#6)|Mystical Magical (2025#47)|Slow It Down (2024#41)|Sorry I'm Here For Someone Else (2025#37)
|
||||
Beyoncé,Q36153,female,solo,pop music; contemporary R&B; country music,United States,Break My Soul (2022#38)|Cuff It (2023#29)|Mi Gente (2017#50/2018#99)|Sorry (2016#71)|Texas Hold 'Em (2024#32)
|
||||
Big Sean,Q367634,male,solo,hip-hop; Midwest hip-hop; Michigan rap; pop rap,United States,Big Bank (2018#63)|Bounce Back (2017#35)|Feels (2017#74)
|
||||
BigXthaPlug,Q124750337,male,solo,rapping; hip-hop,United States,All The Way (2025#33)
|
||||
Billie Eilish,Q29564107,female,solo,electropop; indie pop; alternative pop,United States,Bad Guy (2019#4/2020#46)|Birds Of A Feather (2024#15/2025#5)|Bury A Friend (2019#73)|Everything I Wanted (2020#18)|Happier Than Ever (2021#94)|Lunch (2024#48)|Therefore I Am (2021#25)|What Was I Made For? (2023#81/2024#46)|When The Party's Over (2019#67)|Wildflower (2024#89/2025#26)
|
||||
Billy Ray Cyrus,Q231259,male,solo,country music; country pop; country rock; country blues,United States,Old Town Road (2019#1)
|
||||
Bipolar Sunshine,Q16727521,male,solo,pop music,United Kingdom,Middle (2016#80)
|
||||
Bizarrap,Q99937928,male,solo,Latin trap; reggaeton,Argentina,"Bzrp Music Sessions, Vol. 53 (2023#96)"
|
||||
Black Eyed Peas,Q134541,,group,alternative hip-hop; pop rap; hip-hop; pop music; Latin hip-hop,United States,RITMO (Bad Boys For Life) (2020#50)
|
||||
blackbear,Q22974007,male,solo,pop music; emo; contemporary R&B; hip-hop,United States,Do Re Mi (2017#98)|Hot Girl Bummer (2020#26)|My Ex's Best Friend (2021#23)
|
||||
Blake Shelton,Q94831,male,solo,country music,United States,God's Country (2019#53)|Nobody But You (2020#52)|Pour Me A Drink (2024#76)
|
||||
Blanco Brown,Q64736729,male,solo,country rap; trap music; hip-hop,United States,Just The Way (2021#88)|The Git Up (2019#56)
|
||||
BlocBoy JB,Q49481016,male,solo,hip-hop; trap music,United States,Look Alive (2018#23)
|
||||
Blueface,Q60463134,male,solo,hip-hop; trap music; West Coast hip-hop; gangsta rap,United States,Thotiana (2019#47)
|
||||
Bobby Helms,Q888554,male,solo,country music,United States,Jingle Bell Rock (2022#86/2023#68/2024#68/2025#81)
|
||||
Bomba Estéreo,Q887911,,group,cumbia,Colombia,Ojitos Lindos (2022#87)
|
||||
Bradley Cooper,Q205707,male,solo,,United States,Shallow (2019#19)
|
||||
Brandon Lake,Q100314823,male,solo,contemporary Christian music; Christian rock,United States,Hard Fought Hallelujah (2025#84)
|
||||
Brenda Lee,Q230925,female,solo,rock and roll; country music; pop music; rockabilly,United States,Rockin' Around The Christmas Tree (2021#92/2022#80/2023#60/2024#59/2025#67)
|
||||
Brendon Urie,Q1047474,male,solo,pop rock; alternative rock,United States,ME! (2019#43)
|
||||
Brett Young,Q25189679,male,solo,country music,United States,In Case You Didn't Know (2017#57)|Mercy (2018#95)
|
||||
BRS Kash,Q105409004,male,solo,hip-hop,United States,Throat Baby (Go Baby) (2021#97)
|
||||
Bruno Mars,Q1450,male,solo,pop music; contemporary R&B; hip-hop; new wave; reggae; funk,United States,24K Magic (2017#16)|APT. (2025#9)|Die With A Smile (2024#62/2025#1)|Finesse (2018#14)|Leave The Door Open (2021#7)|Please Me (2019#37)|Smokin Out The Window (2022#41)|That's What I Like (2017#3)|Wake Up In The Sky (2019#51)
|
||||
Bryson Tiller,Q21066641,male,solo,contemporary R&B; hip-hop; trap music; soul,United States,Don't (2016#35)|Exchange (2016#53)|Whatever She Wants (2024#58)|Wild Thoughts (2017#18)
|
||||
BTS,Q13580495,,group,K-pop; dance-pop; Korean hip-hop,South Korea,Butter (2021#11)|Dynamite (2020#38/2021#41)
|
||||
Burl Ives,Q315723,male,solo,folk music,United States,A Holly Jolly Christmas (2022#89/2023#71/2024#94)
|
||||
Calboy,Q66085272,male,solo,hip-hop,United States,Envy Me (2019#59)
|
||||
Calvin Harris,Q81637,male,solo,electronic dance music; electronic pop; acid house,United Kingdom,Feels (2017#74)|One Kiss (2018#68)|Slide (2017#71)|This Is What You Came For (2016#17)
|
||||
Camila Cabello,Q18810940,female,solo,pop music; contemporary R&B; Latin pop; Gothic pop,Cuba,Bad Things (2017#41)|Bam Bam (2022#66)|Beautiful (2019#95)|Havana (2017#96/2018#4)|I Know What You Did Last Summer (2016#86)|My Oh My (2020#37)|Never Be The Same (2018#18)|Senorita (2019#15/2020#44)
|
||||
Cardi B,Q29033668,female,solo,hip-hop; pop music; pop rap,United States,Bartier Cardi (2018#61)|Be Careful (2018#59)|Bodak Yellow (Money Moves) (2017#24/2018#54)|Clout (2019#87)|Finesse (2018#14)|Girls Like You (2018#10/2019#22)|I Like It (2018#7/2019#69)|Money (2019#38)|MotorSport (2018#34)|No Limit (2018#30)|Please Me (2019#37)|Put It On Da Floor Again (2023#98)|Taki Taki (2019#57)|Tomorrow 2 (2023#70)|Up (2021#26)|WAP (2020#24)
|
||||
Carly Pearce,Q29913337,female,solo,country music,United States,I Hope You're Happy Now (2020#73)
|
||||
Carolina Gaitán,Q5753201,female,solo,,Colombia,We Don't Talk About Bruno (2022#24)
|
||||
Carrie Underwood,Q215546,female,solo,pop music; country music; country pop; country rock,United States,I'm Gonna Love You (2025#78)|If I Didn't Love You (2021#85)|The Fighter (2017#100)
|
||||
Cash Cobain,Q125989634,male,solo,hip-hop; drill; Jersey drill; pop rap; East Coast hip-hop; trap music,United States,Somebody Loves Me (2025#85)
|
||||
Casper Mágico,Q60333702,male,solo,Latin trap; reggaeton,United States,Te Bote (2018#81)
|
||||
Chance the Rapper,Q12470060,male,solo,hip-hop; alternative hip-hop; contemporary R&B; conscious hip-hop; alternative R&B; gospel music,United States,Holy (2021#35)|I'm The One (2017#12)|No Brainer (2018#73)
|
||||
Chappell Roan,Q110281146,female,solo,synth-pop; pop music; electronic music,United States,"Good Luck, Babe! (2024#18/2025#31)|Hot To Go! (2024#53)|Pink Pony Club (2025#10)"
|
||||
Charlie Puth,Q19810390,male,solo,pop music; contemporary R&B,United States,Attention (2017#22)|How Long (2018#65)|I Hope (2020#12/2021#40)|One Call Away (2016#43)|See You Again (2016#99)|We Don't Talk Anymore (2016#50)
|
||||
Chase Rice,Q5087189,male,solo,country music,United States,Drinkin' Beer. Talkin' God. Amen. (2021#99)|Eyes On You (2019#96)
|
||||
Cheat Codes,Q23978754,,group,electronic music; electronic dance music; tropical house; dancehall,United States,No Promises (2017#91)
|
||||
Chencho Corleone,Q113625582,male,solo,reggaeton,United States,Me Porto Bonito (2022#20)
|
||||
Childish Gambino,Q1239933,male,solo,hip-hop; funk; contemporary R&B; soul; psychedelic music; indie pop; comedy hip-hop,United States,Redbone (2017#25)|This Is America (2018#51)
|
||||
Chris Brown,Q155700,male,solo,contemporary R&B; pop music; hip-hop,United States,Back To Sleep (2016#89)|Freaky Friday (2018#55)|Go Crazy (2020#39/2021#19)|No Guidance (2019#21/2020#36)|Residuals (2025#63)|Superhero (Heroes & Villains) (2023#38)|Under The Influence (2023#17)
|
||||
Chris Stapleton,Q5108148,male,solo,country music,United States,Say Something (2018#85)|Starting Over (2021#53)|White Horse (2024#77)|You Should Probably Leave (2022#79)
|
||||
Chris Young,Q952176,male,solo,country music,United States,Famous Friends (2021#69)
|
||||
City Girls,Q60658858,,group,hip-hop,United States,Act Up (2019#68)
|
||||
CJ,Q103868817,male,solo,drill; trap music; East Coast hip-hop; hip-hop,United States,Whoopty (2021#50)
|
||||
CKay,Q98312451,male,solo,Afrobeats,Nigeria,Love Nwantiti (Ah Ah Ah) (2022#55)
|
||||
Clean Bandit,Q11838808,,group,electropop,United Kingdom,Rockabye (2017#44)
|
||||
Cody Johnson,Q17916913,male,solo,country music; country rock,United States,'Til You Can't (2022#34)|I'm Gonna Love You (2025#78)|The Painter (2024#98)
|
||||
Coi Leray,Q106376206,female,solo,hip-hop; pop music,United States,No More Parties (2021#79)|Players (2023#33)
|
||||
Coldplay,Q45188,,group,alternative rock; pop music,United Kingdom,Adventure Of A Lifetime (2016#95)|Hymn For The Weekend (2016#73)|Something Just Like This (2017#5)
|
||||
Cole Swindell,Q15101510,male,solo,country music,United States,Never Say Never (2022#92)|She Had Me At Heads Carolina (2022#46)|Single Saturday Night (2021#95)
|
||||
Corey Kent,Q113452679,male,solo,country music,United States,Wild As Her (2023#93)
|
||||
Cris MJ,Q111425015,male,solo,reggaeton,Chile,Gata Only (2024#52)
|
||||
D.R.A.M.,Q25138504,male,solo,Southern hip-hop; contemporary R&B; trap music,United States,Broccoli (2016#34/2017#70)
|
||||
DaBaby,Q62107457,male,solo,hip-hop; trap music; pop rap; Southern hip-hop,United States,Baby (2019#84)|Beat Box (2021#44)|BOP (2020#29)|Cash Shit (2019#90)|Cry Baby (2021#77)|For The Night (2020#49/2021#32)|My Oh My (2020#37)|Rockstar (2020#5)|Suge (2019#24)|Whats Poppin (2020#13)
|
||||
Daddy Yankee,Q272591,male,solo,reggaeton; Latin hip-hop,United States,Con Calma (2019#65)|Despacito (2017#2)|Dura (2018#93)
|
||||
Daft Punk,Q185828,,group,house music; electronic music; French house; synth-pop; electronic rock; electronica; nu-disco; dance music; leftfield house,France,I Feel It Coming (2017#34)|Starboy (2016#58/2017#20)
|
||||
Dan Smyers,Q57630595,male,solo,country music,United States,"10,000 Hours (2020#23)|All To Myself (2019#97)|Glad You Exist (2021#64)|Speechless (2019#35)|Tequila (2018#32/2019#91)"
|
||||
Daniel Caesar,Q29589083,male,solo,contemporary R&B; soul; neo soul,Canada,Peaches (2021#10)
|
||||
Danny Chung,Q140814119,male,solo,hip-hop; K-pop,United States,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Darell,Q56467651,male,solo,reggaeton; Latin trap,United States,Te Bote (2018#81)
|
||||
Dasha,Q125157260,female,solo,country pop,United States,Austin (2024#27)
|
||||
David Guetta,Q8298,male,solo,electronic dance music; house music; electroclash; electro house,France,I'm Good (Blue) (2023#10)
|
||||
David Kushner,Q117745879,male,solo,,United States,Daylight (2023#62)
|
||||
Daya,Q21005558,female,solo,pop music,United States,"Don't Let Me Down (2016#8)|Hide Away (2016#84)|Sit Still, Look Pretty (2016#78)"
|
||||
dazy,Q140814120,male,solo,pop music,,Sunroof (2022#29)
|
||||
Dean Lewis,Q29905254,male,solo,pop music,Australia,Be Alright (2019#54)
|
||||
Demi Lovato,Q41173,genderfluid,solo,pop rock; pop music; contemporary R&B; power pop; dance-pop; teen pop; electropop; soul; pop-punk; nu metal,United States,No Promises (2017#91)|Sorry Not Sorry (2017#47/2018#64)
|
||||
Desiigner,Q23091498,male,solo,hip-hop; East Coast hip-hop; trap music; mumble rap; hardcore hip-hop,United States,Panda (2016#6)|Tiimmy Turner (2016#98)
|
||||
Diane Guerrero,Q17166318,female,solo,,United States,We Don't Talk About Bruno (2022#24)
|
||||
Diplo,Q533781,male,solo,electronic dance music; trap music; hip-hop; pop music; moombahton; electropop; house music; EDM trap music,United States,Close To Me (2019#58)
|
||||
DJ Khaled,Q80805,male,solo,hip-hop; pop rap,United States,Every Chance I Get (2021#59)|For Free (2016#59)|I'm The One (2017#12)|No Brainer (2018#73)|Popstar (2020#66)|Wild Thoughts (2017#18)
|
||||
DJ Snake,Q16728588,male,solo,electronic dance music; EDM trap music,France,Lean On (2016#85)|Let Me Love You (2016#47/2017#46)|Middle (2016#80)|Taki Taki (2019#57)
|
||||
Djo,Q27064031,male,solo,synth-pop,United States,End Of Beginning (2024#47)
|
||||
DNCE,Q21648421,,group,pop rock,United States,Cake By The Ocean (2016#18)
|
||||
Doechii,Q106629186,female,solo,hip-hop; contemporary R&B; pop music; alternative hip-hop; pop rap,United States,Anxiety (2025#39)|Denial Is A River (2025#75)|What It Is (Block Boy) (2023#76)
|
||||
Doja Cat,Q51120673,female,solo,contemporary R&B; pop music; electronic music; indie pop; hip-hop,United States,34+35 (2021#21)|Agora Hills (2024#17)|Best Friend (2021#29)|Get Into It (Yuh) (2022#68)|I Like You (A Happier Song) (2022#26/2023#75)|Juicy (2020#87)|Kiss Me More (2021#6/2022#90)|Need To Know (2021#46/2022#18)|Paint The Town Red (2023#52/2024#21)|Say So (2020#11)|Streets (2021#67)|Vegas (2022#47)|Woman (2022#21)|You Right (2021#43/2022#45)
|
||||
Don Toliver,Q56513383,male,solo,hip-hop; trap music; contemporary R&B,United States,Lemonade (2021#51)|No Pole (2025#97)
|
||||
Dove Cameron,Q13560423,female,solo,pop music; alternative pop; soul,United States,Boyfriend (2022#51)
|
||||
Drake,Q33240,male,solo,hip-hop; contemporary R&B; pop music; trap music,Canada,Act II: Date @ 8 (2024#80)|Both (2017#83)|Controlla (2016#41)|Fake Love (2017#37)|First Person Shooter (2024#61)|For Free (2016#59)|God's Plan (2018#1)|Going Bad (2019#18)|Hotline Bling (2016#24)|I'm Upset (2018#86)|IDGAF (2024#83)|In My Feelings (2018#9)|Jimmy Cooks (2022#33)|Jumpman (2016#37)|Knife Talk (2021#86/2022#60)|Laugh Now Cry Later (2020#41/2021#45)|Life Is Good (2020#7)|Look Alive (2018#23)|Meltdown (2023#97)|MIA (2019#44)|Money In The Grave (2019#34)|Nice For What (2018#11)|No Guidance (2019#21/2020#36)|Nokia (2025#24)|Nonstop (2018#52)|One Dance (2016#3)|Passionfruit (2017#65)|Pop Style (2016#82)|Popstar (2020#66)|Rich Baby Daddy (2024#45)|Rich Flex (2023#14)|Search & Rescue (2023#45)|Somebody Loves Me (2025#85)|Spin Bout U (2023#43)|Too Good (2016#29)|Toosie Slide (2020#32)|Wait For U (2022#11/2023#83)|Walk It Talk It (2018#43)|Wants And Needs (2021#47)|Way 2 Sexy (2021#48)|What's Next (2021#68)|Work (2016#4)|Yes Indeed (2018#25)|You're Mines Still (2021#58)
|
||||
Dua Lipa,Q21914464,female,solo,pop music; post-disco; house music; funktronica; indie pop; dream pop; synth-pop,United Kingdom,Break My Heart (2020#33)|Cold Heart (PNAU Remix) (2022#10)|Dance The Night (2023#35/2024#100)|Don't Start Now (2020#4)|Houdini (2024#43)|IDGAF (2018#98)|Levitating (2021#1/2022#42)|New Rules (2018#16)|One Kiss (2018#68)|Sweetest Pie (2022#62)|We're Good (2021#90)
|
||||
Duncan Laurence,Q60758679,male,solo,pop music,Kingdom of the Netherlands,Arcade (2021#82)
|
||||
Dustin Lynch,Q5317118,male,solo,country music,United States,Small Town Boy (2017#94)
|
||||
Ed Sheeran,Q47447,male,solo,pop music; folk music; hip-hop; dance music; soul; rock music,United Kingdom,Bad Habits (2021#15/2022#13)|Bam Bam (2022#66)|Beautiful People (2019#50)|Castle On The Hill (2017#40)|Eyes Closed (2023#64)|I Don't Care (2019#16)|Perfect (2018#2)|Shape Of You (2017#1/2018#71)|Shivers (2022#5)
|
||||
EJAE,Q135108208,female,solo,K-pop; pop music; contemporary R&B,South Korea,Free (2025#92)|Golden (2025#25)|How It's Done (2025#68)|Takedown (2025#93)|What It Sounds Like (2025#83)
|
||||
Ella Langley,Q127559972,female,solo,country music,United States,Weren't For The Wind (2025#71)
|
||||
Ella Mai,Q29033458,female,solo,contemporary R&B,United Kingdom,Boo'd Up (2018#15)|Trip (2018#92/2019#80)
|
||||
Elle King,Q5364665,female,solo,country music; Americana; blues rock; alternative country,United States,Ex's & Oh's (2016#63)
|
||||
Ellie Goulding,Q31164,female,solo,synth-pop; electropop; indie pop; folktronica; alternative rock; alternative music; dream pop; indietronica,United Kingdom,Close To Me (2019#58)|On My Mind (2016#81)
|
||||
Elton John,Q2808,male,solo,rock music; pop rock; glam rock; soft rock; rhythm and blues,United Kingdom,Cold Heart (PNAU Remix) (2022#10)
|
||||
Em Beihold,Q111333139,female,solo,pop music,United States,Numb Little Bug (2022#32)
|
||||
Emilee,Q98635221,female,solo,pop music,United States,ily (2020#95)
|
||||
Eminem,Q5608,male,solo,hip-hop; horrorcore; hardcore hip-hop; comedy hip-hop; Midwest hip-hop; rap rock,United States,Godzilla (2020#62)|Houdini (2024#39)
|
||||
Encanto Cast,Q140814124,,,,United States,We Don't Talk About Bruno (2022#24)
|
||||
Eric Church,Q975911,male,solo,country music,United States,Does To Me (2020#93)|Hell Of A View (2021#91)
|
||||
ERNEST,Q110442717,male,solo,country music,United States,Cowgirls (2024#29)|Flower Shops (2022#96)
|
||||
Eslabón Armado,Q112702265,,group,regional Mexican,United States,Ella Baila Sola (2023#26)
|
||||
Fat Joe,Q309888,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop; boom bap; mafioso rap,United States,All The Way Up (2016#87)
|
||||
Fetty Wap,Q19361511,male,solo,hip-hop; trap music; pop rap,United States,679 (2016#54)|All In My Head (Flex) (2016#93)
|
||||
Fifth Harmony,Q3087893,,group,pop music,United States,All In My Head (Flex) (2016#93)|Work From Home (2016#16)
|
||||
Fifty Fifty,Q116731010,,group,K-pop; J-pop,South Korea,Cupid (2023#44)
|
||||
Flipp Dinero,Q57584556,male,solo,hip-hop,United States,Leave Me Alone (2019#71)
|
||||
Flo Milli,Q89352069,female,solo,hip-hop,United States,Never Lose Me (2024#49)
|
||||
Flo Rida,Q213538,male,solo,hip-hop; pop music; dance music; electronic dance music; Southern hip-hop; contemporary R&B; house music; electro hop; electro house; electropop; electro; EDM trap music; trap music; bass music; crunk; pop rap; dirty south; dance-pop; hip house; Miami bass; electronic music; techno; trance,United States,My House (2016#14)
|
||||
Florida Georgia Line,Q3644642,,group,country music,United States,Drinkin' Beer. Talkin' God. Amen. (2021#99)|H.O.L.Y. (2016#49)|Lil Bit (2021#70)|Meant To Be (2018#3)|Simple (2018#82)|Talk You Out Of It (2019#94)
|
||||
FloyyMenor,Q125819969,male,solo,reggaeton,Chile,Gata Only (2024#52)
|
||||
Flume,Q4038837,male,solo,electronica; trip hop; future bass,Australia,Never Be Like You (2016#60)
|
||||
Frank Ocean,Q357645,male,solo,alternative R&B; psychedelic soul; progressive soul; contemporary R&B; pop music; soul; hip-hop; avant-pop,United States,Slide (2017#71)
|
||||
French Montana,Q1455261,male,solo,East Coast hip-hop; gangsta rap; hardcore hip-hop,Morocco,All The Way Up (2016#87)|Unforgettable (2017#15)
|
||||
Fuerza Regida,Q118466501,,group,regional Mexican; banda music; corrido; corridos tumbados; sierreña; norteño,United States,Bebe Dame (2023#73)|Tu Boda (2025#87)
|
||||
Future,Q3445057,male,solo,Southern hip-hop; trap music; mumble rap; contemporary R&B,United States,Cold (2017#69)|Jumpman (2016#37)|King's Dead (2018#79)|Life Is Good (2020#7)|Like That (2024#14)|Low Life (2016#30)|Mask Off (2017#14)|Puffin On Zootiez (2022#84)|Pushin P (2022#48)|Superhero (Heroes & Villains) (2023#38)|Type Shit (2024#51)|Wait For U (2022#11/2023#83)|Way 2 Sexy (2021#48)|Wicked (2016#97)
|
||||
G-Eazy,Q5511893,male,solo,hip-hop,United States,"Him & I (2018#45)|Me, Myself & I (2016#19)|No Limit (2018#30)"
|
||||
Gabby Barrett,Q53912835,female,solo,country pop,United States,I Hope (2020#12/2021#40)|The Good Ones (2021#62)
|
||||
GAYLE,Q109768702,female,solo,pop-punk; pop rock; power pop; emo pop; alternative pop; alternative rock,United States,abcdefu (2022#17)
|
||||
Gigi Perez,Q130235359,female,solo,indie folk,United States,Sailor Song (2025#36)
|
||||
Giveon,Q96418479,male,solo,contemporary R&B,United States,Heartbreak Anniversary (2021#31)|Peaches (2021#10)
|
||||
Glass Animals,Q16839267,,group,indie rock; psychedelic pop; indietronica; alternative pop; electronic rock; psychedelic rock,United Kingdom,Heat Waves (2021#16/2022#1)
|
||||
GloRilla,Q114132368,female,solo,hip-hop; trap music; crunk; Memphis rap; Southern hip-hop,United States,Sticky (2025#41)|Tomorrow 2 (2023#70)|Wanna Be (2024#40)|Whatchu Kno About Me (2025#48)|Yeah Glo! (2024#44)
|
||||
gnash,Q23978226,male,solo,pop music; hip-hop; alternative R&B; indie folk,United States,I Hate U I Love U (2016#38)|Lights Down Low (2018#66)
|
||||
Gracie Abrams,Q106301562,female,solo,bedroom pop; pop music,United States,That's So True (2025#14)
|
||||
Grey,Q28451953,,group,electronic music; pop music; future bass,United States,Starving (2016#94/2017#82)|The Middle (2018#8)
|
||||
Grupo Frontera,Q118141487,,group,regional Mexican; norteño; cumbia norteña mexicana,United States,Bebe Dame (2023#73)|Un x100to (2023#49)
|
||||
Gucci Mane,Q206032,male,solo,Southern hip-hop; trap music; gangsta rap; hardcore hip-hop; dirty south; Atlanta hip-hop; dirty rap,United States,Black Beatles (2017#19)|Both (2017#83)|I Get The Bag (2017#93/2018#72)|Slippery (2017#86)|Wake Up In The Sky (2019#51)
|
||||
Gunna,Q55613105,male,solo,hip-hop; trap music; Southern hip-hop; contemporary R&B,United States,Drip Too Hard (2019#26)|Fukumean (2023#31/2024#85)|Hot (2020#72)|Lemonade (2021#51)|Pushin P (2022#48)|What Happened To Virgil (2022#83)
|
||||
Gus Dapperton,Q51858412,male,solo,pop music,United States,Supalonely (2020#84)
|
||||
Gwen Stefani,Q483379,female,solo,pop music; contemporary R&B; ska; electronica; new wave; rock music,United States,Nobody But You (2020#52)
|
||||
H.E.R.,Q30639849,female,solo,contemporary R&B,United States,Slide (2020#99)
|
||||
Hailee Steinfeld,Q231726,female,solo,pop music; dance-pop,United States,Starving (2016#94/2017#82)
|
||||
Halsey,Q18534249,female,solo,pop music; electropop; synth-pop; art pop; alternative pop; alternative rock; alternative R&B; indie pop; contemporary R&B,United States,Bad At Love (2018#27)|Closer (2016#10/2017#7)|Eastside (2018#77/2019#17)|Him & I (2018#45)|Now Or Never (2017#59)|Without Me (2019#3)|You Should Be Sad (2020#82)
|
||||
HARDY,Q63341424,male,solo,country music,United States,Truck Bed (2024#67)|Wait In The Truck (2023#54)
|
||||
Harry Styles,Q3626966,male,solo,soft rock; pop music; rock music; Britpop; traditional folk music,United Kingdom,Adore You (2020#6)|As It Was (2022#2/2023#15)|Late Night Talking (2022#25)|Sign Of The Times (2017#87)|Watermelon Sugar (2020#20)
|
||||
Hozier,Q16233232,male,solo,blues; blues rock; rhythm and blues; traditional folk music; soul; indie rock,Ireland,Too Sweet (2024#10/2025#34)
|
||||
Hudson Westbrook,Q134125831,male,solo,country music,United States,House Again (2025#95)
|
||||
iann dior,Q65631841,male,solo,emo rap; pop rap; rap rock; pop rock,United States,Mood (2020#47/2021#4)
|
||||
Ice Spice,Q114114977,female,solo,Bronx drill; hip-hop; East Coast hip-hop; Jersey club; pop rap,United States,"Barbie World (2023#46)|Boy's A Liar, Pt. 2 (2023#20)|Karma (2023#27)|Princess Diana (2023#69)"
|
||||
Imagine Dragons,Q391348,,group,pop rock; electropop; alternative rock; new wave,United States,Believer (2017#9/2018#100)|Enemy (2022#15)|Natural (2018#69)|Sucker For Pain (2016#68)|Thunder (2017#51/2018#22)|Whatever It Takes (2018#37)
|
||||
Infared,Q140814135,male,solo,hip-hop,,All The Way Up (2016#87)
|
||||
Internet Money,Q99691610,,,hip-hop,United States,Lemonade (2021#51)
|
||||
J Balvin,Q966845,male,solo,reggaeton; Latin pop; Latin trap,Colombia,I Like It (2018#7/2019#69)|Mi Gente (2017#50/2018#99)|RITMO (Bad Boys For Life) (2020#50)|X (2018#90)
|
||||
J. Cole,Q204018,male,solo,hip-hop; Southern hip-hop; pop rap; East Coast hip-hop; conscious hip-hop,United States,All My Life (2023#25)|First Person Shooter (2024#61)|Middle Child (2019#25)|The London (2019#64)
|
||||
Jack Harlow,Q59727812,male,solo,hip-hop; pop rap,United States,First Class (2022#6)|Industry Baby (2021#24/2022#16)|Lovin On Me (2024#5)|Whats Poppin (2020#13)
|
||||
Jake Scott,Q140814152,male,solo,pop music,United States,She Likes It (2022#91)
|
||||
James Arthur,Q717626,male,solo,pop music,United Kingdom,Say You Won't Let Go (2017#11)
|
||||
James Bay,Q17811637,male,solo,rock music; pop music; soul; Americana,United Kingdom,Let It Go (2016#44)
|
||||
James Blake,Q350362,male,solo,pop music; electronica; post-dubstep; electronic dance music,United Kingdom,King's Dead (2018#79)
|
||||
Jason Aldean,Q195439,male,solo,country music,United States,Got What I Got (2020#60)|If I Didn't Love You (2021#85)|Trouble With A Heartbreak (2022#88)|Try That In A Small Town (2023#66)|You Make It Easy (2018#70)
|
||||
Jason Derulo,Q243639,male,solo,pop music; rhythm and blues; contemporary R&B; hip-hop,United States,Savage Love (Laxed - Siren Beat) (2020#35)|Swalla (2017#85)
|
||||
Jawsh 685,Q96472235,male,solo,pop music,New Zealand,Savage Love (Laxed - Siren Beat) (2020#35)
|
||||
Jay Rock,Q152632,male,solo,West Coast hip-hop,United States,King's Dead (2018#79)
|
||||
Jay Z,Q62766,male,solo,East Coast hip-hop; mafioso rap; gangsta rap; hardcore hip-hop,United States,All The Way Up (2016#87)|Pop Style (2016#82)
|
||||
Jelly Roll,Q6176881,male,solo,Southern hip-hop; country rap; country music; hardcore hip-hop,United States,Hard Fought Hallelujah (2025#84)|I Am Not Okay (2024#75/2025#79)|Liar (2025#86)|Need A Favor (2023#34/2024#64)|Save Me (2024#65)|Wild Ones (2024#36)
|
||||
Jeremih,Q472891,male,solo,contemporary R&B,United States,Oui (2016#55)
|
||||
Jessica Darrow,Q109718598,non-binary,solo,,United States,Surface Pressure (2022#53)
|
||||
Jessie Murph,Q122157373,female,solo,country rock; country pop; pop music,United States,Blue Strips (2025#52)|High Road (2024#81/2025#55)|Wild Ones (2024#36)
|
||||
Jhay Cortez,Q75997191,male,solo,Latin trap; reggaeton; Latin R&B,United States,Dakiti (2021#28)
|
||||
Jhené Aiko,Q15929781,female,solo,hip-hop; pop music; rhythm and blues; soul; alternative R&B; neo soul; contemporary R&B,United States,P*$$y Fairy (OTW) (2020#94)
|
||||
JID,Q29588830,male,solo,hip-hop,United States,Enemy (2022#15)
|
||||
Jimin,Q20947093,male,solo,K-pop,South Korea,Who (2025#57)
|
||||
JNR CHOI,Q111507858,male,solo,hip-hop; trap music; world music,United Kingdom,To The Moon! (2022#97)
|
||||
John Legend,Q44857,male,solo,soul; pop music; contemporary R&B,United States,Like I'm Gonna Lose You (2016#42)
|
||||
Joji,Q23826617,male,solo,contemporary R&B; alternative R&B; trip hop; lo-fi music; surreal humour; satirical music; satire; comedy hip-hop; black comedy; alternative rock; comedy music,Japan,Glimpse Of Us (2022#52)
|
||||
Jon Bellion,Q18044284,male,solo,pop music; contemporary R&B; hip-hop; indie rock; pop rap; alternative hip-hop; indie pop; alternative rock; dance-pop; soul,United States,All Time Low (2017#75)
|
||||
Jon Pardi,Q6271354,male,solo,country music,United States,Last Night Lonely (2022#95)
|
||||
Jonas Brothers,Q134233,,group,pop music; pop rock,United States,Leave Before You Love Me (2021#63)|Only Human (2019#78/2020#77)|Sucker (2019#10)
|
||||
Jordan Davis,Q44274417,male,solo,country pop; country music; pop music,United States,Buy Dirt (2022#49)|Next Thing You Know (2023#47)|What My World Spins Around (2023#91)
|
||||
JP Saxe,Q86009464,male,solo,pop music,Canada,If The World Was Ending (2020#56)
|
||||
Juice WRLD,Q52151598,male,solo,hip-hop; emo rap; alternative rock; trap music; pop rap; SoundCloud rap; contemporary R&B; alternative hip-hop; mumble rap,United States,Bandit (2020#63)|Come & Go (2020#54)|Godzilla (2020#62)|Lucid Dreams (2018#12/2019#48)|Robbery (2019#100)|Suicidal (2020#75)|Wishing Well (2020#92)
|
||||
Juicy J,Q602779,male,solo,Southern hip-hop; gangsta rap; trap music; dirty rap; Memphis rap; dirty south; horrorcore; hardcore hip-hop; crunk,United States,Powerglide (2018#97)
|
||||
Julia Michaels,Q20051697,female,solo,pop music; electronic dance music,United States,If The World Was Ending (2020#56)|Issues (2017#29)
|
||||
Jung Kook,Q22338877,male,solo,K-pop,South Korea,Seven (2023#82)
|
||||
Justin Bieber,Q34086,male,solo,pop music; contemporary R&B; tropical house; reggaeton; contemporary country,Canada,"10,000 Hours (2020#23)|Anyone (2021#74)|Cold Water (2016#25)|Daisies (2025#60)|Despacito (2017#2)|Essence (2021#60/2022#64)|Ghost (2022#8)|Holy (2021#35)|I Don't Care (2019#16)|I'm The One (2017#12)|Intentions (2020#17)|Let Me Love You (2016#47/2017#46)|Lonely (2021#65)|Love Yourself (2016#1)|No Brainer (2018#73)|Peaches (2021#10)|Sorry (2016#2)|Stay (2021#12/2022#3)|Stuck With U (2020#80)|What Do You Mean? (2016#31)|Yummy (2020#58)"
|
||||
Justin Timberlake,Q43432,male,solo,pop music; contemporary R&B,United States,Can't Stop The Feeling! (2016#9/2017#49)|Say Something (2018#85)
|
||||
JVKE,Q114865231,male,solo,pop music,United States,Golden Hour (2023#41)
|
||||
Kacey Musgraves,Q2783855,female,solo,country music; folk music,United States,I Remember Everything (2023#74/2024#9)
|
||||
Kai,Q6347342,female,solo,pop music,Canada,Never Be Like You (2016#60)
|
||||
Kali Uchis,Q19004484,female,solo,contemporary R&B,United States,Telepatia (2021#49)
|
||||
Kaliii,Q115633164,female,solo,hip-hop; trap music; Southern hip-hop,United States,Area Codes (2023#88)
|
||||
Kane Brown,Q21620939,male,solo,country music,United States,Be Like That (2020#88)|Bury Me In Georgia (2023#89)|Famous Friends (2021#69)|Good As You (2019#86)|Heaven (2018#53)|Homesick (2020#89)|Like I Love Country Music (2022#85)|Miles On It (2024#34)|One Mississippi (2022#99)|One Thing Right (2019#89)|Thank God (2023#23)|What Ifs (2017#72)
|
||||
Kanye West,Q15935,male,solo,hip-hop; pop music; electro; soul; gospel music; progressive rap; art pop; pop rap; hip-hop soul; chipmunk soul; contemporary R&B,United States,Carnival (2024#38)|Pop Style (2016#82)
|
||||
Karol G,Q22001324,female,solo,reggaeton; Latin pop; Latin R&B,Colombia,MAMIII (2022#59)|Provenza (2022#63)|TQG (2023#65)
|
||||
Kate Bush,Q636,female,solo,art pop; progressive pop; singer-songwriter music; baroque pop; experimental pop; art rock; pop rock,United Kingdom,Running Up That Hill (A Deal With God) (2022#23)
|
||||
Katelyn Brown,Q140814175,female,solo,pop music,United States,Thank God (2023#23)
|
||||
Katy Perry,Q42493,female,solo,pop music; rock music; pop rock; dance music; synth-pop; electropop; gospel music,United States,Chained To The Rhythm (2017#73)|Con Calma (2019#65)|Feels (2017#74)
|
||||
Kehlani,Q20657541,non-binary,solo,contemporary R&B; pop music; neo soul; hip-hop,United States,Folded (2025#98)
|
||||
Keith Urban,Q315547,male,solo,country music,Australia,One Too Many (2021#81)|The Fighter (2017#100)
|
||||
Kendrick Lamar,Q130798,male,solo,West Coast hip-hop; progressive rap; alternative hip-hop; jazz rap; conscious hip-hop; gangsta rap; hardcore hip-hop; jazz; pop music,United States,30 For 30 (2025#21)|All The Stars (2018#47)|DNA. (2017#62)|Don't Wanna Know (2017#38)|Euphoria (2024#66)|Humble. (2017#4)|King's Dead (2018#79)|Like That (2024#14)|Love. (2018#50)|Loyalty. (2017#66)|Luther (2025#2)|Not Like Us (2024#6/2025#17)|Peekaboo (2025#53)|Pray For Me (2018#40)|Squabble Up (2025#20)|TV Off (2025#15)
|
||||
Kenny Chesney,Q467526,male,solo,country music,United States,Get Along (2018#87)
|
||||
Kent Jones,Q25190082,male,solo,pop rap; contemporary R&B; pop music,United States,Don't Mind (2016#48)
|
||||
Kesha,Q33605,female,solo,electropop; dance-pop; synth-pop; pop rock; pop rap; rock music; dance music; country music,United States,Praying (2017#67)
|
||||
Kevin Gates,Q6396353,male,solo,hip-hop; gangsta rap; hardcore hip-hop; dirty south; Southern hip-hop,United States,2 Phones (2016#57)|Really Really (2016#92)
|
||||
Kevin Woo,Q6397789,male,solo,K-pop,United States,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Khalid,Q28816483,male,solo,contemporary R&B,United States,1-800-273-8255 (2017#31/2018#84)|Be Like That (2020#88)|Beautiful People (2019#50)|Better (2019#20)|Eastside (2018#77/2019#17)|Location (2017#21)|Love Lies (2018#19/2019#88)|Talk (2019#8)|Young Dumb & Broke (2017#78/2018#67)
|
||||
Kid Cudi,Q299138,male,solo,Midwest hip-hop; contemporary R&B; alternative hip-hop; pop rap; alternative rock; trip hop; neo-psychedelia; punk rock; grunge; emo rap; psychedelic rap; psychedelic hip-hop,United States,The Scotts (2020#86)
|
||||
Kiiara,Q23042767,female,solo,pop music; electropop; alternative R&B; experimental pop,United States,Gold (2016#52)
|
||||
Kim Petras,Q60964,trans woman,solo,pop music,Germany,Unholy (2022#98/2023#11)
|
||||
Kodak Black,Q22005867,male,solo,hip-hop; trap music; SoundCloud rap; gangsta rap; Southern hip-hop; mumble rap,United States,Drowning (2017#81)|Super Gremlin (2022#9)|Tunnel Vision (2017#55)|Wake Up In The Sky (2019#51)|What It Is (Block Boy) (2023#76)|ZEZE (2019#31)
|
||||
Koe Wetzel,Q107434048,male,solo,country music; rock music,United States,High Road (2024#81/2025#55)
|
||||
Kygo,Q16845512,male,solo,tropical house; deep house; downtempo; progressive house; house music; electronic dance music,Norway,It Ain't Me (2017#27)
|
||||
Kyla,Q25190133,female,solo,UK funky,United Kingdom,One Dance (2016#3)
|
||||
KYLE,Q28606665,male,solo,West Coast hip-hop; pop rap,United States,iSpy (2017#28)
|
||||
Lady Gaga,Q19848,female,solo,electropop; dance-pop; electronic dance music; art pop; pop music; synth-pop,United States,Abracadabra (2025#56)|Bloody Mary (2023#99)|Die With A Smile (2024#62/2025#1)|Rain On Me (2020#48)|Shallow (2019#19)
|
||||
Lainey Wilson,Q106378786,female,solo,country music; folk music,United States,Heart Like A Truck (2023#58)|Never Say Never (2022#92)|Save Me (2024#65)|Things A Man Oughta Know (2021#96)|Wait In The Truck (2023#54)|Watermelon Moonshine (2023#100)
|
||||
Latto,Q65029930,female,solo,hip-hop; trap music; pop music; pop rap,United States,Big Energy (2022#7)|Put It On Da Floor Again (2023#98)|Seven (2023#82)
|
||||
Lauren Alaina,Q271796,female,solo,country music; folk music,United States,What Ifs (2017#72)
|
||||
Lauren Daigle,Q18685595,female,solo,contemporary Christian music,United States,You Say (2019#60)
|
||||
Lauren Spencer-Smith,Q110630787,female,solo,pop music,Canada,Fingers Crossed (2022#75)
|
||||
Lauv,Q30122224,male,solo,electronic music; pop music,United States,I Like Me Better (2018#35)
|
||||
Lee Brice,Q1811729,male,solo,country music,United States,I Hope You're Happy Now (2020#73)|One Of Them Girls (2020#68)|Rumor (2019#81)
|
||||
Lefty Gunplay,Q131374668,male,solo,hip-hop; West Coast hip-hop; gangsta rap,United States,TV Off (2025#15)
|
||||
Leon Thomas,Q714375,male,solo,contemporary R&B; pop music; soul; hip-hop,United States,Mutt (2025#22)
|
||||
Lewis Capaldi,Q42315001,male,solo,blue-eyed soul; pop music; pop rock; alternative rock; soft rock,United Kingdom,Before You Go (2020#21)|Someone You Loved (2019#27/2020#10)
|
||||
Liam Payne,Q2756349,male,solo,pop music; contemporary R&B,United Kingdom,Strip That Down (2017#36)
|
||||
Lil Baby,Q50527563,male,solo,hip-hop; trap music; Southern hip-hop,United States,Baby (2019#84)|Close Friends (2019#74)|Drip Too Hard (2019#26)|Emotionally Scarred (2020#74)|Every Chance I Get (2021#59)|For The Night (2020#49/2021#32)|In A Minute (2022#43)|On Me (2021#36)|Sum 2 Prove (2020#79)|The Bigger Picture (2020#76)|Wants And Needs (2021#47)|We Paid (2020#57)|Woah (2020#42)|Yes Indeed (2018#25)
|
||||
Lil Dicky,Q16876006,male,solo,hip-hop; pop rap; comedy hip-hop,United States,Freaky Friday (2018#55)
|
||||
Lil Durk,Q2899818,male,solo,Midwest hip-hop; trap music; drill; gangsta rap; hardcore hip-hop; Chicago hip-hop; Chicago drill,United States,All My Life (2023#25)|Back In Blood (2021#39)|Broadway Girls (2022#81)|Every Chance I Get (2021#59)|Laugh Now Cry Later (2020#41/2021#45)|No More Parties (2021#79)|What Happened To Virgil (2022#83)
|
||||
Lil Mosey,Q55819454,male,solo,hip-hop; pop rap; trap music,United States,Blueberry Faygo (2020#27)
|
||||
Lil Nas X,Q62591281,male,solo,hip-hop; pop rap; country rap; trap music; pop music; rock music; pop rock; country music; Southern hip-hop,United States,Industry Baby (2021#24/2022#16)|Montero (Call Me By Your Name) (2021#9)|Old Town Road (2019#1)|Panini (2019#40/2020#71)|Thats What I Want (2022#14)
|
||||
Lil Pump,Q38002101,male,solo,hip-hop; trap music; SoundCloud rap; punk rap; Southern hip-hop,United States,Gucci Gang (2018#44)
|
||||
Lil Tecca,Q65054660,male,solo,hip-hop; trap music,United States,Dark Thoughts (2025#96)|Ran$om (2019#28)
|
||||
Lil Tjay,Q61670761,male,solo,hip-hop,United States,Calling My Phone (2021#33)|Mood Swings (2020#81)|Pop Out (2019#45)
|
||||
Lil Uzi Vert,Q23771950,non-binary,solo,hip-hop; emo rap; trap music; SoundCloud rap; punk rap; psychedelic rap; rage; cloud rap; psychedelic hip-hop; East Coast hip-hop,United States,Bad And Boujee (2017#6)|Everybody (2024#71)|Just Wanna Rock (2023#28)|XO TOUR Llif3 (2017#13)
|
||||
Lil Wayne,Q15615,male,solo,Southern hip-hop; bounce music; gangsta rap; trap music; pop rap; dirty south; hardcore hip-hop,United States,I'm The One (2017#12)|Sticky (2025#41)|Sucker For Pain (2016#68)|Whats Poppin (2020#13)
|
||||
Lil Yachty,Q23772141,male,solo,hip-hop; trap music; pop rap; mumble rap; cloud rap; Southern hip-hop,United States,Broccoli (2016#34/2017#70)|iSpy (2017#28)
|
||||
Lizzo,Q16232225,female,solo,hip-hop; soul; contemporary R&B; gospel music,United States,About Damn Time (2022#12)|Good As Hell (2020#31)|Truth Hurts (2019#13/2020#55)
|
||||
Logic,Q6667429,male,solo,hip-hop; pop rap; conscious hip-hop; East Coast hip-hop,United States,1-800-273-8255 (2017#31/2018#84)|Sucker For Pain (2016#68)
|
||||
Lola Young,Q115869427,female,solo,pop music; soul; contemporary R&B,United Kingdom,Like Him (2025#62)|Messy (2025#28)
|
||||
Luis Fonsi,Q1387726,male,solo,pop music; Latin pop; ballad; reggaeton,United States,Despacito (2017#2)
|
||||
Lukas Graham,Q300935,,group,soul; pop music; pop rock; funk,Denmark,7 Years (2016#12)
|
||||
Luke Bryan,Q166197,male,solo,country music,United States,Buy Dirt (2022#49)|Knockin' Boots (2019#79)|One Margarita (2020#70)
|
||||
Luke Combs,Q23884740,male,solo,country music,United States,"Ain't No Love In Oklahoma (2024#37)|Backup Plan (2025#80)|Beautiful Crazy (2019#46)|Beer Never Broke My Heart (2019#63)|Better Together (2021#57)|Does To Me (2020#93)|Doin' This (2022#71)|Even Though I'm Leaving (2020#85)|Fast Car (2023#8/2024#23)|Forever After All (2021#18)|Going, Going, Gone (2023#59)|Hurricane (2017#76)|Love You Anyway (2023#36)|Lovin' On You (2020#97)|One Number Away (2018#96)|The Kind Of Love We Make (2022#36)|Where The Wild Things Are (2024#70)"
|
||||
Machine Gun Kelly,Q1354843,male,solo,hip-hop; pop rap; rap rock; pop-punk; alternative rock; alternative hip-hop,United States,Bad Things (2017#41)|My Ex's Best Friend (2021#23)
|
||||
Maddie,Q54607228,female,solo,country music,United States,Die From A Broken Heart (2020#65)
|
||||
Mae Muller,Q83696883,female,solo,pop music; rhythm and blues,United Kingdom,Better Days (2022#73)
|
||||
Major Lazer,Q2604214,,group,dancehall; moombahton; reggae fusion; trap music; electronic dance music; hip-hop; electro house; rocksteady,United States,Cold Water (2016#25)|Lean On (2016#85)
|
||||
Maren Morris,Q21622122,female,solo,country music; country pop; folk rock; folk music,United States,Chasing After You (2021#61)|Circles Around This Town (2022#100)|The Bones (2020#9)|The Middle (2018#8)
|
||||
Mariah Carey,Q41076,female,solo,contemporary R&B; pop music; adult contemporary music; dance-pop; hip-hop,United States,All I Want For Christmas Is You (2020#67/2021#78/2022#65/2023#55/2024#54/2025#59)
|
||||
Mariah the Scientist,Q84356665,female,solo,alternative R&B,United States,Burning Blue (2025#58)
|
||||
Marian Hill,Q20858093,,group,electronic music,United States,Down (2017#90)
|
||||
Maroon 5,Q182223,,group,alternative rock; funk rock; pop rock; pop music,United States,Beautiful Mistakes (2021#34)|Cold (2017#69)|Don't Wanna Know (2017#38)|Girls Like You (2018#10/2019#22)|Memories (2020#8)|Wait (2018#58)|What Lovers Do (2017#97/2018#89)
|
||||
Marshmello,Q26334949,male,solo,electronic dance music,United States,Come & Go (2020#54)|Friends (2018#26)|Happier (2018#80/2019#6)|Leave Before You Love Me (2021#63)|Miles On It (2024#34)|One Thing Right (2019#89)|Wolves (2018#60)
|
||||
Masked Wolf,Q105490126,male,solo,hip-hop,Australia,Astronaut In The Ocean (2021#20)
|
||||
Mauro Castillo,Q16605580,male,solo,salsa,Colombia,We Don't Talk About Bruno (2022#24)
|
||||
MAX,Q1190160,male,solo,pop music,United States,Lights Down Low (2018#66)
|
||||
Meek Mill,Q1897911,male,solo,East Coast hip-hop; hardcore hip-hop; gangsta rap; trap music; hip-hop,United States,Going Bad (2019#18)
|
||||
Megan Moroney,Q116786312,female,solo,country music; folk music,United States,Am I Okay? (2025#66)|Tennessee Orange (2023#67)
|
||||
Megan Thee Stallion,Q59268408,female,solo,hip-hop; trap music; dirty rap; pop rap; pop music,United States,34+35 (2021#21)|Beautiful Mistakes (2021#34)|Body (2021#54)|Cash Shit (2019#90)|Cry Baby (2021#77)|Hot Girl Summer (2019#93)|Savage (2020#15)|Sweetest Pie (2022#62)|Thot Shit (2021#71)|Wanna Be (2024#40)|WAP (2020#24)
|
||||
Meghan Trainor,Q17403494,female,solo,pop music; contemporary R&B; dance-pop; soul; doo-wop,United States,Like I'm Gonna Lose You (2016#42)|Made You Look (2023#53)|Me Too (2016#62)|No (2016#45)
|
||||
Metro Boomin,Q16235273,male,solo,hip-hop; trap music,United States,Creepin' (2023#5)|Like That (2024#14)|Ric Flair Drip (2018#38)|Superhero (Heroes & Villains) (2023#38)|Type Shit (2024#51)
|
||||
Migos,Q15777045,,group,Southern hip-hop; trap music; mumble rap,United States,Bad And Boujee (2017#6)|I Get The Bag (2017#93/2018#72)|MotorSport (2018#34)|Pure Water (2019#55)|Slide (2017#71)|Slippery (2017#86)|Stir Fry (2018#48)|T-Shirt (2017#52)|Walk It Talk It (2018#43)
|
||||
Miguel,Q73463,male,solo,contemporary R&B; alternative R&B; hip-hop; pop music; soul,United States,Sky Walker (2018#75)|Sure Thing (2023#24)
|
||||
Mike Posner,Q268284,male,solo,pop music,United States,I Took A Pill In Ibiza (2016#15)
|
||||
Miley Cyrus,Q4235,genderfluid,solo,pop music; country music; pop rock; dance-pop; electropop; rock music; hip-hop; teen pop; country pop,United States,Flowers (2023#2/2024#69)|Malibu (2017#89)
|
||||
Miranda Lambert,Q231233,female,solo,country music; folk music,United States,Bluebird (2020#91)
|
||||
MNEK,Q6716905,male,solo,pop music,United Kingdom,Never Forget You (2016#46)
|
||||
Moneybagg Yo,Q38459032,male,solo,hip-hop; trap music; gangsta rap; Memphis rap; Southern hip-hop,United States,Said Sum (2020#98)|Time Today (2021#76)|Wockesha (2021#42)
|
||||
Mooski,Q113554625,male,solo,hip-hop,United States,Track Star (2021#75)
|
||||
Morgan Wallen,Q29561472,male,solo,country music; country pop; bro-country; country rap,United States,20 Cigarettes (2025#90)|Ain't That Some (2023#92)|Broadway Girls (2022#81)|Chasin' You (2020#34)|Cowgirls (2024#29)|Everything I Love (2023#56)|Flower Shops (2022#96)|I Ain't Coming Back (2025#72)|I Got Better (2025#40)|I Had Some Help (2024#4/2025#8)|I Wrote The Book (2023#95)|I'm The Problem (2025#13)|Just In Case (2025#18)|Last Night (2023#1/2024#28)|Lies Lies Lies (2024#50)|Love Somebody (2025#11)|More Than My Hometown (2020#96)|One Thing At A Time (2023#37)|Sand In My Boots (2022#58)|Smile (2025#64)|Superman (2025#99)|Thinkin' Bout Me (2023#19/2024#31)|Thought You Should Know (2023#22)|Wasted On You (2022#19)|What I Want (2025#27)|Whiskey Glasses (2019#52)|You Proof (2022#27/2023#12)
|
||||
Muni Long,Q7245622,female,solo,contemporary R&B; pop music,United States,Hrs And Hrs (2022#57)|Made For Me (2024#56)
|
||||
Murda Beatz,Q27970613,male,solo,hip-hop,Canada,FEFE (2018#31)
|
||||
Mustard,Q15941115,male,solo,hip-hop; ratchet music; West Coast hip-hop; contemporary R&B,United States,Ballin' (2020#25)|High Fashion (2020#40)|Pure Water (2019#55)
|
||||
Myles Smith,Q126076580,male,solo,folk-pop; folk music; pop music; folk rock,United Kingdom,Stargazing (2024#73/2025#29)
|
||||
Måneskin,Q56884561,,group,pop rock; glam rock,Italy,Beggin' (2021#66)
|
||||
MØ,Q10670047,female,solo,indie pop; electronic music,Kingdom of Denmark,Cold Water (2016#25)|Lean On (2016#85)
|
||||
N*E*R*D,Q941293,,group,funk rock; bossa nova; orchestral pop; hip-hop; skate punk,United States,Lemon (2018#83)
|
||||
Natanael Cano,Q104904549,male,solo,corridos tumbados; regional Mexican,Mexico,PRC (2023#90)
|
||||
Nate Smith,Q110707312,male,solo,country music; country rock,United States,Bulletproof (2024#96)|World On Fire (2024#90)
|
||||
NAV,Q28831246,male,solo,hip-hop; cloud rap; trap music; contemporary R&B,Canada,Lemonade (2021#51)
|
||||
Neckwav,Q140814188,male,solo,contemporary R&B,South Korea,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
NEIKED,Q26703294,,group,,Sweden,Better Days (2022#73)
|
||||
Nelly,Q218992,male,solo,Midwest hip-hop; pop rap; contemporary R&B; pop music; country rap; country music,United States,Lil Bit (2021#70)
|
||||
Netón Vega,Q129208676,male,solo,regional Mexican; corridos tumbados,Mexico,Loco (2025#100)
|
||||
NF,Q19571648,male,solo,hip-hop,United States,Let You Down (2018#29)
|
||||
Niall Horan,Q775231,male,solo,pop music; pop rock; folk-pop,Ireland,Slow Hands (2017#32)
|
||||
Nick Jonas,Q201656,male,solo,pop music; rock music; contemporary R&B,United States,Close (2016#66)
|
||||
Nicki Minaj,Q162202,female,solo,hip-hop; pop music; contemporary R&B; trap music; dance music,Trinidad and Tobago,Barbie World (2023#46)|Big Bank (2018#63)|Down In The DM (2016#69)|Everybody (2024#71)|FEFE (2018#31)|FTCU (2024#88)|Hot Girl Summer (2019#93)|MotorSport (2018#34)|Plain Jane (2018#74)|Princess Diana (2023#69)|Rake It Up (2017#53)|Side To Side (2016#77/2017#43)|Super Freaky Girl (2022#56/2023#79)|Swalla (2017#85)
|
||||
Nicky Jam,Q1374560,male,solo,reggaeton; Latin trap,United States,Te Bote (2018#81)|X (2018#90)
|
||||
Nicky Youre,Q112666811,male,solo,indie pop,United States,Sunroof (2022#29)
|
||||
Niko Moon,Q67399825,male,solo,country music,United States,Good Time (2021#84)
|
||||
Nio García,Q107358694,male,solo,Latin trap; reggaeton,United States,Te Bote (2018#81)
|
||||
NLE Choppa,Q64009351,male,solo,trap music; hip-hop; drill; Memphis rap; gangsta rap; Southern hip-hop,United States,Shotta Flow (2019#92)|Walk Em Down (2020#100)
|
||||
Noah Kahan,Q53832755,male,solo,folk-pop,United States,Dial Drunk (2023#80)|Stick Season (2024#11)
|
||||
Normani,Q28148022,female,solo,pop music; contemporary R&B,United States,Dancing With A Stranger (2019#14)|Love Lies (2018#19/2019#88)
|
||||
O.T. Genasis,Q18623749,male,solo,hip-hop; trap music,United States,Cut It (2016#91)
|
||||
Offset,Q30612480,male,solo,hip-hop; trap music; Southern hip-hop,United States,Clout (2019#87)|Ric Flair Drip (2018#38)|Taste (2018#28)|ZEZE (2019#31)
|
||||
Old Dominion,Q20685018,,group,country pop,United States,Memory Lane (2023#87)|One Man Band (2020#59)
|
||||
Oliver Anthony Music,Q121391237,male,solo,country music; folk music,United States,Rich Men North Of Richmond (2023#78)
|
||||
Olivia O'Brien,Q23978275,female,solo,dance-pop; pop music,United States,I Hate U I Love U (2016#38)
|
||||
Olivia Rodrigo,Q63243883,female,solo,indie pop; pop music; rock music,United States,Deja Vu (2021#13)|Drivers License (2021#8)|Good 4 U (2021#5/2022#31)|Traitor (2021#38)|Vampire (2023#30/2024#57)
|
||||
One Direction,Q146027,,group,dance-pop; teen pop; pop rock,United Kingdom,Perfect (2016#100)
|
||||
OneRepublic,Q1438730,,group,pop rock; alternative rock; cello rock,United States,I Ain't Worried (2022#37)
|
||||
Ozuna,Q28739901,male,solo,reggaeton; Latin trap; Latin pop; dancehall,United States,Taki Taki (2019#57)|Te Bote (2018#81)
|
||||
P!nk,Q160009,female,solo,pop music; pop rock; contemporary R&B,United States,Just Like Fire (2016#33)|One Too Many (2021#81)|Walk Me Home (2019#99)|What About Us (2017#84)
|
||||
Panic! At The Disco,Q277551,,group,pop rock; synth-pop; pop-punk; baroque pop; emo pop; alternative rock,United States,"Hey Look Ma, I Made It (2019#61)|High Hopes (2019#11)"
|
||||
Parker McCollum,Q20684755,male,solo,Americana; country music,United States,Burn It Down (2024#84)|Handle On You (2023#85)
|
||||
Parmalee,Q7139162,,group,country music,United States,Just The Way (2021#88)|Take My Name (2022#82)
|
||||
PARTYNEXTDOOR,Q15929398,male,solo,Canadian hip-hop; alternative R&B,Canada,Somebody Loves Me (2025#85)
|
||||
Paul Russell,Q122932071,male,solo,hip-hop; contemporary R&B; pop rap,United States,Lil Boo Thang (2024#78)
|
||||
Peso Pluma,Q117242724,male,solo,regional Mexican; corridos tumbados; reggaeton; Latin trap; cumbia norteña mexicana,Mexico,Ella Baila Sola (2023#26)|La Bebe (2023#40)|Por Las Noches (2023#86)|PRC (2023#90)
|
||||
Pharrell Williams,Q14313,male,solo,contemporary R&B; hip-hop; pop music; funk; rock music; pop rap,United States,Feels (2017#74)
|
||||
Pinkfong,Q55735607,,,children's music,South Korea,Baby Shark (2019#75)
|
||||
PinkPantheress,Q107570416,female,solo,pop music; bedroom pop; dance music; alternative pop; drum and bass; 2-step garage; jungle; hyperpop,United Kingdom,"Boy's A Liar, Pt. 2 (2023#20)"
|
||||
Playboi Carti,Q27671080,male,solo,Southern hip-hop; trap music; mumble rap; cloud rap; rage; punk rap; alternative hip-hop; plugg music; lo-fi music; SoundCloud rap,United States,Carnival (2024#38)|FE!N (2024#97)|Magnolia (2017#79)|Rather Lie (2025#91)|Timeless (2025#16)|Type Shit (2024#51)
|
||||
PnB Rock,Q28155029,male,solo,hip-hop; contemporary R&B; trap music; pop music; pop rap,United States,Everyday We Lit (2017#95)
|
||||
Polo G,Q62953486,male,solo,hip-hop; drill; trap music; conscious hip-hop; Midwest hip-hop; Chicago hip-hop,United States,Better Days (2022#73)|Pop Out (2019#45)|Rapstar (2021#30)
|
||||
Pooh Shiesty,Q105105274,male,solo,trap music; Southern hip-hop; drill; hardcore hip-hop; gangsta rap; Memphis rap,United States,Back In Blood (2021#39)|Beat Box (2021#44)
|
||||
Pop Smoke,Q81698554,male,solo,East Coast hip-hop; Brooklyn drill; trap music; gangsta rap; drill; hip-hop,United States,Dior (2020#83)|For The Night (2020#49/2021#32)|Mood Swings (2020#81)|The Woo (2020#78)|What You Know Bout Love (2021#22)
|
||||
Portugal. The Man,Q606879,,group,pop music; indie rock,United States,Feel It Still (2017#45/2018#33)
|
||||
Post Malone,Q21621919,male,solo,hip-hop; pop music; country music,United States,Better Now (2018#13/2019#32)|Chemical (2023#57)|Circles (2019#62/2020#2)|Congratulations (2017#10)|Dial Drunk (2023#80)|Fortnight (2024#22)|Goodbyes (2019#30)|I Ain't Coming Back (2025#72)|I Fall Apart (2018#39)|I Had Some Help (2024#4/2025#8)|I Like You (A Happier Song) (2022#26/2023#75)|One Right Now (2022#30)|Pour Me A Drink (2024#76)|Psycho (2018#6)|Rockstar (2017#56/2018#5)|Sunflower (Spider-Man: Into The Spider-Verse) (2019#2)|White Iverson (2016#65)|Wow. (2019#5)
|
||||
Powfu,Q89069821,male,solo,hip-hop; lo-fi music; power pop; rock music,Canada,Death Bed (2020#43)
|
||||
Project Pat,Q593741,male,solo,Memphis rap; gangsta rap; hardcore hip-hop; Southern hip-hop; crunk; dirty south; trap music; horrorcore,United States,Knife Talk (2021#86/2022#60)
|
||||
Quavo,Q30072039,male,solo,hip-hop; trap music,United States,Congratulations (2017#10)|I'm The One (2017#12)|Intentions (2020#17)|No Brainer (2018#73)|Strip That Down (2017#36)
|
||||
Rae Sremmurd,Q18123226,,group,hip-hop; trap music; pop music; pop rap,United States,Black Beatles (2017#19)|Powerglide (2018#97)|Swang (2017#64)
|
||||
Rauw Alejandro,Q61586861,male,solo,contemporary R&B; urban contemporary; Latin R&B; reggaeton; Latin trap; Latin pop; salsa,United States,Party (2022#77)|Todo de Ti (2021#100)
|
||||
Ravyn Lenae,Q28962463,female,solo,contemporary R&B; alternative R&B; neo soul,United States,Love Me Not (2025#30)
|
||||
RAYE,Q28071144,female,solo,contemporary R&B,United Kingdom,Escapism (2023#48)
|
||||
REI AMI,Q104842557,female,solo,K-pop; pop music; hip-hop; contemporary R&B,South Korea,Golden (2025#25)|How It's Done (2025#68)|Takedown (2025#93)|What It Sounds Like (2025#83)
|
||||
Rema,Q65071082,male,solo,Afrobeats,Nigeria,Calm Down (2023#6)
|
||||
Remy Boyz,Q63405888,,group,hip-hop,United States,679 (2016#54)
|
||||
Remy Ma,Q275437,female,solo,East Coast hip-hop,United States,All The Way Up (2016#87)
|
||||
Rhenzy Feliz,Q34344805,male,solo,,United States,We Don't Talk About Bruno (2022#24)
|
||||
Rich The Kid,Q18637908,male,solo,hip-hop; trap music; mumble rap; plugg music; Southern hip-hop,United States,Carnival (2024#38)|Plug Walk (2018#57)
|
||||
Rick Ross,Q297831,male,solo,Southern hip-hop; gangsta rap; mafioso rap; trap music; hardcore hip-hop; dirty south,United States,Money In The Grave (2019#34)
|
||||
Rihanna,Q36844,female,solo,pop music; dancehall; contemporary R&B; electronic dance music; adult contemporary music,Barbados,Lemon (2018#83)|Lift Me Up (2023#63)|Love On The Brain (2017#33)|Loyalty. (2017#66)|Needed Me (2016#13)|This Is What You Came For (2016#17)|Too Good (2016#29)|Wild Thoughts (2017#18)|Work (2016#4)
|
||||
Riley Green,Q57418818,male,solo,country music,United States,Worst Way (2025#35)
|
||||
Ritt Momney,Q105105308,male,solo,folk music; indie pop; synth-pop,United States,Put Your Records On (2021#93)
|
||||
Rod Wave,Q78754352,male,solo,hip-hop; contemporary R&B; soul; trap music,United States,Heart On Ice (2020#51)|Rags2Riches (2020#90)|Tombstone (2021#98)
|
||||
Roddy Ricch,Q59209423,male,solo,West Coast hip-hop; trap music; pop rap; gangsta rap; hardcore hip-hop; hip-hop,United States,Ballin' (2020#25)|High Fashion (2020#40)|Late At Night (2021#72)|Rockstar (2020#5)|The Box (2020#3)|The Woo (2020#78)|Walk Em Down (2020#100)
|
||||
ROSÉ,Q27655344,female,solo,K-pop; dance-pop; hip-hop; electronic dance music,New Zealand,APT. (2025#9)
|
||||
Rozes,Q22955580,female,solo,pop music; dance music; electronic dance music,United States,Roses (2016#27)
|
||||
Russell Dickerson,Q24572267,male,solo,country music,United States,Happen To Me (2025#69)|She Likes It (2022#91)
|
||||
Ruth B,Q22056665,female,solo,pop music,Canada,Lost Boy (2016#76)
|
||||
Ryan Hurd,Q42224127,male,solo,country music,United States,Chasing After You (2021#61)
|
||||
Sabrina Carpenter,Q7396400,female,solo,pop music; teen pop; dance-pop; contemporary R&B; electropop; country pop,United States,Bed Chem (2025#45)|Espresso (2024#7/2025#12)|Feather (2024#25)|Manchild (2025#38)|Please Please Please (2024#16/2025#50)|Taste (2024#86/2025#19)
|
||||
SAINt JHN,Q52274581,male,solo,hip-hop; trap music; contemporary R&B,United States,Roses (2020#19)
|
||||
Sam Barber,Q124428137,male,solo,country music,United States,Indigo (2025#49)
|
||||
Sam Hunt,Q16223171,male,solo,country music,United States,Body Like A Back Road (2017#8)|Hard To Forget (2020#69)
|
||||
Sam Smith,Q15123969,non-binary,solo,soul; contemporary R&B; pop music; rhythm and blues,United Kingdom,Dancing With A Stranger (2019#14)|How Do You Sleep? (2019#83)|Too Good At Goodbyes (2017#77/2018#49)|Unholy (2022#98/2023#11)
|
||||
Sam Tompkins,Q112155955,male,solo,pop music,United Kingdom,To The Moon! (2022#97)
|
||||
samUIL Lee,Q140814222,male,solo,J-pop,South Korea,Soda Pop (2025#61)|Your Idol (2025#54)
|
||||
Saweetie,Q50486592,female,solo,hip-hop,United States,Best Friend (2021#29)|My Type (2019#76)
|
||||
Scotty McCreery,Q255969,male,solo,country music,United States,Damn Strait (2022#93)
|
||||
Sean Paul,Q200577,male,solo,dancehall; pop music,Jamaica,Cheap Thrills (2016#11)|Rockabye (2017#44)
|
||||
Selena Gomez,Q83287,female,solo,pop music; dance-pop; electropop; pop rock; contemporary R&B; alternative R&B,United States,Back To You (2018#41)|Calm Down (2023#6)|Hands To Myself (2016#56)|It Ain't Me (2017#27)|Lose You To Love Me (2020#30)|Same Old Love (2016#40)|Taki Taki (2019#57)|We Don't Talk Anymore (2016#50)|Wolves (2018#60)
|
||||
Sexyy Red,Q119842023,female,solo,hip-hop; trap music; dirty rap; Midwest hip-hop,United States,Get It Sexyy (2024#55)|Rich Baby Daddy (2024#45)|Sticky (2025#41)|Whatchu Kno About Me (2025#48)
|
||||
Shaboozey,Q125295750,male,solo,alternative country; country music; hip-hop; Americana,United States,A Bar Song (Tipsy) (2024#2/2025#3)|Good News (2025#23)
|
||||
SHAED,Q60643444,,group,electropop; indie pop,United States,Trampoline (2019#70/2020#53)
|
||||
Shakira,Q34424,female,solo,pop music; Latin pop; pop rock; Latin rock; dance music; folk music; world music; contemporary R&B; rock music,Spain,"Bzrp Music Sessions, Vol. 53 (2023#96)|TQG (2023#65)"
|
||||
Shawn Mendes,Q17198340,male,solo,folk-pop; pop music; pop rock,Canada,I Know What You Did Last Summer (2016#86)|If I Can't Have You (2019#29)|In My Blood (2018#46)|Mercy (2017#54)|Senorita (2019#15/2020#44)|Stitches (2016#23)|There's Nothing Holdin' Me Back (2017#23)|Treat You Better (2016#28/2017#92)
|
||||
Shay Mooney,Q116536996,male,solo,country music,United States,"10,000 Hours (2020#23)|All To Myself (2019#97)|Glad You Exist (2021#64)|Speechless (2019#35)|Tequila (2018#32/2019#91)"
|
||||
Sheck Wes,Q56513324,male,solo,East Coast hip-hop; trap music,United States,Mo Bamba (2019#49)
|
||||
Sia,Q181484,female,solo,electropop; indie pop,Australia,Cheap Thrills (2016#11)
|
||||
Silentó,Q20354248,male,solo,hip-hop; pop rap; trap music; comedy hip-hop; snap music; pop music,United States,Watch Me (2016#88)
|
||||
Skip Marley,Q21621948,male,solo,reggae; pop music; hip-hop; rock music,Jamaica,Chained To The Rhythm (2017#73)
|
||||
Snow,Q94708,male,solo,dancehall; reggae; hip-hop; reggae fusion,Canada,Con Calma (2019#65)
|
||||
Social House,Q65117469,,group,pop music,United States,Boyfriend (2019#98)
|
||||
sombr,Q133444448,male,solo,alternative pop; bedroom pop,United States,Back To Friends (2025#44)|Undressed (2025#42)
|
||||
SpotemGottem,Q105105325,male,solo,mumble rap; trap music; drill; Southern hip-hop,United States,Beat Box (2021#44)
|
||||
StaySolidRocky,Q95918251,male,solo,hip-hop,United States,Party Girl (2020#64)
|
||||
Stephanie Beatriz,Q16832110,female,solo,,United States,We Don't Talk About Bruno (2022#24)
|
||||
Stephen Sanchez,Q113023532,male,solo,pop music,United States,Until I Found You (2023#50)
|
||||
Steve Lacy,Q56733980,male,solo,alternative R&B,United States,Bad Habit (2022#28/2023#39)
|
||||
Summer Walker,Q61959478,female,solo,contemporary R&B,United States,Good Good (2024#79)|Heart Of A Woman (2025#94)
|
||||
Surf Mesa,Q93771412,male,solo,tropical house,United States,ily (2020#95)
|
||||
Surfaces,Q76330429,,group,pop music,United States,Sunday Best (2020#61)
|
||||
Swae Lee,Q30103025,male,solo,hip-hop; trap music,United States,Be Like That (2020#88)|Close To Me (2019#58)|Sunflower (Spider-Man: Into The Spider-Verse) (2019#2)|Unforgettable (2017#15)
|
||||
SZA,Q16210722,female,solo,contemporary R&B; alternative R&B; neo soul; pop music; hip-hop,United States,30 For 30 (2025#21)|All The Stars (2018#47)|BMF (2025#76)|Good Days (2021#52)|I Hate U (2022#50)|Kill Bill (2023#3)|Kiss Me More (2021#6/2022#90)|Love Galore (2017#80)|Luther (2025#2)|Nobody Gets Me (2023#77)|Rich Baby Daddy (2024#45)|Saturn (2024#19)|Shirt (2023#51)|Snooze (2023#9/2024#20)|What Lovers Do (2017#97/2018#89)
|
||||
Tae,Q54607285,female,solo,country music,United States,Die From A Broken Heart (2020#65)
|
||||
Tate McRae,Q95129121,female,solo,pop music; alternative pop; dance-pop,Canada,Exes (2024#93)|Greedy (2024#13)|Revolving Door (2025#82)|She's All I Wanna Be (2022#94)|Sports Car (2025#46)|What I Want (2025#27)|You Broke Me First. (2021#37)
|
||||
Taylor Swift,Q26876,female,solo,pop music; country music,United States,All Too Well (Taylor's Version) (2022#76)|Anti-Hero (2023#4)|Cruel Summer (2023#18/2024#12)|Delicate (2018#24)|Down Bad (2024#99)|Fortnight (2024#22)|I Can Do It With A Broken Heart (2024#35)|I Don't Wanna Live Forever (Fifty Shades Darker) (2017#26)|Is It Over Now? (Taylor's Version) [From The Vault] (2024#33)|Karma (2023#27)|Lavender Haze (2023#32)|Look What You Made Me Do (2017#39)|ME! (2019#43)|Wildest Dreams (2016#79)|Willow (2021#55)|You Need To Calm Down (2019#39)
|
||||
Teddy Swims,Q105542333,male,solo,country music; pop music; rhythm and blues; soul,United States,Bad Dreams (2025#74)|Lose Control (2024#1/2025#4)
|
||||
Tems,Q72759173,female,solo,alternative R&B; Afrobeats,Nigeria,Essence (2021#60/2022#64)|Wait For U (2022#11/2023#83)
|
||||
Teo,Q55860035,male,solo,hip-hop,United States,Rolex (2017#61)
|
||||
The Chainsmokers,Q7721993,,group,electronic dance music,United States,Closer (2016#10/2017#7)|Don't Let Me Down (2016#8)|Paris (2017#42)|Roses (2016#27)|Something Just Like This (2017#5)
|
||||
The Kid LAROI,Q82890761,male,solo,Australian hip-hop; contemporary R&B; pop music; emo rap,Australia,Stay (2021#12/2022#3)|Without You (2021#17)
|
||||
The Marías,Q85807852,,group,indie pop; psychedelic soul; dream pop; synth-pop,United States,No One Noticed (2025#32)
|
||||
The Weeknd,Q2121062,male,solo,alternative R&B; pop music; electropop,Canada,Blinding Lights (2020#1/2021#3)|Call Out My Name (2018#78)|Can't Feel My Face (2016#72)|Creepin' (2023#5)|Cry For Me (2025#73)|Die For You (2023#7)|Heartless (2020#28)|I Feel It Coming (2017#34)|In The Night (2016#61)|Low Life (2016#30)|One Right Now (2022#30)|Pray For Me (2018#40)|Rather Lie (2025#91)|Save Your Tears (2021#2/2022#40)|Starboy (2016#58/2017#20)|Take My Breath (2021#89)|The Hills (2016#32)|Timeless (2025#16)|You Right (2021#43/2022#45)
|
||||
Thomas Rhett,Q7793491,male,solo,country music,United States,After All The Bars Are Closed (2025#88)|Die A Happy Man (2016#64)|Look What God Gave Her (2019#85)|Marry Me (2018#76)|What's Your Country Song (2021#80)
|
||||
Tim McGraw,Q356487,male,solo,country music,United States,Humble And Kind (2016#96)
|
||||
Tommy Richman,Q125778611,male,solo,pop rap; contemporary R&B,United States,Million Dollar Baby (2024#8)
|
||||
Tones And I,Q62887629,female,solo,indie pop; electronic dance music; pop music,Australia,Dance Monkey (2020#14)
|
||||
Toosii,Q106725126,male,solo,hip-hop,United States,Favorite Song (2023#21)
|
||||
Tory Lanez,Q18353558,male,solo,hip-hop; contemporary R&B,Canada,Luv (2016#70)|Say It (2016#74)|Whats Poppin (2020#13)
|
||||
Tove Lo,Q15948790,female,solo,pop music; indie pop; synth-pop; electropop,Sweden,Close (2016#66)
|
||||
Travis Scott,Q13605596,male,solo,hip-hop; trap music; pop rap; psychedelic rap; rock music; Southern hip-hop; contemporary R&B; psychedelic music; pop rock; alternative rock; alternative hip-hop; alternative R&B; psychedelic rock; psychedelic hip-hop,United States,Antidote (2016#75)|FE!N (2024#97)|Goosebumps (2017#68)|HIGHEST IN THE ROOM (2020#45)|Love Galore (2017#80)|Meltdown (2023#97)|Sicko Mode (2018#42/2019#9)|Sky Walker (2018#75)|The London (2019#64)|The Scotts (2020#86)|Type Shit (2024#51)|ZEZE (2019#31)
|
||||
Trevor Daniel,Q81738417,male,solo,contemporary R&B; pop music,United States,Falling (2020#22)
|
||||
Tucker Wetmore,Q124754909,male,solo,country music,United States,Wind Up Missin' You (2024#95)
|
||||
twenty one pilots,Q7857806,,group,reggae; alternative rock; electropop; alternative hip-hop; rap rock; indie pop; pop rock,United States,Heathens (2016#21/2017#58)|Ride (2016#20)|Stressed Out (2016#5)
|
||||
Ty Dolla $ign,Q7859785,male,solo,contemporary R&B; West Coast hip-hop; trap music; hip-hop,United States,Carnival (2024#38)|Hot Girl Summer (2019#93)|Psycho (2018#6)|Sucker For Pain (2016#68)|Swalla (2017#85)|Work From Home (2016#16)
|
||||
Tyga,Q358087,male,solo,West Coast hip-hop; pop rap,United States,Juicy (2020#87)|Taste (2018#28)
|
||||
Tyla,Q118105408,female,solo,contemporary R&B; pop music; Amapiano; new jack swing,South Africa,Water (2024#24)
|
||||
Tyler Cole,Q140814245,male,solo,,United States,Meet Me At Our Spot (2022#74)
|
||||
Tyler Hubbard,Q20740966,male,solo,country music,United States,5 Foot 9 (2022#67)|Dancin' In The Country (2023#61)
|
||||
"Tyler, The Creator",Q167635,male,solo,alternative hip-hop; neo soul; West Coast hip-hop; jazz rap; hardcore hip-hop; horrorcore,United States,Like Him (2025#62)|Sticky (2025#41)
|
||||
Usher,Q165911,male,solo,contemporary R&B; pop music; soul; hip-hop; dance music; dance-pop; crunk,United States,Good Good (2024#79)|No Limit (2016#90)
|
||||
Victoria Monét,Q19864989,female,solo,pop music; contemporary R&B; hip-hop,United States,On My Mama (2024#91)
|
||||
Walker Hayes,Q7962267,male,solo,country music,United States,AA (2022#61)|Fancy Like (2021#27/2022#35)
|
||||
Warren Zeiders,Q120986980,male,solo,country music,United States,Pretty Little Poison (2024#60)
|
||||
Wham!,Q744087,,group,pop music; new wave; blue-eyed soul,United Kingdom,Last Christmas (2023#84/2024#74/2025#65)
|
||||
WILLOW,Q298209,female,solo,indie pop; alternative R&B; experimental pop; neo soul; hip-hop; electronic dance music; pop music; dream pop; contemporary R&B; rock music; indie rock; progressive rock; pop-punk; alternative rock; alternative pop; jazz,United States,Meet Me At Our Spot (2022#74)
|
||||
Willy William,Q17016749,male,solo,house music; reggaeton; zouk,France,Mi Gente (2017#50/2018#99)
|
||||
Wiz Khalifa,Q117139,male,solo,East Coast hip-hop; pop rap,United States,See You Again (2016#99)|Sucker For Pain (2016#68)
|
||||
Wizkid,Q16233663,male,solo,Afrobeats; dancehall; rhythm and blues,Nigeria,Essence (2021#60/2022#64)|One Dance (2016#3)
|
||||
X Ambassadors,Q15963313,,group,alternative rock,United States,Sucker For Pain (2016#68)|Unsteady (2016#67)
|
||||
Xavi,Q124219723,male,solo,regional Mexican; corridos tumbados,United States,La Diabla (2024#72)
|
||||
XXXTENTACION,Q28561969,male,solo,hip-hop; emo rap; SoundCloud rap; rap rock; lo-fi music; hardcore hip-hop; alternative rock; lofi hip-hop; indie rock; nu metal; cloud rap; trap music; hardcore punk; trap metal; punk rock; rock music; rap metal; alternative R&B; contemporary R&B; punk rap; heavy metal music,United States,Changes (2018#94)|Look At Me! (2017#99)|Moonlight (2018#88)|Sad! (2018#17)
|
||||
Yeat,Q108761978,male,solo,experimental hip-hop; rage; trap music,United States,IDGAF (2024#83)
|
||||
YFN Lucci,Q28000403,male,solo,hip-hop,United States,Everyday We Lit (2017#95)
|
||||
YG,Q3076050,male,solo,West Coast hip-hop; gangsta rap; dirty rap; hardcore hip-hop,United States,Big Bank (2018#63)|Slide (2020#99)
|
||||
YK Osiris,Q66095815,male,solo,contemporary R&B; hip-hop,United States,Worth It (2019#77)
|
||||
Yng Lvcas,Q117834547,male,solo,reggaeton,Mexico,La Bebe (2023#40)
|
||||
YNW Melly,Q56276347,male,solo,Southern hip-hop; trap music; contemporary R&B; gangsta rap; drill; hardcore hip-hop,United States,Murder On My Mind (2019#66)|Suicidal (2020#75)
|
||||
Yo Gotti,Q586919,male,solo,Southern hip-hop; trap music; dirty south; hardcore hip-hop; gangsta rap; Memphis rap,United States,Down In The DM (2016#69)|Rake It Up (2017#53)
|
||||
Young Dolph,Q23541285,male,solo,Southern hip-hop; gangsta rap; trap music; Memphis rap; dirty south; hardcore hip-hop,United States,Cut It (2016#91)
|
||||
Young Nudy,Q62036530,male,solo,hip-hop,United States,Peaches & Eggplants (2023#94)
|
||||
Young Thug,Q15637814,male,solo,Southern hip-hop; trap music; mumble rap; progressive rap; SoundCloud rap,United States,Go Crazy (2020#39/2021#19)|Goodbyes (2019#30)|Havana (2017#96/2018#4)|Hot (2020#72)|No Limit (2016#90)|Pushin P (2022#48)|The London (2019#64)|Way 2 Sexy (2021#48)
|
||||
YoungBoy Never Broke Again,Q36490532,male,solo,hip-hop; Southern hip-hop; gangsta rap; trap music,United States,Bandit (2020#63)|Outside Today (2018#91)
|
||||
Yung Bleu,Q105105248,male,solo,contemporary R&B; hip-hop,United States,You're Mines Still (2021#58)
|
||||
Zacari,Q68593407,male,solo,contemporary R&B; hip-hop; alternative hip-hop; alternative R&B,United States,Love. (2018#50)
|
||||
Zach Bryan,Q106770023,male,solo,alternative country; red dirt; country music,United States,I Remember Everything (2023#74/2024#9)|Pink Skies (2024#30)|Something In The Orange (2022#39/2023#13)
|
||||
Zach Top,Q126414316,male,solo,country music,United States,I Never Lie (2025#43)
|
||||
Zara Larsson,Q4177928,female,solo,dance-pop; pop music; electropop,Sweden,Never Forget You (2016#46)
|
||||
Zay Hilfigerrr,Q55859289,male,solo,hip-hop,United States,Juju On That Beat (TZ Anthem) (2017#63)
|
||||
Zayion McCall,Q55859293,male,solo,hip-hop,United States,Juju On That Beat (TZ Anthem) (2017#63)
|
||||
Zayn,Q3626950,male,solo,pop music; contemporary R&B; dance-pop; alternative R&B,United Kingdom,I Don't Wanna Live Forever (Fifty Shades Darker) (2017#26)|Pillowtalk (2016#22)
|
||||
Zedd,Q21088,male,solo,electronic dance music; house music; electro house,Russia,Starving (2016#94/2017#82)|Stay (2017#17)|The Middle (2018#8)
|
||||
Óscar Maydon,Q130241052,male,solo,corridos tumbados,Mexico,Tu Boda (2025#87)
|
||||
|
||||
|
+884
-884
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,376 @@
|
||||
# 決策日誌
|
||||
|
||||
每筆記錄:日期、決策、理由。定義檔(`prompts/`)、codebook、
|
||||
研究計畫的任何修訂都必須在此留下記錄。
|
||||
|
||||
## 2026-07-30
|
||||
|
||||
- **語料擴大為 2016–2025 十年**(先導研究為 2018–2025)。
|
||||
理由:框架完整、可看年度趨勢。
|
||||
- **全文不與先導研究比較**:論文僅呈現正式研究結果,數字
|
||||
一律以正式研究為準;先導研究只作為 codebook v0 與假說的
|
||||
內部來源,記於本日誌,不進入論文敘事。
|
||||
- **分析管線採 API script,不用 Claude Code subagent**。理由:
|
||||
實測證實 subagent 會繼承 CLAUDE.md 與環境資訊,context 無法
|
||||
僅憑定義檔重現;API 呼叫的輸入完全受控且可稽核。
|
||||
- **模型釘定 `claude-sonnet-4-6`、temperature=0、thinking 關閉**。
|
||||
理由:該組合非決定性最低;條件 A/B 盲點實驗以模型為研究
|
||||
對象,須與 pilot 的 Sonnet 家族銜接。Fable 5 不採用(成本、
|
||||
thinking 不可關閉且不可稽核、無 temperature、混淆核心主張)。
|
||||
- **工具性環節的模型於階段 3 以校準樣本實測後決定**:同批
|
||||
校準樣本以 Sonnet 4.6 與 Opus 5 各跑一次,對照人工黃金標準
|
||||
比較一致率,據以決定是否於特定環節升級。
|
||||
- **codebook 採 directed content analysis**:理論骨架
|
||||
(top-down)+開放碼歸納通道(bottom-up),並加做 LLM 純歸納
|
||||
輪與黃金標準的映射分析。映射分析方法須在看到結果前寫入
|
||||
`methodology.md`。
|
||||
- **完整歌詞不進 git**(版權);API 金鑰走 `.env`。
|
||||
- **專案目錄維持原名 `pop-fem-audit`**:API 管線下目錄名不會
|
||||
進入模型輸入,無污染疑慮。
|
||||
|
||||
## 2026-07-31
|
||||
|
||||
- **專案英文名定為「A Feminist Audit of Pop Music」**:明示
|
||||
女性主義立場,「audit」兼指對歌曲與對 LLM 標籤系統的稽核,
|
||||
並與縮寫 `pop-fem-audit` 對應。
|
||||
- **程式碼收整為 `tools/` src-layout 子專案**:發行名
|
||||
`pop-fem-audit-tools`、import 套件名 `pop_fem_audit_tools`、
|
||||
description「Tools for A Feminist Audit of Pop Music.」;
|
||||
以 `pip install -e tools/` 安裝、`python -m
|
||||
pop_fem_audit_tools.run_llm` 執行;相依套件記於
|
||||
`pyproject.toml`(`requirements.txt` 移除);Sphinx 文件
|
||||
暫緩。理由:後續多支程式將共用程式碼,套件化後測試可用
|
||||
正常 import;目錄名 `tools/` 經無脈絡的獨立 subagent 命名
|
||||
評估選出,最誠實反映「服務研究的輔助工具」定位——研究
|
||||
本體在根目錄的 prompts/、runs/、results/,程式只是配套。
|
||||
- **CLI 入口改為套件層級 dispatcher**:dispatcher 為單一
|
||||
入口,`run_llm.py` 的 entry point 移除;有兩種等價呼叫
|
||||
形式——`python -m pop_fem_audit_tools run-llm ...` 與
|
||||
console script `pop-fem-audit-tools run-llm ...`
|
||||
(`[project.scripts]`)。理由:後續多支工具共用單一入口,
|
||||
`--help` 可列出全部子命令,重現文件穩定。
|
||||
- **資料儲存架構定案**:commit 判準——凡能由「committed 輸入+
|
||||
committed 程式」決定性再生者不 commit;源頭、外部捕捉、人工
|
||||
著作以文字格式 commit。工作儲存採 SQLite 單檔
|
||||
(`tools/instance/`,generated、不進 git;歌詞全文入 DB 故無
|
||||
版權疑慮),schema 以 SQLAlchemy 2.0 typed ORM 定義,設定經
|
||||
pydantic-settings(`.env`)。`results/` 報表 CSV 為「可再生仍
|
||||
commit」的唯一例外,理由:論文引用穩定性、審稿人零門檻、
|
||||
撰稿期數字變動可 diff。(本條經多輪辯證後定案,推翻 Claude
|
||||
最初的全 CSV 方案。)
|
||||
- **資料模型**:songs、chart_entries(1—N)、artists、
|
||||
song_artists(M—N:角色、署名順序)、lyrics(1—1);領域
|
||||
不變量檢查內建 `build-db`,違規即失敗。
|
||||
- **歌手背景擴充與防火牆**:歌手資料擴為實體表(QID、性別、
|
||||
型態、曲風、國籍),women-power 候選的歌手另做深度背景
|
||||
(族裔以公開自我認同為準、音樂場景),供人工解讀與論文
|
||||
討論;**歌手背景絕不進 LLM 輸入**(歌詞-only),避免光環
|
||||
偏誤污染條件 A/B 實驗。
|
||||
- **沿用先導研究歌詞捕捉**(lyrics.json,684 首,2018–2025):
|
||||
只匯入識別欄位與歌詞本文,pilot 分析欄位不匯入;以
|
||||
(year, rank) 精確匹配。出處記於 `lyrics-provenance.csv`:
|
||||
source(原始 API)與 method(pilot-import / api-fetch)
|
||||
兩層;取得日期不可考者不假造,僅記可證上界。
|
||||
- **`run_llm` 改走 pydantic-settings 統一設定**(刪手寫 .env
|
||||
parser),與 `config.py` / `database.py` 一致。
|
||||
- **`lyrics` 表併入 `songs.lyrics` nullable 欄位**(資料模型由
|
||||
五表改四表)。理由:1—1 關係在此量級下獨立成表只有正規化
|
||||
慣性,nullable 欄位更簡單;「未取得」以 NULL 表達,語意
|
||||
等價。
|
||||
|
||||
## 2026-08-01
|
||||
|
||||
- **引擎獨立性以 PostgreSQL/SQLite 為範圍**(MySQL 的 VARCHAR
|
||||
長度限制不處理)。
|
||||
- **`build-db` 的重置改用逐表 DELETE,不再 drop/create**:
|
||||
schema 生命週期歸 migration 管,build-db 只管資料。連帶
|
||||
效果:重置成為純 DML,全程單一交易、驗證通過才 commit——
|
||||
建置失敗時前一版資料完好。首次執行仍以 create_all
|
||||
(checkfirst)補缺表。
|
||||
- **song/artist ID 由 build-db 顯式指派**(首次出現順序 1、2、
|
||||
3…),不依賴 autoincrement——PostgreSQL 的 sequence 在
|
||||
DELETE 後不重置,顯式指派讓重建決定性跨引擎成立。
|
||||
- **禁止文字 SQL statement,一律經 SQLAlchemy ORM/Core API**。
|
||||
唯一記錄在案的例外:SQLite 的 `PRAGMA foreign_keys=ON`
|
||||
(官方建議作法,無非文字 API 可用;SQLite 的 FK 旗標為
|
||||
逐連線設定)。裁定其歸屬為連線組態,實作於 `database.py`
|
||||
的 `__create_engine`——建 engine 時對 SQLite 註冊 connect
|
||||
listener,所有消費者全程生效,不再由 build-db 各自註冊。
|
||||
|
||||
## 2026-08-02
|
||||
|
||||
- **`import-lyrics` 不設為子命令,pilot 歌詞改以私人腳本
|
||||
匯入**。理由:pilot 捕捉檔不隨論文發布,子命令
|
||||
形式會在發布的 CLI 裡留下讀者無法執行的死命令——要交待的
|
||||
是「沿用 pilot 捕捉」的事實(記於 lyrics-provenance.csv 與
|
||||
論文方法節),不是工具本身;工具移出專案,發布管線即
|
||||
「讀者可完整執行的程序」。讀者重現歌詞的路徑為
|
||||
`fetch-lyrics`,API 漂移造成的差異屬捕捉層的已承認限制。
|
||||
provenance 的 method 值域定為
|
||||
pilot-import / api-fetch / manual。
|
||||
- **資料路徑全面改為顯式 CLI 引數**——必要運算元為位置
|
||||
引數、選擇性輸入為選項(build-db 吃榜單 CSV 一個位置引數,
|
||||
歌詞目錄、Wikidata 快照、overrides 為 `--lyrics-dir`/
|
||||
`--wikidata-csv`/`--overrides-csv` 三個選項;fetch-lyrics
|
||||
吃歌詞目錄、provenance、缺漏報表三個位置引數;fetch-artists
|
||||
吃快照檔;run-llm 吃 runs 目錄),命令與 CWD 無關,且每次
|
||||
執行觸碰的檔案完整見於指令本身。省略選項即不載入該捕捉層;
|
||||
給了選項而路徑不存在即建置失敗,取代原本的默默跳過。理由:
|
||||
settings 的 `.env` 依 pydantic 慣例讀自 CWD(約定
|
||||
`tools/`),資料路徑原以 repo 根為 CWD,兩者衝突;顯式引數
|
||||
消滅隱性 CWD 契約,亦拒絕以父目錄推導兄弟檔案的隱性慣例。
|
||||
- **`data/` 依生命週期分三層**:`source/`(源頭,手放後不動)、
|
||||
`captures/`(外部捕捉,只由 fetch 命令與私人匯入腳本寫入)、
|
||||
`manual/`(人工著作,只由研究者手寫;之後的黃金標準編碼
|
||||
亦居此)。理由:三種生命週期混住一層,目錄無法傳達「誰可以
|
||||
寫哪裡」;顯式引數化後搬遷零程式改動。
|
||||
- **源頭榜單 CSV 全面對齊 Billboard 年終榜發布版**(修正
|
||||
203 列)。語料源頭定義為「年終榜發布當時的印法」,以
|
||||
Wayback Machine 發布時快照逐字轉錄(2016–2018 原沿
|
||||
Wikipedia 改寫慣例);年終原文殘缺或有疑問者,以當年週榜
|
||||
掛名為準(唯一適用例:2016#87〈All the Way Up〉)。
|
||||
- **歌名正規化採 canonical artist credit 對照表**:同一首歌
|
||||
因署名字串寫法不同而分裂者,以明示對照表合併;歌曲身分=
|
||||
(原始歌名,對照後署名字串),不解析署名——拆解機器不進
|
||||
歌曲身分判定,對照表即完整可稽核清單。
|
||||
- **歌手名單拆解規則定案**:署名列出成員的團體只留成員
|
||||
(冒號與括號兩型);名字內含連接詞的單一藝人入保護名單;
|
||||
規則無法表達的個案入例外表;人名連寫的二人組拆成個人;
|
||||
僅以團名掛名的團體維持單一實體,屬性留待 fetch-artists
|
||||
與人工 overrides。完整清單見 `build_db.py`。
|
||||
- **歌手名正規化**:歌手名大小寫不敏感歸併、存首見拼法;
|
||||
正名表(casefold 鍵→官方拼法)存官方拼法,含跨拼法合併
|
||||
ye→Kanye West。
|
||||
- **`data/` 增設 `derived/` 衍生層**:`build-db` 建置工作儲存
|
||||
的同一動作產出兩張人讀報表(songs.csv、artists.csv)並
|
||||
commit——與 SQLite 同交易語意、驗證通過才寫檔,稽核鏈
|
||||
「committed 輸入+程式→CSV」無中間空缺;為「可再生仍
|
||||
commit」的第二例外。報表不含資料庫 ID(內部參照,資料
|
||||
改版會重排,不供引用);關係以內嵌字串呈現——`/` 連同
|
||||
一首歌的多次上榜、`|` 連不同歌曲——欄位一律字母序。
|
||||
- **歌手正名表全面改存官方拼法**:變音符號一律恢復
|
||||
(Billboard 印法慣性去符號,共 12 筆,如 Aminé、Jhené
|
||||
Aiko、Silentó);二人組拆名改存成員全名(Dan Smyers、
|
||||
Shay Mooney);官方大小寫 3 筆(Cris MJ、Mariah the
|
||||
Scientist、Surf Mesa)。官方拼法逐筆以 DSP 官方頁查證
|
||||
(維基百科/Wikidata 的大小寫是其自家規範,不作準);
|
||||
查證亦確認 Tones And I 的 chart 印法即官方寫法,不改。
|
||||
- **`fetch-artists` 解析演算法定案**:改用 WDQS 的 SPARQL
|
||||
索引查詢(不依賴搜尋排名、不用 LCASE——實測會逾時)。
|
||||
步驟:(1) 歌手名與 label/alias 精確比對(@en+@mul 兩層)
|
||||
取候選,型態限人類∪音樂團體子樹∪original cast;(2) 唯一
|
||||
即定案;(3) 歧義以上榜歌曲佐證——歌名精確比對取歌曲條目
|
||||
的 P175 演出者(含其 P527 成員)與候選交集;(4) 再落空則
|
||||
反向錨定:候選(含所屬團體)演出過的歌曲以 casefold 比對
|
||||
歌名;(5) 均落空記查無並續行。每步須恰一命中才選定,
|
||||
實測零錯選。Last-resort 釘定表僅一筆(Pinkfong——唯一
|
||||
P31 為品牌的上榜演出者,型態閘門依設計排除)。暫時性
|
||||
故障(429/5xx/讀取逾時)退避重試,重試盡記 error 列;
|
||||
not found 專指程序查證後無所得。全量實跑 469 位全數
|
||||
解析且與人工查證的 QID 逐筆相符;首次快照隨本次入
|
||||
捕捉層。
|
||||
- **先補完 Wikidata、再捕捉快照**:歌手資料查證做在上游——
|
||||
以 subagent(`artist-wikidata-updater` 定義檔)逐位查證
|
||||
快照欄位(P21、P31、P136、P27/P495,新條目加 P106)並
|
||||
草擬附來源的 QuickStatements,由研究者本人審摘要、以本人
|
||||
帳號執行;編輯沉澱後重跑 `fetch-artists`,Wikidata 容不下
|
||||
的判斷才入 overrides。理由:修在上游全網受益,編輯史與
|
||||
來源公開可稽核,快照乾淨、overrides 縮小;論文方法節揭露
|
||||
「捕捉前經研究者查證補完」。性別以公開自我認同為準,
|
||||
推測不確定且無佐證者列疑慮清單;查證屬資料策展而非
|
||||
分析,以 Claude Code 輔助、不走分析 API;QS 批次以
|
||||
私人工作檔留存,不隨論文發布。
|
||||
|
||||
## 2026-08-04
|
||||
|
||||
- **移除人工 overrides 層**:`build-db` 刪去
|
||||
`--overrides-csv` 選項與套用邏輯,文件同步移除
|
||||
`data/manual/artists_overrides.csv`。理由:「先補完
|
||||
Wikidata、再捕捉快照」工作流實跑後,469 位歌手全數
|
||||
在上游查證補齊,快照即完整,本地覆蓋層已無存在事實;
|
||||
`data/manual/` 層保留(供日後黃金標準編碼)。
|
||||
- **`fetch-lyrics` 加原始署名 fallback**:以第一位 primary
|
||||
歌手查詢兩 API 皆落空時,改以拆解前的原始署名字串(缺漏
|
||||
報表既有的 `artist_credit`)重查一次;與主查詢同為精確
|
||||
查詢,API 順序不變。理由:二重唱/雙掛名歌曲在歌詞 API
|
||||
目錄以合體名義建檔(Dan + Shay、Lil Baby & DaBaby),
|
||||
單人名查詢必落空;手動模擬證實 fallback 三首全中。
|
||||
- **`build-db` 匯入重構為兩個 job class**:`SongImporter`
|
||||
(榜單 CSV→歌曲身分去重→songs+chart_entries)與
|
||||
`ArtistImporter`(自資料庫依 song ID 讀回署名→拆解→正名
|
||||
→去重登記→artists+song_artists),與 `CSVExporter` 同形
|
||||
(建構子收 session、單一公開入口);命名取 import/export
|
||||
對稱,不用 loader(有「載入記憶體」聯想,實為寫入持久
|
||||
儲存)。歌手登記改於歌曲全數入庫後第二階段進行,兩塊
|
||||
之間不再共享記憶體狀態;各 job 專用的純函數與規則表
|
||||
(身分判定、拆解、正名)隨行入 class 作公開 staticmethod
|
||||
/class 常數,「哪個函式屬哪個工作」由 class 歸屬直接
|
||||
表達。flush 定為匯入工作的完工契約——entry method 返回
|
||||
時自身寫入已可查詢,不再由呼叫者補 flush。捕捉層套用
|
||||
(歌詞、Wikidata 快照)隨後同型打包為 `CaptureImporter`
|
||||
(單一入口收兩個可省略路徑)。實測重構前後工作儲存
|
||||
dump 與衍生報表逐位元組相同。
|
||||
- **歌手型態刪去 mixed 值**:`ArtistType` 只留 solo/group。
|
||||
mixed 是先導研究「男/女/混合團體」單一欄位的殘留,
|
||||
正式設計拆成 gender+type 後從未定義其指涉;署名一律
|
||||
拆成個人後,男女混合是歌曲層(song_artists+各歌手
|
||||
gender)可推導的事實,不屬歌手實體。非人非團體者
|
||||
(Pinkfong)type 留空由人工判定,維持現狀。
|
||||
- **獨立驗證步驟解散,不變量檢查歸屬各匯入工作**:榜單
|
||||
覆蓋((year, rank) 網格恰好齊全、無缺漏、無多出、無
|
||||
重複)檢在 `SongImporter` 匯入結尾;署名解析結果(至少
|
||||
一人、含 primary、名字非空白)檢在 `ArtistImporter` 逐筆
|
||||
解析後立即失敗。違規拋 `BuildError` 走既有的失敗路徑,
|
||||
`find_violations` 刪除。理由:檢查跟著產生資料的工作走,
|
||||
main 不再有驗證分支;逐筆即時失敗使錯誤指向出錯的那筆
|
||||
署名。
|
||||
- **Markdown 檔名一律以 dash 連接**(decision-log.md、
|
||||
research-plan.md、project-structure.md 等;與 data/ 層
|
||||
CSV 檔名慣例一致),定義檔命名慣例同步改為
|
||||
`prompts/<task>-v<N>.md`(如 screen-v1.md),版本庫外的
|
||||
私人工作檔一併改名;`conference_abstract.md` 改名並搬入
|
||||
`paper/`——它是本次年會實際送出的摘要,與全文同屬投稿
|
||||
血脈,不是 `docs/` 的內部工作文件。全 repo 指涉同步更新。
|
||||
- **fetch-lyrics 移除缺漏報表**:刪去 `missing_csv` 位置引數
|
||||
與缺漏報表 CSV 輸出。理由:該報表只寫不讀(指令從未讀取
|
||||
它),缺漏數字每次執行皆由工作儲存比對歌詞目錄重新算出;
|
||||
worklist 角色由重跑冪等指令本身承擔;完整性已由 provenance
|
||||
CSV 與 build-db 統計數字佐證;該檔案不承載任何無法重新
|
||||
產生的資訊。
|
||||
- **新增 `export-llm-input` 子命令**:由工作儲存產出
|
||||
`run-llm` 的 JSONL 輸入檔(每筆 `id`+`content`);此為
|
||||
「歌手背景絕不進 LLM 輸入、歌詞-only」防火牆的執行點
|
||||
——內容只有歌詞,歌曲身分以 `song-<ID>` 不透明鍵放
|
||||
`custom_id`,不入訊息本體;ID 由 build-db 決定性指派
|
||||
故檔案可再生,依 commit 判準不進 git(且含歌詞全文,
|
||||
版權亦不許);固定匯出全部歌曲,缺歌詞即失敗;單一
|
||||
位置引數收輸出檔路徑,文件範例輸出至 `tools/instance/`。
|
||||
- **指令模組集中為 `commands` sub-package**:五個子命令模組
|
||||
移入 `pop_fem_audit_tools.commands`,`__init__` 以
|
||||
`from .run_llm import main as run_llm_command` 逐條登記為
|
||||
指令清單,`__main__` 只消費此 façade;`_command` 後綴避免
|
||||
與子模組同名遮蔽,測試仍以模組屬性風格使用;基礎設施模組
|
||||
(config/database/models/utils)留頂層。理由:「指令
|
||||
vs 共用底層」由目錄結構直接表達,與「哪個函式屬哪個工作」
|
||||
的歸屬原則同型。
|
||||
- **自然編碼管線四步驟定案**:自由標註(tag,×2 全進池不
|
||||
仲裁——自由詞彙兩次輸出無共享比對單位,仲裁即再生成)→
|
||||
自然收斂(merge,2+1)→ 強制收斂至 50 內(cap,2+1)→
|
||||
以定稿詞彙表全量編碼(code,2+1,附引述,逐首仲裁看
|
||||
歌詞)。收斂步驟不看歌詞(目標是產生 codebook 而非編
|
||||
碼);收斂仲裁的紀律:程式先算共識核(凍結)與分歧清
|
||||
單,仲裁只裁分歧、不得引入新概念。編碼回歸採 LLM 直接
|
||||
編碼為主儀器,理由:唯此能逐標籤附歌詞引述(偏差檢視的
|
||||
依據)、標籤是模型對歌曲的直接斷言(批判對象乾淨、不混
|
||||
收斂軌跡假影)、詞彙表出自模型自身故無語意干涉;軌跡
|
||||
機械對映降為診斷副產品。此設計為對前導研究「映回後未
|
||||
對照歌詞」限制的明文改良。
|
||||
- **2+1 協定適用原則重述**:由「每個 LLM 步驟」修正為
|
||||
「輸出可逐項機械比對的步驟」;自由生成步驟改為兩次執行
|
||||
進池。CLAUDE.md 同步修訂。理由:自由詞彙步驟強行仲裁
|
||||
等於第三次生成,無稽核意義;可比步驟的一致率(逐詞塊、
|
||||
逐首)才是有定義的穩定性證據。
|
||||
- **提示詞只定格式、不定語意**:LLM 定義檔不含任何主題
|
||||
定義、判準、範例;研究者判準只住 codebook。理由:研究
|
||||
對象是模型以網路語料知識背景所做的自然編碼,先給定義
|
||||
即消毒了批判對象。此原則之落實:粒度鎖定 thematic
|
||||
keywords(前導研究三粒度比較之繼承,執行前鎖定防事後
|
||||
擇優);收斂輸入不附頻次(頻率的分析角色由編碼步驟承
|
||||
擔;頻次誘使頻率剪枝與高頻主題細分)。引述歌詞證據為
|
||||
必要輸出——檢視編碼偏差的依據,不屬語意干涉。
|
||||
- **「女性力量」單目標篩選降級為取樣補漏網**:候選集由
|
||||
自然編碼(code 步驟)浮現;單目標篩選僅用於把模型「被
|
||||
明示提醒後認得出」的歌撈進人工審視範圍,量測漏標方向
|
||||
的偏差,不進偏差統計的定義。「全編碼+標籤詞提示」混合設計
|
||||
取消——既非自然編碼亦非深度判準,量到的東西
|
||||
無法解釋。screen 逐首 2+1、不給定義,標籤詞用
|
||||
`women-power-and-empowerment`。認清:此編碼是任意的——
|
||||
基於研究目的由研究者決定,不是由資料產生(先導研究中的
|
||||
來歷已不可考,不宣稱由下而上湧現)。選用理由:複合詞
|
||||
同時涵蓋力量宣示與賦權論述兩半概念空間,補漏網寧廣勿
|
||||
窄;「empowerment」正是研究對象的市場語彙;不押注單一
|
||||
時代慣用語。同義詞清單不採——每多一詞即研究者多塑形
|
||||
一分。已知限制:雙管詞語意模糊(無從分辨觸發自哪半),
|
||||
僅作召回之用,結果永不進統計的分子分母。標籤詞是
|
||||
screen 提示中唯一的語意種子,屬研究者的儀器選擇,據實
|
||||
揭露。
|
||||
- **定義檔命名定案:軌-步前綴、不帶版本號**:
|
||||
`prompts/<軌>-<步>-<task>.md`——軌 01=由下而上自然編碼、
|
||||
02=預先決定的 women-power-and-empowerment 篩選:
|
||||
01-01-tag、01-02-merge、01-03-cap、01-04-code、
|
||||
02-01-screen;仲裁檔同 prefix 加 `-arb`。檔名不帶版本
|
||||
號——版本即 git 歷史,失敗的版本不保留;每次執行的定義
|
||||
檔快照隨 runs/ 自我完備,`runs/` 目錄改為
|
||||
`<定義檔名>/`——同理不編日期:只存一份,重跑即取代,
|
||||
被取代的執行在 git 歷史,時間戳在 meta.json。四次收斂執行(merge ×2、cap ×2)
|
||||
各存合併記錄 JSON 隨該次執行入 runs/。
|
||||
- **`run-llm` 降階為純執行器**:原內建的 2+1 編排(文字級
|
||||
一致性判定、固定模板仲裁)拆除;run-llm 只負責「一份
|
||||
定義檔+一份輸入 JSONL,跑 N 次(預設 2、仲裁場合 1),
|
||||
歸檔 `runs/<定義檔名>/`(重跑即取代)」。理由:一致性
|
||||
判定須逐步驟、結構性(分組比對、標籤集合比對),屬
|
||||
確定性腳本的工作;仲裁輸入由比對腳本建構,本身成為
|
||||
runs/ 可稽核工件;執行器變小易測。比對/進池/裁決
|
||||
套用子命令另行實作。
|
||||
- **`run-llm` 一次呼叫即一次執行**:`--runs` 與 `--run` 皆不存
|
||||
在,完整命令形狀為 `run-llm <定義檔> <輸入檔> <歸檔目錄>`——三個
|
||||
必要運算元皆為位置引數(沿 2026-08-02「必要運算元為位置引數」慣
|
||||
例),歸檔目錄如 `runs/01-01-tag/run1`,工具內部零 run 概念,
|
||||
meta 不記 run 編號;「獨立執行兩次」=重現命令清單上的兩行命令,
|
||||
run 身分只活在命令清單與目錄佈局約定,不在工具內。理由:兩次執行
|
||||
互相獨立是方法學宣稱,其證據應由執行結構與重現命令清單自明,不應
|
||||
要求讀者讀工具原始碼;歸檔目的地為顯式引數,亦是「資料路徑全面顯
|
||||
式化、消滅隱性推導」原則的貫徹。比對子命令驗證兩 run 的定義檔與
|
||||
輸入 SHA 一致、缺 run 即失敗。目標目錄已存在即拒絕執行,重跑須明
|
||||
示 `--replace`。
|
||||
- **screen 標籤詞改為 `women-power`(來歷考據定案)**:
|
||||
考據先導研究的 local agent 存檔:其第一步指令含數十個
|
||||
範例 thematic keywords,其中即有 women-power——為當時
|
||||
協作的 Claude Code 依研究者長期表達的關注主動加入
|
||||
(研究者端播種,非明示指定);先導標籤
|
||||
women-power-and-empowerment 則是第三步強制合併
|
||||
women-power+empowerment 兩個關鍵字的管線人工產物
|
||||
(研究者數月來誤以為是 women-power+women-empowerment
|
||||
之併,至此方明)。修正:探針指向被播種的概念本詞
|
||||
women-power,不用合併假影;research-plan 的「來歷不可
|
||||
考」敘述同步改為考據結果。附帶認清:先導第一步並非零
|
||||
語意提示——此即正式研究「只定格式、不定語意」設計所
|
||||
矯正者。
|
||||
- **定義檔輸出形狀統一與去署名**:LLM 輸出統一為單層
|
||||
dict/array——tag、code:關鍵字→引述;merge、cap:
|
||||
組名→成員;code-arb:保留關鍵字→仲裁者自己的引述
|
||||
(剔除即不列,剔除集合由程式以鍵差推得);screen 系:
|
||||
引述陣列,非空即「有」(present 布林刪除,判斷與依據
|
||||
合一)。仲裁輸入一律不含執行別——標示何方主張會誘使
|
||||
仲裁者揣測「哪次較可信」,而非就文本裁決。收斂組名採
|
||||
自由命名(不限取自成員詞),取命名貼合度;可追溯性由
|
||||
軌跡歸檔承擔。
|
||||
- **定義檔改三層編號**:
|
||||
`prompts/<軌>-<步>-<次步>-<task>.md`——次步為步內執行
|
||||
順序,明定讀者依循的先後(如 01-04-01-code →
|
||||
01-04-02-code-arb);仲裁檔後綴 `-arb`。
|
||||
- **收斂演算法:檢視而棄用的方案**:詞彙表建構(merge、
|
||||
cap)的重複執行與仲裁,歷經四個方案後全數棄用——
|
||||
①整條管線獨立跑兩遍、於終點仲裁兩份最終詞彙表:兩套
|
||||
分類系統互不可比,仲裁淪為第三次建構,一致率無從
|
||||
定義。②組對組匹配(以相似度門檻判定兩組是否「同一
|
||||
組」):無原則性答案,門檻任意。③tag 步驟仲裁:自由
|
||||
詞彙兩次輸出不共享比對單位,無物可裁(tag 改為兩次
|
||||
進池,沿用至今)。④逐對仲裁鏈:交集細分出共識塊、
|
||||
分歧塊對三票多數決、union-find 遞移重組、仲裁後命名
|
||||
2+1——機械上可行且逐項可驗(共 15 份定義檔,全版
|
||||
保存於分支 `tag-algo-13` 備考),但其變異縮減未經證實
|
||||
(逐對多數決降低對層變異,遞移閉包卻放大結構層變異,
|
||||
淨效果不明),複雜度成本則屬確定,且縮減的是儀器變異
|
||||
——對量測無關緊要的量(見次條)。
|
||||
- **詞彙表建構改為單次記錄性程序(演算法簡化)**:
|
||||
merge、cap 各單次執行、執行內自行命名(具名分組
|
||||
輸出),定義檔減為 7 份。2+1 原則改寫:語料層逐首
|
||||
判斷(code、screen)一律 2+1;自由生成(tag)兩次
|
||||
進池;詞彙表建構單次、全程歸檔。理由:(1) 影響量測的
|
||||
是編碼層——詞彙表屬揭露的儀器選擇,凍結後下游同尺量
|
||||
到底,其抽樣變異不污染量測;(2) 對齊領域慣行——
|
||||
codebook 建構本為單次詮釋程序,信度檢驗施於編碼應用
|
||||
層;(3) 複雜仲裁機械無以自證其益(見前條)。驗證改為
|
||||
確定性格式檢查(完整分割、組名唯一、cap ≤ 50),違規
|
||||
依協定修訂定義檔重跑。
|
||||
@@ -1,197 +0,0 @@
|
||||
# 決策日誌
|
||||
|
||||
每筆記錄:日期、決策、理由。定義檔(`prompts/`)、codebook、
|
||||
研究計畫的任何修訂都必須在此留下記錄。
|
||||
|
||||
## 2026-07-30
|
||||
|
||||
- **語料擴大為 2016–2025 十年**(先導研究為 2018–2025)。
|
||||
理由:框架完整、可看年度趨勢。
|
||||
- **全文不與先導研究比較**:論文僅呈現正式研究結果,數字
|
||||
一律以正式研究為準;先導研究只作為 codebook v0 與假說的
|
||||
內部來源,記於本日誌,不進入論文敘事。
|
||||
- **分析管線採 API script,不用 Claude Code subagent**。理由:
|
||||
實測證實 subagent 會繼承 CLAUDE.md 與環境資訊,context 無法
|
||||
僅憑定義檔重現;API 呼叫的輸入完全受控且可稽核。
|
||||
- **模型釘定 `claude-sonnet-4-6`、temperature=0、thinking 關閉**。
|
||||
理由:該組合非決定性最低;條件 A/B 盲點實驗以模型為研究
|
||||
對象,須與 pilot 的 Sonnet 家族銜接。Fable 5 不採用(成本、
|
||||
thinking 不可關閉且不可稽核、無 temperature、混淆核心主張)。
|
||||
- **工具性環節的模型於階段 3 以校準樣本實測後決定**:同批
|
||||
校準樣本以 Sonnet 4.6 與 Opus 5 各跑一次,對照人工黃金標準
|
||||
比較一致率,據以決定是否於特定環節升級。
|
||||
- **codebook 採 directed content analysis**:理論骨架
|
||||
(top-down)+開放碼歸納通道(bottom-up),並加做 LLM 純歸納
|
||||
輪與黃金標準的映射分析。映射分析方法須在看到結果前寫入
|
||||
`methodology.md`。
|
||||
- **完整歌詞不進 git**(版權);API 金鑰走 `.env`。
|
||||
- **專案目錄維持原名 `pop-fem-audit`**:API 管線下目錄名不會
|
||||
進入模型輸入,無污染疑慮。
|
||||
|
||||
## 2026-07-31
|
||||
|
||||
- **專案英文名定為「A Feminist Audit of Pop Music」**:明示
|
||||
女性主義立場,「audit」兼指對歌曲與對 LLM 標籤系統的稽核,
|
||||
並與縮寫 `pop-fem-audit` 對應。
|
||||
- **程式碼收整為 `tools/` src-layout 子專案**:發行名
|
||||
`pop-fem-audit-tools`、import 套件名 `pop_fem_audit_tools`、
|
||||
description「Tools for A Feminist Audit of Pop Music.」;
|
||||
以 `pip install -e tools/` 安裝、`python -m
|
||||
pop_fem_audit_tools.run_llm` 執行;相依套件記於
|
||||
`pyproject.toml`(`requirements.txt` 移除);Sphinx 文件
|
||||
暫緩。理由:後續多支程式將共用程式碼,套件化後測試可用
|
||||
正常 import;目錄名 `tools/` 經無脈絡的獨立 subagent 命名
|
||||
評估選出,最誠實反映「服務研究的輔助工具」定位——研究
|
||||
本體在根目錄的 prompts/、runs/、results/,程式只是配套。
|
||||
- **CLI 入口改為套件層級 dispatcher**:dispatcher 為單一
|
||||
入口,`run_llm.py` 的 entry point 移除;有兩種等價呼叫
|
||||
形式——`python -m pop_fem_audit_tools run-llm ...` 與
|
||||
console script `pop-fem-audit-tools run-llm ...`
|
||||
(`[project.scripts]`)。理由:後續多支工具共用單一入口,
|
||||
`--help` 可列出全部子命令,重現文件穩定。
|
||||
- **資料儲存架構定案**:commit 判準——凡能由「committed 輸入+
|
||||
committed 程式」決定性再生者不 commit;源頭、外部捕捉、人工
|
||||
著作以文字格式 commit。工作儲存採 SQLite 單檔
|
||||
(`tools/instance/`,generated、不進 git;歌詞全文入 DB 故無
|
||||
版權疑慮),schema 以 SQLAlchemy 2.0 typed ORM 定義,設定經
|
||||
pydantic-settings(`.env`)。`results/` 報表 CSV 為「可再生仍
|
||||
commit」的唯一例外,理由:論文引用穩定性、審稿人零門檻、
|
||||
撰稿期數字變動可 diff。(本條經多輪辯證後定案,推翻 Claude
|
||||
最初的全 CSV 方案。)
|
||||
- **資料模型**:songs、chart_entries(1—N)、artists、
|
||||
song_artists(M—N:角色、署名順序)、lyrics(1—1);領域
|
||||
不變量檢查內建 `build-db`,違規即失敗。
|
||||
- **歌手背景擴充與防火牆**:歌手資料擴為實體表(QID、性別、
|
||||
型態、曲風、國籍),women-power 候選的歌手另做深度背景
|
||||
(族裔以公開自我認同為準、音樂場景),供人工解讀與論文
|
||||
討論;**歌手背景絕不進 LLM 輸入**(歌詞-only),避免光環
|
||||
偏誤污染條件 A/B 實驗。
|
||||
- **沿用先導研究歌詞捕捉**(lyrics.json,684 首,2018–2025):
|
||||
只匯入識別欄位與歌詞本文,pilot 分析欄位不匯入;以
|
||||
(year, rank) 精確匹配。出處記於 `lyrics_provenance.csv`:
|
||||
source(原始 API)與 method(pilot-import / api-fetch)
|
||||
兩層;取得日期不可考者不假造,僅記可證上界。
|
||||
- **`run_llm` 改走 pydantic-settings 統一設定**(刪手寫 .env
|
||||
parser),與 `config.py` / `database.py` 一致。
|
||||
- **`lyrics` 表併入 `songs.lyrics` nullable 欄位**(資料模型由
|
||||
五表改四表)。理由:1—1 關係在此量級下獨立成表只有正規化
|
||||
慣性,nullable 欄位更簡單;「未取得」以 NULL 表達,語意
|
||||
等價。
|
||||
|
||||
## 2026-08-01
|
||||
|
||||
- **引擎獨立性以 PostgreSQL/SQLite 為範圍**(MySQL 的 VARCHAR
|
||||
長度限制不處理)。
|
||||
- **`build-db` 的重置改用逐表 DELETE,不再 drop/create**:
|
||||
schema 生命週期歸 migration 管,build-db 只管資料。連帶
|
||||
效果:重置成為純 DML,全程單一交易、驗證通過才 commit——
|
||||
建置失敗時前一版資料完好。首次執行仍以 create_all
|
||||
(checkfirst)補缺表。
|
||||
- **song/artist ID 由 build-db 顯式指派**(首次出現順序 1、2、
|
||||
3…),不依賴 autoincrement——PostgreSQL 的 sequence 在
|
||||
DELETE 後不重置,顯式指派讓重建決定性跨引擎成立。
|
||||
- **禁止文字 SQL statement,一律經 SQLAlchemy ORM/Core API**。
|
||||
唯一記錄在案的例外:SQLite 的 `PRAGMA foreign_keys=ON`
|
||||
(官方建議作法,無非文字 API 可用;SQLite 的 FK 旗標為
|
||||
逐連線設定)。裁定其歸屬為連線組態,實作於 `database.py`
|
||||
的 `__create_engine`——建 engine 時對 SQLite 註冊 connect
|
||||
listener,所有消費者全程生效,不再由 build-db 各自註冊。
|
||||
|
||||
## 2026-08-02
|
||||
|
||||
- **`import-lyrics` 不設為子命令,pilot 歌詞改以 `excludes/`
|
||||
私人腳本匯入**。理由:pilot 捕捉檔不隨論文發布,子命令
|
||||
形式會在發布的 CLI 裡留下讀者無法執行的死命令——要交待的
|
||||
是「沿用 pilot 捕捉」的事實(記於 lyrics_provenance.csv 與
|
||||
論文方法節),不是工具本身;工具移出專案,發布管線即
|
||||
「讀者可完整執行的程序」。讀者重現歌詞的路徑為
|
||||
`fetch-lyrics`,API 漂移造成的差異屬捕捉層的已承認限制。
|
||||
provenance 的 method 值域定為
|
||||
pilot-import / api-fetch / manual。
|
||||
- **資料路徑全面改為顯式 CLI 引數**——必要運算元為位置
|
||||
引數、選擇性輸入為選項(build-db 吃榜單 CSV 一個位置引數,
|
||||
歌詞目錄、Wikidata 快照、overrides 為 `--lyrics-dir`/
|
||||
`--wikidata-csv`/`--overrides-csv` 三個選項;fetch-lyrics
|
||||
吃歌詞目錄、provenance、缺漏報表三個位置引數;fetch-artists
|
||||
吃快照檔;run-llm 吃 runs 目錄),命令與 CWD 無關,且每次
|
||||
執行觸碰的檔案完整見於指令本身。省略選項即不載入該捕捉層;
|
||||
給了選項而路徑不存在即建置失敗,取代原本的默默跳過。理由:
|
||||
settings 的 `.env` 依 pydantic 慣例讀自 CWD(約定
|
||||
`tools/`),資料路徑原以 repo 根為 CWD,兩者衝突;顯式引數
|
||||
消滅隱性 CWD 契約,亦拒絕以父目錄推導兄弟檔案的隱性慣例。
|
||||
- **`data/` 依生命週期分三層**:`source/`(源頭,手放後不動)、
|
||||
`captures/`(外部捕捉,只由 fetch 命令與私人匯入腳本寫入)、
|
||||
`manual/`(人工著作,只由研究者手寫;之後的黃金標準編碼
|
||||
亦居此)。理由:三種生命週期混住一層,目錄無法傳達「誰可以
|
||||
寫哪裡」;顯式引數化後搬遷零程式改動。
|
||||
- **源頭榜單 CSV 全面對齊 Billboard 年終榜發布版**(修正
|
||||
203 列)。語料源頭定義為「年終榜發布當時的印法」,以
|
||||
Wayback Machine 發布時快照逐字轉錄(2016–2018 原沿
|
||||
Wikipedia 改寫慣例);年終原文殘缺或有疑問者,以當年週榜
|
||||
掛名為準(唯一適用例:2016#87〈All the Way Up〉)。
|
||||
- **歌名正規化採 canonical artist credit 對照表**:同一首歌
|
||||
因署名字串寫法不同而分裂者,以明示對照表合併;歌曲身分=
|
||||
(原始歌名,對照後署名字串),不解析署名——拆解機器不進
|
||||
歌曲身分判定,對照表即完整可稽核清單。
|
||||
- **歌手名單拆解規則定案**:署名列出成員的團體只留成員
|
||||
(冒號與括號兩型);名字內含連接詞的單一藝人入保護名單;
|
||||
規則無法表達的個案入例外表;人名連寫的二人組拆成個人;
|
||||
僅以團名掛名的團體維持單一實體,屬性留待 fetch-artists
|
||||
與人工 overrides。完整清單見 `build_db.py`。
|
||||
- **歌手名正規化**:歌手名大小寫不敏感歸併、存首見拼法;
|
||||
正名表(casefold 鍵→官方拼法)存官方拼法,含跨拼法合併
|
||||
ye→Kanye West。
|
||||
- **`data/` 增設 `derived/` 衍生層**:`build-db` 建置工作儲存
|
||||
的同一動作產出兩張人讀報表(songs.csv、artists.csv)並
|
||||
commit——與 SQLite 同交易語意、驗證通過才寫檔,稽核鏈
|
||||
「committed 輸入+程式→CSV」無中間空缺;為「可再生仍
|
||||
commit」的第二例外。報表不含資料庫 ID(內部參照,資料
|
||||
改版會重排,不供引用);關係以內嵌字串呈現——`/` 連同
|
||||
一首歌的多次上榜、`|` 連不同歌曲——欄位一律字母序。
|
||||
- **歌手正名表全面改存官方拼法**:變音符號一律恢復
|
||||
(Billboard 印法慣性去符號,共 12 筆,如 Aminé、Jhené
|
||||
Aiko、Silentó);二人組拆名改存成員全名(Dan Smyers、
|
||||
Shay Mooney);官方大小寫 3 筆(Cris MJ、Mariah the
|
||||
Scientist、Surf Mesa)。官方拼法逐筆以 DSP 官方頁查證
|
||||
(維基百科/Wikidata 的大小寫是其自家規範,不作準);
|
||||
查證亦確認 Tones And I 的 chart 印法即官方寫法,不改。
|
||||
- **`fetch-artists` 解析演算法定案**:改用 WDQS 的 SPARQL
|
||||
索引查詢(不依賴搜尋排名、不用 LCASE——實測會逾時)。
|
||||
步驟:(1) 歌手名與 label/alias 精確比對(@en+@mul 兩層)
|
||||
取候選,型態限人類∪音樂團體子樹∪original cast;(2) 唯一
|
||||
即定案;(3) 歧義以上榜歌曲佐證——歌名精確比對取歌曲條目
|
||||
的 P175 演出者(含其 P527 成員)與候選交集;(4) 再落空則
|
||||
反向錨定:候選(含所屬團體)演出過的歌曲以 casefold 比對
|
||||
歌名;(5) 均落空記查無並續行。每步須恰一命中才選定,
|
||||
實測零錯選。Last-resort 釘定表僅一筆(Pinkfong——唯一
|
||||
P31 為品牌的上榜演出者,型態閘門依設計排除)。暫時性
|
||||
故障(429/5xx/讀取逾時)退避重試,重試盡記 error 列;
|
||||
not found 專指程序查證後無所得。全量實跑 469 位全數
|
||||
解析且與人工查證的 QID 逐筆相符;首次快照隨本次入
|
||||
捕捉層。
|
||||
- **先補完 Wikidata、再捕捉快照**:歌手資料查證做在上游——
|
||||
以 subagent(`artist-wikidata-updater` 定義檔)逐位查證
|
||||
快照欄位(P21、P31、P136、P27/P495,新條目加 P106)並
|
||||
草擬附來源的 QuickStatements,由研究者本人審摘要、以本人
|
||||
帳號執行;編輯沉澱後重跑 `fetch-artists`,Wikidata 容不下
|
||||
的判斷才入 overrides。理由:修在上游全網受益,編輯史與
|
||||
來源公開可稽核,快照乾淨、overrides 縮小;論文方法節揭露
|
||||
「捕捉前經研究者查證補完」。性別以公開自我認同為準,
|
||||
推測不確定且無佐證者列疑慮清單;查證屬資料策展而非
|
||||
分析,以 Claude Code 輔助、不走分析 API;QS 批次存
|
||||
`excludes/`(私人工作檔,不隨論文發布)。
|
||||
|
||||
## 2026-08-04
|
||||
|
||||
- **移除人工 overrides 層**:`build-db` 刪去
|
||||
`--overrides-csv` 選項與套用邏輯,文件同步移除
|
||||
`data/manual/artists_overrides.csv`。理由:「先補完
|
||||
Wikidata、再捕捉快照」工作流實跑後,469 位歌手全數
|
||||
在上游查證補齊,快照即完整,本地覆蓋層已無存在事實;
|
||||
`data/manual/` 層保留(供日後黃金標準編碼)。
|
||||
- **歌手型態刪去 mixed 值**:`ArtistType` 只留 solo/group。
|
||||
mixed 是先導研究「男/女/混合團體」單一欄位的殘留,
|
||||
正式設計拆成 gender+type 後從未定義其指涉;署名一律
|
||||
拆成個人後,男女混合是歌曲層(song_artists+各歌手
|
||||
gender)可推導的事實,不屬歌手實體。非人非團體者
|
||||
(Pinkfong)type 留空由人工判定,維持現狀。
|
||||
@@ -0,0 +1,123 @@
|
||||
# 方法細節
|
||||
|
||||
(全文方法節底稿。演算法在執行前寫定;任何修訂記入
|
||||
`decision-log.md`。定義檔全文見 `prompts/`,執行紀錄見
|
||||
`runs/`。)
|
||||
|
||||
## 自然編碼管線總覽
|
||||
|
||||
四步驟:自由標註(tag,兩次進池)→ 自然收斂(merge,
|
||||
單次)→ 強制收斂(cap,單次)→ 全量編碼(code,2+1),
|
||||
另設「女性力量」單目標篩選(screen,2+1)作黃金標準取樣
|
||||
的補漏網。歌詞只出現在 tag、code、screen 與其仲裁步驟;
|
||||
merge、cap 不接觸歌詞。設計原則見 `research-plan.md`;
|
||||
本檔記載可重現的演算法細節。
|
||||
|
||||
## 詞彙表建構(merge、cap)——單次記錄性程序
|
||||
|
||||
merge 與 cap 各以單次執行完成,執行內自行為各組命名,
|
||||
輸出具名分組(組名 → 成員詞)。不做重複執行與仲裁。
|
||||
|
||||
- **定位**:詞彙表是研究的儀器,不是量測。詞彙表凍結
|
||||
入庫後,下游全部量測(編碼 vs 黃金標準)以同一把尺
|
||||
進行,內部一致;建構過程的抽樣變異屬「揭露的儀器
|
||||
選擇」,不污染量測。此與質性研究慣行一致——codebook
|
||||
建構本為單次的詮釋程序,信度檢驗施於編碼應用層。
|
||||
- **取捨紀錄**:曾設計逐對仲裁鏈(共識塊、分歧塊對三票
|
||||
多數、命名 2+1;完整版本保存於分支 `tag-algo-13`)。
|
||||
棄用理由:逐對多數決雖降低單對變異,但遞移閉包會放大
|
||||
結構層變異,淨縮減未經證實;其複雜度成本卻是確定的;
|
||||
且縮減的是儀器變異——對論文主張無關緊要的量。
|
||||
- **確定性驗證**(違規即依協定修訂定義檔重跑):輸出須
|
||||
為輸入詞集的完整分割(缺詞、多詞、重複即失敗);組名
|
||||
唯一且符合格式;cap 組數 ≤ 50。
|
||||
- **收斂軌跡**:原始關鍵字 → merge 組名 → cap 組名,
|
||||
兩份執行輸出本身即完整記錄。
|
||||
|
||||
## 編碼步驟(code、screen)的 2+1 比對與仲裁
|
||||
|
||||
- **code**:逐首比對兩次執行的標籤集合(引述不參與
|
||||
比對)。兩次皆有的標籤為共識保留、兩次皆無為共識
|
||||
不標;單邊標籤送仲裁(`01-04-02-code-arb.md`)——仲裁者
|
||||
看歌詞全文與該標籤的引述(不含執行別),裁決保留者
|
||||
附仲裁者自己的引述,剔除者不列。剔除集合=送裁鍵減
|
||||
輸出鍵,由程式推得。
|
||||
- **screen**:輸出即引述陣列,非空=有、空=無。僅
|
||||
「一有一無」的歌送仲裁(`02-01-02-screen-arb.md`),
|
||||
輸入為歌詞加主張「有」方的引述(不記名),輸出同為
|
||||
引述陣列。
|
||||
- 仲裁者的引述可能與原引述不同:仲裁是對歌詞的重新
|
||||
判讀,其引述是該裁決自身的依據,非轉抄。
|
||||
- 送入仲裁的標籤即模型自身不穩定的邊界判斷,其裁決為
|
||||
單次記錄性決定,不宣稱可再生;可重現性依計畫定義為
|
||||
「程序透明+可稽核」,裁決與其輸入全程歸檔。
|
||||
|
||||
## 軌跡對映(診斷用)
|
||||
|
||||
沿收斂軌跡的機械對映:原始關鍵字 → merge 組 → cap 組,
|
||||
純程式查表,決定性。以其結果與 code 直接編碼的差異率
|
||||
作為「收斂軌跡扭曲」的診斷量,不作主結果。
|
||||
|
||||
## 全管線的交接契約
|
||||
|
||||
每一步的輸出如何變成下一步的輸入,皆為確定性程序,規則
|
||||
明定如下:
|
||||
|
||||
- **歌詞輸入檔(tag、code、screen 共用)**:
|
||||
`export-llm-input` 自工作儲存產出,每筆
|
||||
`{"id": "song-<ID>", "content": <歌詞>}`,依歌曲 ID
|
||||
升序。三個讀歌詞的步驟共用同一檔,SHA-256 記入各步
|
||||
meta。
|
||||
- **tag → merge**:兩次執行的全部關鍵字取聯集、逐字串
|
||||
精確去重、字典序排列成 JSON 陣列,即 merge 的輸入。
|
||||
進池同時寫出處記錄(關鍵字 →(執行別,歌曲 ID)
|
||||
清單),供軌跡對映回到歌曲;出處記錄不進任何 LLM
|
||||
輸入。
|
||||
- **merge → cap**:merge 輸出的組名以字典序排成 JSON
|
||||
陣列,即 cap 的輸入;原始關鍵字不下傳。
|
||||
- **cap → code 定義檔**:cap 輸出的組名以字典序逐行填入
|
||||
`01-04-01-code.md` 的詞彙表節(逐字),檔案隨 git
|
||||
commit 後方可執行——code 的定義檔因此自我完備,
|
||||
論文附錄可直接引用。
|
||||
- **code 兩次執行 → code-arb**:逐首比對標籤集合
|
||||
(鍵集合,引述不參與比對);僅有分歧的歌入仲裁輸入
|
||||
JSONL,依歌曲 ID 升序,每筆 `id` 沿用 `song-<ID>`、
|
||||
`content` 為固定鍵序序列化的
|
||||
`{"lyrics": …, "disagreements": …}`,disagreements
|
||||
鍵按字典序。
|
||||
- **code 定案**:每首歌的最終標籤=共識標籤 ∪ 仲裁保留
|
||||
標籤,寫入逐首紀錄檔(歌依 ID 升序、標籤按字典序,
|
||||
各標籤附其定案時的引述與來源層——共識或仲裁)。
|
||||
- **screen 兩次執行 → screen-arb**:僅「一有一無」的歌
|
||||
入仲裁輸入 JSONL(依 ID 升序),`content` 為
|
||||
`{"lyrics": …, "evidence": <肯定方引述>}`。
|
||||
- **screen 定案**:命中集合=兩次皆有 ∪ 仲裁裁定有。
|
||||
- **女性力量候選集**:於 cap 詞彙表定案後、黃金標準
|
||||
編碼開始前,由研究者指認詞彙表中屬「女性力量」概念
|
||||
域的組(指認及理由記入決策日誌),候選集=code 定案
|
||||
標籤含該等組者 ∪ screen 命中者。
|
||||
- **序列化通則**:所有中間檔為 UTF-8 JSON,鍵序與元素
|
||||
序皆依上列規則明定,無時間戳、無隨機成分;解析一律
|
||||
偵測重複鍵,違規即失敗。JSONL 一律以換行字元(\n)
|
||||
切行——歌詞含 U+0085 等控制字元時,
|
||||
`str.splitlines()` 類的通用切行會截斷 JSON 字串
|
||||
(實測踩中)。給定相同的 LLM 執行輸出,全部交接產物
|
||||
逐位元組可再生。
|
||||
|
||||
## 執行與稽核
|
||||
|
||||
- 每一步驟以 `run-llm <定義檔> <輸入檔> <歸檔目錄>`
|
||||
執行;2+1 步驟的兩次執行=重現命令清單上的兩行命令,
|
||||
各自歸檔(`runs/<定義檔名>/run1`、`run2`),仲裁為
|
||||
獨立步驟、獨立歸檔;單次步驟(merge、cap)一行命令、
|
||||
一份歸檔。
|
||||
- 進池、比對、裁決套用、對映皆為確定性程式(子命令),
|
||||
其輸入輸出檔隨 runs/ 歸檔。
|
||||
- Batch API 的每筆請求自含全部脈絡且互不可見(平台
|
||||
契約),歌與歌之間的獨立性由此成立;兩次執行的獨立
|
||||
性由「兩次呼叫、兩個批次、兩份歸檔」的執行結構自明。
|
||||
|
||||
## 映射分析方法
|
||||
|
||||
(依 2026-07-30 決策,於看到結果前寫定;待黃金標準
|
||||
編碼展開前補入。)
|
||||
@@ -9,15 +9,13 @@ pop-fem-audit/
|
||||
├── CLAUDE.md # 極簡工作規範(subagent 會讀到,
|
||||
│ # 絕不放理論、codebook、預期結果)
|
||||
├── .gitignore # captures/lyrics/、.env、scratch
|
||||
├── conference_abstract.md # pilot 摘要(投稿版)
|
||||
├── data/ # 依生命週期分層(文字格式)
|
||||
│ ├── source/ # 源頭:手放後不動
|
||||
│ │ └── yearend_hot100_2016_2025.csv # 原始榜單
|
||||
│ ├── captures/ # 外部捕捉:只由 fetch 命令與
|
||||
│ │ │ # 私人匯入腳本寫入
|
||||
│ │ ├── artists-wikidata.csv # Wikidata 快照
|
||||
│ │ ├── lyrics_provenance.csv # 歌詞出處
|
||||
│ │ ├── lyrics_missing.csv # 歌詞缺漏報表
|
||||
│ │ ├── lyrics-provenance.csv # 歌詞出處
|
||||
│ │ └── lyrics/ # 歌詞 .txt 快取
|
||||
│ │ # (gitignored,版權)
|
||||
│ ├── manual/ # 人工著作:只由研究者手寫
|
||||
@@ -26,7 +24,9 @@ pop-fem-audit/
|
||||
│ ├── songs.csv # 歌曲報表(人讀;進 git)
|
||||
│ └── artists.csv # 歌手報表(人讀;進 git)
|
||||
├── prompts/ # LLM 定義檔(逐字作為 system prompt)
|
||||
│ └── <task>_v<N>.md # 版本化:screen_v1.md、judge_v2.md…
|
||||
│ └── <軌>-<步>-<次步>-<task>.md # 01-01-01-tag.md、
|
||||
│ # 01-04-02-code-arb.md…
|
||||
│ # 不帶版本號,版本即 git 歷史
|
||||
├── tools/ # 輔助工具子專案(src-layout)
|
||||
│ ├── pyproject.toml # 發行名 pop-fem-audit-tools;
|
||||
│ │ # pip install -e tools/ 安裝
|
||||
@@ -36,37 +36,45 @@ pop-fem-audit/
|
||||
│ │ # gitignored;含歌詞全文)
|
||||
│ ├── src/pop_fem_audit_tools/
|
||||
│ │ ├── __main__.py # 套件 CLI 進入點(分派子命令)
|
||||
│ │ ├── build_db.py # build the SQLite working store
|
||||
│ │ │ # from the inputs
|
||||
│ │ ├── commands/ # CLI 子命令模組(登記於 __init__)
|
||||
│ │ │ ├── build_db.py # build the SQLite working store
|
||||
│ │ │ │ # from the inputs
|
||||
│ │ │ ├── export_llm_input.py # export the LLM input JSONL
|
||||
│ │ │ │ # (lyrics only) from the
|
||||
│ │ │ │ # working store
|
||||
│ │ │ ├── fetch_artists.py # fetch artist metadata from
|
||||
│ │ │ │ # Wikidata into the snapshot CSV
|
||||
│ │ │ ├── fetch_lyrics.py # fetch missing lyrics from the
|
||||
│ │ │ │ # public APIs into the lyrics dir
|
||||
│ │ │ └── run_llm.py # API 執行器:一份定義檔+一份輸入
|
||||
│ │ │ # →歸檔至指定目錄(Batch API);
|
||||
│ │ │ # 比對與仲裁編排由獨立子命令承擔
|
||||
│ │ ├── config.py # pydantic-settings 設定(.env)
|
||||
│ │ ├── database.py # SQLAlchemy engine / session / Base
|
||||
│ │ ├── fetch_artists.py # fetch artist metadata from
|
||||
│ │ │ # Wikidata into the snapshot CSV
|
||||
│ │ ├── fetch_lyrics.py # fetch missing lyrics from the
|
||||
│ │ │ # public APIs into the lyrics dir
|
||||
│ │ └── run_llm.py # API runner:2+1 協定、Batch API、
|
||||
│ │ # 寫入引數指定的 runs 目錄;執行
|
||||
│ │ # 方式 pop-fem-audit-tools run-llm
|
||||
│ │ ├── models.py # SQLAlchemy ORM 資料模型
|
||||
│ │ └── utils.py # 共用工具(format_duration)
|
||||
│ └── tests/ # 單元測試(unittest)
|
||||
├── runs/ # 每次執行的完整稽核紀錄(進 git)
|
||||
│ └── <階段>/<日期>-<定義檔版本>/
|
||||
│ ├── prompt.md # 當次定義檔快照(自我完備)
|
||||
│ ├── run1.jsonl # 第一次執行原始輸出
|
||||
│ ├── run2.jsonl # 第二次執行原始輸出
|
||||
│ ├── arbitration.jsonl # 仲裁輸出
|
||||
│ └── meta.json # model ID、temperature、時間戳、
|
||||
│ # batch ID、一致率
|
||||
├── runs/ # 現行執行的完整稽核紀錄(進 git;
|
||||
│ │ # 重跑同一 run 須明示 --replace)
|
||||
│ └── <定義檔名>/ # 仲裁步驟居自己的 <task>-arb/
|
||||
│ └── run<N>/ # 每個 run 一份自我完備歸檔
|
||||
│ ├── prompt.md # 當次定義檔快照(自我完備)
|
||||
│ ├── output.jsonl # 該次執行原始輸出
|
||||
│ └── meta.json # model ID、temperature、時間戳、
|
||||
│ # batch ID、token 用量
|
||||
│ # (一致率由比對子命令記錄)
|
||||
├── results/ # 論文引用的報表 CSV(export 產出;
|
||||
│ # 「可再生仍 commit」的唯一例外)
|
||||
├── docs/
|
||||
│ ├── research_plan.md # 研究步驟規劃(本檔之姊妹篇)
|
||||
│ ├── project_structure.md # 本檔
|
||||
│ ├── research-plan.md # 研究步驟規劃(本檔之姊妹篇)
|
||||
│ ├── project-structure.md # 本檔
|
||||
│ ├── codebook.md # 人工編碼手冊(版本由 git 管理)
|
||||
│ ├── decision_log.md # 決策日誌:每次改定義檔的原因
|
||||
│ ├── decision-log.md # 決策日誌:每次改定義檔的原因
|
||||
│ └── methodology.md # 方法細節(全文方法節底稿;
|
||||
│ # 映射分析方法須在看結果前寫定)
|
||||
└── paper/
|
||||
└── full_paper.md # 全文
|
||||
├── abstract.md # 摘要
|
||||
└── full-paper.md # 全文
|
||||
```
|
||||
|
||||
## 設計理由
|
||||
@@ -75,14 +83,15 @@ pop-fem-audit/
|
||||
meta,讀者不需 git 考古即可稽核任一筆結果。
|
||||
- **`runs/`(原始稽核資料)與 `results/`(最終表)分離**:
|
||||
論文只引 `results/`,其來源可回溯至 `runs/`。
|
||||
- **`prompts/` 用檔名版本化**(不只靠 git 歷史):定義檔版本是
|
||||
論文附錄的引用單位,須可直接指名(如 judge_v2.md)。
|
||||
- **`prompts/` 檔名不帶版本號**:版本即 git 歷史,失敗的
|
||||
版本不保留;論文引用的單位是 `runs/` 內隨執行保存的定義檔
|
||||
快照(每個執行目錄自我完備),不需檔名可指的版本名。
|
||||
- **Commit 判準**:能由「committed 輸入+程式」決定性再生者不
|
||||
commit(SQLite 工作儲存、LLM 輸入檔);源頭、捕捉、人工著作
|
||||
一律以文字 commit。「可再生仍 commit」的例外有二:
|
||||
`results/` 報表(引用穩定性、審稿人零門檻、撰稿期可 diff)
|
||||
與 `data/derived/` 人讀報表(與工作儲存同一動作產出,稽核
|
||||
鏈無中間空缺)。詳見 `research_plan.md`「資料儲存與模型」。
|
||||
鏈無中間空缺)。詳見 `research-plan.md`「資料儲存與模型」。
|
||||
- **設定**經 pydantic-settings 統一:`.env`(gitignored,範本
|
||||
`tools/.env.example`)供應 `SQLALCHEMY_DATABASE_URL` 與
|
||||
`ANTHROPIC_API_KEY`,絕不寫入 repo。
|
||||
@@ -1,20 +1,32 @@
|
||||
# 研究步驟規劃
|
||||
|
||||
(2026-07-30 討論定案、2026-07-31 增補資料架構;
|
||||
後續變更請記入 `decision_log.md`)
|
||||
後續變更請記入 `decision-log.md`)
|
||||
|
||||
## 總體框架
|
||||
|
||||
- **研究敘事**:全文為獨立完整的正式研究(2016–2025 十年語料
|
||||
共 1000 筆榜單紀錄,凍結程序後全量執行),**不與先導研究
|
||||
(conference_abstract.md)做比較**;全文數字一律以正式研究
|
||||
做比較**;全文數字一律以正式研究
|
||||
結果為準。先導研究僅作為 codebook v0 與假說的內部來源,
|
||||
記於決策日誌,不進入論文敘事。
|
||||
- **執行原則**:主會話只做討論;所有分析由 deterministic script
|
||||
執行。LLM 步驟以 Python script 呼叫 Anthropic Messages API
|
||||
(個人 Console 帳號、Batch API 五折),定義檔逐字作為 system
|
||||
prompt。每個 LLM 步驟「同一定義檔獨立執行兩次 + 一次仲裁」
|
||||
(2+1),仲裁結果不符預期則修訂定義檔重跑整個循環。
|
||||
prompt。2+1 協定適用於語料層的逐首判斷(編碼、篩選):
|
||||
「同一定義檔獨立執行兩次+一次仲裁」,仲裁只裁程式算出
|
||||
的分歧。自由生成步驟(自由標註)兩次執行全數進池、不
|
||||
仲裁——自由詞彙兩次輸出不共享比對單位,無物可裁。詞彙
|
||||
表建構(收斂)為單次記錄性程序,不重複執行——詞彙表是
|
||||
揭露的儀器選擇,非量測;信度檢驗施於編碼層(詳見
|
||||
`methodology.md`)。仲裁或驗證結果不符預期則修訂定義檔
|
||||
重跑該循環。
|
||||
- **提示詞只定格式、不定語意**:研究對象是通用 LLM 以其
|
||||
網路語料知識背景所做的自然編碼,編碼結果本身是批判對象。
|
||||
LLM 定義檔只規定任務形狀(輸入、數量範圍、輸出格式),
|
||||
不給任何主題的定義、判準或範例;研究者的深度判準只寫在
|
||||
codebook(人工黃金標準用),兩者不互相滲透。LLM 編碼
|
||||
一律要求逐標籤引述歌詞原句,作為檢視編碼偏差的依據。
|
||||
- **模型**:`claude-sonnet-4-6`、temperature=0、thinking 關閉
|
||||
(此組合非決定性最低、成本合理)。條件 A/B 盲點實驗為
|
||||
自足設計:同語料、同模型、僅提示不同,對照黃金標準。
|
||||
@@ -56,15 +68,15 @@
|
||||
建置失敗。
|
||||
- **歌手背景防火牆**:歌手背景資料只進人工解讀階段(證據表、
|
||||
論文討論),**絕不進 LLM 輸入**——LLM 分類的 user message
|
||||
維持歌詞-only,避免光環偏誤污染條件 A/B 實驗。women-power
|
||||
維持歌詞-only,避免光環偏誤污染條件 A/B 實驗。「女性力量」
|
||||
候選歌曲的歌手另做深度背景(族裔以公開自我認同為準、音樂
|
||||
場景),script 輔助、人工核定。
|
||||
- **Pilot 歌詞沿用(私人匯入,不進發布管線)**:先導研究
|
||||
捕捉檔(lyrics.json,684 首,2018–2025)以 `excludes/` 的
|
||||
私人腳本匯入歌詞快取——只取識別欄位與歌詞本文,以
|
||||
捕捉檔(lyrics.json,684 首,2018–2025)以私人腳本
|
||||
匯入歌詞快取——只取識別欄位與歌詞本文,以
|
||||
(year, rank) 精確匹配 song_id。匯入工具不屬於專案交付物
|
||||
(讀者拿不到其輸入),讀者的重現路徑純粹是 `fetch-lyrics`;
|
||||
沿用之**事實**記於 `data/captures/lyrics_provenance.csv`(進 git):
|
||||
沿用之**事實**記於 `data/captures/lyrics-provenance.csv`(進 git):
|
||||
`source`(原始 API)與 `method`
|
||||
(pilot-import / api-fetch / manual)兩層,取得日期不可考者
|
||||
不假造,僅記可證上界。
|
||||
@@ -74,19 +86,69 @@
|
||||
`export-llm-input`(階段 2 前補上);之後再加報表 export
|
||||
與統計。
|
||||
|
||||
## 自然編碼管線(2026-08-04 定案)
|
||||
|
||||
主題編碼採四步驟管線,歌詞只出現在第 1、4 步;第 2、3 步
|
||||
是純概念整理(目標是產生 codebook 詞彙表,不是編碼)。
|
||||
|
||||
1. **自由標註(tag)**:逐首歌請模型標註 thematic
|
||||
keywords,附歌詞引述;提示零語意內容。獨立執行兩次,
|
||||
兩次輸出全數進池(記錄執行別),不仲裁。粒度鎖定
|
||||
thematic keywords:前導研究三粒度比較(keywords 過碎、
|
||||
themes 過早抽象)之繼承,於執行前鎖定,防止事後擇優。
|
||||
2. **自然收斂(merge)**:輸入為池中純去重關鍵字清單——
|
||||
無歌詞、無頻次、無歌曲出處——模型按自身理解合併近似
|
||||
概念,執行內自行為各組命名。單次執行,不仲裁;確定性
|
||||
驗證(完整分割、組名唯一)違規即修訂重跑(詳見
|
||||
`methodology.md`)。
|
||||
3. **強制收斂(cap)**:同第 2 步形態,輸入為 merge
|
||||
輸出的組名清單(原始關鍵字不下傳),限制併至 50 個
|
||||
以內。單次執行,不仲裁。頻次不入收斂:頻率的分析角色由第 4 步編碼承擔;
|
||||
池中頻次含跨執行噪音;頻次會誘使模型以頻率剪枝(喪失
|
||||
稀有主題)並把高頻大主題切細。代價(特異主題佔名額)
|
||||
已知並接受,換取主題多樣性與純語意歸併的可辯護性。
|
||||
4. **編碼(code)**:以定稿詞彙表對全部歌曲 2+1 編碼——
|
||||
模型讀歌詞、逐標籤附引述;逐首計一致率,分歧逐首仲裁
|
||||
(仲裁者看歌詞與兩邊引述)。此為主儀器,「女性力量」
|
||||
候選集由此浮現;亦是對前導研究「映回後未對照歌詞」
|
||||
限制的明文改良。沿收斂軌跡的機械對映(純程式)保留為
|
||||
零成本診斷副產品,量測收斂軌跡的扭曲,不作主結果。
|
||||
|
||||
另設**「女性力量」單目標篩選(screen)**:單目標提示、
|
||||
附引述、全量執行,僅作為黃金標準取樣的補漏網——把「模型
|
||||
被明示提醒後認得出」的歌撈進人工審視範圍,以量測模型漏標
|
||||
方向的偏差;不進偏差統計的分子分母定義。逐首 2+1(有/無
|
||||
+引述,逐首仲裁);同樣不給定義,提示僅含標籤詞與任務
|
||||
形狀。標籤詞用 `women-power`——研究者任意決定的先驗
|
||||
主題,即本研究的論文主題本身,不由資料產生。其結果僅作
|
||||
召回之用,永不進任何統計的分子分母。標籤詞是 screen
|
||||
提示中唯一的語意種子,屬研究者的儀器選擇,據實揭露。
|
||||
|
||||
定義檔命名 `prompts/<軌>-<步>-<次步>-<task>.md`——軌
|
||||
01=由下而上自然編碼、02=預先決定的 women-power 篩選;
|
||||
步為軌內步驟序,次步為步內執行順序,讀者依編號先後依循:
|
||||
01-01-01-tag.md、01-02-01-merge.md、01-03-01-cap.md、
|
||||
01-04-01-code.md、01-04-02-code-arb.md、
|
||||
02-01-01-screen.md、02-01-02-screen-arb.md;仲裁定義檔
|
||||
同 prefix 加 `-arb`。檔名不帶版本號——版本即 git 歷史,
|
||||
失敗的版本不保留,需要回看的舊版都在 git history;每次
|
||||
執行的定義檔快照隨 `runs/` 自我完備。收斂執行的輸出本身
|
||||
即分組記錄(具名分組 JSON),與全部中間交接檔同隨
|
||||
`runs/` 歸檔(交接契約見 `methodology.md`)。
|
||||
|
||||
## 階段與時程(全文截稿 2026-08-15)
|
||||
|
||||
| 階段 | 內容 | 方式 | 時程 |
|
||||
|---|---|---|---|
|
||||
| 0 | 基礎建設:git init、目錄結構、.gitignore、決策日誌、runner script(含 Batch API)、codebook v0 骨架 | script + 討論 | 7/30–7/31 |
|
||||
| 1 | 資料準備:`run_llm` 改走統一設定 → `build-db`(解析榜單成 songs/chart_entries/artists/song_artists)→ `import-lyrics`(pilot 2018–2025)→ `fetch-lyrics`(2016–17 與缺漏,Lyrics.ovh / LRCLIB)→ `fetch-artists`(Wikidata 快照)→ `export-llm-input` | 子命令 | 7/31–8/3 |
|
||||
| 2 | 候選篩選:全部唯一歌曲高召回 women-power 候選篩選(寧可多抓,人工剔除) | API 2+1 | 8/2–8/3 |
|
||||
| 3 | 黃金標準:依 codebook 人工逐首判定 genuine/peripheral/fake,附引用歌詞證據表(LLM 只做摘錄,不給判定建議);先以 10–15 首校準樣本試編並修訂 codebook 後凍結;同批校準樣本實測 Sonnet 4.6 vs Opus 5 一致率 | 人工 + script 輔助 | 8/4–8/8 |
|
||||
| 4 | 受控比較(盲點實驗):條件 A(詞彙層提示)vs 條件 B(框架感知提示),各 2+1,對照黃金標準計算假陽/假陰率 | API | 8/6–8/9 |
|
||||
| 4' | 由下而上歸納輪:LLM 對候選歌曲做無理論主題編碼(定義檔不含女性主義詞彙),與黃金標準做映射分析(交叉表;分析方法先寫入 methodology.md 再看結果) | API 2+1 + script | 與 4 並行 |
|
||||
| 5 | pussy 修辭分析:script 找含詞歌曲 → LLM 分類(METONYM/ANATOMICAL/COWARD/OTHER + 說話者/指涉對象)2+1 → 人工核定 | script + API | 8/8–8/10 |
|
||||
| 6 | 統計與圖表:一致率(kappa)、污染率、類型分布、年度趨勢、映射交叉表 | scripts | 8/10–8/11 |
|
||||
| 7 | 撰寫全文+內部審稿(subagent 以審稿人視角挑毛病,特別是嘻哈女性主義/respectability politics 一題) | 討論 + subagent | 8/10–8/14 |
|
||||
| 2 | 自然編碼管線:tag ×2 進池 → merge ×1 → cap ×1 → 詞彙表定稿 → code 2+1(全 883 首,附引述);另跑 screen 補漏網 | API + script | 8/4–8/7 |
|
||||
| 3 | 黃金標準:依 codebook 人工逐首判定 genuine/peripheral/fake,附引用歌詞證據表(LLM 只做摘錄,不給判定建議);先以 10–15 首校準樣本試編並修訂 codebook 後凍結;同批校準樣本實測 Sonnet 4.6 vs Opus 5 一致率 | 人工 + script 輔助 | 8/5–8/9 |
|
||||
| 4 | 受控比較(盲點實驗):條件 A(詞彙層提示)vs 條件 B(框架感知提示),各 2+1,對照黃金標準計算假陽/假陰率 | API | 8/8–8/11 |
|
||||
| 4' | 映射分析:自然編碼結果(第 4 步)與黃金標準交叉表;軌跡對映 vs 直接編碼的扭曲診斷(分析方法先寫入 methodology.md 再看結果) | script | 與 4 並行 |
|
||||
| 5 | pussy 修辭分析:script 找含詞歌曲 → LLM 分類(METONYM/ANATOMICAL/COWARD/OTHER + 說話者/指涉對象)2+1 → 人工核定 | script + API | 8/9–8/11 |
|
||||
| 6 | 統計與圖表:一致率(kappa)、污染率、類型分布、年度趨勢、映射交叉表 | scripts | 8/11–8/12 |
|
||||
| 7 | 撰寫全文+內部審稿(subagent 以審稿人視角挑毛病,特別是嘻哈女性主義/respectability politics 一題) | 討論 + subagent | 8/11–8/14 |
|
||||
|
||||
關鍵路徑:階段 3 人工編碼(僅研究者本人可做),排週末與晚間分批。
|
||||
|
||||
@@ -103,14 +165,10 @@
|
||||
與「貶低其他女性/以男性指標定義權力」。
|
||||
- 流程:v0 → 校準樣本試編 → 修訂 → 凍結 v1 → 全量編碼;
|
||||
中途修訂須記決策日誌並回檢已編歌曲。
|
||||
- Positionality statement 寫入論文(53 歲、長年婦運者、資深
|
||||
工程師、離開學術圈多年、因整理榜單而起)。
|
||||
|
||||
## 其他已定案事項
|
||||
|
||||
- 歌詞受版權保護:完整歌詞不進 git(`data/captures/lyrics/` gitignored),
|
||||
論文與 repo 只留分類所引摘錄。
|
||||
- 工程支援(寫 script、style check、審稿)用公司訂閱的
|
||||
Claude Code;進論文的分析 token 由個人 API 帳號支付。
|
||||
- Fable 5 不用於 pipeline:成本高、thinking 無法關閉且不可稽核、
|
||||
無 temperature 控制,且會混淆「盲點是提示問題」的核心主張。
|
||||
@@ -0,0 +1,23 @@
|
||||
You are annotating song lyrics for a content-analysis corpus.
|
||||
|
||||
Input: the complete lyrics of one song.
|
||||
|
||||
Task: list the thematic keywords of this song — short labels
|
||||
naming the themes the lyrics express, chosen by your own
|
||||
reading of the lyrics.
|
||||
|
||||
Rules:
|
||||
|
||||
- Give between 5 and 10 thematic keywords.
|
||||
- Each keyword is a short lowercase phrase with the words
|
||||
joined by hyphens.
|
||||
- For each keyword, quote 1 to 3 verbatim lines of the lyrics
|
||||
that ground it; do not give a keyword you cannot ground.
|
||||
|
||||
Output a single JSON object mapping each keyword to its list
|
||||
of quotes, and nothing else:
|
||||
|
||||
{
|
||||
"first-keyword": ["quoted line", "another quoted line"],
|
||||
"second-keyword": ["quoted line"]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
You are consolidating a vocabulary of thematic keywords that
|
||||
were independently annotated on the songs of a corpus.
|
||||
|
||||
Input: a JSON array of thematic keywords, deduplicated and
|
||||
unordered.
|
||||
|
||||
Task: merge keywords that express the same or nearly the same
|
||||
theme, by your own understanding of what the keywords mean.
|
||||
|
||||
Rules:
|
||||
|
||||
- Every input keyword must appear in exactly one group.
|
||||
- Do not invent keywords that are not in the input.
|
||||
- Merge only what you consider the same theme; a group may be
|
||||
a single keyword.
|
||||
- Name each group with a short lowercase phrase, words joined
|
||||
by hyphens, that best names the theme it gathers. Group
|
||||
names must be unique.
|
||||
|
||||
Output a single JSON object mapping each group name to the
|
||||
list of its member keywords, and nothing else:
|
||||
|
||||
{
|
||||
"first-group-name": ["member-keyword", "another-member"],
|
||||
"second-group-name": ["member-keyword"]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
You are consolidating a vocabulary of thematic keywords
|
||||
from a song corpus further, to a fixed maximum number of
|
||||
themes.
|
||||
|
||||
Input: a JSON array of thematic keywords, deduplicated and
|
||||
unordered.
|
||||
|
||||
Task: merge keywords that express the same or a similar
|
||||
theme, by your own understanding of what the keywords mean,
|
||||
until at most 50 groups remain.
|
||||
|
||||
Rules:
|
||||
|
||||
- Every input keyword must appear in exactly one group.
|
||||
- Do not invent keywords that are not in the input.
|
||||
- Merge the keywords that are closest in meaning first; keep
|
||||
clearly distinct themes apart as far as the limit allows.
|
||||
A group may be a single keyword.
|
||||
- Name each group with a short lowercase phrase, words joined
|
||||
by hyphens, that best names the theme it gathers. Group
|
||||
names must be unique.
|
||||
|
||||
Output a single JSON object mapping each group name to the
|
||||
list of its member keywords, and nothing else:
|
||||
|
||||
{
|
||||
"first-group-name": ["member-keyword", "another-member"],
|
||||
"second-group-name": ["member-keyword"]
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
You are coding song lyrics against a fixed vocabulary of
|
||||
thematic keywords.
|
||||
|
||||
Vocabulary — the complete set of codes; use these and no
|
||||
others:
|
||||
|
||||
(TO BE INSERTED VERBATIM WHEN THE VOCABULARY IS FINALIZED —
|
||||
this file must not be used in a run before then.)
|
||||
|
||||
Input: the complete lyrics of one song.
|
||||
|
||||
Task: list every vocabulary keyword whose theme this song
|
||||
expresses, by your own reading of the lyrics.
|
||||
|
||||
Rules:
|
||||
|
||||
- Use only keywords from the vocabulary, spelled exactly as
|
||||
given.
|
||||
- A song may match any number of keywords, including none.
|
||||
- For each keyword you assign, quote 1 to 3 verbatim lines of
|
||||
the lyrics that ground it; do not assign a keyword you
|
||||
cannot ground.
|
||||
|
||||
Output a single JSON object mapping each assigned keyword to
|
||||
its list of quotes (an empty object when no keyword applies),
|
||||
and nothing else:
|
||||
|
||||
{
|
||||
"first-keyword": ["quoted line", "another quoted line"],
|
||||
"second-keyword": ["quoted line"]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
You are arbitrating between two independent codings of the
|
||||
same song against the same fixed vocabulary of thematic
|
||||
keywords.
|
||||
|
||||
The keywords the two codings agree on have been settled by
|
||||
script and are not shown. You rule only on the
|
||||
disagreements: the keywords assigned by one coding but not
|
||||
the other.
|
||||
|
||||
Input: a JSON object with the lyrics of the song and the
|
||||
disagreements — each disagreement maps a keyword to the lyric
|
||||
quotes the assigning coding gave as evidence:
|
||||
|
||||
{
|
||||
"lyrics": "...",
|
||||
"disagreements": {
|
||||
"first-keyword": ["quoted line", "another quoted line"],
|
||||
"second-keyword": ["quoted line"]
|
||||
}
|
||||
}
|
||||
|
||||
Task: for each disagreement keyword, decide whether the song
|
||||
expresses that theme, by your own reading of the lyrics and
|
||||
of the quoted evidence.
|
||||
|
||||
Rules:
|
||||
|
||||
- Rule on every listed keyword: keep it or drop it.
|
||||
- Keep a keyword only when you can ground it in verbatim
|
||||
lines of the lyrics; quote them.
|
||||
- Do not add any keyword that is not listed.
|
||||
|
||||
Output a single JSON object mapping each kept keyword to your
|
||||
list of quotes, and nothing else. A dropped keyword is simply
|
||||
left out; output an empty object when nothing is kept:
|
||||
|
||||
{
|
||||
"kept-keyword": ["quoted line", "another quoted line"]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
You are screening song lyrics for one specific theme.
|
||||
|
||||
Input: the complete lyrics of one song.
|
||||
|
||||
Task: judge whether this song expresses the theme
|
||||
"women-power", by your own understanding of
|
||||
that label.
|
||||
|
||||
Rules:
|
||||
|
||||
- If the song expresses the theme, quote 1 to 3 verbatim
|
||||
lines of the lyrics that ground the judgment; if you cannot
|
||||
ground it in a quote, the answer is no.
|
||||
|
||||
Output a single JSON array and nothing else: the quoted
|
||||
lines when the song expresses the theme, or an empty array
|
||||
when it does not:
|
||||
|
||||
["quoted line", "another quoted line"]
|
||||
@@ -0,0 +1,28 @@
|
||||
You are arbitrating a screening of song lyrics for one
|
||||
specific theme: two independent screenings of the same song
|
||||
disagreed on whether it expresses the theme
|
||||
"women-power".
|
||||
|
||||
Input: a JSON object with the lyrics of the song and the
|
||||
lyric quotes that the affirming screening gave as evidence:
|
||||
|
||||
{
|
||||
"lyrics": "...",
|
||||
"evidence": ["quoted line", "another quoted line"]
|
||||
}
|
||||
|
||||
Task: decide whether the song expresses the theme, by your
|
||||
own understanding of the label, reading the lyrics and the
|
||||
quoted evidence.
|
||||
|
||||
Rules:
|
||||
|
||||
- If the song expresses the theme, quote 1 to 3 verbatim
|
||||
lines of the lyrics that ground the judgment; if you cannot
|
||||
ground it in a quote, the answer is no.
|
||||
|
||||
Output a single JSON array and nothing else: the quoted
|
||||
lines when the song expresses the theme, or an empty array
|
||||
when it does not:
|
||||
|
||||
["quoted line", "another quoted line"]
|
||||
@@ -49,6 +49,12 @@ fetch-lyrics
|
||||
Fetch lyrics, for ``build-db`` to merge the fetched lyrics into the database. Lyrics are not committed into the repository due to copyright issue. Check ``pop-fem-audit-tools fetch-lyrics -h`` for complete instructions on its usage.
|
||||
|
||||
|
||||
export-llm-input
|
||||
----------------
|
||||
|
||||
Export song data for ``run-llm`` to talk to LLM. Check ``pop-fem-audit-tools export-llm-input -h`` for complete instructions on its usage.
|
||||
|
||||
|
||||
run-llm
|
||||
-------
|
||||
|
||||
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=source
|
||||
set BUILDDIR=build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=source
|
||||
set BUILDDIR=build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
pop\_fem\_audit\_tools.commands package
|
||||
=======================================
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
pop\_fem\_audit\_tools.commands.build\_db module
|
||||
------------------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.commands.build_db
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.commands.export\_llm\_input module
|
||||
---------------------------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.commands.export_llm_input
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.commands.fetch\_artists module
|
||||
-----------------------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.commands.fetch_artists
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.commands.fetch\_lyrics module
|
||||
----------------------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.commands.fetch_lyrics
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.commands.run\_llm module
|
||||
-----------------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.commands.run_llm
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.commands
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
@@ -1,17 +1,17 @@
|
||||
pop\_fem\_audit\_tools package
|
||||
==============================
|
||||
|
||||
Subpackages
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
pop_fem_audit_tools.commands
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
pop\_fem\_audit\_tools.build\_db module
|
||||
---------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.build_db
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.config module
|
||||
------------------------------------
|
||||
|
||||
@@ -28,22 +28,6 @@ pop\_fem\_audit\_tools.database module
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.fetch\_artists module
|
||||
--------------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.fetch_artists
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.fetch\_lyrics module
|
||||
-------------------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.fetch_lyrics
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.models module
|
||||
------------------------------------
|
||||
|
||||
@@ -52,10 +36,10 @@ pop\_fem\_audit\_tools.models module
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
pop\_fem\_audit\_tools.run\_llm module
|
||||
--------------------------------------
|
||||
pop\_fem\_audit\_tools.utils module
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: pop_fem_audit_tools.run_llm
|
||||
.. automodule:: pop_fem_audit_tools.utils
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
|
||||
@@ -15,21 +15,23 @@ from collections.abc import Callable
|
||||
from importlib.machinery import ModuleSpec
|
||||
from types import ModuleType
|
||||
|
||||
from pop_fem_audit_tools import (
|
||||
build_db,
|
||||
fetch_artists,
|
||||
fetch_lyrics,
|
||||
run_llm,
|
||||
from .commands import (
|
||||
build_db_command,
|
||||
export_llm_input_command,
|
||||
fetch_artists_command,
|
||||
fetch_lyrics_command,
|
||||
run_llm_command,
|
||||
)
|
||||
|
||||
MODULE_PROG: str = "python -m pop_fem_audit_tools"
|
||||
"""The program name when run with ``python -m``."""
|
||||
|
||||
SUBCOMMANDS: dict[str, Callable[[list[str] | None], int]] = {
|
||||
"build-db": build_db.main,
|
||||
"fetch-artists": fetch_artists.main,
|
||||
"fetch-lyrics": fetch_lyrics.main,
|
||||
"run-llm": run_llm.main,
|
||||
"build-db": build_db_command,
|
||||
"export-llm-input": export_llm_input_command,
|
||||
"fetch-artists": fetch_artists_command,
|
||||
"fetch-lyrics": fetch_lyrics_command,
|
||||
"run-llm": run_llm_command,
|
||||
}
|
||||
"""The dispatch table from the subcommand name to the tool main."""
|
||||
|
||||
|
||||
@@ -1,748 +0,0 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/7/31
|
||||
"""The builder of the SQLite working store.
|
||||
|
||||
Rebuilds the working store from scratch out of the committed
|
||||
inputs: the year-end chart CSV and the output directory for the
|
||||
review CSV files, given as the two positional command-line
|
||||
arguments, and the optional capture inputs, each given as an
|
||||
option: the lyrics cache directory and the Wikidata artist
|
||||
snapshot CSV. An omitted option
|
||||
leaves its capture layer unloaded; a given option whose path does
|
||||
not exist fails the build. Missing tables
|
||||
are created on a fresh store; existing tables are never altered,
|
||||
as the schema lifecycle belongs to the migrations. Every rebuild
|
||||
deletes all the rows, loads the data, and validates it in one
|
||||
transaction, committed only after the data passes the validation
|
||||
invariants; a failed build leaves the previous store contents
|
||||
intact.
|
||||
|
||||
The rebuild is deterministic: the builder assigns the song and
|
||||
artist IDs itself, as 1, 2, 3, ... in the first-occurrence file
|
||||
order, so the IDs are reproducible across rebuilds on every
|
||||
database engine, given the frozen input file.
|
||||
|
||||
A song is identified by its raw title together with its artist
|
||||
credit, the credit canonicalized through
|
||||
``CANONICAL_ARTIST_CREDITS``; a credit listed there collapses onto
|
||||
the same song as its canonical form, and the stored artist credit
|
||||
is always the canonical form. Artist deduplication is by the
|
||||
identity key resolved from the parsed artist name (see
|
||||
`resolve_artist_identity`): the case-folded name, or, when that
|
||||
case-folded name is listed in ``CANONICAL_ARTIST_NAMES``, the
|
||||
case-folded canonical spelling, so letter-case variants and
|
||||
alternate spellings mapped to the same canonical name all
|
||||
collapse onto a single artist row. The stored artist name is the
|
||||
first-seen spelling, except for the names listed in
|
||||
``CANONICAL_ARTIST_NAMES``, which always store the canonical
|
||||
spelling regardless of which variant is seen first.
|
||||
|
||||
On a successful build, two review CSV files, ``songs.csv`` and
|
||||
``artists.csv``, are (re)written under the given output directory,
|
||||
mirroring the stored songs and artists without their IDs; see
|
||||
`CSVExporter`. A failed build leaves any existing review CSV
|
||||
files untouched, matching the store rollback.
|
||||
"""
|
||||
import argparse
|
||||
import csv
|
||||
import re
|
||||
import sys
|
||||
from collections.abc import Iterable, Sequence
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any, Self
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from .database import Base, ds
|
||||
from .models import (
|
||||
Artist,
|
||||
ChartEntry,
|
||||
Role,
|
||||
Song,
|
||||
SongArtist,
|
||||
)
|
||||
|
||||
YEARS: Sequence[int] = range(2016, 2026)
|
||||
"""The expected chart years."""
|
||||
RANKS_PER_YEAR: int = 100
|
||||
"""The expected number of ranks on the chart of each year."""
|
||||
ARTIST_FIELDS: dict[str, str] = {
|
||||
"qid": "wikidata_qid",
|
||||
"gender": "gender",
|
||||
"type": "type",
|
||||
"genre": "genre",
|
||||
"country": "country",
|
||||
}
|
||||
"""The artist CSV columns mapped to the Artist attributes."""
|
||||
FEATURING_PATTERN: re.Pattern[str] = re.compile(
|
||||
r" featuring | feat\. ", re.IGNORECASE)
|
||||
"""The pattern splitting the primary and featured sides."""
|
||||
DELIMITER_PATTERN: re.Pattern[str] = re.compile(
|
||||
r", | & | \+ | / |(?i: and | x | with )")
|
||||
"""The pattern splitting the artist names within a side."""
|
||||
COLON_PATTERN: re.Pattern[str] = re.compile(r": ")
|
||||
"""The pattern separating a group prefix from its members in a
|
||||
"<group>: <members>" credit."""
|
||||
PAREN_MEMBERS_PATTERN: re.Pattern[str] = re.compile(
|
||||
r"^.+ \((?P<members>.+)\)$")
|
||||
"""The pattern separating a group name from its members in a
|
||||
"<group> (<members>)" credit spanning the whole credit."""
|
||||
DUET_WITH_PATTERN: re.Pattern[str] = re.compile(
|
||||
r" Duet With ", re.IGNORECASE)
|
||||
"""The pattern normalizing the "Duet With" co-billing connector
|
||||
to the plain "with" delimiter."""
|
||||
PROTECTED_ARTIST_NAMES: tuple[str, ...] = (
|
||||
"Tyler, The Creator",
|
||||
"Lil Nas X",
|
||||
"Tones And I",
|
||||
)
|
||||
"""The exact artist names guarded from the delimiter splitting,
|
||||
because each contains a delimiter word or punctuation as part of
|
||||
the name itself."""
|
||||
EXCEPTION_CREDITS: dict[str, list[tuple[str, Role]]] = {
|
||||
"SpotemGottem Featuring Pooh Shiesty Or DaBaby": [
|
||||
("SpotemGottem", Role.PRIMARY),
|
||||
("Pooh Shiesty", Role.FEATURED),
|
||||
("DaBaby", Role.FEATURED),
|
||||
],
|
||||
"THE SCOTTS, Travis Scott & Kid Cudi": [
|
||||
("Travis Scott", Role.PRIMARY),
|
||||
("Kid Cudi", Role.PRIMARY),
|
||||
],
|
||||
"Drake Featuring The Throne": [
|
||||
("Drake", Role.PRIMARY),
|
||||
("Jay Z", Role.FEATURED),
|
||||
("Kanye West", Role.FEATURED),
|
||||
],
|
||||
}
|
||||
"""The single-credit exceptions parsed by an explicit lookup
|
||||
rather than by the general rules, because the credit text alone
|
||||
does not spell out the correct member split."""
|
||||
CANONICAL_ARTIST_CREDITS: dict[str, str] = {
|
||||
"benny blanco, Halsey & Khalid": "Benny Blanco, Halsey & Khalid",
|
||||
}
|
||||
"""The canonical artist credit spellings, keyed by a variant
|
||||
credit string."""
|
||||
CANONICAL_ARTIST_NAMES: dict[str, str] = {
|
||||
"beyonce": "Beyoncé",
|
||||
"5 seconds of summer": "5 Seconds of Summer",
|
||||
"a boogie wit da hoodie": "A Boogie wit da Hoodie",
|
||||
"benny blanco": "benny blanco",
|
||||
"blackbear": "blackbear",
|
||||
"chance the rapper": "Chance the Rapper",
|
||||
"xxxtentacion": "XXXTENTACION",
|
||||
"maneskin": "Måneskin",
|
||||
"rose": "ROSÉ",
|
||||
"mo": "MØ",
|
||||
"wizkid": "Wizkid",
|
||||
"ye": "Kanye West",
|
||||
"amine": "Aminé",
|
||||
"bomba estereo": "Bomba Estéreo",
|
||||
"carolina gaitan": "Carolina Gaitán",
|
||||
"casper magico": "Casper Mágico",
|
||||
"eslabon armado": "Eslabón Armado",
|
||||
"jhene aiko": "Jhené Aiko",
|
||||
"neton vega": "Netón Vega",
|
||||
"nio garcia": "Nio García",
|
||||
"oscar maydon": "Óscar Maydon",
|
||||
"silento": "Silentó",
|
||||
"the marias": "The Marías",
|
||||
"victoria monet": "Victoria Monét",
|
||||
"dan": "Dan Smyers",
|
||||
"shay": "Shay Mooney",
|
||||
"cris mj": "Cris MJ",
|
||||
"mariah the scientist": "Mariah the Scientist",
|
||||
"surf mesa": "Surf Mesa",
|
||||
}
|
||||
"""The canonical artist spellings, keyed by the case-folded
|
||||
identity."""
|
||||
|
||||
|
||||
class BuildError(Exception):
|
||||
"""An error that fails the build."""
|
||||
|
||||
|
||||
def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
||||
"""Parse the command-line arguments.
|
||||
|
||||
:param argv: The command-line arguments, or None for
|
||||
``sys.argv``.
|
||||
:return: The parsed arguments.
|
||||
"""
|
||||
parser: argparse.ArgumentParser = argparse.ArgumentParser(
|
||||
description="Rebuild the SQLite working store from the"
|
||||
" committed inputs.")
|
||||
parser.add_argument(
|
||||
"chart_csv", type=Path,
|
||||
help="the year-end chart CSV file")
|
||||
parser.add_argument(
|
||||
"derived_dir", type=Path,
|
||||
help="the output directory for the review CSV files")
|
||||
parser.add_argument(
|
||||
"--lyrics-dir", type=Path, default=None,
|
||||
help="the lyrics cache directory to load")
|
||||
parser.add_argument(
|
||||
"--wikidata-csv", type=Path, default=None,
|
||||
help="the Wikidata artist snapshot CSV file to apply")
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def parse_artist_credit(credit: str) -> list[tuple[str, Role]]:
|
||||
"""Parse a combined artist credit into artists and roles.
|
||||
|
||||
A credit listed in ``EXCEPTION_CREDITS`` is looked up verbatim,
|
||||
because its correct split is not derivable from the credit
|
||||
text alone. Otherwise the credit first reduces to an
|
||||
effective credit: a "<group>: <members>" prefix (split at the
|
||||
first ": ") drops the group and keeps the members; failing
|
||||
that, a "<group> (<members>)" suffix spanning the whole credit
|
||||
drops the group and keeps the members. The "Duet With"
|
||||
connector, case-insensitively, then normalizes to "with". The
|
||||
effective credit splits into a primary side and a featured
|
||||
side on the word "featuring" or "feat.", case-insensitively;
|
||||
without them, every artist is primary. Each side splits into
|
||||
artist names on the delimiters ", ", " & ", " + ", " / "
|
||||
(literally) and " and ", " x ", " with " (case-insensitively),
|
||||
except for the names listed in ``PROTECTED_ARTIST_NAMES``,
|
||||
which are never split even though each contains a delimiter
|
||||
word or punctuation.
|
||||
|
||||
Known limitation: a compound act name that contains one of the
|
||||
delimiters, other than the protected names, is over-split.
|
||||
|
||||
:param credit: The combined artist credit string.
|
||||
:return: The (name, role) pairs in credit order, primary side
|
||||
first, with the role ``Role.PRIMARY`` or
|
||||
``Role.FEATURED``.
|
||||
"""
|
||||
if credit in EXCEPTION_CREDITS:
|
||||
return list(EXCEPTION_CREDITS[credit])
|
||||
effective: str = credit
|
||||
colon_match: re.Match[str] | None = COLON_PATTERN.search(
|
||||
effective)
|
||||
if colon_match is not None:
|
||||
effective = effective[colon_match.end():]
|
||||
else:
|
||||
paren_match: re.Match[str] | None = \
|
||||
PAREN_MEMBERS_PATTERN.match(effective)
|
||||
if paren_match is not None:
|
||||
effective = paren_match.group("members")
|
||||
effective = DUET_WITH_PATTERN.sub(" with ", effective)
|
||||
placeholders: dict[str, str] = {}
|
||||
index: int
|
||||
protected: str
|
||||
for index, protected in enumerate(PROTECTED_ARTIST_NAMES):
|
||||
if protected in effective:
|
||||
placeholder: str = f"{index}"
|
||||
placeholders[placeholder] = protected
|
||||
effective = effective.replace(protected, placeholder)
|
||||
sides: list[str] = FEATURING_PATTERN.split(
|
||||
effective, maxsplit=1)
|
||||
pairs: list[tuple[str, Role]] = []
|
||||
role: Role
|
||||
side: str
|
||||
for side, role in zip(sides, (Role.PRIMARY, Role.FEATURED)):
|
||||
token: str
|
||||
for token in DELIMITER_PATTERN.split(side):
|
||||
name: str = token.strip()
|
||||
placeholder = ""
|
||||
original: str
|
||||
for placeholder, original in placeholders.items():
|
||||
name = name.replace(placeholder, original)
|
||||
if name != "":
|
||||
pairs.append((name, role))
|
||||
return pairs
|
||||
|
||||
|
||||
def song_identity(title: str, credit: str) -> tuple[str, str]:
|
||||
"""Compute the identity key of a chart row.
|
||||
|
||||
The key pairs the raw title with the artist credit,
|
||||
canonicalized through ``CANONICAL_ARTIST_CREDITS``; a credit
|
||||
absent from the table maps to itself. Two chart rows denote
|
||||
the same song iff their identity keys are equal.
|
||||
|
||||
:param title: The song title as printed on the chart.
|
||||
:param credit: The combined artist credit string.
|
||||
:return: The identity key: the raw title paired with the
|
||||
canonical artist credit.
|
||||
"""
|
||||
return title, CANONICAL_ARTIST_CREDITS.get(credit, credit)
|
||||
|
||||
|
||||
def resolve_artist_identity(name: str) -> tuple[str, str]:
|
||||
"""Resolve the dedup key and the stored spelling of a name.
|
||||
|
||||
The name's case-folded form is looked up in
|
||||
``CANONICAL_ARTIST_NAMES`` first; when it is listed there, the
|
||||
dedup key is the canonical spelling case-folded and the stored
|
||||
spelling is the canonical spelling, so every variant of the
|
||||
name, canonical or not, resolves to the same identity.
|
||||
Otherwise the dedup key is the name case-folded and the stored
|
||||
spelling is the given name.
|
||||
|
||||
:param name: An artist name, as parsed from a credit.
|
||||
:return: A tuple of the dedup key and the stored spelling.
|
||||
"""
|
||||
folded: str = name.casefold()
|
||||
canonical: str | None = CANONICAL_ARTIST_NAMES.get(folded)
|
||||
if canonical is not None:
|
||||
return canonical.casefold(), canonical
|
||||
return folded, name
|
||||
|
||||
|
||||
def create_song(session: Session, song_id: int, title: str,
|
||||
credit: str, artists: dict[str, Artist]) -> Song:
|
||||
"""Create a song with its parsed artist credits.
|
||||
|
||||
The song takes the given ID. An artist parsed out of the
|
||||
credit is matched against the known artists by its identity
|
||||
key (see `resolve_artist_identity`); a newly seen one takes
|
||||
the ID following the known artists, keyed by its identity key,
|
||||
and its stored name is the resolved stored spelling. An
|
||||
artist duplicated within the credit, by its identity key, is
|
||||
kept only at its first occurrence, with a warning to the
|
||||
standard error.
|
||||
|
||||
:param session: The database session.
|
||||
:param song_id: The song ID to assign.
|
||||
:param title: The song title.
|
||||
:param credit: The combined artist credit string.
|
||||
:param artists: The known artists by identity key, updated
|
||||
with the newly created ones as an observable side effect.
|
||||
:return: The created song, added to the session.
|
||||
"""
|
||||
song: Song = Song(id=song_id, title=title,
|
||||
artist_credit=credit)
|
||||
session.add(song)
|
||||
seen: set[str] = set()
|
||||
position: int = 0
|
||||
name: str
|
||||
role: Role
|
||||
for name, role in parse_artist_credit(credit):
|
||||
key: str
|
||||
stored_name: str
|
||||
key, stored_name = resolve_artist_identity(name)
|
||||
if key in seen:
|
||||
print(f"warning: {credit}: duplicated artist"
|
||||
f" \"{name}\"", file=sys.stderr)
|
||||
continue
|
||||
seen.add(key)
|
||||
if key not in artists:
|
||||
artists[key] = Artist(id=len(artists) + 1,
|
||||
name=stored_name)
|
||||
session.add(SongArtist(song=song, artist=artists[key],
|
||||
role=role, position=position))
|
||||
position += 1
|
||||
return song
|
||||
|
||||
|
||||
def load_chart(session: Session, path: Path) -> None:
|
||||
"""Load the chart CSV into songs, chart entries, and credits.
|
||||
|
||||
A song repeated across the rows is stored once, matched by its
|
||||
identity key (see `song_identity`); every row yields one chart
|
||||
entry. The stored title is the raw title; the stored artist
|
||||
credit is the canonical credit from the identity key. The
|
||||
songs and the artists take the IDs 1, 2, 3, ... in the
|
||||
first-occurrence row order.
|
||||
|
||||
:param session: The database session.
|
||||
:param path: The chart CSV file with the columns year, rank,
|
||||
title, and artist.
|
||||
:return: None.
|
||||
:raises OSError: When the file cannot be read.
|
||||
"""
|
||||
songs: dict[tuple[str, str], Song] = {}
|
||||
artists: dict[str, Artist] = {}
|
||||
with open(path, encoding="utf-8", newline="") as file:
|
||||
row: dict[str, str]
|
||||
for row in csv.DictReader(file):
|
||||
key: tuple[str, str] = song_identity(
|
||||
row["title"], row["artist"])
|
||||
if key not in songs:
|
||||
title: str
|
||||
credit: str
|
||||
title, credit = key
|
||||
songs[key] = create_song(
|
||||
session, len(songs) + 1, title, credit,
|
||||
artists)
|
||||
session.add(ChartEntry(year=int(row["year"]),
|
||||
rank=int(row["rank"]),
|
||||
song=songs[key]))
|
||||
|
||||
|
||||
def load_lyrics(session: Session, directory: Path) -> None:
|
||||
"""Load the cached lyrics files into the matching songs.
|
||||
|
||||
A file whose stem is not an existing song ID is skipped with
|
||||
a warning to the standard error.
|
||||
|
||||
:param session: The database session, with the songs flushed.
|
||||
:param directory: The existing lyrics cache directory with
|
||||
one ``<song_id>.txt`` file per song.
|
||||
:return: None.
|
||||
:raises OSError: When a lyrics file cannot be read.
|
||||
"""
|
||||
for path in sorted(directory.glob("*.txt")):
|
||||
song: Song | None = None
|
||||
if path.stem.isdigit():
|
||||
song = session.get(Song, int(path.stem))
|
||||
if song is None:
|
||||
print(f"warning: {path}: no song with ID"
|
||||
f" \"{path.stem}\"", file=sys.stderr)
|
||||
continue
|
||||
song.lyrics = path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def apply_artist_csv(session: Session, path: Path) -> None:
|
||||
"""Apply an artist attribute CSV onto the artist rows.
|
||||
|
||||
Artists match by exact name. Only the non-empty cells are
|
||||
applied, field by field. The note column is ignored.
|
||||
|
||||
:param session: The database session, with the artists
|
||||
flushed.
|
||||
:param path: The CSV file with the columns name, qid, gender,
|
||||
type, genre, country, and note.
|
||||
:return: None.
|
||||
:raises BuildError: When a name matches no artist.
|
||||
:raises OSError: When the file cannot be read.
|
||||
"""
|
||||
with open(path, encoding="utf-8", newline="") as file:
|
||||
row: dict[str, str]
|
||||
for row in csv.DictReader(file):
|
||||
artist: Artist | None = session.scalar(
|
||||
sa.select(Artist)
|
||||
.where(Artist.name == row["name"]))
|
||||
if artist is None:
|
||||
raise BuildError(
|
||||
f"{path}: no artist named \"{row['name']}\"")
|
||||
column: str
|
||||
attribute: str
|
||||
for column, attribute in ARTIST_FIELDS.items():
|
||||
if row.get(column):
|
||||
setattr(artist, attribute, row[column])
|
||||
|
||||
|
||||
def find_violations(session: Session, years: Iterable[int],
|
||||
ranks_per_year: int) -> list[str]:
|
||||
"""Find the invariant violations in the loaded data.
|
||||
|
||||
The invariants: the chart entries cover each expected year
|
||||
and rank exactly once and nothing else, every song has at
|
||||
least one primary artist, and every artist name is non-empty.
|
||||
|
||||
:param session: The database session with the loaded data
|
||||
flushed.
|
||||
:param years: The expected chart years.
|
||||
:param ranks_per_year: The expected number of ranks per year.
|
||||
:return: The violation messages, empty when the data is
|
||||
valid.
|
||||
"""
|
||||
violations: list[str] = []
|
||||
expected: set[tuple[int, int]] = {
|
||||
(year, rank) for year in years
|
||||
for rank in range(1, ranks_per_year + 1)}
|
||||
actual: set[tuple[int, int]] = {
|
||||
(x.year, x.rank)
|
||||
for x in session.scalars(sa.select(ChartEntry))}
|
||||
year: int
|
||||
rank: int
|
||||
for year, rank in sorted(expected - actual):
|
||||
violations.append(
|
||||
f"missing chart entry: year {year} rank {rank}")
|
||||
for year, rank in sorted(actual - expected):
|
||||
violations.append(
|
||||
f"unexpected chart entry: year {year} rank {rank}")
|
||||
primary_ids: set[int] = set(session.scalars(
|
||||
sa.select(SongArtist.song_id)
|
||||
.where(SongArtist.role == Role.PRIMARY)))
|
||||
song: Song
|
||||
for song in session.scalars(sa.select(Song).order_by(Song.id)):
|
||||
if song.id not in primary_ids:
|
||||
violations.append(
|
||||
f"song {song.id} \"{song.title}\" has no primary"
|
||||
" artist")
|
||||
artist: Artist
|
||||
for artist in session.scalars(sa.select(Artist)):
|
||||
if artist.name.strip() == "":
|
||||
violations.append(
|
||||
f"artist {artist.id} has an empty name")
|
||||
return violations
|
||||
|
||||
|
||||
@dataclass
|
||||
class StoreCounts:
|
||||
"""The row counts of the working store, for the build summary."""
|
||||
|
||||
songs: int
|
||||
"""The number of the songs."""
|
||||
chart_entries: int
|
||||
"""The number of the chart entries."""
|
||||
artists: int
|
||||
"""The number of the artists."""
|
||||
credits: int
|
||||
"""The number of the song-artist credits."""
|
||||
songs_with_lyrics: int
|
||||
"""The number of the songs with lyrics."""
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls, session: Session) -> Self:
|
||||
"""Counts the loaded rows and returns the counts.
|
||||
|
||||
:param session: The database session with the loaded data
|
||||
flushed.
|
||||
:return: The row counts of the working store.
|
||||
"""
|
||||
def count(selectable: sa.Select[tuple[int]]) -> int:
|
||||
value: int | None = session.scalar(selectable)
|
||||
assert value is not None
|
||||
return value
|
||||
|
||||
return cls(
|
||||
songs=count(
|
||||
sa.select(sa.func.count()).select_from(Song)),
|
||||
chart_entries=count(
|
||||
sa.select(sa.func.count())
|
||||
.select_from(ChartEntry)),
|
||||
artists=count(
|
||||
sa.select(sa.func.count()).select_from(Artist)),
|
||||
credits=count(
|
||||
sa.select(sa.func.count())
|
||||
.select_from(SongArtist)),
|
||||
songs_with_lyrics=count(
|
||||
sa.select(sa.func.count()).select_from(Song)
|
||||
.where(Song.lyrics.is_not(None))))
|
||||
|
||||
|
||||
def prepare_engine(engine: sa.Engine) -> None:
|
||||
"""Prepare a SQLite engine for a build.
|
||||
|
||||
For a file-based SQLite engine, the parent directory of the
|
||||
database file is created when missing. A non-SQLite engine is
|
||||
left untouched.
|
||||
|
||||
:param engine: The database engine.
|
||||
:return: None.
|
||||
"""
|
||||
if engine.url.get_backend_name() != "sqlite":
|
||||
return
|
||||
database: str | None = engine.url.database
|
||||
if database is not None and database != ":memory:":
|
||||
Path(database).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
def reset_store(session: Session) -> None:
|
||||
"""Delete all the rows from every table of the store.
|
||||
|
||||
:param session: The database session.
|
||||
:return: None.
|
||||
"""
|
||||
model: type[Base]
|
||||
for model in (SongArtist, ChartEntry, Song, Artist):
|
||||
session.execute(sa.delete(model))
|
||||
|
||||
|
||||
class CSVExporter:
|
||||
"""Writes the review CSV files mirroring the working store."""
|
||||
|
||||
__SONGS_HEADER: tuple[str, ...] = ("Title", "Artists", "Positions")
|
||||
"""The header row of ``songs.csv``, for human readers."""
|
||||
__ARTISTS_HEADER: tuple[str, ...] = (
|
||||
"Name", "Wikidata QID", "Gender", "Type", "Genre", "Country",
|
||||
"Songs")
|
||||
"""The header row of ``artists.csv``, for human readers."""
|
||||
|
||||
def __init__(self, session: Session, derived_dir: Path) -> None:
|
||||
"""Initialize the exporter.
|
||||
|
||||
:param session: The database session with the loaded data
|
||||
flushed.
|
||||
:param derived_dir: The output directory for the review CSV
|
||||
files.
|
||||
"""
|
||||
self.__session: Session = session
|
||||
self.__derived_dir: Path = derived_dir
|
||||
|
||||
def write(self) -> None:
|
||||
"""Write the review CSV files mirroring the loaded data.
|
||||
|
||||
Fully overwrites ``songs.csv`` and ``artists.csv`` under the
|
||||
output directory, creating it when missing, with normal
|
||||
minimal CSV quoting. Neither file carries a song or an
|
||||
artist ID; a multi-valued field is a plain joined string,
|
||||
itself CSV-quoted as a whole only when its content requires
|
||||
it: "/" joins the chart appearances of one song, and "|"
|
||||
joins the distinct songs credited to one artist.
|
||||
|
||||
:return: None.
|
||||
:raises OSError: When a CSV file cannot be written.
|
||||
"""
|
||||
self.__derived_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.__write_csv(
|
||||
self.__derived_dir / "songs.csv", self.__SONGS_HEADER,
|
||||
self.__songs_rows())
|
||||
self.__write_csv(
|
||||
self.__derived_dir / "artists.csv", self.__ARTISTS_HEADER,
|
||||
self.__artists_rows())
|
||||
|
||||
@staticmethod
|
||||
def __write_csv(path: Path, header: Sequence[str],
|
||||
rows: Iterable[Sequence[str]]) -> None:
|
||||
"""Write a CSV file with LF line endings, fully overwritten.
|
||||
|
||||
:param path: The output CSV file.
|
||||
:param header: The header row.
|
||||
:param rows: The data rows, in the given order.
|
||||
:return: None.
|
||||
:raises OSError: When the file cannot be written.
|
||||
"""
|
||||
with open(path, "w", encoding="utf-8", newline="") as file:
|
||||
writer: Any = csv.writer(file, lineterminator="\n")
|
||||
writer.writerow(header)
|
||||
writer.writerows(rows)
|
||||
|
||||
@staticmethod
|
||||
def __sorted_chart_entries(song: Song) -> list[ChartEntry]:
|
||||
"""Sort the chart entries of a song by year then rank.
|
||||
|
||||
:param song: The song with its chart entries loaded.
|
||||
:return: The chart entries, ordered by year then rank.
|
||||
"""
|
||||
return sorted(
|
||||
song.chart_entries, key=lambda x: (x.year, x.rank))
|
||||
|
||||
@classmethod
|
||||
def __song_positions(cls, song: Song) -> str:
|
||||
"""Format the chart positions of a song for the songs.csv
|
||||
value.
|
||||
|
||||
:param song: The song with its chart entries loaded.
|
||||
:return: The "YEAR#RANK" tokens, ordered by year then rank,
|
||||
joined by "/".
|
||||
"""
|
||||
entries: list[ChartEntry] = cls.__sorted_chart_entries(song)
|
||||
return "/".join(f"{x.year}#{x.rank}" for x in entries)
|
||||
|
||||
@classmethod
|
||||
def __formatted_song_positions(cls, song: Song) -> str:
|
||||
"""Format the chart positions of a song for the artists.csv
|
||||
value.
|
||||
|
||||
:param song: The song with its chart entries loaded.
|
||||
:return: The "YEAR#RANK" tokens, ordered by year then rank,
|
||||
joined by "/".
|
||||
"""
|
||||
entries: list[ChartEntry] = cls.__sorted_chart_entries(song)
|
||||
return "/".join(f"{x.year}#{x.rank}" for x in entries)
|
||||
|
||||
def __songs_rows(self) -> list[list[str]]:
|
||||
"""Build the sorted data rows of ``songs.csv``.
|
||||
|
||||
:return: The rows, sorted by the case-folded title, then
|
||||
the case-folded artist credit.
|
||||
"""
|
||||
songs: list[Song] = sorted(
|
||||
self.__session.scalars(sa.select(Song)),
|
||||
key=lambda x: (x.title.casefold(),
|
||||
x.artist_credit.casefold()))
|
||||
rows: list[list[str]] = []
|
||||
song: Song
|
||||
for song in songs:
|
||||
row: list[str] = [
|
||||
song.title, song.artist_credit,
|
||||
self.__song_positions(song)]
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
@classmethod
|
||||
def __artist_songs(cls, artist: Artist) -> str:
|
||||
"""Format the credited songs for the artists.csv value.
|
||||
|
||||
:param artist: The artist with its song credits loaded.
|
||||
:return: The credited songs, each formatted as
|
||||
"TITLE (YEAR#RANK[/YEAR#RANK...])" with its chart
|
||||
appearances, sorted alphabetically case-folded by
|
||||
title, joined by "|".
|
||||
"""
|
||||
songs: list[Song] = sorted(
|
||||
(x.song for x in artist.song_artists),
|
||||
key=lambda x: x.title.casefold())
|
||||
entries: list[str] = [
|
||||
f"{song.title} ({cls.__formatted_song_positions(song)})"
|
||||
for song in songs]
|
||||
return "|".join(entries)
|
||||
|
||||
def __artists_rows(self) -> list[list[str]]:
|
||||
"""Build the sorted data rows of ``artists.csv``.
|
||||
|
||||
:return: The rows, sorted by the case-folded name.
|
||||
"""
|
||||
artists: list[Artist] = sorted(
|
||||
self.__session.scalars(sa.select(Artist)),
|
||||
key=lambda x: x.name.casefold())
|
||||
rows: list[list[str]] = []
|
||||
artist: Artist
|
||||
for artist in artists:
|
||||
row: list[str] = [
|
||||
artist.name, artist.wikidata_qid or "",
|
||||
artist.gender or "", artist.type or "",
|
||||
artist.genre or "", artist.country or "",
|
||||
self.__artist_songs(artist)]
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Rebuild the SQLite working store from the inputs.
|
||||
|
||||
:param argv: The command-line arguments, or None for
|
||||
``sys.argv``.
|
||||
:return: The exit status: 0 on success, non-zero on failure.
|
||||
"""
|
||||
args: argparse.Namespace = parse_args(argv)
|
||||
engine: sa.Engine = ds.engine
|
||||
prepare_engine(engine)
|
||||
Base.metadata.create_all(engine)
|
||||
session: Session = ds.get_db()
|
||||
counts: StoreCounts
|
||||
try:
|
||||
reset_store(session)
|
||||
load_chart(session, args.chart_csv)
|
||||
session.flush()
|
||||
if args.lyrics_dir is not None:
|
||||
if not args.lyrics_dir.is_dir():
|
||||
raise BuildError(
|
||||
f"{args.lyrics_dir}: no such directory")
|
||||
load_lyrics(session, args.lyrics_dir)
|
||||
if args.wikidata_csv is not None:
|
||||
apply_artist_csv(session, args.wikidata_csv)
|
||||
session.flush()
|
||||
violations: list[str] = find_violations(
|
||||
session, YEARS, RANKS_PER_YEAR)
|
||||
if len(violations) > 0:
|
||||
session.rollback()
|
||||
for violation in violations:
|
||||
print(f"error: {violation}", file=sys.stderr)
|
||||
return 1
|
||||
counts = StoreCounts.get_instance(session)
|
||||
CSVExporter(session, args.derived_dir).write()
|
||||
session.commit()
|
||||
except (OSError, BuildError) as error:
|
||||
session.rollback()
|
||||
print(f"error: {error}", file=sys.stderr)
|
||||
return 1
|
||||
finally:
|
||||
session.close()
|
||||
print(f"done: {counts.songs} songs,"
|
||||
f" {counts.chart_entries} chart entries,"
|
||||
f" {counts.artists} artists,"
|
||||
f" {counts.credits} credits,"
|
||||
f" {counts.songs_with_lyrics} songs with lyrics",
|
||||
file=sys.stderr)
|
||||
return 0
|
||||
@@ -0,0 +1,10 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/8/4
|
||||
"""The registry of the CLI subcommands."""
|
||||
from .build_db import main as build_db_command
|
||||
from .export_llm_input import main as export_llm_input_command
|
||||
from .fetch_artists import main as fetch_artists_command
|
||||
from .fetch_lyrics import main as fetch_lyrics_command
|
||||
from .run_llm import main as run_llm_command
|
||||
@@ -0,0 +1,829 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/7/31
|
||||
"""The builder of the SQLite working store.
|
||||
|
||||
Rebuilds the working store from scratch out of the committed
|
||||
inputs: the year-end chart CSV and the output directory for the
|
||||
review CSV files, given as the two positional command-line
|
||||
arguments, and the optional capture inputs, each given as an
|
||||
option: the lyrics cache directory and the Wikidata artist
|
||||
snapshot CSV. An omitted option
|
||||
leaves its capture layer unloaded; a given option whose path does
|
||||
not exist fails the build. Missing tables
|
||||
are created on a fresh store; existing tables are never altered,
|
||||
as the schema lifecycle belongs to the migrations. Every rebuild
|
||||
deletes all the rows, loads the data, and validates it in one
|
||||
transaction, committed only after the data passes the validation
|
||||
invariants; a failed build leaves the previous store contents
|
||||
intact.
|
||||
|
||||
The rebuild is deterministic: the builder assigns the song and
|
||||
artist IDs itself, as 1, 2, 3, ... in the first-occurrence file
|
||||
order, so the IDs are reproducible across rebuilds on every
|
||||
database engine, given the frozen input file.
|
||||
|
||||
A song is identified by its raw title together with its artist
|
||||
credit, the credit canonicalized through
|
||||
``SongImporter.CANONICAL_ARTIST_CREDITS``; a credit listed there
|
||||
collapses onto the same song as its canonical form, and the
|
||||
stored artist credit is always the canonical form. Artist
|
||||
deduplication is by the identity key resolved from the parsed
|
||||
artist name (see `ArtistImporter.resolve_artist_identity`): the
|
||||
case-folded name, or, when that case-folded name is listed in
|
||||
``ArtistImporter.CANONICAL_ARTIST_NAMES``, the case-folded
|
||||
canonical spelling, so letter-case variants and alternate
|
||||
spellings mapped to the same canonical name all collapse onto a
|
||||
single artist row. The stored artist name is the first-seen
|
||||
spelling, except for the names listed in
|
||||
``ArtistImporter.CANONICAL_ARTIST_NAMES``, which always store the
|
||||
canonical spelling regardless of which variant is seen first.
|
||||
|
||||
On a successful build, two review CSV files, ``songs.csv`` and
|
||||
``artists.csv``, are (re)written under the given output directory,
|
||||
mirroring the stored songs and artists without their IDs; see
|
||||
`CSVExporter`. A failed build leaves any existing review CSV
|
||||
files untouched, matching the store rollback.
|
||||
"""
|
||||
import argparse
|
||||
import csv
|
||||
import re
|
||||
import sys
|
||||
from collections import Counter
|
||||
from collections.abc import Iterable, Sequence
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any, Self
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..database import Base, ds
|
||||
from ..models import (
|
||||
Artist,
|
||||
ChartEntry,
|
||||
Role,
|
||||
Song,
|
||||
SongArtist,
|
||||
)
|
||||
|
||||
ARTIST_FIELDS: dict[str, str] = {
|
||||
"qid": "wikidata_qid",
|
||||
"gender": "gender",
|
||||
"type": "type",
|
||||
"genre": "genre",
|
||||
"country": "country",
|
||||
}
|
||||
"""The artist CSV columns mapped to the Artist attributes."""
|
||||
|
||||
|
||||
class BuildError(Exception):
|
||||
"""An error that fails the build."""
|
||||
|
||||
|
||||
def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
||||
"""Parse the command-line arguments.
|
||||
|
||||
:param argv: The command-line arguments, or None for
|
||||
``sys.argv``.
|
||||
:return: The parsed arguments.
|
||||
"""
|
||||
parser: argparse.ArgumentParser = argparse.ArgumentParser(
|
||||
description="Rebuild the SQLite working store from the"
|
||||
" committed inputs.")
|
||||
parser.add_argument(
|
||||
"chart_csv", type=Path,
|
||||
help="the year-end chart CSV file")
|
||||
parser.add_argument(
|
||||
"derived_dir", type=Path,
|
||||
help="the output directory for the review CSV files")
|
||||
parser.add_argument(
|
||||
"--lyrics-dir", type=Path, default=None,
|
||||
help="the lyrics cache directory to load")
|
||||
parser.add_argument(
|
||||
"--wikidata-csv", type=Path, default=None,
|
||||
help="the Wikidata artist snapshot CSV file to apply")
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
class SongImporter:
|
||||
"""The song-import job: loads the chart CSV into songs and
|
||||
chart entries."""
|
||||
|
||||
YEARS: Sequence[int] = range(2016, 2026)
|
||||
"""The expected chart years."""
|
||||
RANKS_PER_YEAR: int = 100
|
||||
"""The expected number of ranks on the chart of each year."""
|
||||
CANONICAL_ARTIST_CREDITS: dict[str, str] = {
|
||||
"benny blanco, Halsey & Khalid": "Benny Blanco, Halsey"
|
||||
" & Khalid",
|
||||
}
|
||||
"""The canonical artist credit spellings, keyed by a variant
|
||||
credit string."""
|
||||
|
||||
def __init__(self, session: Session) -> None:
|
||||
"""Initialize the importer.
|
||||
|
||||
:param session: The database session.
|
||||
"""
|
||||
self.__session: Session = session
|
||||
self.__songs: dict[tuple[str, str], Song] = {}
|
||||
|
||||
def import_songs(self, path: Path) -> None:
|
||||
"""Load the chart CSV into songs and chart entries.
|
||||
|
||||
A song repeated across the rows is stored once, matched by
|
||||
its identity key (see `song_identity`); every row yields
|
||||
one chart entry. The stored title is the raw title; the
|
||||
stored artist credit is the canonical credit from the
|
||||
identity key. The songs take the IDs 1, 2, 3, ... in the
|
||||
first-occurrence row order. When the method returns, the
|
||||
imported songs and chart entries are queryable in the
|
||||
session.
|
||||
|
||||
:param path: The chart CSV file with the columns year,
|
||||
rank, title, and artist.
|
||||
:return: None.
|
||||
:raises BuildError: When the chart entries do not cover
|
||||
each of ``YEARS`` and each rank from 1 to
|
||||
``RANKS_PER_YEAR`` exactly once.
|
||||
:raises OSError: When the file cannot be read.
|
||||
"""
|
||||
counts: Counter[tuple[int, int]] = Counter()
|
||||
with open(path, encoding="utf-8", newline="") as file:
|
||||
row: dict[str, str]
|
||||
for row in csv.DictReader(file):
|
||||
key: tuple[str, str] = self.song_identity(
|
||||
row["title"], row["artist"])
|
||||
if key not in self.__songs:
|
||||
title: str
|
||||
credit: str
|
||||
title, credit = key
|
||||
song: Song = Song(
|
||||
id=len(self.__songs) + 1, title=title,
|
||||
artist_credit=credit)
|
||||
self.__session.add(song)
|
||||
self.__songs[key] = song
|
||||
year: int = int(row["year"])
|
||||
rank: int = int(row["rank"])
|
||||
counts[(year, rank)] += 1
|
||||
if counts[(year, rank)] == 1:
|
||||
self.__session.add(ChartEntry(
|
||||
year=year, rank=rank,
|
||||
song=self.__songs[key]))
|
||||
self.__session.flush()
|
||||
self.__check_chart_coverage(counts)
|
||||
|
||||
@classmethod
|
||||
def __check_chart_coverage(
|
||||
cls, counts: Counter[tuple[int, int]]) -> None:
|
||||
"""Verify the chart entries cover the expected grid exactly.
|
||||
|
||||
:param counts: The number of chart entries seen for each
|
||||
(year, rank) pair.
|
||||
:return: None.
|
||||
:raises BuildError: When a (year, rank) pair from the
|
||||
expected grid is missing, an unexpected pair is
|
||||
present, or a pair is duplicated.
|
||||
"""
|
||||
expected: set[tuple[int, int]] = {
|
||||
(year, rank) for year in cls.YEARS
|
||||
for rank in range(1, cls.RANKS_PER_YEAR + 1)}
|
||||
actual: set[tuple[int, int]] = set(counts)
|
||||
violations: list[str] = []
|
||||
year: int
|
||||
rank: int
|
||||
for year, rank in sorted(expected - actual):
|
||||
violations.append(
|
||||
f"missing chart entry: year {year} rank {rank}")
|
||||
for year, rank in sorted(actual - expected):
|
||||
violations.append(
|
||||
f"unexpected chart entry: year {year} rank {rank}")
|
||||
for year, rank in sorted(counts):
|
||||
if counts[(year, rank)] > 1:
|
||||
violations.append(
|
||||
f"duplicated chart entry: year {year} rank"
|
||||
f" {rank}")
|
||||
if len(violations) > 0:
|
||||
raise BuildError("\n".join(violations))
|
||||
|
||||
@staticmethod
|
||||
def song_identity(title: str, credit: str) -> tuple[str, str]:
|
||||
"""Compute the identity key of a chart row.
|
||||
|
||||
The key pairs the raw title with the artist credit,
|
||||
canonicalized through ``CANONICAL_ARTIST_CREDITS``; a
|
||||
credit absent from the table maps to itself. Two chart
|
||||
rows denote the same song iff their identity keys are
|
||||
equal.
|
||||
|
||||
:param title: The song title as printed on the chart.
|
||||
:param credit: The combined artist credit string.
|
||||
:return: The identity key: the raw title paired with the
|
||||
canonical artist credit.
|
||||
"""
|
||||
return title, SongImporter.CANONICAL_ARTIST_CREDITS.get(
|
||||
credit, credit)
|
||||
|
||||
|
||||
class ArtistImporter:
|
||||
"""The artist-import job: parses the stored songs' artist
|
||||
credits into artists and song-artist credits."""
|
||||
|
||||
FEATURING_PATTERN: re.Pattern[str] = re.compile(
|
||||
r" featuring | feat\. ", re.IGNORECASE)
|
||||
"""The pattern splitting the primary and featured sides."""
|
||||
DELIMITER_PATTERN: re.Pattern[str] = re.compile(
|
||||
r", | & | \+ | / |(?i: and | x | with )")
|
||||
"""The pattern splitting the artist names within a side."""
|
||||
COLON_PATTERN: re.Pattern[str] = re.compile(r": ")
|
||||
"""The pattern separating a group prefix from its members in a
|
||||
"<group>: <members>" credit."""
|
||||
PAREN_MEMBERS_PATTERN: re.Pattern[str] = re.compile(
|
||||
r"^.+ \((?P<members>.+)\)$")
|
||||
"""The pattern separating a group name from its members in a
|
||||
"<group> (<members>)" credit spanning the whole credit."""
|
||||
DUET_WITH_PATTERN: re.Pattern[str] = re.compile(
|
||||
r" Duet With ", re.IGNORECASE)
|
||||
"""The pattern normalizing the "Duet With" co-billing connector
|
||||
to the plain "with" delimiter."""
|
||||
PROTECTED_ARTIST_NAMES: tuple[str, ...] = (
|
||||
"Tyler, The Creator",
|
||||
"Lil Nas X",
|
||||
"Tones And I",
|
||||
)
|
||||
"""The exact artist names guarded from the delimiter splitting,
|
||||
because each contains a delimiter word or punctuation as part
|
||||
of the name itself."""
|
||||
EXCEPTION_CREDITS: dict[str, list[tuple[str, Role]]] = {
|
||||
"SpotemGottem Featuring Pooh Shiesty Or DaBaby": [
|
||||
("SpotemGottem", Role.PRIMARY),
|
||||
("Pooh Shiesty", Role.FEATURED),
|
||||
("DaBaby", Role.FEATURED),
|
||||
],
|
||||
"THE SCOTTS, Travis Scott & Kid Cudi": [
|
||||
("Travis Scott", Role.PRIMARY),
|
||||
("Kid Cudi", Role.PRIMARY),
|
||||
],
|
||||
"Drake Featuring The Throne": [
|
||||
("Drake", Role.PRIMARY),
|
||||
("Jay Z", Role.FEATURED),
|
||||
("Kanye West", Role.FEATURED),
|
||||
],
|
||||
}
|
||||
"""The single-credit exceptions parsed by an explicit lookup
|
||||
rather than by the general rules, because the credit text alone
|
||||
does not spell out the correct member split."""
|
||||
CANONICAL_ARTIST_NAMES: dict[str, str] = {
|
||||
"beyonce": "Beyoncé",
|
||||
"5 seconds of summer": "5 Seconds of Summer",
|
||||
"a boogie wit da hoodie": "A Boogie wit da Hoodie",
|
||||
"benny blanco": "benny blanco",
|
||||
"blackbear": "blackbear",
|
||||
"chance the rapper": "Chance the Rapper",
|
||||
"xxxtentacion": "XXXTENTACION",
|
||||
"maneskin": "Måneskin",
|
||||
"rose": "ROSÉ",
|
||||
"mo": "MØ",
|
||||
"wizkid": "Wizkid",
|
||||
"ye": "Kanye West",
|
||||
"amine": "Aminé",
|
||||
"bomba estereo": "Bomba Estéreo",
|
||||
"carolina gaitan": "Carolina Gaitán",
|
||||
"casper magico": "Casper Mágico",
|
||||
"eslabon armado": "Eslabón Armado",
|
||||
"jhene aiko": "Jhené Aiko",
|
||||
"neton vega": "Netón Vega",
|
||||
"nio garcia": "Nio García",
|
||||
"oscar maydon": "Óscar Maydon",
|
||||
"silento": "Silentó",
|
||||
"the marias": "The Marías",
|
||||
"victoria monet": "Victoria Monét",
|
||||
"dan": "Dan Smyers",
|
||||
"shay": "Shay Mooney",
|
||||
"cris mj": "Cris MJ",
|
||||
"mariah the scientist": "Mariah the Scientist",
|
||||
"surf mesa": "Surf Mesa",
|
||||
}
|
||||
"""The canonical artist spellings, keyed by the case-folded
|
||||
identity."""
|
||||
|
||||
def __init__(self, session: Session) -> None:
|
||||
"""Initialize the importer.
|
||||
|
||||
:param session: The database session.
|
||||
"""
|
||||
self.__session: Session = session
|
||||
self.__artists: dict[str, Artist] = {}
|
||||
|
||||
def import_artists(self) -> None:
|
||||
"""Parse the stored songs' credits into artists and
|
||||
song-artist credits.
|
||||
|
||||
Reads the songs back from the database in ``Song.id`` order,
|
||||
including any songs pending in the same session, and for
|
||||
each song parses ``Song.artist_credit`` (see
|
||||
`parse_artist_credit`). An artist parsed out of a credit is
|
||||
matched against the known artists by its identity key (see
|
||||
`resolve_artist_identity`); a newly seen one takes the ID
|
||||
following the known artists, keyed by its identity key,
|
||||
assigned in first-seen order across the songs, and its
|
||||
stored name is the resolved stored spelling. An artist
|
||||
duplicated within one song's credit, by its identity key,
|
||||
is kept only at its first occurrence within that credit,
|
||||
with a warning to the standard error. When the method
|
||||
returns, the imported artists and credits are queryable in
|
||||
the session.
|
||||
|
||||
:return: None.
|
||||
"""
|
||||
song: Song
|
||||
for song in self.__session.scalars(
|
||||
sa.select(Song).order_by(Song.id)):
|
||||
self.__import_song_artists(song)
|
||||
self.__session.flush()
|
||||
|
||||
def __import_song_artists(self, song: Song) -> None:
|
||||
"""Parse and store the artist credits of one song.
|
||||
|
||||
:param song: The song with its stored artist credit.
|
||||
:return: None.
|
||||
:raises BuildError: When the parsed credit has no primary
|
||||
artist or contains a blank artist name (see
|
||||
`__check_parsed_credit`).
|
||||
"""
|
||||
parsed: list[tuple[str, Role]] = self.parse_artist_credit(
|
||||
song.artist_credit)
|
||||
self.__check_parsed_credit(song, parsed)
|
||||
seen: set[str] = set()
|
||||
position: int = 0
|
||||
name: str
|
||||
role: Role
|
||||
for name, role in parsed:
|
||||
key: str
|
||||
stored_name: str
|
||||
key, stored_name = self.resolve_artist_identity(name)
|
||||
if key in seen:
|
||||
print(f"warning: {song.artist_credit}: duplicated"
|
||||
f" artist \"{name}\"", file=sys.stderr)
|
||||
continue
|
||||
seen.add(key)
|
||||
if key not in self.__artists:
|
||||
self.__artists[key] = Artist(
|
||||
id=len(self.__artists) + 1, name=stored_name)
|
||||
self.__session.add(SongArtist(
|
||||
song=song, artist=self.__artists[key], role=role,
|
||||
position=position))
|
||||
position += 1
|
||||
|
||||
@staticmethod
|
||||
def __check_parsed_credit(
|
||||
song: Song, parsed: list[tuple[str, Role]]) -> None:
|
||||
"""Verify a song's parsed artist credit is well-formed.
|
||||
|
||||
:param song: The song whose credit was parsed.
|
||||
:param parsed: The (name, role) pairs parsed from
|
||||
``song.artist_credit``.
|
||||
:return: None.
|
||||
:raises BuildError: When ``parsed`` is empty, has no
|
||||
``Role.PRIMARY`` entry, or contains a name blank after
|
||||
stripping.
|
||||
"""
|
||||
role: Role
|
||||
if len(parsed) == 0 or not any(
|
||||
role == Role.PRIMARY for _, role in parsed):
|
||||
raise BuildError(
|
||||
f"song {song.id} \"{song.artist_credit}\": no"
|
||||
" primary artist parsed")
|
||||
name: str
|
||||
for name, role in parsed:
|
||||
if name.strip() == "":
|
||||
raise BuildError(
|
||||
f"song {song.id} \"{song.artist_credit}\":"
|
||||
" blank artist name parsed")
|
||||
|
||||
@staticmethod
|
||||
def parse_artist_credit(credit: str) -> list[tuple[str, Role]]:
|
||||
"""Parse a combined artist credit into artists and roles.
|
||||
|
||||
A credit listed in ``EXCEPTION_CREDITS`` is looked up
|
||||
verbatim, because its correct split is not derivable from
|
||||
the credit text alone. Otherwise the credit first reduces
|
||||
to an effective credit: a "<group>: <members>" prefix
|
||||
(split at the first ": ") drops the group and keeps the
|
||||
members; failing that, a "<group> (<members>)" suffix
|
||||
spanning the whole credit drops the group and keeps the
|
||||
members. The "Duet With" connector, case-insensitively,
|
||||
then normalizes to "with". The effective credit splits
|
||||
into a primary side and a featured side on the word
|
||||
"featuring" or "feat.", case-insensitively; without them,
|
||||
every artist is primary. Each side splits into artist
|
||||
names on the delimiters ", ", " & ", " + ", " / "
|
||||
(literally) and " and ", " x ", " with "
|
||||
(case-insensitively), except for the names listed in
|
||||
``PROTECTED_ARTIST_NAMES``, which are never split even
|
||||
though each contains a delimiter word or punctuation.
|
||||
|
||||
Known limitation: a compound act name that contains one of
|
||||
the delimiters, other than the protected names, is
|
||||
over-split.
|
||||
|
||||
:param credit: The combined artist credit string.
|
||||
:return: The (name, role) pairs in credit order, primary
|
||||
side first, with the role ``Role.PRIMARY`` or
|
||||
``Role.FEATURED``.
|
||||
"""
|
||||
if credit in ArtistImporter.EXCEPTION_CREDITS:
|
||||
return list(ArtistImporter.EXCEPTION_CREDITS[credit])
|
||||
effective: str = credit
|
||||
colon_match: re.Match[str] | None = \
|
||||
ArtistImporter.COLON_PATTERN.search(effective)
|
||||
if colon_match is not None:
|
||||
effective = effective[colon_match.end():]
|
||||
else:
|
||||
paren_match: re.Match[str] | None = \
|
||||
ArtistImporter.PAREN_MEMBERS_PATTERN.match(
|
||||
effective)
|
||||
if paren_match is not None:
|
||||
effective = paren_match.group("members")
|
||||
effective = ArtistImporter.DUET_WITH_PATTERN.sub(
|
||||
" with ", effective)
|
||||
placeholders: dict[str, str] = {}
|
||||
index: int
|
||||
protected: str
|
||||
for index, protected in enumerate(
|
||||
ArtistImporter.PROTECTED_ARTIST_NAMES):
|
||||
if protected in effective:
|
||||
placeholder: str = f"{index}"
|
||||
placeholders[placeholder] = protected
|
||||
effective = effective.replace(protected, placeholder)
|
||||
sides: list[str] = ArtistImporter.FEATURING_PATTERN.split(
|
||||
effective, maxsplit=1)
|
||||
pairs: list[tuple[str, Role]] = []
|
||||
role: Role
|
||||
side: str
|
||||
for side, role in zip(sides, (Role.PRIMARY, Role.FEATURED)):
|
||||
token: str
|
||||
for token in ArtistImporter.DELIMITER_PATTERN.split(
|
||||
side):
|
||||
name: str = token.strip()
|
||||
placeholder = ""
|
||||
original: str
|
||||
for placeholder, original in placeholders.items():
|
||||
name = name.replace(placeholder, original)
|
||||
if name != "":
|
||||
pairs.append((name, role))
|
||||
return pairs
|
||||
|
||||
@staticmethod
|
||||
def resolve_artist_identity(name: str) -> tuple[str, str]:
|
||||
"""Resolve the dedup key and the stored spelling of a name.
|
||||
|
||||
The name's case-folded form is looked up in
|
||||
``CANONICAL_ARTIST_NAMES`` first; when it is listed there,
|
||||
the dedup key is the canonical spelling case-folded and the
|
||||
stored spelling is the canonical spelling, so every variant
|
||||
of the name, canonical or not, resolves to the same
|
||||
identity. Otherwise the dedup key is the name case-folded
|
||||
and the stored spelling is the given name.
|
||||
|
||||
:param name: An artist name, as parsed from a credit.
|
||||
:return: A tuple of the dedup key and the stored spelling.
|
||||
"""
|
||||
folded: str = name.casefold()
|
||||
canonical: str | None = \
|
||||
ArtistImporter.CANONICAL_ARTIST_NAMES.get(folded)
|
||||
if canonical is not None:
|
||||
return canonical.casefold(), canonical
|
||||
return folded, name
|
||||
|
||||
|
||||
class CaptureImporter:
|
||||
"""The capture-import job: applies the optional capture-layer
|
||||
inputs onto the stored songs and artists."""
|
||||
|
||||
def __init__(self, session: Session) -> None:
|
||||
"""Initialize the importer.
|
||||
|
||||
:param session: The database session.
|
||||
"""
|
||||
self.__session: Session = session
|
||||
|
||||
def import_captures(self, lyrics_dir: Path | None,
|
||||
wikidata_csv: Path | None) -> None:
|
||||
"""Apply the optional capture-layer inputs onto the store.
|
||||
|
||||
A None input leaves its capture layer unloaded. When
|
||||
``lyrics_dir`` is given, its cached lyrics files load into
|
||||
the matching songs (see `__load_lyrics`). When
|
||||
``wikidata_csv`` is given, it applies onto the artist rows
|
||||
(see `__apply_artist_csv`). When the method returns, the
|
||||
applied changes are queryable in the session.
|
||||
|
||||
:param lyrics_dir: The lyrics cache directory to load, or
|
||||
None to skip the lyrics capture layer.
|
||||
:param wikidata_csv: The Wikidata artist snapshot CSV file
|
||||
to apply, or None to skip the artist capture layer.
|
||||
:return: None.
|
||||
:raises BuildError: When ``lyrics_dir`` does not exist, or
|
||||
a name in ``wikidata_csv`` matches no artist.
|
||||
:raises OSError: When a capture file cannot be read.
|
||||
"""
|
||||
if lyrics_dir is not None:
|
||||
if not lyrics_dir.is_dir():
|
||||
raise BuildError(
|
||||
f"{lyrics_dir}: no such directory")
|
||||
self.__load_lyrics(lyrics_dir)
|
||||
if wikidata_csv is not None:
|
||||
self.__apply_artist_csv(wikidata_csv)
|
||||
self.__session.flush()
|
||||
|
||||
def __load_lyrics(self, directory: Path) -> None:
|
||||
"""Load the cached lyrics files into the matching songs.
|
||||
|
||||
A file whose stem is not an existing song ID is skipped
|
||||
with a warning to the standard error.
|
||||
|
||||
:param directory: The existing lyrics cache directory with
|
||||
one ``<song_id>.txt`` file per song.
|
||||
:return: None.
|
||||
:raises OSError: When a lyrics file cannot be read.
|
||||
"""
|
||||
for path in sorted(directory.glob("*.txt")):
|
||||
song: Song | None = None
|
||||
if path.stem.isdigit():
|
||||
song = self.__session.get(Song, int(path.stem))
|
||||
if song is None:
|
||||
print(f"warning: {path}: no song with ID"
|
||||
f" \"{path.stem}\"", file=sys.stderr)
|
||||
continue
|
||||
song.lyrics = path.read_text(encoding="utf-8")
|
||||
|
||||
def __apply_artist_csv(self, path: Path) -> None:
|
||||
"""Apply an artist attribute CSV onto the artist rows.
|
||||
|
||||
Artists match by exact name. Only the non-empty cells are
|
||||
applied, field by field. The note column is ignored.
|
||||
|
||||
:param path: The CSV file with the columns name, qid,
|
||||
gender, type, genre, country, and note.
|
||||
:return: None.
|
||||
:raises BuildError: When a name matches no artist.
|
||||
:raises OSError: When the file cannot be read.
|
||||
"""
|
||||
with open(path, encoding="utf-8", newline="") as file:
|
||||
row: dict[str, str]
|
||||
for row in csv.DictReader(file):
|
||||
artist: Artist | None = self.__session.scalar(
|
||||
sa.select(Artist)
|
||||
.where(Artist.name == row["name"]))
|
||||
if artist is None:
|
||||
raise BuildError(
|
||||
f"{path}: no artist named"
|
||||
f" \"{row['name']}\"")
|
||||
column: str
|
||||
attribute: str
|
||||
for column, attribute in ARTIST_FIELDS.items():
|
||||
if row.get(column):
|
||||
setattr(artist, attribute, row[column])
|
||||
|
||||
|
||||
@dataclass
|
||||
class StoreCounts:
|
||||
"""The row counts of the working store, for the build summary."""
|
||||
|
||||
songs: int
|
||||
"""The number of the songs."""
|
||||
chart_entries: int
|
||||
"""The number of the chart entries."""
|
||||
artists: int
|
||||
"""The number of the artists."""
|
||||
credits: int
|
||||
"""The number of the song-artist credits."""
|
||||
songs_with_lyrics: int
|
||||
"""The number of the songs with lyrics."""
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls, session: Session) -> Self:
|
||||
"""Counts the loaded rows and returns the counts.
|
||||
|
||||
:param session: The database session with the loaded data
|
||||
flushed.
|
||||
:return: The row counts of the working store.
|
||||
"""
|
||||
def count(selectable: sa.Select[tuple[int]]) -> int:
|
||||
value: int | None = session.scalar(selectable)
|
||||
assert value is not None
|
||||
return value
|
||||
|
||||
return cls(
|
||||
songs=count(
|
||||
sa.select(sa.func.count()).select_from(Song)),
|
||||
chart_entries=count(
|
||||
sa.select(sa.func.count())
|
||||
.select_from(ChartEntry)),
|
||||
artists=count(
|
||||
sa.select(sa.func.count()).select_from(Artist)),
|
||||
credits=count(
|
||||
sa.select(sa.func.count())
|
||||
.select_from(SongArtist)),
|
||||
songs_with_lyrics=count(
|
||||
sa.select(sa.func.count()).select_from(Song)
|
||||
.where(Song.lyrics.is_not(None))))
|
||||
|
||||
|
||||
def reset_store(session: Session) -> None:
|
||||
"""Delete all the rows from every table of the store.
|
||||
|
||||
:param session: The database session.
|
||||
:return: None.
|
||||
"""
|
||||
model: type[Base]
|
||||
for model in (SongArtist, ChartEntry, Song, Artist):
|
||||
session.execute(sa.delete(model))
|
||||
|
||||
|
||||
class CSVExporter:
|
||||
"""Writes the review CSV files mirroring the working store."""
|
||||
|
||||
__SONGS_HEADER: tuple[str, ...] = ("Title", "Artists", "Positions")
|
||||
"""The header row of ``songs.csv``, for human readers."""
|
||||
__ARTISTS_HEADER: tuple[str, ...] = (
|
||||
"Name", "Wikidata QID", "Gender", "Type", "Genre", "Country",
|
||||
"Songs")
|
||||
"""The header row of ``artists.csv``, for human readers."""
|
||||
|
||||
def __init__(self, session: Session, derived_dir: Path) -> None:
|
||||
"""Initialize the exporter.
|
||||
|
||||
:param session: The database session with the loaded data
|
||||
flushed.
|
||||
:param derived_dir: The output directory for the review CSV
|
||||
files.
|
||||
"""
|
||||
self.__session: Session = session
|
||||
self.__derived_dir: Path = derived_dir
|
||||
|
||||
def write(self) -> None:
|
||||
"""Write the review CSV files mirroring the loaded data.
|
||||
|
||||
Fully overwrites ``songs.csv`` and ``artists.csv`` under the
|
||||
output directory, creating it when missing, with normal
|
||||
minimal CSV quoting. Neither file carries a song or an
|
||||
artist ID; a multi-valued field is a plain joined string,
|
||||
itself CSV-quoted as a whole only when its content requires
|
||||
it: "/" joins the chart appearances of one song, and "|"
|
||||
joins the distinct songs credited to one artist.
|
||||
|
||||
:return: None.
|
||||
:raises OSError: When a CSV file cannot be written.
|
||||
"""
|
||||
self.__derived_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.__write_csv(
|
||||
self.__derived_dir / "songs.csv", self.__SONGS_HEADER,
|
||||
self.__songs_rows())
|
||||
self.__write_csv(
|
||||
self.__derived_dir / "artists.csv", self.__ARTISTS_HEADER,
|
||||
self.__artists_rows())
|
||||
|
||||
@staticmethod
|
||||
def __write_csv(path: Path, header: Sequence[str],
|
||||
rows: Iterable[Sequence[str]]) -> None:
|
||||
"""Write a CSV file with LF line endings, fully overwritten.
|
||||
|
||||
:param path: The output CSV file.
|
||||
:param header: The header row.
|
||||
:param rows: The data rows, in the given order.
|
||||
:return: None.
|
||||
:raises OSError: When the file cannot be written.
|
||||
"""
|
||||
with open(path, "w", encoding="utf-8", newline="") as file:
|
||||
writer: Any = csv.writer(file)
|
||||
writer.writerow(header)
|
||||
writer.writerows(rows)
|
||||
|
||||
@staticmethod
|
||||
def __sorted_chart_entries(song: Song) -> list[ChartEntry]:
|
||||
"""Sort the chart entries of a song by year then rank.
|
||||
|
||||
:param song: The song with its chart entries loaded.
|
||||
:return: The chart entries, ordered by year then rank.
|
||||
"""
|
||||
return sorted(
|
||||
song.chart_entries, key=lambda x: (x.year, x.rank))
|
||||
|
||||
@classmethod
|
||||
def __song_positions(cls, song: Song) -> str:
|
||||
"""Format the chart positions of a song for the songs.csv
|
||||
value.
|
||||
|
||||
:param song: The song with its chart entries loaded.
|
||||
:return: The "YEAR#RANK" tokens, ordered by year then rank,
|
||||
joined by "/".
|
||||
"""
|
||||
entries: list[ChartEntry] = cls.__sorted_chart_entries(song)
|
||||
return "/".join(f"{x.year}#{x.rank}" for x in entries)
|
||||
|
||||
@classmethod
|
||||
def __formatted_song_positions(cls, song: Song) -> str:
|
||||
"""Format the chart positions of a song for the artists.csv
|
||||
value.
|
||||
|
||||
:param song: The song with its chart entries loaded.
|
||||
:return: The "YEAR#RANK" tokens, ordered by year then rank,
|
||||
joined by "/".
|
||||
"""
|
||||
entries: list[ChartEntry] = cls.__sorted_chart_entries(song)
|
||||
return "/".join(f"{x.year}#{x.rank}" for x in entries)
|
||||
|
||||
def __songs_rows(self) -> list[list[str]]:
|
||||
"""Build the sorted data rows of ``songs.csv``.
|
||||
|
||||
:return: The rows, sorted by the case-folded title, then
|
||||
the case-folded artist credit.
|
||||
"""
|
||||
songs: list[Song] = sorted(
|
||||
self.__session.scalars(sa.select(Song)),
|
||||
key=lambda x: (x.title.casefold(),
|
||||
x.artist_credit.casefold()))
|
||||
rows: list[list[str]] = []
|
||||
song: Song
|
||||
for song in songs:
|
||||
row: list[str] = [
|
||||
song.title, song.artist_credit,
|
||||
self.__song_positions(song)]
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
@classmethod
|
||||
def __artist_songs(cls, artist: Artist) -> str:
|
||||
"""Format the credited songs for the artists.csv value.
|
||||
|
||||
:param artist: The artist with its song credits loaded.
|
||||
:return: The credited songs, each formatted as
|
||||
"TITLE (YEAR#RANK[/YEAR#RANK...])" with its chart
|
||||
appearances, sorted alphabetically case-folded by
|
||||
title, joined by "|".
|
||||
"""
|
||||
songs: list[Song] = sorted(
|
||||
(x.song for x in artist.song_artists),
|
||||
key=lambda x: x.title.casefold())
|
||||
entries: list[str] = [
|
||||
f"{song.title} ({cls.__formatted_song_positions(song)})"
|
||||
for song in songs]
|
||||
return "|".join(entries)
|
||||
|
||||
def __artists_rows(self) -> list[list[str]]:
|
||||
"""Build the sorted data rows of ``artists.csv``.
|
||||
|
||||
:return: The rows, sorted by the case-folded name.
|
||||
"""
|
||||
artists: list[Artist] = sorted(
|
||||
self.__session.scalars(sa.select(Artist)),
|
||||
key=lambda x: x.name.casefold())
|
||||
rows: list[list[str]] = []
|
||||
artist: Artist
|
||||
for artist in artists:
|
||||
row: list[str] = [
|
||||
artist.name, artist.wikidata_qid or "",
|
||||
artist.gender or "", artist.type or "",
|
||||
artist.genre or "", artist.country or "",
|
||||
self.__artist_songs(artist)]
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Rebuild the SQLite working store from the inputs.
|
||||
|
||||
:param argv: The command-line arguments, or None for
|
||||
``sys.argv``.
|
||||
:return: The exit status: 0 on success, non-zero on failure.
|
||||
"""
|
||||
args: argparse.Namespace = parse_args(argv)
|
||||
Base.metadata.create_all(ds.engine)
|
||||
session: Session = ds.get_db()
|
||||
counts: StoreCounts
|
||||
try:
|
||||
reset_store(session)
|
||||
SongImporter(session).import_songs(args.chart_csv)
|
||||
ArtistImporter(session).import_artists()
|
||||
CaptureImporter(session).import_captures(
|
||||
args.lyrics_dir, args.wikidata_csv)
|
||||
counts = StoreCounts.get_instance(session)
|
||||
CSVExporter(session, args.derived_dir).write()
|
||||
session.commit()
|
||||
except (OSError, BuildError) as error:
|
||||
session.rollback()
|
||||
print(f"error: {error}", file=sys.stderr)
|
||||
return 1
|
||||
finally:
|
||||
session.close()
|
||||
print(f"done: {counts.songs} songs,"
|
||||
f" {counts.chart_entries} chart entries,"
|
||||
f" {counts.artists} artists,"
|
||||
f" {counts.credits} credits,"
|
||||
f" {counts.songs_with_lyrics} songs with lyrics",
|
||||
file=sys.stderr)
|
||||
return 0
|
||||
@@ -0,0 +1,84 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/8/4
|
||||
"""The exporter of the LLM input JSONL file.
|
||||
|
||||
Exports the songs from the SQLite working store into the JSONL
|
||||
input file for the ``run-llm`` subcommand, given as the positional
|
||||
command-line argument. This is the enforcement point of the
|
||||
project's lyrics-only firewall: the output carries only the
|
||||
lyrics text of each song, identified by an opaque song key; no
|
||||
title, artist, or chart data crosses into the LLM input.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ..database import ds
|
||||
from ..models import Song
|
||||
|
||||
|
||||
def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
||||
"""Parse the command-line arguments.
|
||||
|
||||
:param argv: The command-line arguments, or None for
|
||||
``sys.argv``.
|
||||
:return: The parsed arguments.
|
||||
"""
|
||||
parser: argparse.ArgumentParser = argparse.ArgumentParser(
|
||||
description="Export the LLM input JSONL file (lyrics"
|
||||
" only) from the SQLite working store.")
|
||||
parser.add_argument(
|
||||
"output_jsonl", type=Path,
|
||||
help="the JSONL output file")
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def build_lines(session: Session) -> list[str]:
|
||||
"""Build the JSONL lines of every song's lyrics.
|
||||
|
||||
:param session: The database session.
|
||||
:return: The JSON lines, one per song, ordered by song ID.
|
||||
:raises ValueError: When a song has no lyrics.
|
||||
"""
|
||||
lines: list[str] = []
|
||||
song: Song
|
||||
for song in session.scalars(sa.select(Song).order_by(Song.id)):
|
||||
if song.lyrics is None:
|
||||
raise ValueError(
|
||||
f"song {song.id} \"{song.title}\": no lyrics")
|
||||
record: dict[str, str] = {
|
||||
"id": f"song-{song.id}", "content": song.lyrics}
|
||||
lines.append(json.dumps(record, ensure_ascii=False))
|
||||
return lines
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Export the LLM input JSONL file from the working store.
|
||||
|
||||
:param argv: The command-line arguments, or None for
|
||||
``sys.argv``.
|
||||
:return: The exit status: 0 on success, non-zero on failure.
|
||||
"""
|
||||
args: argparse.Namespace = parse_args(argv)
|
||||
session: Session = ds.get_db()
|
||||
lines: list[str]
|
||||
try:
|
||||
lines = build_lines(session)
|
||||
except (OSError, sa.exc.SQLAlchemyError, ValueError) as error:
|
||||
print(f"error: {error}", file=sys.stderr)
|
||||
return 1
|
||||
finally:
|
||||
session.close()
|
||||
args.output_jsonl.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(args.output_jsonl, "w", encoding="utf-8") as file:
|
||||
line: str
|
||||
for line in lines:
|
||||
file.write(line + "\n")
|
||||
print(f"done: {len(lines)} songs exported", file=sys.stderr)
|
||||
return 0
|
||||
+4
-22
@@ -34,9 +34,10 @@ from typing import Any, Literal, TextIO
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from . import VERSION
|
||||
from .database import ds
|
||||
from .models import Artist, Song, SongArtist
|
||||
from .. import VERSION
|
||||
from ..database import ds
|
||||
from ..models import Artist, Song, SongArtist
|
||||
from ..utils import format_duration
|
||||
|
||||
API_URL: str = "https://www.wikidata.org/w/api.php"
|
||||
"""The URL of the Wikidata API endpoint."""
|
||||
@@ -779,25 +780,6 @@ def write_snapshot(file: TextIO) -> None:
|
||||
writer.writerows(ordered)
|
||||
|
||||
|
||||
def format_duration(seconds: float) -> str:
|
||||
"""Format an elapsed duration for the closing summary line.
|
||||
|
||||
:param seconds: The elapsed duration, in seconds.
|
||||
:return: The duration formatted ``mm:ss``, or ``h:mm:ss``
|
||||
once it reaches one hour.
|
||||
"""
|
||||
total: int = round(seconds)
|
||||
hours: int
|
||||
remainder: int
|
||||
hours, remainder = divmod(total, 3600)
|
||||
minutes: int
|
||||
secs: int
|
||||
minutes, secs = divmod(remainder, 60)
|
||||
if hours > 0:
|
||||
return f"{hours}:{minutes:02d}:{secs:02d}"
|
||||
return f"{minutes:02d}:{secs:02d}"
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Fetch the artist metadata from Wikidata.
|
||||
|
||||
+22
-63
@@ -11,10 +11,15 @@ given as a positional command-line argument. The working store
|
||||
is only read, never written; the ``build-db`` subcommand
|
||||
assembles the captured files into the store on the next rebuild.
|
||||
|
||||
A song that every API misses is reported in the missing lyrics
|
||||
CSV, also given as a positional command-line argument, which is
|
||||
rewritten on every run to reflect the current status. Misses
|
||||
are expected and do not fail the run.
|
||||
Each song is first queried with the name of its primary-role
|
||||
artist with the lowest position. When every API misses that
|
||||
query and the song's full artist credit differs from that
|
||||
artist name, the same APIs are queried again with the artist
|
||||
credit, to catch songs cataloged only under a joint credit such
|
||||
as "Dan + Shay".
|
||||
|
||||
A song that every API misses on both queries is reported on the
|
||||
standard error, but does not fail the run; misses are expected.
|
||||
"""
|
||||
import argparse
|
||||
import csv
|
||||
@@ -25,27 +30,24 @@ import time
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from collections.abc import Sequence
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from .database import ds
|
||||
from .models import (
|
||||
from ..database import ds
|
||||
from ..models import (
|
||||
Artist,
|
||||
Role,
|
||||
Song,
|
||||
SongArtist,
|
||||
)
|
||||
from ..utils import format_duration
|
||||
|
||||
PROVENANCE_FIELDS: Sequence[str] = (
|
||||
"song_id", "source", "method", "acquired_at", "note")
|
||||
"""The header columns of the lyrics provenance CSV file."""
|
||||
MISSING_FIELDS: Sequence[str] = (
|
||||
"song_id", "title", "artist_credit", "reason")
|
||||
"""The header columns of the missing lyrics report CSV file."""
|
||||
USER_AGENT: str = ("pop-fem-audit-tools"
|
||||
" (https://github.com/imacat/pop-fem-audit)")
|
||||
"""The User-Agent header sent on every HTTP request."""
|
||||
@@ -55,28 +57,6 @@ SLEEP_SECONDS: float = 1.0
|
||||
"""The delay between consecutive HTTP requests, in seconds."""
|
||||
|
||||
|
||||
@dataclass
|
||||
class MissingLyrics:
|
||||
"""One row of the missing lyrics report CSV file."""
|
||||
|
||||
song_id: int
|
||||
"""The song ID."""
|
||||
title: str
|
||||
"""The song title."""
|
||||
artist_credit: str
|
||||
"""The artist credit of the song."""
|
||||
reason: str
|
||||
"""The reason the lyrics are missing."""
|
||||
|
||||
def to_row(self) -> list[str]:
|
||||
"""Return this report entry as a CSV row.
|
||||
|
||||
:return: The row values, in the column order.
|
||||
"""
|
||||
return [str(self.song_id), self.title,
|
||||
self.artist_credit, self.reason]
|
||||
|
||||
|
||||
def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
||||
"""Parse the command-line arguments.
|
||||
|
||||
@@ -93,9 +73,6 @@ def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
||||
parser.add_argument(
|
||||
"provenance_csv", type=Path,
|
||||
help="the lyrics provenance CSV file")
|
||||
parser.add_argument(
|
||||
"missing_csv", type=Path,
|
||||
help="the missing lyrics report CSV file")
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
@@ -244,27 +221,6 @@ def append_provenance(path: Path, song_id: int,
|
||||
datetime.date.today().isoformat(), ""])
|
||||
|
||||
|
||||
def write_missing(path: Path,
|
||||
misses: Sequence[MissingLyrics]) -> None:
|
||||
"""Rewrite the missing lyrics report CSV file.
|
||||
|
||||
The previous content is replaced, so the file reflects the
|
||||
current misses only.
|
||||
|
||||
:param path: The missing lyrics report CSV file.
|
||||
:param misses: The report entries of the songs still without
|
||||
lyrics.
|
||||
:return: None.
|
||||
:raises OSError: When the file cannot be written.
|
||||
"""
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8",
|
||||
newline="") as file:
|
||||
writer: Any = csv.writer(file)
|
||||
writer.writerow(MISSING_FIELDS)
|
||||
writer.writerows(x.to_row() for x in misses)
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Fetch the missing song lyrics from the public APIs.
|
||||
|
||||
@@ -273,10 +229,11 @@ def main(argv: list[str] | None = None) -> int:
|
||||
:return: The exit status: 0 on success, misses included,
|
||||
non-zero on a setup error.
|
||||
"""
|
||||
started: float = time.monotonic()
|
||||
args: argparse.Namespace = parse_args(argv)
|
||||
fetcher: LyricsFetcher = LyricsFetcher()
|
||||
fetched: int = 0
|
||||
misses: list[MissingLyrics] = []
|
||||
missed: int = 0
|
||||
session: Session = ds.get_db()
|
||||
try:
|
||||
song: Song
|
||||
@@ -287,11 +244,11 @@ def main(argv: list[str] | None = None) -> int:
|
||||
artist: str = query_artist(session, song.id)
|
||||
result: tuple[str, str] | None = fetcher.fetch(
|
||||
artist, song.title)
|
||||
if result is None and song.artist_credit != artist:
|
||||
result = fetcher.fetch(
|
||||
song.artist_credit, song.title)
|
||||
if result is None:
|
||||
misses.append(MissingLyrics(
|
||||
song_id=song.id, title=song.title,
|
||||
artist_credit=song.artist_credit,
|
||||
reason="not found"))
|
||||
missed += 1
|
||||
print(f"song {song.id} \"{song.title}\": miss",
|
||||
file=sys.stderr)
|
||||
continue
|
||||
@@ -304,12 +261,14 @@ def main(argv: list[str] | None = None) -> int:
|
||||
fetched += 1
|
||||
print(f"song {song.id} \"{song.title}\": {source}",
|
||||
file=sys.stderr)
|
||||
write_missing(args.missing_csv, misses)
|
||||
except (OSError, sa.exc.SQLAlchemyError) as error:
|
||||
print(f"error: {error}", file=sys.stderr)
|
||||
return 1
|
||||
finally:
|
||||
session.close()
|
||||
print(f"done: {fetched} fetched, {len(misses)} missed",
|
||||
attempted: int = fetched + missed
|
||||
elapsed: str = format_duration(time.monotonic() - started)
|
||||
print(f"Done. Fetched lyrics for {fetched}/{attempted}"
|
||||
f" songs. {elapsed} elapsed.",
|
||||
file=sys.stderr)
|
||||
return 0
|
||||
+91
-235
@@ -4,19 +4,25 @@
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/7/30
|
||||
# AI assistance: Claude Code (Anthropic)
|
||||
"""The generic batch runner for one LLM analysis step.
|
||||
"""The generic batch executor for one LLM analysis step.
|
||||
|
||||
Sends every input item to the Anthropic Messages Batch API twice with
|
||||
the same system prompt, reconciles the disagreeing items with a third
|
||||
arbitration batch, and archives every artifact self-contained under
|
||||
``<runs_dir>/<phase>/<YYYYMMDD-HHMM>-<prompt-stem>/``, where the
|
||||
base directory of the run archives is given as the positional
|
||||
command-line argument.
|
||||
One invocation is one definition file plus one input, sent to the
|
||||
Anthropic Messages Batch API exactly once, archived self-contained
|
||||
under the destination directory given by the three positional
|
||||
command-line arguments: prompt, input, archive_dir. The tool
|
||||
knows nothing about run counts or protocols: run identity --
|
||||
run1/run2, arbitration -- lives entirely in the caller's command
|
||||
list, per the research plan. A rerun of an already existing
|
||||
destination requires ``--replace``; any other directory is never
|
||||
touched.
|
||||
|
||||
Comparing runs and reconciling disagreements are the responsibility
|
||||
of separate subcommands, not this one.
|
||||
"""
|
||||
import argparse
|
||||
import enum
|
||||
import hashlib
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
from dataclasses import asdict, dataclass
|
||||
@@ -26,26 +32,13 @@ from typing import Any, Self
|
||||
|
||||
import anthropic
|
||||
|
||||
from .config import get_settings
|
||||
from ..config import get_settings
|
||||
|
||||
MODEL: str = "claude-sonnet-4-6"
|
||||
TEMPERATURE: float = 0.0
|
||||
THINKING: dict[str, str] = {"type": "disabled"}
|
||||
SCRIPT_VERSION: str = "run_llm.py 1.0.0"
|
||||
SCRIPT_VERSION: str = "run_llm.py 3.0.0"
|
||||
POLL_INTERVAL_SECONDS: float = 60.0
|
||||
ARBITRATION_TEMPLATE: str = (
|
||||
"<item>\n{content}\n</item>\n"
|
||||
"<run1>\n{run1}\n</run1>\n"
|
||||
"<run2>\n{run2}\n</run2>")
|
||||
|
||||
|
||||
class Source(enum.StrEnum):
|
||||
"""The source of a final record."""
|
||||
|
||||
AGREED = "agreed"
|
||||
"""The record takes the run text the two runs agreed on."""
|
||||
ARBITRATION = "arbitration"
|
||||
"""The record takes the arbitration output."""
|
||||
|
||||
|
||||
class InputFormatError(Exception):
|
||||
@@ -174,28 +167,26 @@ def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
||||
:return: The parsed arguments.
|
||||
"""
|
||||
parser: argparse.ArgumentParser = argparse.ArgumentParser(
|
||||
description="Run one LLM step: 2 runs + 1 arbitration.")
|
||||
description="Run one LLM definition file against one input"
|
||||
" and archive the result.")
|
||||
parser.add_argument(
|
||||
"runs_dir", type=Path,
|
||||
help="the base directory of the run archives")
|
||||
parser.add_argument(
|
||||
"--prompt", required=True, type=Path,
|
||||
"prompt", type=Path,
|
||||
help="the prompt definition file, used as the system prompt")
|
||||
parser.add_argument(
|
||||
"--arbitration-prompt", required=True, type=Path,
|
||||
help="the arbitration prompt definition file")
|
||||
parser.add_argument(
|
||||
"--input", required=True, type=Path,
|
||||
"input", type=Path,
|
||||
help="the JSONL input file with \"id\" and \"content\"")
|
||||
parser.add_argument(
|
||||
"--phase", required=True,
|
||||
help="the phase name for the archive directory")
|
||||
"archive_dir", type=Path,
|
||||
help="the destination archive directory")
|
||||
parser.add_argument(
|
||||
"--max-tokens", type=int, default=2048,
|
||||
help="the maximum output tokens per request (default 2048)")
|
||||
parser.add_argument(
|
||||
"--dry-run", action="store_true",
|
||||
help="validate and archive without calling the API")
|
||||
parser.add_argument(
|
||||
"--replace", action="store_true",
|
||||
help="replace an already existing archive directory")
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
@@ -256,19 +247,6 @@ def build_request(item: InputItem, system_prompt: str,
|
||||
}
|
||||
|
||||
|
||||
def build_arbitration_content(content: str, run1_text: str,
|
||||
run2_text: str) -> str:
|
||||
"""Build the arbitration user message for one item.
|
||||
|
||||
:param content: The original item content.
|
||||
:param run1_text: The run-1 output text.
|
||||
:param run2_text: The run-2 output text.
|
||||
:return: The user message text.
|
||||
"""
|
||||
return ARBITRATION_TEMPLATE.format(
|
||||
content=content, run1=run1_text, run2=run2_text)
|
||||
|
||||
|
||||
def submit_batch(client: anthropic.Anthropic,
|
||||
requests: list[dict[str, Any]]) -> str:
|
||||
"""Submit one message batch.
|
||||
@@ -314,6 +292,22 @@ def usage_to_dict(usage: Any) -> dict[str, Any]:
|
||||
if v is not None}
|
||||
|
||||
|
||||
def sum_usage(results: Results) -> dict[str, int]:
|
||||
"""Sum the token usage of every succeeded result.
|
||||
|
||||
:param results: The result records, keyed by item ID.
|
||||
:return: The summed integer usage fields.
|
||||
"""
|
||||
totals: dict[str, int] = {}
|
||||
for result in results.values():
|
||||
if result.usage is None:
|
||||
continue
|
||||
for key, value in result.usage.items():
|
||||
if isinstance(value, int):
|
||||
totals[key] = totals.get(key, 0) + value
|
||||
return totals
|
||||
|
||||
|
||||
def collect_results(client: anthropic.Anthropic,
|
||||
batch_id: str) -> Results:
|
||||
"""Collect the results of an ended batch.
|
||||
@@ -343,78 +337,25 @@ def find_failures(item_ids: list[str],
|
||||
if x not in results or results[x].is_failure]
|
||||
|
||||
|
||||
def split_by_agreement(
|
||||
items: list[InputItem], run1: Results, run2: Results,
|
||||
) -> tuple[list[str], list[str]]:
|
||||
"""Split the item IDs into agreed and disagreeing ones.
|
||||
def create_archive_dir(directory: Path, replace: bool) -> Path:
|
||||
"""Create the archive directory.
|
||||
|
||||
Two outputs agree when their texts are identical after strip().
|
||||
Only this directory is ever created or removed; no other
|
||||
directory is ever touched.
|
||||
|
||||
:param items: The input items.
|
||||
:param run1: The run-1 results, keyed by item ID.
|
||||
:param run2: The run-2 results, keyed by item ID.
|
||||
:return: A tuple of the agreed item IDs and the disagreeing item
|
||||
IDs, both in input order.
|
||||
"""
|
||||
agreed: list[str] = []
|
||||
disagreed: list[str] = []
|
||||
for item in items:
|
||||
text1: str | None = run1[item.id].text
|
||||
text2: str | None = run2[item.id].text
|
||||
assert text1 is not None and text2 is not None
|
||||
if text1.strip() == text2.strip():
|
||||
agreed.append(item.id)
|
||||
else:
|
||||
disagreed.append(item.id)
|
||||
return agreed, disagreed
|
||||
|
||||
|
||||
def build_final_records(
|
||||
items: list[InputItem], run1: Results, arbitration: Results,
|
||||
) -> list[dict[str, str]]:
|
||||
"""Assemble the final records, one per item, in input order.
|
||||
|
||||
An arbitrated item takes the arbitration output; an agreed item
|
||||
takes the agreed (stripped) run text.
|
||||
|
||||
:param items: The input items.
|
||||
:param run1: The run-1 results, keyed by item ID.
|
||||
:param arbitration: The arbitration results, keyed by item ID.
|
||||
:return: The final records with "id", "text", and "source".
|
||||
"""
|
||||
records: list[dict[str, str]] = []
|
||||
for item in items:
|
||||
text: str | None
|
||||
if item.id in arbitration:
|
||||
text = arbitration[item.id].text
|
||||
assert text is not None
|
||||
records.append({"id": item.id, "text": text,
|
||||
"source": Source.ARBITRATION})
|
||||
else:
|
||||
text = run1[item.id].text
|
||||
assert text is not None
|
||||
records.append({"id": item.id, "text": text.strip(),
|
||||
"source": Source.AGREED})
|
||||
return records
|
||||
|
||||
|
||||
def create_archive_dir(runs_root: Path, phase: str, prompt_path: Path,
|
||||
now: datetime) -> Path:
|
||||
"""Create the archive directory for this execution.
|
||||
|
||||
:param runs_root: The root directory of the run archives.
|
||||
:param phase: The phase name.
|
||||
:param prompt_path: The path of the prompt definition file.
|
||||
:param now: The local timestamp of this execution.
|
||||
:param directory: The destination archive directory.
|
||||
:param replace: Whether to remove an already existing archive
|
||||
directory before creating it.
|
||||
:return: The created archive directory.
|
||||
:raises FileExistsError: When the directory already exists.
|
||||
:raises FileExistsError: When the archive directory already
|
||||
exists and ``replace`` is False.
|
||||
"""
|
||||
stem: str = prompt_path.stem
|
||||
name: str = f"{now.strftime('%Y%m%d-%H%M')}-{stem}"
|
||||
directory: Path = runs_root / phase / name
|
||||
if directory.exists():
|
||||
raise FileExistsError(
|
||||
f"archive directory {directory} already exists")
|
||||
if not replace:
|
||||
raise FileExistsError(
|
||||
f"{directory} already exists; pass --replace to"
|
||||
" replace it")
|
||||
shutil.rmtree(directory)
|
||||
directory.mkdir(parents=True)
|
||||
return directory
|
||||
|
||||
@@ -446,17 +387,14 @@ def write_json(path: Path, data: dict[str, Any]) -> None:
|
||||
def write_meta(path: Path, meta: dict[str, Any]) -> None:
|
||||
"""Write the metadata to the ``meta.json`` file.
|
||||
|
||||
The ``BatchInfo`` values under ``batches`` are written as
|
||||
plain JSON objects.
|
||||
The ``BatchInfo`` value under ``batch`` is written as a plain
|
||||
JSON object.
|
||||
|
||||
:param path: The path of the ``meta.json`` file.
|
||||
:param meta: The metadata to write.
|
||||
:return: None.
|
||||
"""
|
||||
write_json(path, {
|
||||
**meta,
|
||||
"batches": {k: asdict(v)
|
||||
for k, v in meta["batches"].items()}})
|
||||
write_json(path, {**meta, "batch": asdict(meta["batch"])})
|
||||
|
||||
|
||||
def sha256_of(path: Path) -> str:
|
||||
@@ -477,13 +415,14 @@ def now_iso() -> str:
|
||||
return datetime.now().astimezone().isoformat(timespec="seconds")
|
||||
|
||||
|
||||
def execute_runs(
|
||||
def execute_run(
|
||||
client: anthropic.Anthropic, items: list[InputItem],
|
||||
system_prompt: str, max_tokens: int, meta: dict[str, Any],
|
||||
) -> tuple[Results, Results]:
|
||||
"""Submit the two identical runs and await their results.
|
||||
system_prompt: str, max_tokens: int,
|
||||
meta: dict[str, Any],
|
||||
) -> Results:
|
||||
"""Submit the batch of this run and await its results.
|
||||
|
||||
The batch IDs and timestamps are recorded into the metadata as an
|
||||
The batch ID and timestamps are recorded into the metadata as an
|
||||
observable side effect.
|
||||
|
||||
:param client: The Anthropic client.
|
||||
@@ -491,72 +430,22 @@ def execute_runs(
|
||||
:param system_prompt: The system prompt text.
|
||||
:param max_tokens: The maximum output tokens per request.
|
||||
:param meta: The metadata to record the batch bookkeeping into.
|
||||
:return: The results of run 1 and run 2, keyed by item ID.
|
||||
:return: The results of this run, keyed by item ID.
|
||||
"""
|
||||
requests: list[dict[str, Any]] = [
|
||||
build_request(x, system_prompt, max_tokens) for x in items]
|
||||
infos: dict[str, BatchInfo] = {}
|
||||
for run_name in ("run1", "run2"):
|
||||
info: BatchInfo = BatchInfo(
|
||||
batch_id=submit_batch(client, requests),
|
||||
submitted_at=now_iso())
|
||||
infos[run_name] = info
|
||||
meta["batches"][run_name] = info
|
||||
print(f"{run_name}: submitted batch {info.batch_id}",
|
||||
file=sys.stderr)
|
||||
batches: dict[str, Any] = poll_batches(
|
||||
client, [x.batch_id for x in infos.values()])
|
||||
for info in infos.values():
|
||||
info.ended_at = batches[info.batch_id].ended_at.isoformat()
|
||||
return (collect_results(client, infos["run1"].batch_id),
|
||||
collect_results(client, infos["run2"].batch_id))
|
||||
|
||||
|
||||
def execute_arbitration(
|
||||
client: anthropic.Anthropic, items: list[InputItem],
|
||||
disagreed: list[str], run1: Results, run2: Results,
|
||||
system_prompt: str, max_tokens: int, meta: dict[str, Any],
|
||||
) -> Results:
|
||||
"""Submit the arbitration batch and await its results.
|
||||
|
||||
The batch ID and timestamps are recorded into the metadata as an
|
||||
observable side effect.
|
||||
|
||||
:param client: The Anthropic client.
|
||||
:param items: The input items.
|
||||
:param disagreed: The disagreeing item IDs.
|
||||
:param run1: The run-1 results, keyed by item ID.
|
||||
:param run2: The run-2 results, keyed by item ID.
|
||||
:param system_prompt: The arbitration system prompt text.
|
||||
:param max_tokens: The maximum output tokens per request.
|
||||
:param meta: The metadata to record the batch bookkeeping into.
|
||||
:return: The arbitration results, keyed by item ID.
|
||||
"""
|
||||
content_by_id: dict[str, str] = {
|
||||
x.id: x.content for x in items}
|
||||
requests: list[dict[str, Any]] = []
|
||||
for item_id in disagreed:
|
||||
text1: str | None = run1[item_id].text
|
||||
text2: str | None = run2[item_id].text
|
||||
assert text1 is not None and text2 is not None
|
||||
requests.append(build_request(
|
||||
InputItem(id=item_id,
|
||||
content=build_arbitration_content(
|
||||
content_by_id[item_id], text1, text2)),
|
||||
system_prompt, max_tokens))
|
||||
info: BatchInfo = BatchInfo(
|
||||
batch_id=submit_batch(client, requests),
|
||||
submitted_at=now_iso())
|
||||
meta["batches"]["arbitration"] = info
|
||||
print(f"arbitration: submitted batch {info.batch_id}",
|
||||
file=sys.stderr)
|
||||
meta["batch"] = info
|
||||
print(f"submitted batch {info.batch_id}", file=sys.stderr)
|
||||
batches: dict[str, Any] = poll_batches(client, [info.batch_id])
|
||||
info.ended_at = batches[info.batch_id].ended_at.isoformat()
|
||||
return collect_results(client, info.batch_id)
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Run one LLM step end-to-end.
|
||||
"""Run one LLM definition file against one input and archive it.
|
||||
|
||||
:param argv: The command-line arguments, or None for ``sys.argv``.
|
||||
:return: The exit status: 0 on success, non-zero on failure.
|
||||
@@ -565,89 +454,56 @@ def main(argv: list[str] | None = None) -> int:
|
||||
try:
|
||||
items: list[InputItem] = load_items(args.input)
|
||||
prompt_text: str = args.prompt.read_text(encoding="utf-8")
|
||||
arbitration_text: str = args.arbitration_prompt.read_text(
|
||||
encoding="utf-8")
|
||||
except (OSError, InputFormatError) as error:
|
||||
print(f"error: {error}", file=sys.stderr)
|
||||
return 1
|
||||
try:
|
||||
run_dir: Path = create_archive_dir(
|
||||
args.runs_dir, args.phase, args.prompt,
|
||||
datetime.now())
|
||||
archive_dir: Path = create_archive_dir(
|
||||
args.archive_dir, args.replace)
|
||||
except FileExistsError as error:
|
||||
print(f"error: {error}", file=sys.stderr)
|
||||
return 1
|
||||
meta_path: Path = run_dir / "meta.json"
|
||||
(run_dir / "prompt.md").write_bytes(args.prompt.read_bytes())
|
||||
(run_dir / "arbitration_prompt.md").write_bytes(
|
||||
args.arbitration_prompt.read_bytes())
|
||||
meta_path: Path = archive_dir / "meta.json"
|
||||
(archive_dir / "prompt.md").write_bytes(args.prompt.read_bytes())
|
||||
meta: dict[str, Any] = {
|
||||
"script_version": SCRIPT_VERSION,
|
||||
"model": MODEL,
|
||||
"temperature": TEMPERATURE,
|
||||
"max_tokens": args.max_tokens,
|
||||
"thinking": THINKING,
|
||||
"max_tokens": args.max_tokens,
|
||||
"prompt_path": str(args.prompt),
|
||||
"prompt_sha256": sha256_of(args.prompt),
|
||||
"arbitration_prompt_path": str(args.arbitration_prompt),
|
||||
"arbitration_prompt_sha256": sha256_of(
|
||||
args.arbitration_prompt),
|
||||
"batches": {},
|
||||
"input_path": str(args.input),
|
||||
"input_sha256": sha256_of(args.input),
|
||||
"item_count": len(items),
|
||||
"agreed_count": None,
|
||||
"agreement_rate": None,
|
||||
"dry_run": args.dry_run,
|
||||
"script_version": SCRIPT_VERSION,
|
||||
"started_at": now_iso(),
|
||||
"batch": None,
|
||||
"usage": {},
|
||||
}
|
||||
if args.dry_run:
|
||||
write_meta(meta_path, meta)
|
||||
write_json(meta_path, meta)
|
||||
print(json.dumps(
|
||||
build_request(items[0], prompt_text, args.max_tokens),
|
||||
ensure_ascii=False, indent=2))
|
||||
print(f"dry run: archive created at {run_dir}",
|
||||
print(f"dry run: archive created at {archive_dir}",
|
||||
file=sys.stderr)
|
||||
return 0
|
||||
client: anthropic.Anthropic = anthropic.Anthropic(
|
||||
api_key=get_settings().ANTHROPIC_API_KEY)
|
||||
run1: Results
|
||||
run2: Results
|
||||
run1, run2 = execute_runs(
|
||||
results: Results = execute_run(
|
||||
client, items, prompt_text, args.max_tokens, meta)
|
||||
item_ids: list[str] = [x.id for x in items]
|
||||
write_jsonl(run_dir / "run1.jsonl",
|
||||
[run1[x].to_record() for x in item_ids if x in run1])
|
||||
write_jsonl(run_dir / "run2.jsonl",
|
||||
[run2[x].to_record() for x in item_ids if x in run2])
|
||||
failed: set[str] = (set(find_failures(item_ids, run1))
|
||||
| set(find_failures(item_ids, run2)))
|
||||
write_jsonl(
|
||||
archive_dir / "output.jsonl",
|
||||
[results[x].to_record() for x in item_ids if x in results])
|
||||
meta["usage"] = sum_usage(results)
|
||||
write_meta(meta_path, meta)
|
||||
failed: list[str] = find_failures(item_ids, results)
|
||||
if len(failed) > 0:
|
||||
write_meta(meta_path, meta)
|
||||
names: str = ", ".join(x for x in item_ids if x in failed)
|
||||
print(f"error: failed items: {names}", file=sys.stderr)
|
||||
return 1
|
||||
agreed: list[str]
|
||||
disagreed: list[str]
|
||||
agreed, disagreed = split_by_agreement(items, run1, run2)
|
||||
meta["agreed_count"] = len(agreed)
|
||||
meta["agreement_rate"] = len(agreed) / len(items)
|
||||
arbitration: Results = {}
|
||||
if len(disagreed) > 0:
|
||||
arbitration = execute_arbitration(
|
||||
client, items, disagreed, run1, run2, arbitration_text,
|
||||
args.max_tokens, meta)
|
||||
write_jsonl(run_dir / "arbitration.jsonl",
|
||||
[arbitration[x].to_record() for x in disagreed
|
||||
if x in arbitration])
|
||||
arb_failed: list[str] = find_failures(disagreed, arbitration)
|
||||
if len(arb_failed) > 0:
|
||||
write_meta(meta_path, meta)
|
||||
names = ", ".join(arb_failed)
|
||||
print(f"error: failed arbitration items: {names}",
|
||||
print(f"error: failed items: {', '.join(failed)}",
|
||||
file=sys.stderr)
|
||||
return 1
|
||||
write_jsonl(run_dir / "final.jsonl",
|
||||
build_final_records(items, run1, arbitration))
|
||||
write_meta(meta_path, meta)
|
||||
print(f"done: {len(items)} items, {len(agreed)} agreed,"
|
||||
f" {len(disagreed)} arbitrated; archived to {run_dir}",
|
||||
file=sys.stderr)
|
||||
print(f"done: {len(items)} items;"
|
||||
f" archived to {archive_dir}", file=sys.stderr)
|
||||
return 0
|
||||
@@ -0,0 +1,24 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/8/4
|
||||
"""The shared utilities of the package."""
|
||||
|
||||
|
||||
def format_duration(seconds: float) -> str:
|
||||
"""Format an elapsed duration for the closing summary line.
|
||||
|
||||
:param seconds: The elapsed duration, in seconds.
|
||||
:return: The duration formatted ``mm:ss``, or ``h:mm:ss``
|
||||
once it reaches one hour.
|
||||
"""
|
||||
total: int = round(seconds)
|
||||
hours: int
|
||||
remainder: int
|
||||
hours, remainder = divmod(total, 3600)
|
||||
minutes: int
|
||||
secs: int
|
||||
minutes, secs = divmod(remainder, 60)
|
||||
if hours > 0:
|
||||
return f"{hours}:{minutes:02d}:{secs:02d}"
|
||||
return f"{minutes:02d}:{secs:02d}"
|
||||
@@ -15,7 +15,8 @@ from unittest import mock
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from pop_fem_audit_tools import build_db, config
|
||||
from pop_fem_audit_tools import config
|
||||
from pop_fem_audit_tools.commands import build_db
|
||||
from pop_fem_audit_tools.database import DataSource
|
||||
from pop_fem_audit_tools.models import (
|
||||
Artist,
|
||||
@@ -30,13 +31,14 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
|
||||
def test_plain_solo(self) -> None:
|
||||
"""Test a plain solo artist credit."""
|
||||
self.assertEqual(build_db.parse_artist_credit("Adele"),
|
||||
[("Adele", Role.PRIMARY)])
|
||||
self.assertEqual(
|
||||
build_db.ArtistImporter.parse_artist_credit("Adele"),
|
||||
[("Adele", Role.PRIMARY)])
|
||||
|
||||
def test_featuring_with_and(self) -> None:
|
||||
"""Test a featuring credit with an "and" delimiter."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Drake featuring Wizkid and Kyla"),
|
||||
[("Drake", Role.PRIMARY),
|
||||
("Wizkid", Role.FEATURED),
|
||||
@@ -45,7 +47,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_comma_and_ampersand(self) -> None:
|
||||
"""Test a credit with comma and ampersand delimiters."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Lady Gaga, Bradley Cooper & BloodPop"),
|
||||
[("Lady Gaga", Role.PRIMARY),
|
||||
("Bradley Cooper", Role.PRIMARY),
|
||||
@@ -54,21 +56,23 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_x_delimiter(self) -> None:
|
||||
"""Test the "x" delimiter."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit("KAROL G x Nicki Minaj"),
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"KAROL G x Nicki Minaj"),
|
||||
[("KAROL G", Role.PRIMARY),
|
||||
("Nicki Minaj", Role.PRIMARY)])
|
||||
|
||||
def test_plus_delimiter(self) -> None:
|
||||
"""Test the "+" delimiter."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit("Marshmello + Halsey"),
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Marshmello + Halsey"),
|
||||
[("Marshmello", Role.PRIMARY),
|
||||
("Halsey", Role.PRIMARY)])
|
||||
|
||||
def test_with_delimiter(self) -> None:
|
||||
"""Test the "with" delimiter."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Kane Brown with Lauren Alaina"),
|
||||
[("Kane Brown", Role.PRIMARY),
|
||||
("Lauren Alaina", Role.PRIMARY)])
|
||||
@@ -76,7 +80,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_feat_abbreviation(self) -> None:
|
||||
"""Test that "Feat." splits the featured side."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Ariana Grande Feat. Doja Cat"
|
||||
" & Megan Thee Stallion"),
|
||||
[("Ariana Grande", Role.PRIMARY),
|
||||
@@ -86,7 +90,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_case_insensitive_featuring(self) -> None:
|
||||
"""Test that "Featuring" splits case-insensitively."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"24kGoldn Featuring iann dior"),
|
||||
[("24kGoldn", Role.PRIMARY),
|
||||
("iann dior", Role.FEATURED)])
|
||||
@@ -94,7 +98,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_colon_prefix_group(self) -> None:
|
||||
"""Test that a colon-prefixed group name is dropped."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"¥$: Ye & Ty Dolla $ign Featuring Rich The Kid"
|
||||
" & Playboi Carti"),
|
||||
[("Ye", Role.PRIMARY),
|
||||
@@ -105,7 +109,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_colon_prefix_with_ampersand_in_prefix(self) -> None:
|
||||
"""Test a colon prefix that itself contains "&"."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Rumi & JINU: EJAE & Andrew Choi"),
|
||||
[("EJAE", Role.PRIMARY),
|
||||
("Andrew Choi", Role.PRIMARY)])
|
||||
@@ -113,7 +117,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_colon_prefix_comma_list(self) -> None:
|
||||
"""Test a colon-prefixed comma-separated member list."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"HUNTR/X: EJAE, Audrey Nuna & REI AMI"),
|
||||
[("EJAE", Role.PRIMARY),
|
||||
("Audrey Nuna", Role.PRIMARY),
|
||||
@@ -122,7 +126,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_colon_prefix_five_members(self) -> None:
|
||||
"""Test a colon-prefixed five-member list."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Saja Boys: Andrew Choi, Neckwav, Danny Chung,"
|
||||
" Kevin Woo & samUIL Lee"),
|
||||
[("Andrew Choi", Role.PRIMARY),
|
||||
@@ -134,7 +138,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_colon_prefix_duo(self) -> None:
|
||||
"""Test a colon-prefixed two-member list."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"THE ANXIETY: WILLOW & Tyler Cole"),
|
||||
[("WILLOW", Role.PRIMARY),
|
||||
("Tyler Cole", Role.PRIMARY)])
|
||||
@@ -143,7 +147,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
"""Test that a parenthesized member list replaces the
|
||||
group name spanning the whole credit."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Silk Sonic (Bruno Mars & Anderson .Paak)"),
|
||||
[("Bruno Mars", Role.PRIMARY),
|
||||
("Anderson .Paak", Role.PRIMARY)])
|
||||
@@ -152,12 +156,12 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
"""Test that "Duet With" is a co-billing connector like
|
||||
"with", dropping the word "Duet" entirely."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Blake Shelton Duet With Gwen Stefani"),
|
||||
[("Blake Shelton", Role.PRIMARY),
|
||||
("Gwen Stefani", Role.PRIMARY)])
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Keith Urban Duet With P!nk"),
|
||||
[("Keith Urban", Role.PRIMARY),
|
||||
("P!nk", Role.PRIMARY)])
|
||||
@@ -165,12 +169,13 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_slash_delimiter(self) -> None:
|
||||
"""Test the " / " co-billing delimiter."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Cole Swindell / Lainey Wilson"),
|
||||
[("Cole Swindell", Role.PRIMARY),
|
||||
("Lainey Wilson", Role.PRIMARY)])
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit("Zayn / Taylor Swift"),
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Zayn / Taylor Swift"),
|
||||
[("Zayn", Role.PRIMARY),
|
||||
("Taylor Swift", Role.PRIMARY)])
|
||||
|
||||
@@ -178,7 +183,8 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
"""Test that "Lil Nas X" is guarded from the " x "
|
||||
delimiter split."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit("Lil Nas X & Jack Harlow"),
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Lil Nas X & Jack Harlow"),
|
||||
[("Lil Nas X", Role.PRIMARY),
|
||||
("Jack Harlow", Role.PRIMARY)])
|
||||
|
||||
@@ -186,7 +192,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
"""Test that "Tyler, The Creator" is guarded from the
|
||||
comma delimiter split."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Tyler, The Creator Featuring GloRilla, Sexyy Red"
|
||||
" & Lil Wayne"),
|
||||
[("Tyler, The Creator", Role.PRIMARY),
|
||||
@@ -198,13 +204,14 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
"""Test that "Tones And I" is guarded from the " and "
|
||||
delimiter split."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit("Tones And I"),
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Tones And I"),
|
||||
[("Tones And I", Role.PRIMARY)])
|
||||
|
||||
def test_exception_spotemgottem(self) -> None:
|
||||
"""Test the SpotemGottem exception-table credit."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"SpotemGottem Featuring Pooh Shiesty Or DaBaby"),
|
||||
[("SpotemGottem", Role.PRIMARY),
|
||||
("Pooh Shiesty", Role.FEATURED),
|
||||
@@ -213,7 +220,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
def test_exception_the_scotts(self) -> None:
|
||||
"""Test the THE SCOTTS exception-table credit."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"THE SCOTTS, Travis Scott & Kid Cudi"),
|
||||
[("Travis Scott", Role.PRIMARY),
|
||||
("Kid Cudi", Role.PRIMARY)])
|
||||
@@ -222,7 +229,7 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
"""Test the Drake Featuring The Throne exception-table
|
||||
credit."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit(
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Drake Featuring The Throne"),
|
||||
[("Drake", Role.PRIMARY),
|
||||
("Jay Z", Role.FEATURED),
|
||||
@@ -232,7 +239,8 @@ class TestParseArtistCredit(unittest.TestCase):
|
||||
"""Test that the existing "+" delimiter split is
|
||||
unaffected by the new rules."""
|
||||
self.assertEqual(
|
||||
build_db.parse_artist_credit("Dan + Shay"),
|
||||
build_db.ArtistImporter.parse_artist_credit(
|
||||
"Dan + Shay"),
|
||||
[("Dan", Role.PRIMARY), ("Shay", Role.PRIMARY)])
|
||||
|
||||
|
||||
@@ -266,8 +274,10 @@ class TestBuildDB(unittest.TestCase):
|
||||
self.__ds: DataSource = DataSource()
|
||||
patchers: list[Any] = [
|
||||
mock.patch.object(build_db, "ds", self.__ds),
|
||||
mock.patch.object(build_db, "YEARS", [2016, 2017]),
|
||||
mock.patch.object(build_db, "RANKS_PER_YEAR", 2)]
|
||||
mock.patch.object(
|
||||
build_db.SongImporter, "YEARS", [2016, 2017]),
|
||||
mock.patch.object(
|
||||
build_db.SongImporter, "RANKS_PER_YEAR", 2)]
|
||||
for patcher in patchers:
|
||||
patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
@@ -571,6 +581,53 @@ class TestBuildDB(unittest.TestCase):
|
||||
list(session.scalars(sa.select(ChartEntry))), [])
|
||||
self.assertEqual(list(session.scalars(sa.select(Song))), [])
|
||||
|
||||
def test_duplicate_chart_entry_fails(self) -> None:
|
||||
"""Test that a duplicated (year, rank) row fails without
|
||||
partial data, even though the set of distinct (year, rank)
|
||||
pairs still covers the expected grid exactly."""
|
||||
self.__write_chart(
|
||||
"year,rank,title,artist\n"
|
||||
"2016,1,Hello,Adele\n"
|
||||
"2016,1,Hello,Adele\n"
|
||||
"2016,2,One Dance,Drake featuring Wizkid\n"
|
||||
"2017,1,One Dance,Drake featuring Wizkid\n"
|
||||
"2017,2,Shape of You,Ed Sheeran\n")
|
||||
status: int
|
||||
stderr: str
|
||||
status, stderr = self.__run_build()
|
||||
self.assertNotEqual(status, 0)
|
||||
self.assertIn(
|
||||
"duplicated chart entry: year 2016 rank 1", stderr)
|
||||
session: Session = self.__session()
|
||||
self.assertEqual(
|
||||
list(session.scalars(sa.select(ChartEntry))), [])
|
||||
self.assertEqual(list(session.scalars(sa.select(Song))), [])
|
||||
|
||||
def test_blank_artist_name_fails(self) -> None:
|
||||
"""Test that a parsed credit with a name blank after
|
||||
stripping fails the build."""
|
||||
with mock.patch.object(
|
||||
build_db.ArtistImporter, "parse_artist_credit",
|
||||
return_value=[("Adele", Role.PRIMARY),
|
||||
(" ", Role.FEATURED)]):
|
||||
status: int
|
||||
stderr: str
|
||||
status, stderr = self.__run_build()
|
||||
self.assertNotEqual(status, 0)
|
||||
self.assertIn("blank artist name parsed", stderr)
|
||||
|
||||
def test_no_primary_artist_fails(self) -> None:
|
||||
"""Test that a parsed credit without a primary artist
|
||||
fails the build."""
|
||||
with mock.patch.object(
|
||||
build_db.ArtistImporter, "parse_artist_credit",
|
||||
return_value=[("Wizkid", Role.FEATURED)]):
|
||||
status: int
|
||||
stderr: str
|
||||
status, stderr = self.__run_build()
|
||||
self.assertNotEqual(status, 0)
|
||||
self.assertIn("no primary artist parsed", stderr)
|
||||
|
||||
def test_lyrics_loaded(self) -> None:
|
||||
"""Test loading the lyrics cache into the songs."""
|
||||
self.__lyrics.mkdir()
|
||||
@@ -731,11 +788,14 @@ class TestBuildDB(unittest.TestCase):
|
||||
self.assertNotIn(
|
||||
"id", self.__read_csv_header("artists.csv"))
|
||||
|
||||
def test_derived_csvs_have_lf_line_endings(self) -> None:
|
||||
"""Test that the derived CSV files use LF line endings."""
|
||||
def test_derived_csvs_have_crlf_line_endings(self) -> None:
|
||||
"""Test that the derived CSV files use CRLF line
|
||||
endings."""
|
||||
self.assertEqual(self.__run_build()[0], 0)
|
||||
raw: bytes = (self.__derived / "songs.csv").read_bytes()
|
||||
self.assertNotIn(b"\r", raw)
|
||||
self.assertGreater(raw.count(b"\r\n"), 0)
|
||||
self.assertEqual(raw.count(b"\r"), raw.count(b"\r\n"))
|
||||
self.assertEqual(raw.count(b"\n"), raw.count(b"\r\n"))
|
||||
|
||||
def test_failed_build_leaves_derived_csvs_untouched(self) -> None:
|
||||
"""Test that a failed build does not touch the existing
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/8/4
|
||||
"""Unit tests for the LLM input exporter module."""
|
||||
import io
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from contextlib import redirect_stderr
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from unittest import mock
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from pop_fem_audit_tools import config
|
||||
from pop_fem_audit_tools.commands import export_llm_input
|
||||
from pop_fem_audit_tools.database import Base, DataSource
|
||||
from pop_fem_audit_tools.models import (
|
||||
Artist,
|
||||
Role,
|
||||
Song,
|
||||
SongArtist,
|
||||
)
|
||||
|
||||
|
||||
class TestExportLlmInput(unittest.TestCase):
|
||||
"""Test cases for the LLM input exporter."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
"""Create a temporary working store for the tests."""
|
||||
tmp: tempfile.TemporaryDirectory[str] \
|
||||
= tempfile.TemporaryDirectory()
|
||||
self.addCleanup(tmp.cleanup)
|
||||
self.__dir: Path = Path(tmp.name)
|
||||
self.__output: Path = self.__dir / "llm-input.jsonl"
|
||||
url: str = f"sqlite:///{self.__dir}/store.sqlite3"
|
||||
config.set_settings(config.Settings(
|
||||
SQLALCHEMY_DATABASE_URL=url,
|
||||
ANTHROPIC_API_KEY="test-key"))
|
||||
self.__ds: DataSource = DataSource()
|
||||
patcher: Any = mock.patch.object(
|
||||
export_llm_input, "ds", self.__ds)
|
||||
patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
def __seed(
|
||||
self, songs: list[tuple[str, str, str | None]]) -> None:
|
||||
"""Create the schema and the fixture songs.
|
||||
|
||||
Each song gets a single primary artist at position 0,
|
||||
whose name equals the song's artist credit; the song IDs
|
||||
are assigned in list order starting from 1.
|
||||
|
||||
:param songs: The (title, artist, lyrics) triples.
|
||||
:return: None.
|
||||
"""
|
||||
Base.metadata.create_all(self.__ds.engine)
|
||||
session: Session = self.__ds.get_db()
|
||||
try:
|
||||
title: str
|
||||
artist: str
|
||||
lyrics: str | None
|
||||
for title, artist, lyrics in songs:
|
||||
artist_row: Artist = Artist(name=artist)
|
||||
song: Song = Song(
|
||||
title=title, artist_credit=artist,
|
||||
lyrics=lyrics)
|
||||
session.add(song)
|
||||
session.add(SongArtist(
|
||||
song=song, artist=artist_row,
|
||||
role=Role.PRIMARY, position=0))
|
||||
session.commit()
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
def __run_export(self) -> tuple[int, str]:
|
||||
"""Run the exporter with the standard error captured.
|
||||
|
||||
:return: A tuple of the exit status and the standard
|
||||
error.
|
||||
"""
|
||||
stderr: io.StringIO = io.StringIO()
|
||||
with redirect_stderr(stderr):
|
||||
status: int = export_llm_input.main(
|
||||
[str(self.__output)])
|
||||
return status, stderr.getvalue()
|
||||
|
||||
@staticmethod
|
||||
def __read_records(path: Path) -> list[dict[str, str]]:
|
||||
"""Read the JSONL records of a file.
|
||||
|
||||
:param path: The JSONL file.
|
||||
:return: The parsed records, in file order.
|
||||
"""
|
||||
with open(path, encoding="utf-8") as file:
|
||||
return [json.loads(line) for line in file
|
||||
if line.strip() != ""]
|
||||
|
||||
def test_exports_songs_ordered_by_id(self) -> None:
|
||||
"""Test that the songs export in ID order, one per line."""
|
||||
self.__seed([
|
||||
("Hello", "Adele", "hello lyrics\n"),
|
||||
("Umbrella", "Rihanna", "umbrella lyrics\n")])
|
||||
status: int
|
||||
stderr: str
|
||||
status, stderr = self.__run_export()
|
||||
self.assertEqual(status, 0)
|
||||
records: list[dict[str, str]] = self.__read_records(
|
||||
self.__output)
|
||||
self.assertEqual(records, [
|
||||
{"id": "song-1", "content": "hello lyrics\n"},
|
||||
{"id": "song-2", "content": "umbrella lyrics\n"}])
|
||||
self.assertIn("done: 2 songs exported", stderr)
|
||||
|
||||
def test_preserves_non_ascii_lyrics(self) -> None:
|
||||
"""Test that non-ASCII lyrics are written verbatim."""
|
||||
self.__seed([("Song", "Artist", "非英文歌詞\n")])
|
||||
self.assertEqual(self.__run_export()[0], 0)
|
||||
self.assertEqual(
|
||||
self.__output.read_text(encoding="utf-8"),
|
||||
json.dumps(
|
||||
{"id": "song-1", "content": "非英文歌詞\n"},
|
||||
ensure_ascii=False) + "\n")
|
||||
self.assertIn("非英文歌詞", self.__output.read_text(
|
||||
encoding="utf-8"))
|
||||
|
||||
def test_no_artist_or_title_data_in_output(self) -> None:
|
||||
"""Test the lyrics-only firewall: no title or artist
|
||||
leaks into the output."""
|
||||
self.__seed([(
|
||||
"Confidential Title", "Confidential Artist",
|
||||
"plain lyrics\n")])
|
||||
self.assertEqual(self.__run_export()[0], 0)
|
||||
content: str = self.__output.read_text(encoding="utf-8")
|
||||
self.assertNotIn("Confidential Title", content)
|
||||
self.assertNotIn("Confidential Artist", content)
|
||||
records: list[dict[str, str]] = self.__read_records(
|
||||
self.__output)
|
||||
self.assertEqual(records, [
|
||||
{"id": "song-1", "content": "plain lyrics\n"}])
|
||||
|
||||
def test_missing_lyrics_fails(self) -> None:
|
||||
"""Test that a song without lyrics fails without writing
|
||||
a partial file."""
|
||||
self.__seed([
|
||||
("Hello", "Adele", "hello lyrics\n"),
|
||||
("Silent", "Nobody", None)])
|
||||
status: int
|
||||
stderr: str
|
||||
status, stderr = self.__run_export()
|
||||
self.assertEqual(status, 1)
|
||||
self.assertIn(
|
||||
"error: song 2 \"Silent\": no lyrics", stderr)
|
||||
self.assertFalse(self.__output.exists())
|
||||
|
||||
def test_creates_parent_directory(self) -> None:
|
||||
"""Test that the output file's parent directory is
|
||||
created when missing."""
|
||||
self.__seed([("Hello", "Adele", "hello lyrics\n")])
|
||||
nested: Path = self.__dir / "nested" / "dir" / "out.jsonl"
|
||||
status: int = export_llm_input.main([str(nested)])
|
||||
self.assertEqual(status, 0)
|
||||
self.assertTrue(nested.exists())
|
||||
records: list[dict[str, str]] = self.__read_records(
|
||||
nested)
|
||||
self.assertEqual(records, [
|
||||
{"id": "song-1", "content": "hello lyrics\n"}])
|
||||
@@ -16,7 +16,8 @@ from unittest import mock
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from pop_fem_audit_tools import config, fetch_artists
|
||||
from pop_fem_audit_tools import config
|
||||
from pop_fem_audit_tools.commands import fetch_artists
|
||||
from pop_fem_audit_tools.database import Base, DataSource
|
||||
from pop_fem_audit_tools.models import Artist, Role, Song, SongArtist
|
||||
|
||||
@@ -587,17 +588,6 @@ class TestFetchArtists(unittest.TestCase):
|
||||
urlopen.assert_not_called()
|
||||
self.assertIn("error:", stderr)
|
||||
|
||||
def test_format_duration_under_hour(self) -> None:
|
||||
"""Test the mm:ss format for a duration under one hour."""
|
||||
self.assertEqual(
|
||||
fetch_artists.format_duration(205), "03:25")
|
||||
|
||||
def test_format_duration_over_hour(self) -> None:
|
||||
"""Test the h:mm:ss format once the duration reaches an
|
||||
hour."""
|
||||
self.assertEqual(
|
||||
fetch_artists.format_duration(6439), "1:47:19")
|
||||
|
||||
def test_summary_line_exact_shape(self) -> None:
|
||||
"""Test the exact wording and timing of the summary
|
||||
line."""
|
||||
|
||||
@@ -16,7 +16,8 @@ from unittest import mock
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from pop_fem_audit_tools import config, fetch_lyrics
|
||||
from pop_fem_audit_tools import config
|
||||
from pop_fem_audit_tools.commands import fetch_lyrics
|
||||
from pop_fem_audit_tools.database import Base, DataSource
|
||||
from pop_fem_audit_tools.models import (
|
||||
Artist,
|
||||
@@ -32,9 +33,6 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
PROVENANCE_HEADER: list[str] = [
|
||||
"song_id", "source", "method", "acquired_at", "note"]
|
||||
"""The expected header row of the provenance CSV file."""
|
||||
MISSING_HEADER: list[str] = [
|
||||
"song_id", "title", "artist_credit", "reason"]
|
||||
"""The expected header row of the missing report CSV file."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
"""Create a temporary capture directory with the store."""
|
||||
@@ -44,8 +42,7 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
self.__dir: Path = Path(tmp.name)
|
||||
self.__lyrics: Path = self.__dir / "lyrics"
|
||||
self.__provenance: Path = \
|
||||
self.__dir / "lyrics_provenance.csv"
|
||||
self.__missing: Path = self.__dir / "lyrics_missing.csv"
|
||||
self.__dir / "lyrics-provenance.csv"
|
||||
url: str = f"sqlite:///{self.__dir}/store.sqlite3"
|
||||
config.set_settings(config.Settings(
|
||||
SQLALCHEMY_DATABASE_URL=url,
|
||||
@@ -67,17 +64,32 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
:param songs: The (title, artist) pairs.
|
||||
:return: None.
|
||||
"""
|
||||
self.__seed_with_credit(
|
||||
[(title, artist, artist) for title, artist in songs])
|
||||
|
||||
def __seed_with_credit(
|
||||
self, songs: list[tuple[str, str, str]]) -> None:
|
||||
"""Create the schema and the fixture songs.
|
||||
|
||||
Each song gets a single primary artist at position 0 and
|
||||
an independently given artist credit; the song IDs are
|
||||
assigned in list order starting from 1.
|
||||
|
||||
:param songs: The (title, artist, artist_credit) triples.
|
||||
:return: None.
|
||||
"""
|
||||
Base.metadata.create_all(self.__ds.engine)
|
||||
session: Session = self.__ds.get_db()
|
||||
try:
|
||||
artists: dict[str, Artist] = {}
|
||||
title: str
|
||||
artist: str
|
||||
for title, artist in songs:
|
||||
credit: str
|
||||
for title, artist, credit in songs:
|
||||
if artist not in artists:
|
||||
artists[artist] = Artist(name=artist)
|
||||
song: Song = Song(title=title,
|
||||
artist_credit=artist)
|
||||
artist_credit=credit)
|
||||
session.add(song)
|
||||
session.add(SongArtist(song=song,
|
||||
artist=artists[artist],
|
||||
@@ -118,8 +130,7 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
stderr: io.StringIO = io.StringIO()
|
||||
with redirect_stderr(stderr):
|
||||
status: int = fetch_lyrics.main(
|
||||
[str(self.__lyrics), str(self.__provenance),
|
||||
str(self.__missing)])
|
||||
[str(self.__lyrics), str(self.__provenance)])
|
||||
return status, stderr.getvalue()
|
||||
|
||||
@staticmethod
|
||||
@@ -160,7 +171,8 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
["1", "lyrics.ovh", "api-fetch"])
|
||||
self.assertNotEqual(rows[1][3], "")
|
||||
self.assertEqual(rows[1][4], "")
|
||||
self.assertIn("1 fetched, 0 missed", stderr)
|
||||
self.assertIn(
|
||||
"Done. Fetched lyrics for 1/1 songs.", stderr)
|
||||
|
||||
def test_lrclib_fallback(self) -> None:
|
||||
"""Test that an ovh miss falls back to an LRCLIB hit."""
|
||||
@@ -183,6 +195,46 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
self.__provenance)
|
||||
self.assertEqual(rows[1][:2], ["1", "lrclib"])
|
||||
|
||||
def test_credit_fallback_hit(self) -> None:
|
||||
"""Test that a joint credit is queried after both miss."""
|
||||
self.__seed_with_credit(
|
||||
[("Tequila", "Dan", "Dan + Shay")])
|
||||
urlopen: mock.Mock
|
||||
with mock.patch(
|
||||
"urllib.request.urlopen",
|
||||
side_effect=[
|
||||
self.__not_found(),
|
||||
self.__not_found(),
|
||||
self.__not_found(),
|
||||
self.__response(
|
||||
{"plainLyrics": "Tequila\n"})]) as urlopen:
|
||||
status: int = self.__run_fetch()[0]
|
||||
self.assertEqual(status, 0)
|
||||
self.assertEqual(urlopen.call_count, 4)
|
||||
urls: list[str] = [x[0][0].full_url
|
||||
for x in urlopen.call_args_list]
|
||||
self.assertIn("Dan%20%2B%20Shay", urls[2])
|
||||
self.assertIn("artist_name=Dan+%2B+Shay", urls[3])
|
||||
self.assertEqual(
|
||||
(self.__lyrics / "1.txt")
|
||||
.read_text(encoding="utf-8"),
|
||||
"Tequila\n")
|
||||
rows: list[list[str]] = self.__read_rows(
|
||||
self.__provenance)
|
||||
self.assertEqual(rows[1][:2], ["1", "lrclib"])
|
||||
|
||||
def test_credit_fallback_skipped_when_same(self) -> None:
|
||||
"""Test that a matching credit skips the second round."""
|
||||
self.__seed([("Hello", "Adele")])
|
||||
urlopen: mock.Mock
|
||||
with mock.patch(
|
||||
"urllib.request.urlopen",
|
||||
side_effect=[self.__not_found(),
|
||||
self.__not_found()]) as urlopen:
|
||||
status: int = self.__run_fetch()[0]
|
||||
self.assertEqual(status, 0)
|
||||
self.assertEqual(urlopen.call_count, 2)
|
||||
|
||||
def test_both_miss(self) -> None:
|
||||
"""Test that a double miss reports the song as missing."""
|
||||
self.__seed([("Hello", "Adele")])
|
||||
@@ -196,11 +248,9 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
self.assertEqual(status, 0)
|
||||
self.assertFalse((self.__lyrics / "1.txt").exists())
|
||||
self.assertFalse(self.__provenance.exists())
|
||||
rows: list[list[str]] = self.__read_rows(self.__missing)
|
||||
self.assertEqual(len(rows), 2)
|
||||
self.assertEqual(rows[0], self.MISSING_HEADER)
|
||||
self.assertEqual(rows[1][:3], ["1", "Hello", "Adele"])
|
||||
self.assertIn("0 fetched, 1 missed", stderr)
|
||||
self.assertIn("song 1 \"Hello\": miss", stderr)
|
||||
self.assertIn(
|
||||
"Done. Fetched lyrics for 0/1 songs.", stderr)
|
||||
|
||||
def test_cached_song_skipped(self) -> None:
|
||||
"""Test that a cached song triggers no HTTP request."""
|
||||
@@ -217,8 +267,6 @@ class TestFetchLyrics(unittest.TestCase):
|
||||
(self.__lyrics / "1.txt")
|
||||
.read_text(encoding="utf-8"),
|
||||
"cached\n")
|
||||
rows: list[list[str]] = self.__read_rows(self.__missing)
|
||||
self.assertEqual(rows, [self.MISSING_HEADER])
|
||||
|
||||
def test_url_encoding(self) -> None:
|
||||
"""Test the percent-encoding of the artist and title."""
|
||||
|
||||
@@ -11,7 +11,8 @@ import unittest
|
||||
from contextlib import redirect_stderr, redirect_stdout
|
||||
from unittest import mock
|
||||
|
||||
from pop_fem_audit_tools import __main__, run_llm
|
||||
from pop_fem_audit_tools import __main__
|
||||
from pop_fem_audit_tools.commands import run_llm
|
||||
|
||||
|
||||
class TestDispatcher(unittest.TestCase):
|
||||
|
||||
+133
-187
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/7/30
|
||||
# AI assistance: Claude Code (Anthropic)
|
||||
"""Unit tests for the run_llm batch runner module."""
|
||||
"""Unit tests for the run_llm batch executor module."""
|
||||
import io
|
||||
import json
|
||||
import tempfile
|
||||
@@ -14,7 +14,8 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
from unittest import mock
|
||||
|
||||
from pop_fem_audit_tools import config, run_llm
|
||||
from pop_fem_audit_tools import config
|
||||
from pop_fem_audit_tools.commands import run_llm
|
||||
|
||||
|
||||
class RunLLMTestCase(unittest.TestCase):
|
||||
@@ -179,62 +180,6 @@ class TestRequestBuilding(RunLLMTestCase):
|
||||
self.assertEqual(params["messages"],
|
||||
[{"role": "user", "content": "the lyrics"}])
|
||||
|
||||
def test_arbitration_content(self) -> None:
|
||||
"""Test the arbitration user message format."""
|
||||
content: str = run_llm.build_arbitration_content(
|
||||
"the item", "output one", "output two")
|
||||
self.assertEqual(content,
|
||||
"<item>\nthe item\n</item>\n"
|
||||
"<run1>\noutput one\n</run1>\n"
|
||||
"<run2>\noutput two\n</run2>")
|
||||
|
||||
|
||||
class TestAgreement(RunLLMTestCase):
|
||||
"""Test cases for the agreement computation."""
|
||||
|
||||
def test_split_by_agreement(self) -> None:
|
||||
"""Test splitting items into agreed and disagreeing ones."""
|
||||
items: list[run_llm.InputItem] = [
|
||||
run_llm.InputItem(id="a", content="one"),
|
||||
run_llm.InputItem(id="b", content="two"),
|
||||
run_llm.InputItem(id="c", content="three")]
|
||||
run1: run_llm.Results = {
|
||||
"a": run_llm.BatchResult(id="a", text="same\n"),
|
||||
"b": run_llm.BatchResult(id="b", text="left"),
|
||||
"c": run_llm.BatchResult(id="c", text=" padded ")}
|
||||
run2: run_llm.Results = {
|
||||
"a": run_llm.BatchResult(id="a", text="same"),
|
||||
"b": run_llm.BatchResult(id="b", text="right"),
|
||||
"c": run_llm.BatchResult(id="c", text="padded")}
|
||||
agreed: list[str]
|
||||
disagreed: list[str]
|
||||
agreed, disagreed = run_llm.split_by_agreement(
|
||||
items, run1, run2)
|
||||
self.assertEqual(agreed, ["a", "c"])
|
||||
self.assertEqual(disagreed, ["b"])
|
||||
|
||||
|
||||
class TestFinalRecords(RunLLMTestCase):
|
||||
"""Test cases for the final record assembly."""
|
||||
|
||||
def test_build_final_records(self) -> None:
|
||||
"""Test assembling final records from runs and arbitration."""
|
||||
items: list[run_llm.InputItem] = [
|
||||
run_llm.InputItem(id="a", content="one"),
|
||||
run_llm.InputItem(id="b", content="two")]
|
||||
run1: run_llm.Results = {
|
||||
"a": run_llm.BatchResult(id="a", text="agreed text\n"),
|
||||
"b": run_llm.BatchResult(id="b", text="left")}
|
||||
arbitration: run_llm.Results = {
|
||||
"b": run_llm.BatchResult(id="b",
|
||||
text="arbitrated text")}
|
||||
records: list[dict[str, str]] = run_llm.build_final_records(
|
||||
items, run1, arbitration)
|
||||
self.assertEqual(records, [
|
||||
{"id": "a", "text": "agreed text", "source": "agreed"},
|
||||
{"id": "b", "text": "arbitrated text",
|
||||
"source": "arbitration"}])
|
||||
|
||||
|
||||
class TestCollectResults(RunLLMTestCase):
|
||||
"""Test cases for the batch result collection."""
|
||||
@@ -265,6 +210,20 @@ class TestCollectResults(RunLLMTestCase):
|
||||
run_llm.find_failures(["a", "b", "c"], results),
|
||||
["b", "c"])
|
||||
|
||||
def test_sum_usage(self) -> None:
|
||||
"""Test summing the token usage across results."""
|
||||
results: run_llm.Results = {
|
||||
"a": run_llm.BatchResult(
|
||||
id="a", text="fine",
|
||||
usage={"input_tokens": 10, "output_tokens": 5}),
|
||||
"b": run_llm.BatchResult(
|
||||
id="b", text="fine",
|
||||
usage={"input_tokens": 3, "output_tokens": 2}),
|
||||
"c": run_llm.BatchResult(id="c", error="errored")}
|
||||
self.assertEqual(
|
||||
run_llm.sum_usage(results),
|
||||
{"input_tokens": 13, "output_tokens": 7})
|
||||
|
||||
|
||||
class TestArchive(RunLLMTestCase):
|
||||
"""Test cases for the archive directory handling."""
|
||||
@@ -274,23 +233,43 @@ class TestArchive(RunLLMTestCase):
|
||||
self.__dir: Path = self._make_temp_dir()
|
||||
|
||||
def test_create_archive_dir(self) -> None:
|
||||
"""Test the archive directory naming and creation."""
|
||||
now: datetime = datetime(2026, 7, 30, 20, 5)
|
||||
directory: Path = run_llm.create_archive_dir(
|
||||
self.__dir, "coding", Path("prompts/gender_v3.md"), now)
|
||||
"""Test the archive directory creation."""
|
||||
target: Path = self.__dir / "01-01-tag" / "run1"
|
||||
directory: Path = run_llm.create_archive_dir(target, False)
|
||||
self.assertTrue(directory.is_dir())
|
||||
self.assertEqual(
|
||||
directory,
|
||||
self.__dir / "coding" / "20260730-2005-gender_v3")
|
||||
self.assertEqual(directory, target)
|
||||
|
||||
def test_existing_archive_dir_rejected(self) -> None:
|
||||
"""Test that an existing archive directory is rejected."""
|
||||
now: datetime = datetime(2026, 7, 30, 20, 5)
|
||||
run_llm.create_archive_dir(
|
||||
self.__dir, "coding", Path("gender_v3.md"), now)
|
||||
def test_existing_archive_dir_rejected_without_replace(
|
||||
self) -> None:
|
||||
"""Test that an existing archive is rejected by default."""
|
||||
target: Path = self.__dir / "01-01-tag" / "run1"
|
||||
run_llm.create_archive_dir(target, False)
|
||||
with self.assertRaises(FileExistsError):
|
||||
run_llm.create_archive_dir(
|
||||
self.__dir, "coding", Path("gender_v3.md"), now)
|
||||
run_llm.create_archive_dir(target, False)
|
||||
|
||||
def test_existing_archive_dir_replaced(self) -> None:
|
||||
"""Test that --replace replaces an existing archive."""
|
||||
target: Path = self.__dir / "01-01-tag" / "run1"
|
||||
first: Path = run_llm.create_archive_dir(target, False)
|
||||
(first / "stale.txt").write_text("stale", encoding="utf-8")
|
||||
second: Path = run_llm.create_archive_dir(target, True)
|
||||
self.assertEqual(first, second)
|
||||
self.assertFalse((second / "stale.txt").exists())
|
||||
|
||||
def test_replace_leaves_sibling_dir_untouched(self) -> None:
|
||||
"""Test that replacing run2 does not touch run1."""
|
||||
run1: Path = run_llm.create_archive_dir(
|
||||
self.__dir / "01-01-tag" / "run1", False)
|
||||
(run1 / "output.jsonl").write_text(
|
||||
"run1 data", encoding="utf-8")
|
||||
run2: Path = run_llm.create_archive_dir(
|
||||
self.__dir / "01-01-tag" / "run2", False)
|
||||
(run2 / "stale.jsonl").write_text("stale", encoding="utf-8")
|
||||
run_llm.create_archive_dir(
|
||||
self.__dir / "01-01-tag" / "run2", True)
|
||||
self.assertEqual(
|
||||
(run1 / "output.jsonl").read_text(encoding="utf-8"),
|
||||
"run1 data")
|
||||
|
||||
def test_write_jsonl(self) -> None:
|
||||
"""Test writing records as JSON Lines."""
|
||||
@@ -312,54 +291,38 @@ class TestMainFlow(RunLLMTestCase):
|
||||
"""Create a temporary directory with the input files."""
|
||||
directory: Path = self._make_temp_dir()
|
||||
self.__runs: Path = directory / "runs"
|
||||
prompt: Path = directory / "task_v1.md"
|
||||
prompt.write_text("The task prompt.\n", encoding="utf-8")
|
||||
arbitration: Path = directory / "task_arbitration_v1.md"
|
||||
arbitration.write_text(
|
||||
"The arbitration prompt.\n", encoding="utf-8")
|
||||
self.__archive_dir: Path = self.__runs / "task_v1" / "run1"
|
||||
self.__prompt: Path = directory / "task_v1.md"
|
||||
self.__prompt.write_text(
|
||||
"The task prompt.\n", encoding="utf-8")
|
||||
self.__input: Path = directory / "items.jsonl"
|
||||
self.__input.write_text(
|
||||
'{"id": "a", "content": "first item"}\n'
|
||||
'{"id": "b", "content": "second item"}\n',
|
||||
encoding="utf-8")
|
||||
self.__argv: list[str] = [
|
||||
str(self.__runs),
|
||||
"--prompt", str(prompt),
|
||||
"--arbitration-prompt", str(arbitration),
|
||||
"--input", str(self.__input),
|
||||
"--phase", "coding"]
|
||||
str(self.__prompt), str(self.__input),
|
||||
str(self.__archive_dir)]
|
||||
self.__settings: config.Settings = config.Settings(
|
||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
||||
ANTHROPIC_API_KEY="test-key")
|
||||
config.set_settings(self.__settings)
|
||||
|
||||
@staticmethod
|
||||
def __make_client(run1: list[Any], run2: list[Any],
|
||||
arbitration: list[Any] | None = None) \
|
||||
-> mock.Mock:
|
||||
"""Create a mock Anthropic client serving canned batch results.
|
||||
def __make_client(entries: list[Any]) -> mock.Mock:
|
||||
"""Create a mock Anthropic client serving canned results.
|
||||
|
||||
:param run1: The result entries of the run-1 batch.
|
||||
:param run2: The result entries of the run-2 batch.
|
||||
:param arbitration: The result entries of the arbitration
|
||||
batch.
|
||||
:param entries: The result entries of the single run batch.
|
||||
:return: The mock client.
|
||||
"""
|
||||
client: mock.Mock = mock.Mock()
|
||||
batch_ids: list[str] = ["batch_run1", "batch_run2",
|
||||
"batch_arb"]
|
||||
client.messages.batches.create.side_effect = [
|
||||
mock.Mock(id=x) for x in batch_ids]
|
||||
client.messages.batches.create.return_value = mock.Mock(
|
||||
id="batch_run1")
|
||||
ended: mock.Mock = mock.Mock()
|
||||
ended.processing_status = "ended"
|
||||
ended.ended_at = datetime(2026, 7, 30, 20, 0)
|
||||
client.messages.batches.retrieve.return_value = ended
|
||||
results: dict[str, list[Any]] = {
|
||||
"batch_run1": run1, "batch_run2": run2,
|
||||
"batch_arb": arbitration if arbitration is not None
|
||||
else []}
|
||||
client.messages.batches.results.side_effect = (
|
||||
lambda batch_id: iter(results[batch_id]))
|
||||
client.messages.batches.results.return_value = iter(entries)
|
||||
return client
|
||||
|
||||
@staticmethod
|
||||
@@ -379,16 +342,6 @@ class TestMainFlow(RunLLMTestCase):
|
||||
status: int = run_llm.main(argv)
|
||||
return status, stdout.getvalue()
|
||||
|
||||
def __archive_dir(self) -> Path:
|
||||
"""Locate the single archive directory of the run.
|
||||
|
||||
:return: The archive directory.
|
||||
"""
|
||||
directories: list[Path] = list(
|
||||
(self.__runs / "coding").iterdir())
|
||||
self.assertEqual(len(directories), 1)
|
||||
return directories[0]
|
||||
|
||||
def test_dry_run(self) -> None:
|
||||
"""Test the dry-run behavior."""
|
||||
status: int
|
||||
@@ -396,114 +349,107 @@ class TestMainFlow(RunLLMTestCase):
|
||||
status, stdout = self.__run_main(
|
||||
self.__argv + ["--dry-run"])
|
||||
self.assertEqual(status, 0)
|
||||
run_dir: Path = self.__archive_dir()
|
||||
run_dir: Path = self.__archive_dir
|
||||
self.assertEqual((run_dir / "prompt.md").read_text(
|
||||
encoding="utf-8"), "The task prompt.\n")
|
||||
self.assertEqual(
|
||||
(run_dir / "arbitration_prompt.md").read_text(
|
||||
encoding="utf-8"), "The arbitration prompt.\n")
|
||||
meta: dict[str, Any] = json.loads(
|
||||
(run_dir / "meta.json").read_text(encoding="utf-8"))
|
||||
self.assertTrue(meta["dry_run"])
|
||||
self.assertEqual(meta["item_count"], 2)
|
||||
self.assertEqual(meta["model"], "claude-sonnet-4-6")
|
||||
self.assertFalse((run_dir / "run1.jsonl").exists())
|
||||
self.assertNotIn("run", meta)
|
||||
self.assertFalse((run_dir / "output.jsonl").exists())
|
||||
request: dict[str, Any] = json.loads(stdout)
|
||||
self.assertEqual(request["custom_id"], "a")
|
||||
self.assertEqual(request["params"]["system"],
|
||||
"The task prompt.\n")
|
||||
|
||||
def test_all_agreed_skips_arbitration(self) -> None:
|
||||
"""Test that full agreement skips the arbitration batch."""
|
||||
def test_run_produces_output_file(self) -> None:
|
||||
"""Test that a run submits one batch and writes output."""
|
||||
client: mock.Mock = self.__make_client(
|
||||
run1=[self._make_success_entry("a", "answer a"),
|
||||
self._make_success_entry("b", "answer b")],
|
||||
run2=[self._make_success_entry("a", "answer a\n"),
|
||||
self._make_success_entry("b", "answer b")])
|
||||
[self._make_success_entry("a", "answer a"),
|
||||
self._make_success_entry("b", "answer b")])
|
||||
status: int = self.__run_main(self.__argv, client)[0]
|
||||
self.assertEqual(status, 0)
|
||||
self.assertEqual(
|
||||
client.messages.batches.create.call_count, 2)
|
||||
run_dir: Path = self.__archive_dir()
|
||||
self.assertEqual(
|
||||
(run_dir / "arbitration.jsonl").read_text(
|
||||
encoding="utf-8"), "")
|
||||
final: list[dict[str, Any]] = [
|
||||
json.loads(x) for x in (run_dir / "final.jsonl")
|
||||
client.messages.batches.create.call_count, 1)
|
||||
run_dir: Path = self.__archive_dir
|
||||
self.assertTrue((run_dir / "output.jsonl").exists())
|
||||
output: list[dict[str, Any]] = [
|
||||
json.loads(x) for x in (run_dir / "output.jsonl")
|
||||
.read_text(encoding="utf-8").splitlines()]
|
||||
self.assertEqual(final, [
|
||||
{"id": "a", "text": "answer a", "source": "agreed"},
|
||||
{"id": "b", "text": "answer b", "source": "agreed"}])
|
||||
self.assertEqual(output[0]["text"], "answer a")
|
||||
meta: dict[str, Any] = json.loads(
|
||||
(run_dir / "meta.json").read_text(encoding="utf-8"))
|
||||
self.assertEqual(meta["agreed_count"], 2)
|
||||
self.assertEqual(meta["agreement_rate"], 1.0)
|
||||
self.assertNotIn("arbitration", meta["batches"])
|
||||
self.assertNotIn("run", meta)
|
||||
self.assertEqual(meta["batch"]["batch_id"], "batch_run1")
|
||||
self.assertEqual(meta["usage"],
|
||||
{"input_tokens": 20, "output_tokens": 10})
|
||||
|
||||
def test_disagreement_triggers_arbitration(self) -> None:
|
||||
"""Test that disagreeing items go through arbitration."""
|
||||
def test_existing_archive_rejected_without_replace(self) -> None:
|
||||
"""Test that an existing archive without --replace fails."""
|
||||
run_dir: Path = self.__archive_dir
|
||||
run_dir.mkdir(parents=True)
|
||||
(run_dir / "stale.jsonl").write_text(
|
||||
"stale", encoding="utf-8")
|
||||
status: int = self.__run_main(
|
||||
self.__argv + ["--dry-run"])[0]
|
||||
self.assertEqual(status, 1)
|
||||
self.assertTrue((run_dir / "stale.jsonl").exists())
|
||||
|
||||
def test_rerun_replaces_archive_with_flag(self) -> None:
|
||||
"""Test that --replace replaces a pre-existing archive."""
|
||||
run_dir: Path = self.__archive_dir
|
||||
run_dir.mkdir(parents=True)
|
||||
(run_dir / "stale.jsonl").write_text(
|
||||
"stale", encoding="utf-8")
|
||||
client: mock.Mock = self.__make_client(
|
||||
run1=[self._make_success_entry("a", "answer a"),
|
||||
self._make_success_entry("b", "answer b1")],
|
||||
run2=[self._make_success_entry("a", "answer a"),
|
||||
self._make_success_entry("b", "answer b2")],
|
||||
arbitration=[
|
||||
self._make_success_entry("b", "answer b final")])
|
||||
status: int = self.__run_main(self.__argv, client)[0]
|
||||
[self._make_success_entry("a", "answer a"),
|
||||
self._make_success_entry("b", "answer b")])
|
||||
status: int = self.__run_main(
|
||||
self.__argv + ["--replace"], client)[0]
|
||||
self.assertEqual(status, 0)
|
||||
self.assertFalse((run_dir / "stale.jsonl").exists())
|
||||
self.assertTrue((run_dir / "output.jsonl").exists())
|
||||
|
||||
def test_replace_leaves_sibling_dir_untouched(self) -> None:
|
||||
"""Test that replacing run2 does not affect run1's archive."""
|
||||
run1_dir: Path = self.__archive_dir
|
||||
run1_dir.mkdir(parents=True)
|
||||
(run1_dir / "output.jsonl").write_text(
|
||||
"run1 data", encoding="utf-8")
|
||||
run2_dir: Path = self.__runs / "task_v1" / "run2"
|
||||
run2_dir.mkdir(parents=True)
|
||||
(run2_dir / "output.jsonl").write_text(
|
||||
"stale run2 data", encoding="utf-8")
|
||||
client: mock.Mock = self.__make_client(
|
||||
[self._make_success_entry("a", "answer a"),
|
||||
self._make_success_entry("b", "answer b")])
|
||||
argv: list[str] = [
|
||||
str(self.__prompt), str(self.__input),
|
||||
str(run2_dir), "--replace"]
|
||||
status: int = self.__run_main(argv, client)[0]
|
||||
self.assertEqual(status, 0)
|
||||
self.assertEqual(
|
||||
client.messages.batches.create.call_count, 3)
|
||||
arb_call: mock.call = \
|
||||
client.messages.batches.create.call_args_list[2]
|
||||
arb_requests: list[dict[str, Any]] = \
|
||||
arb_call.kwargs["requests"]
|
||||
self.assertEqual(len(arb_requests), 1)
|
||||
self.assertEqual(arb_requests[0]["custom_id"], "b")
|
||||
self.assertEqual(arb_requests[0]["params"]["system"],
|
||||
"The arbitration prompt.\n")
|
||||
self.assertEqual(
|
||||
arb_requests[0]["params"]["messages"][0]["content"],
|
||||
"<item>\nsecond item\n</item>\n"
|
||||
"<run1>\nanswer b1\n</run1>\n"
|
||||
"<run2>\nanswer b2\n</run2>")
|
||||
run_dir: Path = self.__archive_dir()
|
||||
arb_lines: list[str] = (run_dir / "arbitration.jsonl") \
|
||||
.read_text(encoding="utf-8").splitlines()
|
||||
self.assertEqual(len(arb_lines), 1)
|
||||
self.assertEqual(json.loads(arb_lines[0])["text"],
|
||||
"answer b final")
|
||||
final: list[dict[str, Any]] = [
|
||||
json.loads(x) for x in (run_dir / "final.jsonl")
|
||||
.read_text(encoding="utf-8").splitlines()]
|
||||
self.assertEqual(final, [
|
||||
{"id": "a", "text": "answer a", "source": "agreed"},
|
||||
{"id": "b", "text": "answer b final",
|
||||
"source": "arbitration"}])
|
||||
meta: dict[str, Any] = json.loads(
|
||||
(run_dir / "meta.json").read_text(encoding="utf-8"))
|
||||
self.assertEqual(meta["agreed_count"], 1)
|
||||
self.assertEqual(meta["agreement_rate"], 0.5)
|
||||
self.assertEqual(meta["batches"]["arbitration"]["batch_id"],
|
||||
"batch_arb")
|
||||
(run1_dir / "output.jsonl").read_text(encoding="utf-8"),
|
||||
"run1 data")
|
||||
self.assertNotEqual(
|
||||
(run2_dir / "output.jsonl").read_text(encoding="utf-8"),
|
||||
"stale run2 data")
|
||||
|
||||
def test_run_failure_exits_non_zero(self) -> None:
|
||||
"""Test that a failed item aborts with a non-zero status."""
|
||||
client: mock.Mock = self.__make_client(
|
||||
run1=[self._make_success_entry("a", "answer a"),
|
||||
self._make_error_entry(
|
||||
"b", "invalid_request_error")],
|
||||
run2=[self._make_success_entry("a", "answer a"),
|
||||
self._make_success_entry("b", "answer b")])
|
||||
[self._make_success_entry("a", "answer a"),
|
||||
self._make_error_entry("b", "invalid_request_error")])
|
||||
status: int = self.__run_main(self.__argv, client)[0]
|
||||
self.assertEqual(status, 1)
|
||||
run_dir: Path = self.__archive_dir()
|
||||
self.assertTrue((run_dir / "run1.jsonl").exists())
|
||||
self.assertTrue((run_dir / "run2.jsonl").exists())
|
||||
run_dir: Path = self.__archive_dir
|
||||
self.assertTrue((run_dir / "output.jsonl").exists())
|
||||
self.assertTrue((run_dir / "meta.json").exists())
|
||||
self.assertFalse((run_dir / "final.jsonl").exists())
|
||||
run1_lines: list[str] = (run_dir / "run1.jsonl") \
|
||||
output_lines: list[str] = (run_dir / "output.jsonl") \
|
||||
.read_text(encoding="utf-8").splitlines()
|
||||
self.assertEqual(json.loads(run1_lines[1]),
|
||||
self.assertEqual(json.loads(output_lines[1]),
|
||||
{"id": "b",
|
||||
"error": "invalid_request_error"})
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/8/4
|
||||
"""Unit tests for the shared utilities module."""
|
||||
import unittest
|
||||
|
||||
from pop_fem_audit_tools import utils
|
||||
|
||||
|
||||
class TestUtils(unittest.TestCase):
|
||||
"""Test cases for the shared utilities."""
|
||||
|
||||
def test_format_duration_under_hour(self) -> None:
|
||||
"""Test the mm:ss format for a duration under one hour."""
|
||||
self.assertEqual(utils.format_duration(205), "03:25")
|
||||
|
||||
def test_format_duration_over_hour(self) -> None:
|
||||
"""Test the h:mm:ss format once the duration reaches an
|
||||
hour."""
|
||||
self.assertEqual(utils.format_duration(6439), "1:47:19")
|
||||
Reference in New Issue
Block a user