Skip to content

Commit 48ea520

Browse files
authored
Improvement/youtubei (pytube#1029)
* Adds functionality for interacting with certain endpoints of the innertube API.
1 parent 1f5162c commit 48ea520

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

pytube/innertube.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""This module is designed to interact with the innertube API.
2+
3+
This module is NOT intended to be used directly by end users, as each of the
4+
interfaces returns raw results. These should instead be parsed to extract
5+
the useful information for the end user.
6+
"""
7+
# Native python imports
8+
import json
9+
from urllib import parse
10+
11+
# Local imports
12+
from pytube import request
13+
14+
15+
class InnerTube:
16+
"""Object for interacting with the innertube API."""
17+
@property
18+
def base_url(self):
19+
"""Return the base url endpoint for the innertube API."""
20+
return 'https://www.youtube.com/youtubei/v1'
21+
22+
@property
23+
def base_data(self):
24+
"""Return the base json data to transmit to the innertube API."""
25+
return {
26+
'context': {
27+
'client': {
28+
'clientName': 'WEB',
29+
'clientVersion': '2.20200720.00.02'
30+
}
31+
}
32+
}
33+
34+
@property
35+
def base_params(self):
36+
"""Return the base query parameters to transmit to the innertube API."""
37+
return {
38+
'key': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8'
39+
}
40+
41+
def _call_api(self, endpoint, query, data):
42+
"""Make a request to a given endpoint with the provided query parameters and data."""
43+
endpoint_url = f'{endpoint}?{parse.urlencode(query)}'
44+
response = request._execute_request(
45+
endpoint_url,
46+
'POST',
47+
headers={
48+
'Content-Type': 'application/json',
49+
},
50+
data=data
51+
)
52+
return json.loads(response.read())
53+
54+
def browse(self):
55+
"""Make a request to the browse endpoint.
56+
57+
TODO: Figure out how we can use this
58+
"""
59+
# endpoint = f'{self.base_url}/browse' # noqa:E800
60+
...
61+
# return self._call_api(endpoint, query, self.base_data) # noqa:E800
62+
63+
def config(self):
64+
"""Make a request to the config endpoint.
65+
66+
TODO: Figure out how we can use this
67+
"""
68+
# endpoint = f'{self.base_url}/config' # noqa:E800
69+
...
70+
# return self._call_api(endpoint, query, self.base_data) # noqa:E800
71+
72+
def guide(self):
73+
"""Make a request to the guide endpoint.
74+
75+
TODO: Figure out how we can use this
76+
"""
77+
# endpoint = f'{self.base_url}/guide' # noqa:E800
78+
...
79+
# return self._call_api(endpoint, query, self.base_data) # noqa:E800
80+
81+
def next(self):
82+
"""Make a request to the next endpoint.
83+
84+
TODO: Figure out how we can use this
85+
"""
86+
# endpoint = f'{self.base_url}/next' # noqa:E800
87+
...
88+
# return self._call_api(endpoint, query, self.base_data) # noqa:E800
89+
90+
def player(self, video_id):
91+
"""Make a request to the player endpoint.
92+
93+
:param str video_id:
94+
The video id to get player info for.
95+
:rtype: dict
96+
:returns:
97+
Raw player info results.
98+
"""
99+
endpoint = f'{self.base_url}/player'
100+
query = {
101+
'videoId': video_id,
102+
}
103+
query.update(self.base_params)
104+
return self._call_api(endpoint, query, self.base_data)
105+
106+
def search(self, search_query):
107+
"""Make a request to the search endpoint.
108+
109+
:param str search_query:
110+
The query to search.
111+
:rtype: dict
112+
:returns:
113+
Raw search query results.
114+
"""
115+
endpoint = f'{self.base_url}/search'
116+
query = {
117+
'query': search_query
118+
}
119+
query.update(self.base_params)
120+
return self._call_api(endpoint, query, self.base_data)

0 commit comments

Comments
 (0)