sporc 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sporc-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 SPORC Package Maintainer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include LICENSE
3
+ include MANIFEST.in
4
+ recursive-include sporc *.py
5
+ recursive-exclude * __pycache__
6
+ recursive-exclude * *.py[co]
sporc-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,624 @@
1
+ Metadata-Version: 2.4
2
+ Name: sporc
3
+ Version: 0.1.0
4
+ Summary: A Python package for working with the SPORC (Structured Podcast Open Research Corpus) dataset
5
+ Home-page: https://github.com/yourusername/sporc
6
+ Author: SPORC Package Maintainer
7
+ Author-email: David Jurgens <jurgens@umich.edu>
8
+ Maintainer-email: David Jurgens <jurgens@umich.edu>
9
+ License: MIT
10
+ Project-URL: Homepage, https://github.com/davidjurgens/sporc
11
+ Project-URL: Documentation, https://github.com/davidjurgens/sporc/wiki
12
+ Project-URL: Repository, https://github.com/davidjurgens/sporc.git
13
+ Project-URL: Bug Tracker, https://github.com/davidjurgens/sporc/issues
14
+ Project-URL: Source Code, https://github.com/davidjurgens/sporc
15
+ Project-URL: Dataset, https://huggingface.co/datasets/blitt/SPoRC
16
+ Keywords: podcast,dataset,nlp,conversation,speech,transcript,huggingface
17
+ Classifier: Development Status :: 4 - Beta
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: License :: OSI Approved :: MIT License
21
+ Classifier: Operating System :: OS Independent
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3.8
24
+ Classifier: Programming Language :: Python :: 3.9
25
+ Classifier: Programming Language :: Python :: 3.10
26
+ Classifier: Programming Language :: Python :: 3.11
27
+ Classifier: Programming Language :: Python :: 3.12
28
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
29
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
30
+ Classifier: Topic :: Text Processing :: Linguistic
31
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
32
+ Requires-Python: >=3.8
33
+ Description-Content-Type: text/markdown
34
+ License-File: LICENSE
35
+ Requires-Dist: datasets>=2.0.0
36
+ Requires-Dist: huggingface_hub>=0.16.0
37
+ Requires-Dist: psutil>=5.8.0
38
+ Provides-Extra: dev
39
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
40
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
41
+ Requires-Dist: black>=22.0.0; extra == "dev"
42
+ Requires-Dist: isort>=5.0.0; extra == "dev"
43
+ Requires-Dist: flake8>=5.0.0; extra == "dev"
44
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
45
+ Requires-Dist: pre-commit>=2.20.0; extra == "dev"
46
+ Provides-Extra: docs
47
+ Requires-Dist: sphinx>=5.0.0; extra == "docs"
48
+ Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "docs"
49
+ Requires-Dist: myst-parser>=0.18.0; extra == "docs"
50
+ Provides-Extra: test
51
+ Requires-Dist: pytest>=7.0.0; extra == "test"
52
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
53
+ Requires-Dist: pytest-mock>=3.8.0; extra == "test"
54
+ Dynamic: author
55
+ Dynamic: home-page
56
+ Dynamic: license-file
57
+ Dynamic: requires-python
58
+
59
+ # SPORC: Structured Podcast Open Research Corpus
60
+
61
+ A Python package for working with the [SPORC (Structured Podcast Open Research Corpus)](https://huggingface.co/datasets/blitt/SPoRC) dataset from Hugging Face.
62
+
63
+ ## Overview
64
+
65
+ SPORC is a large multimodal dataset for the study of the podcast ecosystem. This package provides easy-to-use Python classes and functions to interact with the dataset, including:
66
+
67
+ - **Podcast** class: Collection of episodes and metadata about a podcast
68
+ - **Episode** class: Single episode with information about its contents
69
+ - Search functionality for podcasts and episodes
70
+ - Conversation turn analysis and filtering
71
+ - Time-based and speaker-based queries
72
+ - **Streaming support** for memory-efficient processing of large datasets
73
+ - **Selective loading** for filtering and loading specific podcast subsets into memory
74
+
75
+ ## Installation
76
+
77
+ ### Prerequisites
78
+
79
+ Before installing this package, you need to:
80
+
81
+ 1. **Accept the SPORC dataset terms** on Hugging Face:
82
+ - Visit [https://huggingface.co/datasets/blitt/SPoRC](https://huggingface.co/datasets/blitt/SPoRC)
83
+ - Log in to your Hugging Face account
84
+ - Click "I agree" to accept the dataset terms
85
+
86
+ 2. **Set up Hugging Face credentials** on your local machine:
87
+ ```bash
88
+ pip install huggingface_hub
89
+ huggingface-cli login
90
+ ```
91
+
92
+ ### Install the Package
93
+
94
+ ```bash
95
+ pip install sporc
96
+ ```
97
+
98
+ Or install from source:
99
+
100
+ ```bash
101
+ git clone https://github.com/yourusername/sporc.git
102
+ cd sporc
103
+ pip install -e .
104
+ ```
105
+
106
+ ## Quick Start
107
+
108
+ ```python
109
+ from sporc import SPORCDataset
110
+
111
+ # Initialize the dataset (memory mode - default)
112
+ sporc = SPORCDataset()
113
+
114
+ # Or use streaming mode for memory efficiency
115
+ sporc_streaming = SPORCDataset(streaming=True)
116
+
117
+ # Or use selective mode to load specific podcasts into memory
118
+ sporc_selective = SPORCDataset(streaming=True)
119
+ sporc_selective.load_podcast_subset(categories=['education'])
120
+
121
+ # Search for a specific podcast
122
+ podcast = sporc.search_podcast("SingOut SpeakOut")
123
+
124
+ # Get all episodes for this podcast
125
+ for episode in podcast.episodes:
126
+ print(f"Episode: {episode.title}")
127
+ print(f"Duration: {episode.duration_seconds} seconds")
128
+ print(f"Hosts: {episode.host_names}")
129
+ print("---")
130
+
131
+ # Search for episodes with specific criteria
132
+ episodes = sporc.search_episodes(
133
+ min_duration=300, # At least 5 minutes
134
+ max_speakers=3, # Maximum 3 speakers
135
+ host_name="Simon Shapiro"
136
+ )
137
+
138
+ # Get conversation turns for a specific episode
139
+ episode = episodes[0]
140
+ turns = episode.get_turns_by_time_range(0, 180) # First 3 minutes
141
+ for turn in turns:
142
+ print(f"Speaker: {turn.speaker}")
143
+ print(f"Text: {turn.text[:100]}...")
144
+ print(f"Duration: {turn.duration} seconds")
145
+ print("---")
146
+ ```
147
+
148
+ ## Memory vs Streaming vs Selective Mode
149
+
150
+ The SPORC package supports three modes for loading the dataset:
151
+
152
+ ### Memory Mode (Default)
153
+ ```python
154
+ sporc = SPORCDataset() # streaming=False (default)
155
+ ```
156
+
157
+ **Advantages:**
158
+ - Fast access to all data
159
+ - Can use `len()` to get dataset size
160
+ - All search operations are instant
161
+ - Can iterate over data multiple times
162
+ - Full dataset statistics available immediately
163
+
164
+ **Disadvantages:**
165
+ - High memory usage (loads entire dataset into RAM)
166
+ - Slower initial loading time
167
+ - May not work on systems with limited memory
168
+
169
+ ### Streaming Mode
170
+ ```python
171
+ sporc = SPORCDataset(streaming=True)
172
+ ```
173
+
174
+ **Advantages:**
175
+ - Low memory usage (loads data on-demand)
176
+ - Fast initial loading
177
+ - Works on systems with limited memory
178
+ - Can process datasets larger than available RAM
179
+
180
+ **Disadvantages:**
181
+ - Slower access to individual items
182
+ - Cannot use `len()` (raises RuntimeError)
183
+ - Search operations require iterating through data
184
+ - Cannot iterate over data multiple times without reloading
185
+ - Statistics calculation requires full iteration
186
+
187
+ ### Selective Mode
188
+ ```python
189
+ sporc = SPORCDataset(streaming=True)
190
+ sporc.load_podcast_subset(categories=['education'])
191
+ ```
192
+
193
+ **Advantages:**
194
+ - Memory efficient (only loads selected subset)
195
+ - O(1) access to selected podcasts and episodes
196
+ - Fast search operations on the subset
197
+ - Can iterate over data multiple times
198
+ - Statistics available immediately for the subset
199
+ - Best of both worlds: memory efficiency + fast access
200
+
201
+ **Disadvantages:**
202
+ - Initial filtering requires O(n) iteration
203
+ - Cannot access podcasts outside the selected subset
204
+ - Requires knowing filtering criteria in advance
205
+
206
+ ### When to Use Each Mode
207
+
208
+ **Use Memory Mode when:**
209
+ - You have sufficient RAM (8GB+ recommended)
210
+ - You need fast access to multiple episodes
211
+ - You want to perform complex searches frequently
212
+ - You need to iterate over data multiple times
213
+ - You're working with smaller subsets of the dataset
214
+
215
+ **Use Streaming Mode when:**
216
+ - You have limited RAM (< 8GB)
217
+ - You're processing the entire dataset sequentially
218
+ - You only need to access a few episodes
219
+ - You're doing one-pass analysis
220
+ - You're working on systems with memory constraints
221
+
222
+ **Use Selective Mode when:**
223
+ - You want to work with a specific genre, host, or category
224
+ - You have limited RAM but need fast access to a subset
225
+ - You want to perform frequent searches on a filtered dataset
226
+ - You know your filtering criteria in advance
227
+ - You want the best balance of memory efficiency and performance
228
+
229
+ ### Selective Mode Examples
230
+
231
+ ```python
232
+ # Initialize streaming mode
233
+ sporc = SPORCDataset(streaming=True)
234
+
235
+ # Load only education podcasts
236
+ sporc.load_podcast_subset(categories=['education'])
237
+ print(f"Loaded {len(sporc)} episodes from education podcasts")
238
+
239
+ # Now you have O(1) access to education podcasts
240
+ education_podcasts = sporc.get_all_podcasts()
241
+ for podcast in education_podcasts:
242
+ print(f"Education podcast: {podcast.title}")
243
+
244
+ # Fast search within the subset
245
+ long_education_episodes = sporc.search_episodes(min_duration=1800) # 30+ minutes
246
+ print(f"Found {len(long_education_episodes)} long education episodes")
247
+
248
+ # Load podcasts by specific hosts
249
+ sporc = SPORCDataset(streaming=True)
250
+ sporc.load_podcast_subset(hosts=['Simon Shapiro', 'John Doe'])
251
+ print(f"Loaded {len(sporc)} episodes from selected hosts")
252
+
253
+ # Load podcasts with at least 10 episodes
254
+ sporc = SPORCDataset(streaming=True)
255
+ sporc.load_podcast_subset(min_episodes=10)
256
+ print(f"Loaded {len(sporc)} episodes from podcasts with 10+ episodes")
257
+
258
+ # Load English podcasts with at least 5 hours of content
259
+ sporc = SPORCDataset(streaming=True)
260
+ sporc.load_podcast_subset(language='en', min_total_duration=5.0)
261
+ print(f"Loaded {len(sporc)} episodes from substantial English podcasts")
262
+
263
+ # Complex filtering
264
+ sporc = SPORCDataset(streaming=True)
265
+ sporc.load_podcast_subset(
266
+ categories=['education', 'science'],
267
+ min_episodes=5,
268
+ min_total_duration=2.0, # 2+ hours
269
+ language='en'
270
+ )
271
+ print(f"Loaded {len(sporc)} episodes from substantial English education/science podcasts")
272
+ ```
273
+
274
+ ## Core Classes
275
+
276
+ ### SPORCDataset
277
+
278
+ The main class for interacting with the SPORC dataset.
279
+
280
+ ```python
281
+ from sporc import SPORCDataset
282
+
283
+ # Memory mode
284
+ sporc = SPORCDataset()
285
+
286
+ # Streaming mode
287
+ sporc = SPORCDataset(streaming=True)
288
+
289
+ # Selective mode
290
+ sporc = SPORCDataset(streaming=True)
291
+ sporc.load_podcast_subset(categories=['education'])
292
+ ```
293
+
294
+ **Methods:**
295
+ - `search_podcast(name: str) -> Podcast`: Find a podcast by name
296
+ - `search_episodes(**criteria) -> List[Episode]`: Search episodes by various criteria
297
+ - `get_all_podcasts() -> List[Podcast]`: Get all podcasts in the dataset
298
+ - `get_all_episodes() -> List[Episode]`: Get all episodes in the dataset
299
+ - `iterate_episodes() -> Iterator[Episode]`: Iterate over episodes (streaming only)
300
+ - `iterate_podcasts() -> Iterator[Podcast]`: Iterate over podcasts (streaming only)
301
+ - `load_podcast_subset(**criteria) -> None`: Load filtered subset into memory (streaming only)
302
+ - `get_dataset_statistics() -> Dict[str, Any]`: Get dataset statistics
303
+
304
+ ### Podcast
305
+
306
+ Represents a podcast with its episodes and metadata.
307
+
308
+ ```python
309
+ podcast = sporc.search_podcast("Example Podcast")
310
+ print(f"Title: {podcast.title}")
311
+ print(f"Description: {podcast.description}")
312
+ print(f"Category: {podcast.category}")
313
+ print(f"Number of episodes: {len(podcast.episodes)}")
314
+ ```
315
+
316
+ **Properties:**
317
+ - `title`: Podcast title
318
+ - `description`: Podcast description
319
+ - `category`: Primary category
320
+ - `episodes`: List of Episode objects
321
+ - `host_names`: List of predicted host names
322
+
323
+ ### Episode
324
+
325
+ Represents a single podcast episode.
326
+
327
+ ```python
328
+ episode = podcast.episodes[0]
329
+ print(f"Title: {episode.title}")
330
+ print(f"Duration: {episode.duration_seconds} seconds")
331
+ print(f"Hosts: {episode.host_names}")
332
+ print(f"Guests: {episode.guest_names}")
333
+ ```
334
+
335
+ **Methods:**
336
+ - `get_turns_by_time_range(start_time: float, end_time: float) -> List[Turn]`
337
+ - `get_turns_by_speaker(speaker_name: str) -> List[Turn]`
338
+ - `get_turns_by_min_length(min_length: int) -> List[Turn]`
339
+ - `get_all_turns() -> List[Turn]`
340
+
341
+ **Properties:**
342
+ - `title`: Episode title
343
+ - `description`: Episode description
344
+ - `duration_seconds`: Episode duration in seconds
345
+ - `host_names`: List of predicted host names
346
+ - `guest_names`: List of predicted guest names
347
+ - `main_speakers`: List of main speaker labels
348
+ - `transcript`: Full episode transcript
349
+
350
+ ### Turn
351
+
352
+ Represents a single conversation turn in an episode.
353
+
354
+ ```python
355
+ turn = episode.get_all_turns()[0]
356
+ print(f"Speaker: {turn.speaker}")
357
+ print(f"Text: {turn.text}")
358
+ print(f"Start time: {turn.start_time} seconds")
359
+ print(f"End time: {turn.end_time} seconds")
360
+ print(f"Duration: {turn.duration} seconds")
361
+ ```
362
+
363
+ **Properties:**
364
+ - `speaker`: Speaker label (e.g., "SPEAKER_00")
365
+ - `text`: Spoken text
366
+ - `start_time`: Turn start time in seconds
367
+ - `end_time`: Turn end time in seconds
368
+ - `duration`: Turn duration in seconds
369
+ - `inferred_role`: Inferred speaker role (host, guest, etc.)
370
+ - `inferred_name`: Inferred speaker name
371
+
372
+ ## Search Examples
373
+
374
+ ### Search by Podcast Name
375
+ ```python
376
+ podcast = sporc.search_podcast("Brazen Education")
377
+ ```
378
+
379
+ ### Search Episodes by Duration
380
+ ```python
381
+ # Episodes longer than 10 minutes
382
+ long_episodes = sporc.search_episodes(min_duration=600)
383
+
384
+ # Episodes between 5-15 minutes
385
+ medium_episodes = sporc.search_episodes(min_duration=300, max_duration=900)
386
+ ```
387
+
388
+ ### Search Episodes by Speaker Count
389
+ ```python
390
+ # Episodes with exactly 2 speakers
391
+ two_speaker_episodes = sporc.search_episodes(min_speakers=2, max_speakers=2)
392
+
393
+ # Episodes with 3 or more speakers
394
+ multi_speaker_episodes = sporc.search_episodes(min_speakers=3)
395
+ ```
396
+
397
+ ### Search Episodes by Host
398
+ ```python
399
+ # Episodes hosted by Simon Shapiro
400
+ simon_episodes = sporc.search_episodes(host_name="Simon Shapiro")
401
+ ```
402
+
403
+ ### Search Episodes by Category
404
+ ```python
405
+ # Education podcasts
406
+ education_episodes = sporc.search_episodes(category="education")
407
+
408
+ # Music podcasts
409
+ music_episodes = sporc.search_episodes(category="music")
410
+ ```
411
+
412
+ ## Selective Loading Examples
413
+
414
+ ### Load by Category
415
+ ```python
416
+ # Load only education podcasts
417
+ sporc = SPORCDataset(streaming=True)
418
+ sporc.load_podcast_subset(categories=['education'])
419
+
420
+ # Now fast access to education content
421
+ education_podcasts = sporc.get_all_podcasts()
422
+ long_education_episodes = sporc.search_episodes(min_duration=1800)
423
+ ```
424
+
425
+ ### Load by Host
426
+ ```python
427
+ # Load podcasts by specific hosts
428
+ sporc = SPORCDataset(streaming=True)
429
+ sporc.load_podcast_subset(hosts=['Simon Shapiro', 'John Doe'])
430
+
431
+ # Fast access to episodes from these hosts
432
+ host_episodes = sporc.get_all_episodes()
433
+ ```
434
+
435
+ ### Load by Episode Count
436
+ ```python
437
+ # Load podcasts with substantial episode counts
438
+ sporc = SPORCDataset(streaming=True)
439
+ sporc.load_podcast_subset(min_episodes=10)
440
+
441
+ # Work with established podcasts
442
+ established_podcasts = sporc.get_all_podcasts()
443
+ ```
444
+
445
+ ### Load by Duration
446
+ ```python
447
+ # Load podcasts with substantial content
448
+ sporc = SPORCDataset(streaming=True)
449
+ sporc.load_podcast_subset(min_total_duration=5.0) # 5+ hours
450
+
451
+ # Work with substantial podcasts
452
+ substantial_podcasts = sporc.get_all_podcasts()
453
+ ```
454
+
455
+ ### Complex Filtering
456
+ ```python
457
+ # Load substantial English education/science podcasts
458
+ sporc = SPORCDataset(streaming=True)
459
+ sporc.load_podcast_subset(
460
+ categories=['education', 'science'],
461
+ min_episodes=5,
462
+ min_total_duration=2.0,
463
+ language='en'
464
+ )
465
+
466
+ # Now you have fast access to a curated subset
467
+ curated_episodes = sporc.get_all_episodes()
468
+ curated_podcasts = sporc.get_all_podcasts()
469
+ ```
470
+
471
+ ## Conversation Turn Analysis
472
+
473
+ ### Get Turns by Time Range
474
+ ```python
475
+ # First 5 minutes of an episode
476
+ early_turns = episode.get_turns_by_time_range(0, 300)
477
+
478
+ # Last 10 minutes of an episode
479
+ late_turns = episode.get_turns_by_time_range(
480
+ episode.duration_seconds - 600,
481
+ episode.duration_seconds
482
+ )
483
+ ```
484
+
485
+ ### Get Turns by Speaker
486
+ ```python
487
+ # All turns by the host
488
+ host_turns = episode.get_turns_by_speaker("SPEAKER_00")
489
+
490
+ # All turns by a specific guest
491
+ guest_turns = episode.get_turns_by_speaker("SPEAKER_01")
492
+ ```
493
+
494
+ ### Get Turns by Length
495
+ ```python
496
+ # Turns longer than 30 seconds
497
+ long_turns = episode.get_turns_by_min_length(30)
498
+
499
+ # Turns longer than 2 minutes
500
+ very_long_turns = episode.get_turns_by_min_length(120)
501
+ ```
502
+
503
+ ## Data Quality Indicators
504
+
505
+ The SPORC dataset includes several quality indicators that can help you filter data:
506
+
507
+ ```python
508
+ episode = podcast.episodes[0]
509
+
510
+ # Diarization quality indicators
511
+ print(f"Overlap proportion (duration): {episode.overlap_prop_duration}")
512
+ print(f"Overlap proportion (turn count): {episode.overlap_prop_turn_count}")
513
+ print(f"Average turn duration: {episode.avg_turn_duration}")
514
+ print(f"Total speaker labels: {episode.total_speaker_labels}")
515
+
516
+ # Filter episodes with good diarization quality
517
+ good_quality_episodes = sporc.search_episodes(
518
+ max_overlap_prop_duration=0.1, # Less than 10% overlap
519
+ max_overlap_prop_turn_count=0.2 # Less than 20% overlapping turns
520
+ )
521
+ ```
522
+
523
+ ## Performance Considerations
524
+
525
+ ### Memory Usage
526
+
527
+ **Memory Mode:**
528
+ - Initial memory usage: ~2-4GB (depending on dataset size)
529
+ - Memory usage remains constant during processing
530
+ - Fast access to all data
531
+
532
+ **Streaming Mode:**
533
+ - Initial memory usage: ~50-100MB
534
+ - Memory usage varies during processing (typically 100-500MB per episode)
535
+ - Memory is freed after processing each episode
536
+
537
+ **Selective Mode:**
538
+ - Initial memory usage: ~50-100MB
539
+ - Memory usage after loading: ~100MB-2GB (depending on subset size)
540
+ - Memory usage remains constant during processing
541
+ - Fast access to selected subset
542
+
543
+ ### Processing Speed
544
+
545
+ **Memory Mode:**
546
+ - Fast search operations (O(1) for indexed data)
547
+ - Instant access to any episode
548
+ - Slower initial loading
549
+
550
+ **Streaming Mode:**
551
+ - Slower search operations (O(n) - must iterate through data)
552
+ - Slower access to individual episodes
553
+ - Fast initial loading
554
+
555
+ **Selective Mode:**
556
+ - Initial filtering: O(n) (one-time cost)
557
+ - Fast search operations on subset (O(1) for indexed data)
558
+ - Fast access to selected episodes
559
+ - Fast initial loading
560
+
561
+ ### Recommended System Requirements
562
+
563
+ **Memory Mode:**
564
+ - RAM: 8GB+ recommended
565
+ - Storage: 10GB+ for dataset cache
566
+ - CPU: Any modern processor
567
+
568
+ **Streaming Mode:**
569
+ - RAM: 4GB+ minimum, 8GB+ recommended
570
+ - Storage: 10GB+ for dataset cache
571
+ - CPU: Any modern processor
572
+
573
+ **Selective Mode:**
574
+ - RAM: 4GB+ minimum, 8GB+ recommended
575
+ - Storage: 10GB+ for dataset cache
576
+ - CPU: Any modern processor
577
+
578
+ ## Error Handling
579
+
580
+ The package includes comprehensive error handling for common issues:
581
+
582
+ ```python
583
+ from sporc import SPORCDataset, SPORCError
584
+
585
+ try:
586
+ sporc = SPORCDataset()
587
+ podcast = sporc.search_podcast("Nonexistent Podcast")
588
+ except SPORCError as e:
589
+ print(f"Error: {e}")
590
+ ```
591
+
592
+ ## Contributing
593
+
594
+ Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
595
+
596
+ ## License
597
+
598
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
599
+
600
+ ## Citation
601
+
602
+ If you use this package in your research, please cite the original SPORC paper:
603
+
604
+ ```bibtex
605
+ @article{blitt2025sporc,
606
+ title={SPORC: the Structured Podcast Open Research Corpus},
607
+ author={Litterer, Ben and Jurgens, David and Card, Dallas},
608
+ booktitle={Proceedings of the 63rd Annual Meeting of the Association for Computational Linguistics},
609
+ year={2025}
610
+ }
611
+ ```
612
+
613
+ ## Support
614
+
615
+ For questions, issues, or feature requests, please:
616
+
617
+ 1. Check the [documentation](https://github.com/yourusername/sporc/wiki)
618
+ 2. Search existing [issues](https://github.com/yourusername/sporc/issues)
619
+ 3. Create a new issue if your problem isn't already addressed
620
+
621
+ ## Acknowledgments
622
+
623
+ - Hugging Face for hosting the dataset
624
+ - The open-source community for the tools that made this package possible