nficano commited on
Commit
328e22b
·
1 Parent(s): 72ee5b1

move coverage

Browse files
README.rst CHANGED
@@ -14,7 +14,7 @@ pytube
14
  :alt: Documentation Status
15
  :target: http://python-pytube.readthedocs.io/en/latest/?badge=latest
16
 
17
- .. image:: https://coveralls.io/repos/github/nficano/pytube/badge.svg?branch=master#23e6f7ac5623e96f
18
  :alt: Code Coverage
19
  :target: https://coveralls.io/github/nficano/pytube?branch=master
20
 
 
14
  :alt: Documentation Status
15
  :target: http://python-pytube.readthedocs.io/en/latest/?badge=latest
16
 
17
+ .. image:: https://coveralls.io/repos/github/nficano/pytube/badge.svg?branch=master#23e6f7ac5623e
18
  :alt: Code Coverage
19
  :target: https://coveralls.io/github/nficano/pytube?branch=master
20
 
pytube/request.py CHANGED
@@ -4,7 +4,7 @@ from pytube.compat import urlopen
4
 
5
 
6
  def get(
7
- url=None, processes=2, headers=False,
8
  streaming=False, chunk_size=8 * 1024,
9
  ):
10
  """Send an http GET request.
@@ -13,8 +13,6 @@ def get(
13
  The URL to perform the GET request for.
14
  :param list urls:
15
  List of URLs to perform the GET request for concurrently.
16
- :param int processes:
17
- How many worker processes to start.
18
  :param bool headers:
19
  Only return the http headers.
20
  :param bool streaming:
 
4
 
5
 
6
  def get(
7
+ url=None, headers=False,
8
  streaming=False, chunk_size=8 * 1024,
9
  ):
10
  """Send an http GET request.
 
13
  The URL to perform the GET request for.
14
  :param list urls:
15
  List of URLs to perform the GET request for concurrently.
 
 
16
  :param bool headers:
17
  Only return the http headers.
18
  :param bool streaming:
tests/conftest.py CHANGED
@@ -11,32 +11,41 @@ import pytest
11
  from pytube import YouTube
12
 
13
 
14
- def load_from_playback_file(filename):
15
- cur_dir = os.path.dirname(os.path.realpath(__file__))
 
16
  fp = os.path.join(cur_dir, 'mocks', filename)
17
- video = None
18
  with gzip.open(fp, 'rb') as fh:
19
- video = json.loads(fh.read().decode('utf-8'))
20
- yt = YouTube(
21
- url='https://www.youtube.com/watch?v=9bZkp7q19f0',
22
- defer_prefetch_init=True,
23
- )
24
- yt.watch_html = video['watch_html']
25
- yt.js = video['js']
26
- yt.vid_info = video['video_info']
 
 
27
  yt.init()
28
  return yt
29
 
30
 
31
  @pytest.fixture
32
- def gangnam_style():
33
  """Youtube instance initialized with video id 9bZkp7q19f0."""
34
  filename = 'yt-video-9bZkp7q19f0-1507588332.json.tar.gz'
35
- return load_from_playback_file(filename)
36
 
37
 
38
  @pytest.fixture
39
- def youtube_captions_and_subtitles():
40
  """Youtube instance initialized with video id QRS8MkLhQmM."""
41
  filename = 'yt-video-QRS8MkLhQmM-1507588031.json.tar.gz'
42
- return load_from_playback_file(filename)
 
 
 
 
 
 
 
 
11
  from pytube import YouTube
12
 
13
 
14
+ def load_playback_file(filename):
15
+ cur_fp = os.path.realpath(__file__)
16
+ cur_dir = os.path.dirname(cur_fp)
17
  fp = os.path.join(cur_dir, 'mocks', filename)
 
18
  with gzip.open(fp, 'rb') as fh:
19
+ content = fh.read().decode('utf-8')
20
+ return json.loads(content)
21
+
22
+
23
+ def load_and_init_from_playback_file(filename):
24
+ pb = load_playback_file(filename)
25
+ yt = YouTube(pb['url'], defer_prefetch_init=True)
26
+ yt.watch_html = pb['watch_html']
27
+ yt.js = pb['js']
28
+ yt.vid_info = pb['video_info']
29
  yt.init()
30
  return yt
31
 
32
 
33
  @pytest.fixture
34
+ def cipher_signature():
35
  """Youtube instance initialized with video id 9bZkp7q19f0."""
36
  filename = 'yt-video-9bZkp7q19f0-1507588332.json.tar.gz'
37
+ return load_and_init_from_playback_file(filename)
38
 
39
 
40
  @pytest.fixture
41
+ def presigned_video():
42
  """Youtube instance initialized with video id QRS8MkLhQmM."""
43
  filename = 'yt-video-QRS8MkLhQmM-1507588031.json.tar.gz'
44
+ return load_and_init_from_playback_file(filename)
45
+
46
+
47
+ @pytest.fixture
48
+ def age_restricted():
49
+ """Youtube instance initialized with video id zRbsm3e2ltw."""
50
+ filename = 'yt-video-zRbsm3e2ltw-1507777044.json.tar.gz'
51
+ return load_playback_file(filename)
tests/mocks/yt-video-zRbsm3e2ltw-1507777044.json.tar.gz ADDED
Binary file (20.6 kB). View file
 
tests/test_cipher.py ADDED
File without changes
tests/test_cli.py ADDED
File without changes
tests/test_extract.py CHANGED
@@ -15,11 +15,11 @@ def test_extract_watch_url():
15
  assert watch_url == 'https://youtube.com/watch?v=9bZkp7q19f0'
16
 
17
 
18
- def test_info_url(gangnam_style):
19
  video_info_url = extract.video_info_url(
20
- video_id=gangnam_style.video_id,
21
- watch_url=gangnam_style.watch_url,
22
- watch_html=gangnam_style.watch_html,
23
  )
24
  expected = (
25
  'https://youtube.com/get_video_info?video_id=9bZkp7q19f0&el=%24el'
@@ -29,7 +29,15 @@ def test_info_url(gangnam_style):
29
  assert video_info_url == expected
30
 
31
 
32
- def test_js_url(gangnam_style):
33
  expected = 'https://youtube.com/yts/jsbin/player-vflOdyxa4/en_US/base.js'
34
- result = extract.js_url(gangnam_style.watch_html)
35
  assert expected == result
 
 
 
 
 
 
 
 
 
15
  assert watch_url == 'https://youtube.com/watch?v=9bZkp7q19f0'
16
 
17
 
18
+ def test_info_url(cipher_signature):
19
  video_info_url = extract.video_info_url(
20
+ video_id=cipher_signature.video_id,
21
+ watch_url=cipher_signature.watch_url,
22
+ watch_html=cipher_signature.watch_html,
23
  )
24
  expected = (
25
  'https://youtube.com/get_video_info?video_id=9bZkp7q19f0&el=%24el'
 
29
  assert video_info_url == expected
30
 
31
 
32
+ def test_js_url(cipher_signature):
33
  expected = 'https://youtube.com/yts/jsbin/player-vflOdyxa4/en_US/base.js'
34
+ result = extract.js_url(cipher_signature.watch_html)
35
  assert expected == result
36
+
37
+
38
+ def test_age_restricted(age_restricted):
39
+ assert extract.is_age_restricted(age_restricted['watch_html'])
40
+
41
+
42
+ def test_non_age_restricted(cipher_signature):
43
+ assert not extract.is_age_restricted(cipher_signature.watch_html)
tests/test_main.py ADDED
File without changes
tests/test_mixins.py CHANGED
@@ -1,3 +1,3 @@
1
  # -*- coding: utf-8 -*-
2
- def test_pre_signed_video(youtube_captions_and_subtitles):
3
- assert youtube_captions_and_subtitles.streams.count() == 15
 
1
  # -*- coding: utf-8 -*-
2
+ def test_pre_signed_video(presigned_video):
3
+ assert presigned_video.streams.count() == 15
tests/test_query.py CHANGED
@@ -3,8 +3,8 @@
3
  import pytest
4
 
5
 
6
- def test_count(gangnam_style):
7
- assert gangnam_style.streams.count() == 22
8
 
9
 
10
  @pytest.mark.parametrize(
@@ -27,29 +27,31 @@ def test_count(gangnam_style):
27
  ({'custom_filter_functions': [lambda s: s.itag == '22']}, ['22']),
28
  ],
29
  )
30
- def test_filters(test_input, expected, gangnam_style):
31
- result = [s.itag for s in gangnam_style.streams.filter(**test_input).all()]
 
 
32
  assert result == expected
33
 
34
 
35
  @pytest.mark.parametrize('test_input', ['first', 'last'])
36
- def test_empty(test_input, gangnam_style):
37
- query = gangnam_style.streams.filter(video_codec='vp20')
38
  fn = getattr(query, test_input)
39
  assert fn() is None
40
 
41
 
42
- def test_get_last(gangnam_style):
43
- assert gangnam_style.streams.last().itag == '251'
44
 
45
 
46
- def test_get_first(gangnam_style):
47
- assert gangnam_style.streams.first().itag == '22'
48
 
49
 
50
- def test_order_by(gangnam_style):
51
  itags = [
52
- s.itag for s in gangnam_style.streams
53
  .filter(progressive=True)
54
  .order_by('itag')
55
  .all()
@@ -58,9 +60,9 @@ def test_order_by(gangnam_style):
58
  assert itags == ['17', '18', '22', '36', '43']
59
 
60
 
61
- def test_order_by_descending(gangnam_style):
62
  itags = [
63
- s.itag for s in gangnam_style.streams
64
  .filter(progressive=True)
65
  .order_by('itag')
66
  .desc()
@@ -70,9 +72,9 @@ def test_order_by_descending(gangnam_style):
70
  assert itags == ['43', '36', '22', '18', '17']
71
 
72
 
73
- def test_order_by_ascending(gangnam_style):
74
  itags = [
75
- s.itag for s in gangnam_style.streams
76
  .filter(progressive=True)
77
  .order_by('itag')
78
  .asc()
@@ -82,9 +84,9 @@ def test_order_by_ascending(gangnam_style):
82
  assert itags == ['17', '18', '22', '36', '43']
83
 
84
 
85
- def test_get_by_itag(gangnam_style):
86
- assert gangnam_style.streams.get_by_itag(22).itag == '22'
87
 
88
 
89
- def test_get_by_non_existent_itag(gangnam_style):
90
- assert not gangnam_style.streams.get_by_itag(22983)
 
3
  import pytest
4
 
5
 
6
+ def test_count(cipher_signature):
7
+ assert cipher_signature.streams.count() == 22
8
 
9
 
10
  @pytest.mark.parametrize(
 
27
  ({'custom_filter_functions': [lambda s: s.itag == '22']}, ['22']),
28
  ],
29
  )
30
+ def test_filters(test_input, expected, cipher_signature):
31
+ result = [s.itag for s in cipher_signature.streams.filter(
32
+ **test_input
33
+ ).all()]
34
  assert result == expected
35
 
36
 
37
  @pytest.mark.parametrize('test_input', ['first', 'last'])
38
+ def test_empty(test_input, cipher_signature):
39
+ query = cipher_signature.streams.filter(video_codec='vp20')
40
  fn = getattr(query, test_input)
41
  assert fn() is None
42
 
43
 
44
+ def test_get_last(cipher_signature):
45
+ assert cipher_signature.streams.last().itag == '251'
46
 
47
 
48
+ def test_get_first(cipher_signature):
49
+ assert cipher_signature.streams.first().itag == '22'
50
 
51
 
52
+ def test_order_by(cipher_signature):
53
  itags = [
54
+ s.itag for s in cipher_signature.streams
55
  .filter(progressive=True)
56
  .order_by('itag')
57
  .all()
 
60
  assert itags == ['17', '18', '22', '36', '43']
61
 
62
 
63
+ def test_order_by_descending(cipher_signature):
64
  itags = [
65
+ s.itag for s in cipher_signature.streams
66
  .filter(progressive=True)
67
  .order_by('itag')
68
  .desc()
 
72
  assert itags == ['43', '36', '22', '18', '17']
73
 
74
 
75
+ def test_order_by_ascending(cipher_signature):
76
  itags = [
77
+ s.itag for s in cipher_signature.streams
78
  .filter(progressive=True)
79
  .order_by('itag')
80
  .asc()
 
84
  assert itags == ['17', '18', '22', '36', '43']
85
 
86
 
87
+ def test_get_by_itag(cipher_signature):
88
+ assert cipher_signature.streams.get_by_itag(22).itag == '22'
89
 
90
 
91
+ def test_get_by_non_existent_itag(cipher_signature):
92
+ assert not cipher_signature.streams.get_by_itag(22983)
tests/test_request.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import os
3
+
4
+ import mock
5
+
6
+ from pytube import request
7
+
8
+
9
+ @mock.patch('pytube.request.urlopen')
10
+ def test_get_streaming(mock_urlopen):
11
+ fake_stream_binary = [
12
+ iter(os.urandom(8 * 1024)),
13
+ iter(os.urandom(8 * 1024)),
14
+ iter(os.urandom(8 * 1024)),
15
+ None,
16
+ ]
17
+ response = mock.Mock()
18
+ response.read.side_effect = fake_stream_binary
19
+ mock_urlopen.return_value = response
20
+ response = request.get('fakeassurl.gov', streaming=True)
21
+ call_count = 0
22
+ for i in response:
23
+ call_count += 1
24
+ assert call_count == 3
25
+
26
+
27
+ @mock.patch('pytube.request.urlopen')
28
+ def test_get_headers(mock_urlopen):
29
+ response = mock.Mock()
30
+ response.info.return_value = {'Content-Length': '16384'}
31
+ mock_urlopen.return_value = response
32
+ response = request.get('fakeassurl.gov', headers=True)
33
+ assert response == {'Content-Length': '16384'}
34
+
35
+
36
+ @mock.patch('pytube.request.urlopen')
37
+ def test_get(mock_urlopen):
38
+ response = mock.Mock()
39
+ response.read.return_value = '<html></html>'.encode('utf-8')
40
+ mock_urlopen.return_value = response
41
+ response = request.get('fakeassurl.gov')
42
+ assert response == '<html></html>'
tests/test_streams.py CHANGED
@@ -7,19 +7,19 @@ from pytube import request
7
  from pytube import Stream
8
 
9
 
10
- def test_filesize(gangnam_style, mocker):
11
  mocker.patch.object(request, 'get')
12
  request.get.return_value = {'Content-Length': '6796391'}
13
- assert gangnam_style.streams.first().filesize == 6796391
14
 
15
 
16
- def test_default_filename(gangnam_style):
17
  expected = 'PSY - GANGNAM STYLE(강남스타일) MV.mp4'
18
- stream = gangnam_style.streams.first()
19
  assert stream.default_filename == expected
20
 
21
 
22
- def test_download(gangnam_style, mocker):
23
  mocker.patch.object(request, 'get')
24
  request.get.side_effect = [
25
  {'Content-Length': '16384'},
@@ -27,23 +27,23 @@ def test_download(gangnam_style, mocker):
27
  iter([str(random.getrandbits(8 * 1024))]),
28
  ]
29
  with mock.patch('pytube.streams.open', mock.mock_open(), create=True):
30
- stream = gangnam_style.streams.first()
31
  stream.download()
32
 
33
 
34
- def test_progressive_streams_return_includes_audio_track(gangnam_style):
35
- stream = gangnam_style.streams.filter(progressive=True).first()
36
  assert stream.includes_audio_track
37
 
38
 
39
- def test_progressive_streams_return_includes_video_track(gangnam_style):
40
- stream = gangnam_style.streams.filter(progressive=True).first()
41
  assert stream.includes_video_track
42
 
43
 
44
- def test_on_progress_hook(gangnam_style, mocker):
45
  callback_fn = mock.MagicMock()
46
- gangnam_style.register_on_progress_callback(callback_fn)
47
 
48
  mocker.patch.object(request, 'get')
49
  request.get.side_effect = [
@@ -52,7 +52,7 @@ def test_on_progress_hook(gangnam_style, mocker):
52
  iter([str(random.getrandbits(8 * 1024))]),
53
  ]
54
  with mock.patch('pytube.streams.open', mock.mock_open(), create=True):
55
- stream = gangnam_style.streams.first()
56
  stream.download()
57
  assert callback_fn.called
58
  args, _ = callback_fn.call_args
@@ -61,9 +61,9 @@ def test_on_progress_hook(gangnam_style, mocker):
61
  assert isinstance(stream, Stream)
62
 
63
 
64
- def test_on_complete_hook(gangnam_style, mocker):
65
  callback_fn = mock.MagicMock()
66
- gangnam_style.register_on_complete_callback(callback_fn)
67
 
68
  mocker.patch.object(request, 'get')
69
  request.get.side_effect = [
@@ -72,13 +72,13 @@ def test_on_complete_hook(gangnam_style, mocker):
72
  iter([str(random.getrandbits(8 * 1024))]),
73
  ]
74
  with mock.patch('pytube.streams.open', mock.mock_open(), create=True):
75
- stream = gangnam_style.streams.first()
76
  stream.download()
77
  assert callback_fn.called
78
 
79
 
80
- def test_repr_for_audio_streams(gangnam_style):
81
- stream = str(gangnam_style.streams.filter(only_audio=True).first())
82
  expected = (
83
  '<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" '
84
  'acodec="mp4a.40.2">'
@@ -86,8 +86,8 @@ def test_repr_for_audio_streams(gangnam_style):
86
  assert stream == expected
87
 
88
 
89
- def test_repr_for_video_streams(gangnam_style):
90
- stream = str(gangnam_style.streams.filter(only_video=True).first())
91
  expected = (
92
  '<Stream: itag="137" mime_type="video/mp4" res="1080p" '
93
  'fps="30fps" vcodec="avc1.640028">'
@@ -95,8 +95,8 @@ def test_repr_for_video_streams(gangnam_style):
95
  assert stream == expected
96
 
97
 
98
- def test_repr_for_progressive_streams(gangnam_style):
99
- stream = str(gangnam_style.streams.filter(progressive=True).first())
100
  expected = (
101
  '<Stream: itag="22" mime_type="video/mp4" res="720p" '
102
  'fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">'
@@ -104,8 +104,8 @@ def test_repr_for_progressive_streams(gangnam_style):
104
  assert stream == expected
105
 
106
 
107
- def test_repr_for_adaptive_streams(gangnam_style):
108
- stream = str(gangnam_style.streams.filter(adaptive=True).first())
109
  expected = (
110
  '<Stream: itag="137" mime_type="video/mp4" res="1080p" '
111
  'fps="30fps" vcodec="avc1.640028">'
 
7
  from pytube import Stream
8
 
9
 
10
+ def test_filesize(cipher_signature, mocker):
11
  mocker.patch.object(request, 'get')
12
  request.get.return_value = {'Content-Length': '6796391'}
13
+ assert cipher_signature.streams.first().filesize == 6796391
14
 
15
 
16
+ def test_default_filename(cipher_signature):
17
  expected = 'PSY - GANGNAM STYLE(강남스타일) MV.mp4'
18
+ stream = cipher_signature.streams.first()
19
  assert stream.default_filename == expected
20
 
21
 
22
+ def test_download(cipher_signature, mocker):
23
  mocker.patch.object(request, 'get')
24
  request.get.side_effect = [
25
  {'Content-Length': '16384'},
 
27
  iter([str(random.getrandbits(8 * 1024))]),
28
  ]
29
  with mock.patch('pytube.streams.open', mock.mock_open(), create=True):
30
+ stream = cipher_signature.streams.first()
31
  stream.download()
32
 
33
 
34
+ def test_progressive_streams_return_includes_audio_track(cipher_signature):
35
+ stream = cipher_signature.streams.filter(progressive=True).first()
36
  assert stream.includes_audio_track
37
 
38
 
39
+ def test_progressive_streams_return_includes_video_track(cipher_signature):
40
+ stream = cipher_signature.streams.filter(progressive=True).first()
41
  assert stream.includes_video_track
42
 
43
 
44
+ def test_on_progress_hook(cipher_signature, mocker):
45
  callback_fn = mock.MagicMock()
46
+ cipher_signature.register_on_progress_callback(callback_fn)
47
 
48
  mocker.patch.object(request, 'get')
49
  request.get.side_effect = [
 
52
  iter([str(random.getrandbits(8 * 1024))]),
53
  ]
54
  with mock.patch('pytube.streams.open', mock.mock_open(), create=True):
55
+ stream = cipher_signature.streams.first()
56
  stream.download()
57
  assert callback_fn.called
58
  args, _ = callback_fn.call_args
 
61
  assert isinstance(stream, Stream)
62
 
63
 
64
+ def test_on_complete_hook(cipher_signature, mocker):
65
  callback_fn = mock.MagicMock()
66
+ cipher_signature.register_on_complete_callback(callback_fn)
67
 
68
  mocker.patch.object(request, 'get')
69
  request.get.side_effect = [
 
72
  iter([str(random.getrandbits(8 * 1024))]),
73
  ]
74
  with mock.patch('pytube.streams.open', mock.mock_open(), create=True):
75
+ stream = cipher_signature.streams.first()
76
  stream.download()
77
  assert callback_fn.called
78
 
79
 
80
+ def test_repr_for_audio_streams(cipher_signature):
81
+ stream = str(cipher_signature.streams.filter(only_audio=True).first())
82
  expected = (
83
  '<Stream: itag="140" mime_type="audio/mp4" abr="128kbps" '
84
  'acodec="mp4a.40.2">'
 
86
  assert stream == expected
87
 
88
 
89
+ def test_repr_for_video_streams(cipher_signature):
90
+ stream = str(cipher_signature.streams.filter(only_video=True).first())
91
  expected = (
92
  '<Stream: itag="137" mime_type="video/mp4" res="1080p" '
93
  'fps="30fps" vcodec="avc1.640028">'
 
95
  assert stream == expected
96
 
97
 
98
+ def test_repr_for_progressive_streams(cipher_signature):
99
+ stream = str(cipher_signature.streams.filter(progressive=True).first())
100
  expected = (
101
  '<Stream: itag="22" mime_type="video/mp4" res="720p" '
102
  'fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">'
 
104
  assert stream == expected
105
 
106
 
107
+ def test_repr_for_adaptive_streams(cipher_signature):
108
+ stream = str(cipher_signature.streams.filter(adaptive=True).first())
109
  expected = (
110
  '<Stream: itag="137" mime_type="video/mp4" res="1080p" '
111
  'fps="30fps" vcodec="avc1.640028">'