A modern interface to the BBC Sounds radio catalogue.
❧ Click here for ProgrammeCatalogue examples
To obtain an up-to-date ProgrammeCatalogue
with just programme PIDs and titles:
beeb.api.get_programme_dict("r4", n_days=1)
⇣
{'b00cs19l': 'Midnight News',
'b006qfvv': 'Shipping Forecast',
'b006s54y': 'Selection of BBC World Service Programmes',
'b007rhyn': 'News Briefing',
'b006qmpj': 'Prayer for the Day',
'b006qj8q': 'Farming Today',
'b01s6xyk': 'Tweet of the Day',
'b006qj9z': 'Today',
'b09zgd6y': 'Chinese Characters',
'b007qlvb': "Woman's Hour",
'm0002rjm': "Alexei Sayle's The Absence of Normal",
'b04fc120': 'News Summary',
'b006qps9': 'You and Yours',
'b007rn05': 'Weather',
'b006qptc': 'World at One',
'b006qpgr': 'The Archers',
'b04xxp0g': 'Drama',
'b006qjnv': 'Money Box',
'b019dl1b': 'Inside Health',
'm000s2kt': 'Sideways',
'b00dv9hq': 'The Media Show',
'b006qskw': 'PM',
'b006qjxt': "Six O'Clock News",
'b006qsq5': 'Front Row',
'b006qk11': 'Moral Maze',
'b006xp1x': 'Lent Talks',
'b006r4wn': 'Costing the Earth',
'b006qtl3': 'The World Tonight',
'm000czyb': 'The Skewer',
'b006qtqd': 'Today in Parliament'}
To obtain a ProgrammeCatalogue
with genres (be warned — for the last 30 days this takes 60 seconds):
beeb.api.get_genre_programme_dict("r4", n_days=30)
⇣
{'Arts': [('b006v8jn', 'A Good Read')],
'Arts, Culture & the Media': [('b01875r3', 'One to One'),
('b006qsq5', 'Front Row'),
('b00dv9hq', 'The Media Show'),
('b006qp6p', 'Open Book'),
('b006r5jt', 'The Film Programme'),
('b006slnx', 'Feedback'),
('m00055q2', 'Rewinder'),
('b006qjym', 'Loose Ends'),
('b06p0p0g', 'The Why Factor'),
('b006qpdd', 'Pick of the Week'),
('b006r9xr', 'Start the Week'),
('b006s5sf', 'Bookclub'),
('b09w07c4', 'Art of Now')],
'Biographical': [('b0721qqk', 'Riot Girls')],
'Chat': [('p04x5pd7', 'Fortunately... with Fi and Jane'),
('m000s9s1', 'Between Ourselves with Marian Keyes'),
('b00snr0w', 'The Infinite Monkey Cage')],
'Classic & Period': [('m000j0t9', 'Electric Decade')],
'Comedy': [('b00x8dq1', 'My Teenage Diary'),
('b08mj1wj', 'Reluctant Persuaders'),
('m0002rjm', "Alexei Sayle's The Absence of Normal")],
'Consumer': [('b006qps9', 'You and Yours')],
'Crime & Justice': [('b006tgy1', 'Law in Action'), ('m0000nfh', 'Intrigue')],
'Disability': [('b006qxww', 'In Touch')],
'Drama': [('b04xxp0g', 'Drama'),
('b08lw2hh', 'Short Works'),
('m000s855', "Hardy's Women")],
'Entertainment': [('b060cdyj', 'Bunk Bed')],
'Factual': [('b006s54y', 'Selection of BBC World Service Programmes'),
('b007qlvb', "Woman's Hour"),
('m0001kbd', 'Born in Bradford'),
('b006th08', 'File on 4'),
('m000s2kt', 'Sideways'),
('b006qk11', 'Moral Maze'),
('b006qjlq', 'From Our Own Correspondent'),
('b006qnc7', 'Radio 4 Appeal'),
('b07cblx9', 'The Briefing Room'),
('b006qng8', 'A Point of View'),
('b006qnj3', 'Broadcasting House'),
('m0003r3t', 'My Name Is...'),
('m00019hp', 'Archive on 4'),
('b007qxpr', 'Round Britain Quiz'),
('b03w7bwg', 'Out of the Ordinary'),
('b09zgd6y', 'Chinese Characters')],
'Families & Relationships': [('b006qgj4', 'Saturday Live')],
'Food & Drink': [('b006qnx3', 'The Food Programme')],
'Gardens': [('b006qp2f', "Gardeners' Question Time")],
'Health & Wellbeing': [('b019dl1b', 'Inside Health')],
'Historical': [('m000sqkk', 'Gudrun')],
'History': [('b006qykl', 'In Our Time'),
('b00nrtd2', 'A History of the World in 100 Objects')],
'Life Stories': [('b01mk3f8', 'Short Cuts'),
('b006qnmr', 'Desert Island Discs'),
('b006qpmv', 'Last Word'),
('b006qjz5', 'Profile'),
('b03cdpww', 'Meeting Myself Coming Back'),
('b01cqx3b', 'The Listening Project')],
'Money': [('b006qjnv', 'Money Box'), ('b006sz6t', 'The Bottom Line')],
'Music': [('b00704s1', 'Counterpoint')],
'Nature & Environment': [('b006qj8q', 'Farming Today'),
('b006xrr2', 'Ramblings'),
('b05w99gb', 'Natural Histories'),
('b006r4wn', 'Costing the Earth')],
'News': [('b00cs19l', 'Midnight News'),
('b007rhyn', 'News Briefing'),
('b006qj9z', 'Today'),
('b04fc120', 'News Summary'),
('b006qptc', 'World at One'),
('b006qskw', 'PM'),
('b006qjxt', "Six O'Clock News"),
('b006qtl3', 'The World Tonight'),
('b007rhyy', 'News and Papers'),
('b00g3j4x', 'News'),
('b006qnz4', 'The World This Weekend')],
'Panel Shows': [('b006s5dp', 'Just a Minute')],
'Politics': [('b006qtqd', 'Today in Parliament'),
('b006qgvj', 'Any Questions?'),
('b006qjfq', 'The Week in Westminster'),
('b006qmmy', 'Any Answers?'),
('m0001xq1', 'The Battles That Won Our Freedoms'),
('b006r4vz', 'Analysis'),
('b006s624', 'Westminster Hour')],
'Religion & Ethics': [('b006qmpj', 'Prayer for the Day'),
('b006xp1x', 'Lent Talks'),
('b006sgsh', 'Bells on Sunday'),
('b006qn7f', 'Something Understood'),
('b006qnbd', 'Sunday'),
('b006qnds', 'Sunday Worship')],
'Satire': [('b09rwvwt', 'Henry Normal: A Normal...'),
('m000czyb', 'The Skewer'),
('b006qgt7', 'The Now Show')],
'Science & Nature': [('b01s6xyk', 'Tweet of the Day'),
('b07dx75g', 'The Curious Cases of Rutherford & Fry'),
('b036f7w2', 'BBC Inside Science'),
('b06vy2jd', 'Science Stories')],
'Science & Technology': [('b01n7094', 'The Digital Human')],
'Sitcoms': [('b0b2nh1n', 'Ability')],
'Sketch': [('b00kvs8r', 'Newsjack')],
'Soaps': [('b006qpgr', 'The Archers'), ('b006qnkc', 'The Archers Omnibus')],
'Standup': [('b0b22qhr', 'Stand-Up Specials'),
('b011tzjy', 'Meet David Sedaris')],
'Weather': [('b006qfvv', 'Shipping Forecast'), ('b007rn05', 'Weather')]}
This is equivalent to constructing the class directly and accessing its .keyed_by_genre
property.
beeb.nav.ProgrammeCatalogue("r4", n_days=30, with_genre=True)
- This takes about 7 or 8 seconds (fast given the number of requests it's making!)
- Note that these requests occasionally fail (async sessions are prone to rare connection errors),
and are silently retried up to 3 times (one seems to be enough in my experience).
The programme catalogues can be stored in a database and then restored from there:
>>> pc = beeb.nav.ProgrammeCatalogue("r4", n_days=1, with_genre=True, async_pull=True)'
>>> pc.store_db()
>>> rc = beeb.nav.ProgrammeCatalogue.regenerate_from_db("r4")
>>> pc == rc, pc.genred == rc.genred, pc.db.path == rc.db.path, type(rc) is type(pc)
(True, True, True, True)
Note that regenerated catalogues have no associated day range
>>> rc.n_days
0
The SQLite3 database programme_catalogue.db
records a simple four field table, programmes
, in beeb.data.store
:
SELECT * FROM programmes;
⇣
m000tcdg|Midnight News|News|r4
m000tcdj|Shipping Forecast|Weather|r4
m000tcdl|Selection of BBC World Service Programmes|Factual|r4
...
If your programme(s) of interest are regular, long-running ones, they should be
included in the database of programmes which ships with beeb.