or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

captions.mdcollections.mdexceptions.mdindex.mdstream-management.mdvideo-downloads.md

collections.mddocs/

0

# Collection Operations

1

2

Playlist, channel, and search functionality for working with multiple YouTube videos, including bulk downloads and metadata extraction from video collections.

3

4

## Capabilities

5

6

### Playlist Class

7

8

Handle YouTube playlist operations for downloading and extracting metadata from multiple videos in a playlist.

9

10

```python { .api }

11

class Playlist:

12

def __init__(self, url: str, proxies: Optional[Dict[str, str]] = None):

13

"""

14

Initialize a Playlist object.

15

16

Args:

17

url (str): YouTube playlist URL

18

proxies (dict, optional): HTTP proxy configuration

19

"""

20

```

21

22

### Playlist Identification

23

24

Access playlist identification and URL properties.

25

26

```python { .api }

27

@property

28

def playlist_id(self) -> str:

29

"""Get the unique playlist identifier."""

30

31

@property

32

def playlist_url(self) -> str:

33

"""Get the full playlist URL."""

34

```

35

36

### Playlist Content Access

37

38

Access videos and URLs within the playlist.

39

40

```python { .api }

41

@property

42

def video_urls(self) -> DeferredGeneratorList:

43

"""

44

Get a list of video URLs in the playlist.

45

46

Returns:

47

DeferredGeneratorList: Lazy-loaded list of video URLs

48

"""

49

50

@property

51

def videos(self) -> Iterable[YouTube]:

52

"""

53

Get YouTube objects for each video in the playlist.

54

55

Returns:

56

Iterable[YouTube]: Iterator of YouTube objects

57

"""

58

59

def videos_generator(self) -> Iterator[YouTube]:

60

"""

61

Generator function that yields YouTube objects for playlist videos.

62

63

Returns:

64

Iterator[YouTube]: Generator yielding YouTube objects

65

"""

66

67

def url_generator(self) -> Iterator[str]:

68

"""

69

Generator function that yields video URLs from the playlist.

70

71

Returns:

72

Iterator[str]: Generator yielding video URLs

73

"""

74

```

75

76

### Playlist Metadata

77

78

Extract playlist information and statistics.

79

80

```python { .api }

81

@property

82

def title(self) -> Optional[str]:

83

"""Get the playlist title."""

84

85

@property

86

def description(self) -> str:

87

"""Get the playlist description."""

88

89

@property

90

def length(self) -> int:

91

"""Get the number of videos in the playlist."""

92

93

@property

94

def views(self) -> int:

95

"""Get the total playlist view count."""

96

97

@property

98

def last_updated(self) -> Optional[date]:

99

"""Get the last update date of the playlist."""

100

```

101

102

### Playlist Owner Information

103

104

Access information about the playlist creator.

105

106

```python { .api }

107

@property

108

def owner(self) -> str:

109

"""Get the playlist owner's name."""

110

111

@property

112

def owner_id(self) -> str:

113

"""Get the playlist owner's channel ID."""

114

115

@property

116

def owner_url(self) -> str:

117

"""Get the playlist owner's channel URL."""

118

```

119

120

### Playlist Navigation

121

122

Navigate and slice through playlist content.

123

124

```python { .api }

125

def trimmed(self, video_id: str) -> Iterable[str]:

126

"""

127

Get video URLs starting from a specific video ID.

128

129

Args:

130

video_id (str): Video ID to start from

131

132

Returns:

133

Iterable[str]: Video URLs from the specified point onward

134

"""

135

136

def __getitem__(self, i: Union[slice, int]) -> Union[str, List[str]]:

137

"""

138

Get video URL(s) by index or slice.

139

140

Args:

141

i (int or slice): Index or slice object

142

143

Returns:

144

str or List[str]: Video URL(s) at specified index/slice

145

"""

146

147

def __len__(self) -> int:

148

"""

149

Get the number of videos in the playlist.

150

151

Returns:

152

int: Number of videos

153

"""

154

```

155

156

### Playlist Technical Properties

157

158

Access technical information about the playlist.

159

160

```python { .api }

161

@property

162

def html(self) -> str:

163

"""Get the raw HTML content of the playlist page."""

164

165

@property

166

def ytcfg(self) -> dict:

167

"""Get the YouTube configuration data."""

168

169

@property

170

def initial_data(self) -> dict:

171

"""Get the initial data from the playlist page."""

172

173

@property

174

def sidebar_info(self) -> dict:

175

"""Get sidebar information from the playlist page."""

176

177

@property

178

def yt_api_key(self) -> str:

179

"""Get the YouTube API key extracted from the page."""

180

```

181

182

### Channel Class

183

184

Handle YouTube channel operations, providing access to all videos uploaded by a specific channel.

185

186

```python { .api }

187

class Channel(Playlist):

188

def __init__(self, url: str, proxies: Optional[Dict[str, str]] = None):

189

"""

190

Initialize a Channel object (inherits from Playlist).

191

192

Args:

193

url (str): YouTube channel URL

194

proxies (dict, optional): HTTP proxy configuration

195

"""

196

```

197

198

### Channel Identification

199

200

Access channel-specific identification properties.

201

202

```python { .api }

203

@property

204

def channel_name(self) -> str:

205

"""Get the channel display name."""

206

207

@property

208

def channel_id(self) -> str:

209

"""Get the unique channel identifier."""

210

211

@property

212

def channel_uri(self) -> str:

213

"""Get the channel URI."""

214

215

@property

216

def vanity_url(self) -> Optional[str]:

217

"""Get the custom channel URL (if available). Returns None if it doesn't exist."""

218

```

219

220

### Channel URLs

221

222

Access different channel page URLs.

223

224

```python { .api }

225

@property

226

def channel_url(self) -> str:

227

"""Get the main channel URL."""

228

229

@property

230

def videos_url(self) -> str:

231

"""Get the channel videos page URL."""

232

233

@property

234

def playlists_url(self) -> str:

235

"""Get the channel playlists page URL."""

236

237

@property

238

def community_url(self) -> str:

239

"""Get the channel community page URL."""

240

241

@property

242

def featured_channels_url(self) -> str:

243

"""Get the featured channels page URL."""

244

245

@property

246

def about_url(self) -> str:

247

"""Get the channel about page URL."""

248

```

249

250

### Channel Page Content

251

252

Access HTML content from different channel pages.

253

254

```python { .api }

255

@property

256

def html(self) -> str:

257

"""Get the main channel page HTML content."""

258

259

@property

260

def playlists_html(self) -> str:

261

"""Get the HTML content of the playlists page."""

262

263

@property

264

def community_html(self) -> str:

265

"""Get the HTML content of the community page."""

266

267

@property

268

def featured_channels_html(self) -> str:

269

"""Get the HTML content of the featured channels page."""

270

271

@property

272

def about_html(self) -> str:

273

"""Get the HTML content of the about page."""

274

```

275

276

### Search Class

277

278

Search YouTube videos with query-based video discovery and result pagination.

279

280

```python { .api }

281

class Search:

282

def __init__(self, query: str):

283

"""

284

Initialize a Search object.

285

286

Args:

287

query (str): Search query string

288

"""

289

```

290

291

### Search Properties

292

293

Access search query information and results.

294

295

```python { .api }

296

@property

297

def query(self) -> str:

298

"""Get the current search query."""

299

300

@property

301

def results(self) -> list:

302

"""

303

Get the list of search result YouTube objects.

304

305

Returns:

306

list: List of YouTube objects from search results

307

"""

308

309

@property

310

def completion_suggestions(self) -> list:

311

"""

312

Get query auto-completion suggestions.

313

314

Returns:

315

list: List of suggested search terms

316

"""

317

```

318

319

### Search Operations

320

321

Manage search results and pagination.

322

323

```python { .api }

324

def get_next_results(self) -> None:

325

"""

326

Load additional search results (pagination).

327

328

Appends new results to the existing results list.

329

"""

330

331

def fetch_and_parse(self, continuation=None) -> Tuple[List[YouTube], str]:

332

"""

333

Fetch and parse a page of search results.

334

335

Args:

336

continuation (str, optional): Continuation token for pagination

337

338

Returns:

339

Tuple[List[YouTube], str]: Tuple of (YouTube objects, next continuation token)

340

"""

341

342

def fetch_query(self, continuation=None) -> dict:

343

"""

344

Fetch raw search query results from YouTube.

345

346

Args:

347

continuation (str, optional): Continuation token for pagination

348

349

Returns:

350

dict: Raw search result data

351

"""

352

```

353

354

## Usage Examples

355

356

### Basic Playlist Download

357

358

```python

359

from pytube import Playlist

360

361

# Initialize playlist

362

playlist = Playlist('https://www.youtube.com/playlist?list=PLrqL3dXNe2Kej3sR4lZ7O2JFXOzd5Y0yV')

363

364

# Get playlist information

365

print(f"Playlist: {playlist.title}")

366

print(f"Owner: {playlist.owner}")

367

print(f"Videos: {playlist.length}")

368

369

# Download all videos

370

for video in playlist.videos:

371

try:

372

print(f"Downloading: {video.title}")

373

stream = video.streams.get_highest_resolution()

374

stream.download()

375

except Exception as e:

376

print(f"Failed to download {video.title}: {e}")

377

```

378

379

### Selective Playlist Processing

380

381

```python

382

from pytube import Playlist

383

384

playlist = Playlist('https://www.youtube.com/playlist?list=PLrqL3dXNe2Kej3sR4lZ7O2JFXOzd5Y0yV')

385

386

# Process only first 5 videos

387

for i, video in enumerate(playlist.videos):

388

if i >= 5:

389

break

390

391

print(f"Video {i+1}: {video.title}")

392

print(f"Duration: {video.length} seconds")

393

print(f"Views: {video.views:,}")

394

print("---")

395

396

# Or use slicing

397

first_five_urls = playlist.video_urls[:5]

398

print(f"First 5 URLs: {first_five_urls}")

399

```

400

401

### Channel Video Discovery

402

403

```python

404

from pytube import Channel

405

406

# Initialize channel

407

channel = Channel('https://www.youtube.com/c/PythonProgramming')

408

409

print(f"Channel: {channel.channel_name}")

410

print(f"Channel ID: {channel.channel_id}")

411

print(f"Total videos: {channel.length}")

412

413

# Get recent videos (first 10)

414

recent_videos = []

415

for i, video in enumerate(channel.videos):

416

if i >= 10:

417

break

418

recent_videos.append({

419

'title': video.title,

420

'views': video.views,

421

'duration': video.length,

422

'publish_date': video.publish_date

423

})

424

425

# Sort by publish date

426

recent_videos.sort(key=lambda x: x['publish_date'], reverse=True)

427

428

for video in recent_videos:

429

print(f"{video['title']} - {video['views']:,} views")

430

```

431

432

### Search and Filter Videos

433

434

```python

435

from pytube import Search

436

437

# Search for videos

438

search = Search('python programming tutorial')

439

440

print(f"Search query: '{search.query}'")

441

print("Completion suggestions:", search.completion_suggestions[:5])

442

443

# Process first page of results

444

print(f"Found {len(search.results)} initial results")

445

446

for video in search.results[:5]:

447

print(f"Title: {video.title}")

448

print(f"Author: {video.author}")

449

print(f"Duration: {video.length // 60}:{video.length % 60:02d}")

450

print(f"Views: {video.views:,}")

451

print("---")

452

453

# Load more results

454

search.get_next_results()

455

print(f"Total results after loading more: {len(search.results)}")

456

```

457

458

### Bulk Download with Progress Tracking

459

460

```python

461

from pytube import Playlist

462

import os

463

from datetime import datetime

464

465

def download_playlist_with_progress(playlist_url, download_dir):

466

"""Download entire playlist with progress tracking."""

467

playlist = Playlist(playlist_url)

468

469

# Create download directory

470

safe_title = "".join(c for c in playlist.title if c.isalnum() or c in (' ', '-', '_')).rstrip()

471

full_download_dir = os.path.join(download_dir, safe_title)

472

os.makedirs(full_download_dir, exist_ok=True)

473

474

print(f"Downloading playlist: {playlist.title}")

475

print(f"Total videos: {playlist.length}")

476

print(f"Download directory: {full_download_dir}")

477

478

successful_downloads = 0

479

failed_downloads = 0

480

481

for i, video in enumerate(playlist.videos, 1):

482

try:

483

print(f"[{i}/{playlist.length}] {video.title}")

484

485

# Get best available stream

486

stream = video.streams.get_highest_resolution()

487

if not stream:

488

stream = video.streams.first()

489

490

# Download with safe filename

491

safe_filename = "".join(c for c in video.title if c.isalnum() or c in (' ', '-', '_')).rstrip()

492

file_path = stream.download(

493

output_path=full_download_dir,

494

filename=safe_filename

495

)

496

497

successful_downloads += 1

498

print(f"✓ Downloaded: {os.path.basename(file_path)}")

499

500

except Exception as e:

501

failed_downloads += 1

502

print(f"✗ Failed: {e}")

503

504

print(f"\nDownload completed!")

505

print(f"Successful: {successful_downloads}")

506

print(f"Failed: {failed_downloads}")

507

508

# Usage

509

download_playlist_with_progress(

510

'https://www.youtube.com/playlist?list=PLrqL3dXNe2Kej3sR4lZ7O2JFXOzd5Y0yV',

511

'./downloads'

512

)

513

```

514

515

### Advanced Collection Filtering

516

517

```python

518

from pytube import Channel

519

from datetime import datetime, timedelta

520

521

def get_recent_channel_videos(channel_url, days=30, min_views=1000):

522

"""Get recent videos from a channel with view threshold."""

523

channel = Channel(channel_url)

524

cutoff_date = datetime.now() - timedelta(days=days)

525

526

recent_videos = []

527

528

for video in channel.videos:

529

# Check if video meets criteria

530

if (video.publish_date and

531

video.publish_date > cutoff_date and

532

video.views >= min_views):

533

534

recent_videos.append({

535

'title': video.title,

536

'url': video.watch_url,

537

'views': video.views,

538

'duration': video.length,

539

'publish_date': video.publish_date

540

})

541

542

# Sort by views (most popular first)

543

recent_videos.sort(key=lambda x: x['views'], reverse=True)

544

545

return recent_videos

546

547

# Usage

548

popular_recent = get_recent_channel_videos(

549

'https://www.youtube.com/c/PythonProgramming',

550

days=60,

551

min_views=5000

552

)

553

554

print(f"Found {len(popular_recent)} popular recent videos:")

555

for video in popular_recent[:10]:

556

print(f"{video['title']} - {video['views']:,} views")

557

```

558

559

### Search with Custom Filters

560

561

```python

562

from pytube import Search

563

564

def search_videos_with_duration_filter(query, min_duration=300, max_duration=1800):

565

"""Search for videos within a specific duration range."""

566

search = Search(query)

567

568

filtered_videos = []

569

processed = 0

570

max_process = 50 # Limit to avoid excessive API calls

571

572

while len(filtered_videos) < 10 and processed < max_process:

573

for video in search.results[processed:]:

574

processed += 1

575

576

# Check duration constraints

577

if min_duration <= video.length <= max_duration:

578

filtered_videos.append({

579

'title': video.title,

580

'author': video.author,

581

'duration': video.length,

582

'views': video.views,

583

'url': video.watch_url

584

})

585

586

if len(filtered_videos) >= 10:

587

break

588

589

# Load more results if needed

590

if len(filtered_videos) < 10 and processed >= len(search.results):

591

search.get_next_results()

592

593

return filtered_videos

594

595

# Usage: Find 5-30 minute Python tutorials

596

medium_tutorials = search_videos_with_duration_filter(

597

'python tutorial beginner',

598

min_duration=300, # 5 minutes

599

max_duration=1800 # 30 minutes

600

)

601

602

for video in medium_tutorials:

603

duration_str = f"{video['duration'] // 60}:{video['duration'] % 60:02d}"

604

print(f"{video['title']} ({duration_str}) - {video['views']:,} views")

605

```

606

607

## Types

608

609

```python { .api }

610

from typing import Dict, List, Optional, Union, Iterable, Iterator, Tuple, Any

611

from datetime import date

612

613

# Deferred generator list for lazy loading

614

class DeferredGeneratorList:

615

"""

616

Lazy-loaded list that generates items on demand.

617

618

A wrapper class for deferring list generation to improve performance

619

when working with large collections like playlists and channels.

620

Items are only fetched and processed when accessed, preventing

621

unnecessary web requests and memory usage.

622

"""

623

624

def __init__(self, generator):

625

"""

626

Initialize DeferredGeneratorList with a generator.

627

628

Args:

629

generator: The deferrable generator to create a wrapper for

630

"""

631

632

def __getitem__(self, key: Union[int, slice]) -> Any:

633

"""

634

Get item(s) by index or slice, generating only as needed.

635

636

Args:

637

key (int or slice): Index or slice object

638

639

Returns:

640

Any: Item(s) at specified index/slice

641

642

Raises:

643

TypeError: If key is not int or slice

644

IndexError: If index is out of range

645

"""

646

647

def __iter__(self) -> Iterator[Any]:

648

"""

649

Iterate through items, generating dynamically.

650

651

Returns:

652

Iterator[Any]: Iterator over generated items

653

"""

654

655

def __len__(self) -> int:

656

"""

657

Get total length by generating all items.

658

659

Returns:

660

int: Total number of items in the collection

661

"""

662

663

def __repr__(self) -> str:

664

"""

665

String representation of all items.

666

667

Returns:

668

str: String representation of the complete list

669

"""

670

671

def __reversed__(self) -> List[Any]:

672

"""

673

Get reversed list of all items.

674

675

Returns:

676

List[Any]: Reversed list of all items

677

"""

678

679

def generate_all(self) -> None:

680

"""

681

Force generation of all items in the collection.

682

683

Useful when you need to access the complete list immediately

684

rather than generating items on-demand.

685

"""

686

687

# Collection filtering types

688

CollectionFilter = Callable[[YouTube], bool]

689

```