2522 lines
99 KiB
Python
2522 lines
99 KiB
Python
"""
|
||
Main Api implementation.
|
||
"""
|
||
|
||
from typing import Optional, List, Union
|
||
|
||
import requests
|
||
from requests.auth import HTTPBasicAuth
|
||
from requests.models import Response
|
||
from requests_oauthlib.oauth2_session import OAuth2Session
|
||
|
||
from pyyoutube.error import ErrorCode, ErrorMessage, PyYouTubeException
|
||
from pyyoutube.models import (
|
||
AccessToken,
|
||
UserProfile,
|
||
ActivityListResponse,
|
||
CaptionListResponse,
|
||
ChannelListResponse,
|
||
ChannelSectionResponse,
|
||
PlaylistListResponse,
|
||
PlaylistItemListResponse,
|
||
VideoListResponse,
|
||
CommentThreadListResponse,
|
||
CommentListResponse,
|
||
VideoCategoryListResponse,
|
||
SearchListResponse,
|
||
SubscriptionListResponse,
|
||
I18nRegionListResponse,
|
||
I18nLanguageListResponse,
|
||
MemberListResponse,
|
||
MembershipsLevelListResponse,
|
||
VideoAbuseReportReasonListResponse,
|
||
)
|
||
from pyyoutube.utils.params_checker import enf_comma_separated, enf_parts
|
||
|
||
|
||
class Api(object):
|
||
"""
|
||
Example usage:
|
||
To create an instance of pyyoutube.Api class:
|
||
|
||
>>> import pyyoutube
|
||
>>> api = pyyoutube.Api(api_key="your api key")
|
||
|
||
To get one channel info:
|
||
|
||
>>> res = api.get_channel_info(channel_id="UC_x5XG1OV2P6uZZ5FSM9Ttw")
|
||
>>> print(res.items[0])
|
||
|
||
Now this api provide methods as follows:
|
||
>>> api.get_authorization_url()
|
||
>>> api.generate_access_token()
|
||
>>> api.refresh_token()
|
||
>>> api.get_channel_info()
|
||
>>> api.get_playlist_by_id()
|
||
>>> api.get_playlists()
|
||
>>> api.get_playlist_item_by_id()
|
||
>>> api.get_playlist_items()
|
||
>>> api.get_video_by_id()
|
||
>>> api.get_videos_by_chart()
|
||
>>> api.get_videos_by_myrating()
|
||
>>> api.get_comment_thread_by_id()
|
||
>>> api.get_comment_threads()
|
||
>>> api.get_comment_by_id()
|
||
>>> api.get_comments()
|
||
>>> api.get_video_categories()
|
||
>>> api.get_subscription_by_id()
|
||
>>> api.get_subscription_by_channel()
|
||
>>> api.get_subscription_by_me()
|
||
>>> api.get_activities_by_channel()
|
||
>>> api.get_activities_by_me()
|
||
>>> api.get_captions_by_video()
|
||
>>> api.get_channel_sections_by_id()
|
||
>>> api.get_channel_sections_by_channel()
|
||
>>> api.get_i18n_regions()
|
||
>>> api.get_i18n_languages()
|
||
>>> api.get_video_abuse_report_reason()
|
||
>>> api.search()
|
||
>>> api.search_by_keywords()
|
||
>>> api.search_by_developer()
|
||
>>> api.search_by_mine()
|
||
>>> api.search_by_related_video()
|
||
"""
|
||
|
||
BASE_URL = "https://www.googleapis.com/youtube/v3/"
|
||
AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/v2/auth"
|
||
EXCHANGE_ACCESS_TOKEN_URL = "https://oauth2.googleapis.com/token"
|
||
USER_INFO_URL = "https://www.googleapis.com/oauth2/v1/userinfo"
|
||
|
||
DEFAULT_REDIRECT_URI = "https://localhost/"
|
||
|
||
DEFAULT_SCOPE = [
|
||
"https://www.googleapis.com/auth/youtube",
|
||
"https://www.googleapis.com/auth/userinfo.profile",
|
||
]
|
||
|
||
DEFAULT_STATE = "PyYouTube"
|
||
DEFAULT_TIMEOUT = 10
|
||
DEFAULT_QUOTA = 10000 # this quota reset at 00:00:00(GMT-7) every day.
|
||
|
||
def __init__(
|
||
self,
|
||
client_id: Optional[str] = None,
|
||
client_secret: Optional[str] = None,
|
||
api_key: Optional[str] = None,
|
||
access_token: Optional[str] = None,
|
||
timeout: Optional[int] = None,
|
||
proxies: Optional[dict] = None,
|
||
) -> None:
|
||
"""
|
||
This Api provide two method to work. Use api key or use access token.
|
||
|
||
Args:
|
||
client_id(str, optional):
|
||
Your google app's ID.
|
||
client_secret (str, optional):
|
||
Your google app's secret.
|
||
api_key(str, optional):
|
||
The api key which you create from google api console.
|
||
access_token(str, optional):
|
||
If you not provide api key, you can do authorization to get an access token.
|
||
If all api key and access token provided. Use access token first.
|
||
timeout(int, optional):
|
||
The request timeout.
|
||
proxies(dict, optional):
|
||
If you want use proxy, need point this param.
|
||
param style like requests lib style.
|
||
Refer https://2.python-requests.org//en/latest/user/advanced/#proxies
|
||
|
||
Returns:
|
||
YouTube Api instance.
|
||
"""
|
||
self._client_id = client_id
|
||
self._client_secret = client_secret
|
||
self._api_key = api_key
|
||
self._access_token = access_token
|
||
self._refresh_token = None # This keep current user's refresh token.
|
||
self._timeout = timeout
|
||
self.session = requests.Session()
|
||
self.proxies = proxies
|
||
|
||
if not (
|
||
(self._client_id and self._client_secret)
|
||
or self._api_key
|
||
or self._access_token
|
||
):
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message="Must specify either client key info or api key.",
|
||
)
|
||
)
|
||
|
||
if self._timeout is None:
|
||
self._timeout = self.DEFAULT_TIMEOUT
|
||
|
||
def _get_oauth_session(
|
||
self,
|
||
redirect_uri: Optional[str] = None,
|
||
scope: Optional[List[str]] = None,
|
||
**kwargs,
|
||
) -> OAuth2Session:
|
||
"""
|
||
Build a request session for OAuth.
|
||
|
||
Args:
|
||
redirect_uri(str, optional)
|
||
Determines how Google's authorization server sends a response to your app.
|
||
If not provide will use default https://localhost/
|
||
scope (list, optional)
|
||
The scope you want give permission.
|
||
If you not provide, will use default scope.
|
||
kwargs(dict, optional)
|
||
Some other params you want provide.
|
||
|
||
Returns:
|
||
OAuth2 Session
|
||
"""
|
||
if redirect_uri is None:
|
||
redirect_uri = self.DEFAULT_REDIRECT_URI
|
||
|
||
if scope is None:
|
||
scope = self.DEFAULT_SCOPE
|
||
|
||
return OAuth2Session(
|
||
client_id=self._client_id,
|
||
scope=scope,
|
||
redirect_uri=redirect_uri,
|
||
state=self.DEFAULT_STATE,
|
||
**kwargs,
|
||
)
|
||
|
||
def get_authorization_url(
|
||
self,
|
||
redirect_uri: Optional[str] = None,
|
||
scope: Optional[List[str]] = None,
|
||
**kwargs,
|
||
) -> (str, str):
|
||
"""
|
||
Build authorization url to do authorize.
|
||
|
||
Args:
|
||
redirect_uri(str, optional)
|
||
Determines how Google's authorization server sends a response to your app.
|
||
If not provide will use default https://localhost/
|
||
scope (list, optional)
|
||
The scope you want give permission.
|
||
If you not provide, will use default scope.
|
||
kwargs(dict, optional)
|
||
Some other params you want provide.
|
||
|
||
Returns:
|
||
The uri you can open on browser to do authorize.
|
||
"""
|
||
oauth_session = self._get_oauth_session(
|
||
redirect_uri=redirect_uri,
|
||
scope=scope,
|
||
**kwargs,
|
||
)
|
||
authorization_url, state = oauth_session.authorization_url(
|
||
self.AUTHORIZATION_URL,
|
||
access_type="offline",
|
||
prompt="select_account",
|
||
**kwargs,
|
||
)
|
||
|
||
return authorization_url, state
|
||
|
||
def generate_access_token(
|
||
self,
|
||
authorization_response: str,
|
||
redirect_uri: Optional[str] = None,
|
||
scope: Optional[List[str]] = None,
|
||
return_json: bool = False,
|
||
**kwargs,
|
||
) -> Union[dict, AccessToken]:
|
||
"""
|
||
Use the google auth response to get access token
|
||
|
||
Args:
|
||
authorization_response (str)
|
||
The response url which google redirect.
|
||
redirect_uri(str, optional)
|
||
Determines how Google's authorization server sends a response to your app.
|
||
If not provide will use default https://localhost/
|
||
scope (list, optional)
|
||
The scope you want give permission.
|
||
If you not provide, will use default scope.
|
||
return_json(bool, optional)
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return pyyoutube.AccessToken
|
||
kwargs(dict, optional)
|
||
Some other params you want provide.
|
||
Return:
|
||
Retrieved access token's info, pyyoutube.AccessToken instance.
|
||
"""
|
||
|
||
oauth_session = self._get_oauth_session(
|
||
redirect_uri=redirect_uri,
|
||
scope=scope,
|
||
**kwargs,
|
||
)
|
||
token = oauth_session.fetch_token(
|
||
self.EXCHANGE_ACCESS_TOKEN_URL,
|
||
client_secret=self._client_secret,
|
||
authorization_response=authorization_response,
|
||
proxies=self.proxies,
|
||
)
|
||
self._access_token = oauth_session.access_token
|
||
self._refresh_token = oauth_session.token["refresh_token"]
|
||
if return_json:
|
||
return token
|
||
else:
|
||
return AccessToken.from_dict(token)
|
||
|
||
def refresh_token(
|
||
self, refresh_token: Optional[str] = None, return_json: bool = False
|
||
) -> Union[dict, AccessToken]:
|
||
"""
|
||
Refresh token by api return refresh token.
|
||
|
||
Args:
|
||
refresh_token (str)
|
||
The refresh token which the api returns.
|
||
return_json (bool, optional):
|
||
If True JSON data will be returned, instead of pyyoutube.AccessToken
|
||
Return:
|
||
Retrieved new access token's info, pyyoutube.AccessToken instance.
|
||
"""
|
||
|
||
refresh_token = refresh_token if refresh_token else self._refresh_token
|
||
|
||
if refresh_token is None:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message=f"Must provide the refresh token or api has been authorized.",
|
||
)
|
||
)
|
||
|
||
oauth_session = OAuth2Session(client_id=self._client_id)
|
||
auth = HTTPBasicAuth(self._client_id, self._client_secret)
|
||
new_token = oauth_session.refresh_token(
|
||
self.EXCHANGE_ACCESS_TOKEN_URL,
|
||
refresh_token=refresh_token,
|
||
auth=auth,
|
||
)
|
||
self._access_token = oauth_session.access_token
|
||
if return_json:
|
||
return new_token
|
||
else:
|
||
return AccessToken.from_dict(new_token)
|
||
|
||
@staticmethod
|
||
def _parse_response(response: Response) -> dict:
|
||
"""
|
||
Parse response data and check whether errors exists.
|
||
|
||
Args:
|
||
response (Response)
|
||
The response which the request return.
|
||
Return:
|
||
response's data
|
||
"""
|
||
data = response.json()
|
||
if "error" in data:
|
||
raise PyYouTubeException(response)
|
||
return data
|
||
|
||
@staticmethod
|
||
def _parse_data(data: Optional[dict]) -> Union[dict, list]:
|
||
"""
|
||
Parse resp data.
|
||
|
||
Args:
|
||
data (dict)
|
||
The response data by response.json()
|
||
Return:
|
||
response's items
|
||
"""
|
||
items = data["items"]
|
||
return items
|
||
|
||
def _request(
|
||
self, resource, method=None, args=None, post_args=None, enforce_auth=True
|
||
) -> Response:
|
||
"""
|
||
Main request sender.
|
||
|
||
Args:
|
||
resource(str)
|
||
Resource field is which type data you want to retrieve.
|
||
Such as channels,videos and so on.
|
||
method(str, optional)
|
||
The method this request to send request.
|
||
Default is 'GET'
|
||
args(dict, optional)
|
||
The url params for this request.
|
||
post_args(dict, optional)
|
||
The Post params for this request.
|
||
enforce_auth(bool, optional)
|
||
Whether use google credentials
|
||
Returns:
|
||
response
|
||
"""
|
||
if method is None:
|
||
method = "GET"
|
||
|
||
if args is None:
|
||
args = dict()
|
||
|
||
if post_args is not None:
|
||
method = "POST"
|
||
|
||
key = None
|
||
access_token = None
|
||
if self._api_key is not None:
|
||
key = "key"
|
||
access_token = self._api_key
|
||
if self._access_token is not None:
|
||
key = "access_token"
|
||
access_token = self._access_token
|
||
if access_token is None and enforce_auth:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message="You must provide your credentials.",
|
||
)
|
||
)
|
||
|
||
if enforce_auth:
|
||
if method == "POST" and key not in post_args:
|
||
post_args[key] = access_token
|
||
elif method == "GET" and key not in args:
|
||
args[key] = access_token
|
||
|
||
try:
|
||
response = self.session.request(
|
||
method=method,
|
||
url=self.BASE_URL + resource,
|
||
timeout=self._timeout,
|
||
params=args,
|
||
data=post_args,
|
||
proxies=self.proxies,
|
||
)
|
||
except requests.HTTPError as e:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(status_code=ErrorCode.HTTP_ERROR, message=e.args[0])
|
||
)
|
||
else:
|
||
return response
|
||
|
||
def get_profile(
|
||
self, access_token: Optional[str] = None, return_json: Optional[bool] = False
|
||
) -> Union[dict, UserProfile]:
|
||
"""
|
||
Get token user info.
|
||
|
||
Args:
|
||
access_token(str, optional)
|
||
user access token. If not provide, use api instance access token
|
||
return_json(bool, optional)
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return pyyoutube.UserProfile
|
||
|
||
Returns:
|
||
The data for you given access token's user info.
|
||
"""
|
||
if access_token is None:
|
||
access_token = self._access_token
|
||
if access_token is None:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message=f"Must provide the access token or api has been authorized.",
|
||
)
|
||
)
|
||
try:
|
||
response = self.session.get(
|
||
self.USER_INFO_URL,
|
||
params={"access_token": access_token},
|
||
timeout=self._timeout,
|
||
proxies=self.proxies,
|
||
)
|
||
except requests.HTTPError as e:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(status_code=ErrorCode.HTTP_ERROR, message=e.args[0])
|
||
)
|
||
data = self._parse_response(response)
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return UserProfile.from_dict(data)
|
||
|
||
def paged_by_page_token(
|
||
self,
|
||
resource: str,
|
||
args: dict,
|
||
count: Optional[int] = None,
|
||
):
|
||
"""
|
||
Response paged by response's page token. If not provide response token
|
||
|
||
Args:
|
||
resource (str):
|
||
The resource string need to retrieve data.
|
||
args (dict)
|
||
The args for api.
|
||
count (int, optional):
|
||
The count for result items you want to get.
|
||
If provide this with None, will retrieve all items.
|
||
Note:
|
||
The all items maybe too much. Notice your app's cost.
|
||
Returns:
|
||
Data api origin response.
|
||
"""
|
||
res_data: Optional[dict] = None
|
||
current_items: List[dict] = []
|
||
page_token: Optional[str] = None
|
||
now_items_count: int = 0
|
||
|
||
while True:
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
resp = self._request(resource=resource, method="GET", args=args)
|
||
data = self._parse_response(resp) # origin response
|
||
# set page token
|
||
page_token = data.get("nextPageToken")
|
||
prev_page_token = data.get("prevPageToken")
|
||
|
||
# parse results.
|
||
items = self._parse_data(data)
|
||
current_items.extend(items)
|
||
now_items_count += len(items)
|
||
if res_data is None:
|
||
res_data = data
|
||
# first check the count if satisfies.
|
||
if count is not None:
|
||
if now_items_count >= count:
|
||
current_items = current_items[:count]
|
||
break
|
||
# if have no page token, mean no more data.
|
||
if page_token is None:
|
||
break
|
||
res_data["items"] = current_items
|
||
|
||
# use last request page token
|
||
res_data["nextPageToken"] = page_token
|
||
res_data["prevPageToken"] = prev_page_token
|
||
return res_data
|
||
|
||
def get_activities_by_channel(
|
||
self,
|
||
*,
|
||
channel_id: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
before: Optional[str] = None,
|
||
after: Optional[str] = None,
|
||
region_code: Optional[str] = None,
|
||
count: Optional[int] = 20,
|
||
limit: int = 20,
|
||
page_token: Optional[str] = None,
|
||
return_json: bool = False,
|
||
):
|
||
"""
|
||
Retrieve given channel's activities data.
|
||
|
||
Args:
|
||
channel_id (str):
|
||
The id for channel which you want to get activities data.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for activities you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
before (str, optional):
|
||
Set this will only return the activities occurred before this timestamp.
|
||
This need specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
|
||
after (str, optional):
|
||
Set this will only return the activities occurred after this timestamp.
|
||
This need specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
|
||
region_code (str, optional):
|
||
Set this will only return the activities for the specified country.
|
||
This need specified with an ISO 3166-1 alpha-2 country code.
|
||
count (int, optional):
|
||
The count will retrieve activities data.
|
||
Default is 20.
|
||
If provide this with None, will retrieve all activities.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For activities, this should not be more than 50.
|
||
Default is 20.
|
||
page_token (str, optional):
|
||
The token of the page of activities result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the page result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.ActivityListResponse instance.
|
||
|
||
Returns:
|
||
ActivityListResponse or original data.
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 50 # for activities the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"channelId": channel_id,
|
||
"part": enf_parts(resource="activities", value=parts),
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if before:
|
||
args["publishedBefore"] = before
|
||
if after:
|
||
args["publishedAfter"] = after
|
||
if region_code:
|
||
args["regionCode"] = region_code
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="activities", args=args, count=count
|
||
)
|
||
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return ActivityListResponse.from_dict(res_data)
|
||
|
||
def get_activities_by_me(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
before: Optional[str] = None,
|
||
after: Optional[str] = None,
|
||
region_code: Optional[str] = None,
|
||
count: Optional[int] = 20,
|
||
limit: int = 20,
|
||
page_token: Optional[str] = None,
|
||
return_json: bool = False,
|
||
):
|
||
"""
|
||
Retrieve authorized user's activities.
|
||
|
||
Note:
|
||
This need you do authorize first.
|
||
|
||
Args:
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for activities you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
before (str, optional):
|
||
Set this will only return the activities occurred before this timestamp.
|
||
This need specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
|
||
after (str, optional):
|
||
Set this will only return the activities occurred after this timestamp.
|
||
This need specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
|
||
region_code (str, optional):
|
||
Set this will only return the activities for the specified country.
|
||
This need specified with an ISO 3166-1 alpha-2 country code.
|
||
count (int, optional):
|
||
The count will retrieve activities data.
|
||
Default is 20.
|
||
If provide this with None, will retrieve all activities.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For activities, this should not be more than 50.
|
||
Default is 20.
|
||
page_token (str, optional):
|
||
The token of the page of activities result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the page result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.ActivityListResponse instance.
|
||
|
||
Returns:
|
||
ActivityListResponse or original data.
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 50 # for activities the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"mine": True,
|
||
"part": enf_parts(resource="activities", value=parts),
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if before:
|
||
args["publishedBefore"] = before
|
||
if after:
|
||
args["publishedAfter"] = after
|
||
if region_code:
|
||
args["regionCode"] = region_code
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="activities", args=args, count=count
|
||
)
|
||
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return ActivityListResponse.from_dict(res_data)
|
||
|
||
def get_captions_by_video(
|
||
self,
|
||
*,
|
||
video_id: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
caption_id: Optional[Union[str, list, tuple, set]] = None,
|
||
return_json: bool = False,
|
||
):
|
||
"""
|
||
Retrieve authorized user's video's caption data.
|
||
|
||
Note:
|
||
This need you do authorize first.
|
||
|
||
Args:
|
||
video_id (str):
|
||
The id for video which you want to get caption.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for caption you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
caption_id ((str,list,tuple,set)):
|
||
The id for caption that you want to get data.
|
||
You can pass this with single id str,comma-separated id str, or list, tuple, set of id str.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.CaptionListResponse instance.
|
||
Returns:
|
||
CaptionListResponse or original data.
|
||
"""
|
||
|
||
args = {
|
||
"videoId": video_id,
|
||
"part": enf_parts("captions", parts),
|
||
}
|
||
|
||
if caption_id is not None:
|
||
args["id"] = enf_comma_separated("caption_id", caption_id)
|
||
|
||
resp = self._request(resource="captions", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return CaptionListResponse.from_dict(data)
|
||
|
||
def get_channel_info(
|
||
self,
|
||
*,
|
||
channel_id: Optional[Union[str, list, tuple, set]] = None,
|
||
for_username: Optional[str] = None,
|
||
mine: Optional[bool] = None,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: str = "en_US",
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve channel data from YouTube Data API.
|
||
|
||
Note:
|
||
1. Don't know why, but now you couldn't get channel list by given an guide category.
|
||
You can only get list by parameters mine,forUsername,id.
|
||
Refer: https://developers.google.com/youtube/v3/guides/implementation/channels
|
||
2. The origin maxResult param not work for these filter method.
|
||
|
||
Args:
|
||
channel_id ((str,list,tuple,set), optional):
|
||
The id or comma-separated id string for youtube channel which you want to get.
|
||
You can also pass this with an id list, tuple, set.
|
||
for_username (str, optional):
|
||
The name for YouTube username which you want to get.
|
||
Note: This name may the old youtube version's channel's user's username, Not the the channel name.
|
||
Refer: https://developers.google.com/youtube/v3/guides/working_with_channel_ids
|
||
mine (bool, optional):
|
||
If you have give the authorization. Will return your channels.
|
||
Must provide the access token.
|
||
parts (str, optional):
|
||
Comma-separated list of one or more channel resource properties.
|
||
If not provided. will use default public properties.
|
||
hl (str, optional):
|
||
If provide this. Will return channel's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.ChannelListResponse instance.
|
||
Returns:
|
||
ChannelListResponse instance or original data.
|
||
"""
|
||
|
||
args = {
|
||
"part": enf_parts(resource="channels", value=parts),
|
||
"hl": hl,
|
||
}
|
||
if for_username is not None:
|
||
args["forUsername"] = for_username
|
||
elif channel_id is not None:
|
||
args["id"] = enf_comma_separated("channel_id", channel_id)
|
||
elif mine is not None:
|
||
args["mine"] = mine
|
||
else:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message=f"Specify at least one of channel_id,channel_name or mine",
|
||
)
|
||
)
|
||
|
||
resp = self._request(resource="channels", method="GET", args=args)
|
||
|
||
data = self._parse_response(resp)
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return ChannelListResponse.from_dict(data)
|
||
|
||
def get_channel_sections_by_id(
|
||
self,
|
||
*,
|
||
section_id: Union[str, list, tuple, set],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[ChannelSectionResponse, dict]:
|
||
"""
|
||
Retrieve channel section info by his ids(s).
|
||
|
||
Args:
|
||
section_id:
|
||
The id(s) for channel sections.
|
||
You can pass this with single id str, comma-separated id str, or a list,tuple,set of ids.
|
||
parts:
|
||
The resource parts for channel section you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
return_json:
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.ChannelSectionResponse instance.
|
||
Returns:
|
||
ChannelSectionResponse or original data.
|
||
"""
|
||
|
||
args = {
|
||
"id": enf_comma_separated(field="section_id", value=section_id),
|
||
"part": enf_parts(resource="channelSections", value=parts),
|
||
}
|
||
|
||
resp = self._request(resource="channelSections", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return ChannelSectionResponse.from_dict(data)
|
||
|
||
def get_channel_sections_by_channel(
|
||
self,
|
||
*,
|
||
channel_id: Optional[str] = None,
|
||
mine: bool = False,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[ChannelSectionResponse, dict]:
|
||
"""
|
||
Retrieve channel sections by channel id.
|
||
|
||
Args:
|
||
channel_id:
|
||
The id for channel which you want to get channel sections.
|
||
mine:
|
||
If you want to get your channel's sections, set this with True.
|
||
And this need your authorization.
|
||
parts:
|
||
The resource parts for channel section you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
return_json:
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.ChannelSectionResponse instance.
|
||
Returns:
|
||
ChannelSectionResponse or original data.
|
||
"""
|
||
|
||
args = {
|
||
"part": enf_parts(resource="channelSections", value=parts),
|
||
}
|
||
|
||
if mine:
|
||
args["mine"] = mine
|
||
else:
|
||
args["channelId"] = channel_id
|
||
|
||
resp = self._request(resource="channelSections", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return ChannelSectionResponse.from_dict(data)
|
||
|
||
def get_comment_by_id(
|
||
self,
|
||
*,
|
||
comment_id: Union[str, list, tuple, set],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
text_format: Optional[str] = "html",
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve comment info by given comment id str.
|
||
|
||
Args:
|
||
comment_id (str, optional):
|
||
The id for comment that you want to retrieve data.
|
||
You can pass this with single id str, comma-separated id str, or a list,tuple,set of ids.
|
||
parts ((str,list,tuple,set), optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
text_format (str, optional):
|
||
Comments left by users format style.
|
||
Acceptable values are: html, plainText.
|
||
Default is html.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.CommentListResponse instance.
|
||
|
||
Returns:
|
||
CommentListResponse or original data
|
||
"""
|
||
|
||
args = {
|
||
"id": enf_comma_separated(field="comment_id", value=comment_id),
|
||
"part": enf_parts(resource="comments", value=parts),
|
||
"textFormat": text_format,
|
||
}
|
||
|
||
resp = self._request(resource="comments", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return CommentListResponse.from_dict(data)
|
||
|
||
def get_comments(
|
||
self,
|
||
*,
|
||
parent_id: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
text_format: Optional[str] = "html",
|
||
count: Optional[int] = 20,
|
||
limit: Optional[int] = 20,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve comments info by given parent id.
|
||
Note: YouTube currently supports replies only for top-level comments.
|
||
However, replies to replies may be supported in the future.
|
||
|
||
Args:
|
||
parent_id (str):
|
||
Provide the ID of the comment for which replies should be retrieved.
|
||
parts ((str,list,tuple,set), optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
text_format (str, optional):
|
||
Comments left by users format style.
|
||
Acceptable values are: html, plainText.
|
||
Default is html.
|
||
count (int, optional):
|
||
The count will retrieve videos data.
|
||
Default is 20.
|
||
If provide this with None, will retrieve all comments.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For comments, this should not be more than 100.
|
||
Default is 20.
|
||
page_token(str, optional):
|
||
The token of the page of comments result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.CommentListResponse instance.
|
||
Returns:
|
||
CommentListResponse or original data
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 100 # for comments the max limit for per request is 100
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"parentId": parent_id,
|
||
"part": enf_parts(resource="comments", value=parts),
|
||
"textFormat": text_format,
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(resource="comments", args=args, count=count)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return CommentListResponse.from_dict(res_data)
|
||
|
||
def get_comment_thread_by_id(
|
||
self,
|
||
*,
|
||
comment_thread_id: Union[str, list, tuple, set],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
text_format: Optional[str] = "html",
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve the comment thread info by given id.
|
||
|
||
Args:
|
||
comment_thread_id ((str,list,tuple,set)):
|
||
The id for comment thread that you want to retrieve data.
|
||
You can pass this with single id str, comma-separated id str, or a list,tuple,set of ids.
|
||
parts ((str,list,tuple,set), optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
text_format (str, optional):
|
||
Comments left by users format style.
|
||
Acceptable values are: html, plainText.
|
||
Default is html.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.CommentThreadListResponse instance.
|
||
Returns:
|
||
CommentThreadListResponse or original data
|
||
"""
|
||
|
||
args = {
|
||
"id": enf_comma_separated("comment_thread_id", comment_thread_id),
|
||
"part": enf_parts(resource="commentThreads", value=parts),
|
||
"textFormat": text_format,
|
||
}
|
||
|
||
resp = self._request(resource="commentThreads", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return CommentThreadListResponse.from_dict(data)
|
||
|
||
def get_comment_threads(
|
||
self,
|
||
*,
|
||
all_to_channel_id: Optional[str] = None,
|
||
channel_id: Optional[str] = None,
|
||
video_id: Optional[str] = None,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
moderation_status: Optional[str] = None,
|
||
order: Optional[str] = None,
|
||
search_terms: Optional[str] = None,
|
||
text_format: Optional[str] = "html",
|
||
count: Optional[int] = 20,
|
||
limit: Optional[int] = 20,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve the comment threads info by given filter condition.
|
||
|
||
Args:
|
||
all_to_channel_id (str, optional):
|
||
If you provide this with a channel id, will return all comment threads associated with the channel.
|
||
The response can include comments about the channel or about the channel's videos.
|
||
channel_id (str, optional):
|
||
If you provide this with a channel id, will return the comment threads associated with the channel.
|
||
But the response not include comments about the channel's videos.
|
||
video_id (str, optional):
|
||
If you provide this with a video id, will return the comment threads associated with the video.
|
||
parts ((str,list,tuple,set), optional)
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
moderation_status (str, optional):
|
||
This parameter must used with authorization.
|
||
If you provide this. the response will return comment threads match this filter only.
|
||
Acceptable values are:
|
||
- heldForReview: Retrieve comment threads that are awaiting review by a moderator.
|
||
- likelySpam: Retrieve comment threads classified as likely to be spam.
|
||
- published: Retrieve threads of published comments. this is default for all.
|
||
See more: https://developers.google.com/youtube/v3/docs/commentThreads/list#parameters
|
||
order (str, optional):
|
||
Order parameter specifies the order in which the API response should list comment threads.
|
||
Acceptable values are:
|
||
- time: Comment threads are ordered by time. This is the default behavior.
|
||
- relevance: Comment threads are ordered by relevance.
|
||
search_terms (str, optional):
|
||
The searchTerms parameter instructs the API to limit the API response to only contain comments
|
||
that contain the specified search terms.
|
||
text_format (str, optional):
|
||
Comments left by users format style.
|
||
Acceptable values are: html, plainText.
|
||
Default is html.
|
||
count (int, optional):
|
||
The count will retrieve comment threads data.
|
||
Default is 20.
|
||
If provide this with None, will retrieve all comment threads.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For comment threads, this should not be more than 100.
|
||
Default is 20.
|
||
page_token(str, optional):
|
||
The token of the page of commentThreads result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.CommentThreadListResponse instance.
|
||
|
||
Returns:
|
||
CommentThreadListResponse or original data
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 100 # for commentThreads the max limit for per request is 100
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"part": enf_parts(resource="commentThreads", value=parts),
|
||
"maxResults": limit,
|
||
"textFormat": text_format,
|
||
}
|
||
|
||
if all_to_channel_id:
|
||
args["allThreadsRelatedToChannelId"] = (all_to_channel_id,)
|
||
elif channel_id:
|
||
args["channelId"] = channel_id
|
||
elif video_id:
|
||
args["videoId"] = video_id
|
||
else:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message=f"Specify at least one of all_to_channel_id, channel_id or video_id",
|
||
)
|
||
)
|
||
|
||
if moderation_status:
|
||
args["moderationStatus"] = moderation_status
|
||
if order:
|
||
args["order"] = order
|
||
if search_terms:
|
||
args["searchTerms"] = search_terms
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="commentThreads", args=args, count=count
|
||
)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return CommentThreadListResponse.from_dict(res_data)
|
||
|
||
def get_i18n_languages(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[I18nLanguageListResponse, dict]:
|
||
"""
|
||
Returns a list of application languages that the YouTube website supports.
|
||
|
||
Args:
|
||
parts:
|
||
The resource parts for i18n language you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
hl:
|
||
If provide this. Will return i18n language's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
return_json:
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.I18nLanguageListResponse instance.
|
||
|
||
Returns:
|
||
I18nLanguageListResponse or original data.
|
||
"""
|
||
|
||
args = {"hl": hl, "part": enf_parts(resource="i18nLanguages", value=parts)}
|
||
|
||
resp = self._request(resource="i18nLanguages", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return I18nLanguageListResponse.from_dict(data)
|
||
|
||
def get_i18n_regions(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[I18nRegionListResponse, dict]:
|
||
"""
|
||
Retrieve all available regions.
|
||
|
||
Args:
|
||
parts:
|
||
The resource parts for i18n region you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
hl:
|
||
If provide this. Will return i18n region's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
return_json:
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.I18nRegionListResponse instance.
|
||
Returns:
|
||
I18nRegionListResponse or origin data
|
||
"""
|
||
|
||
args = {"hl": hl, "part": enf_parts(resource="i18nRegions", value=parts)}
|
||
|
||
resp = self._request(resource="i18nRegions", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return I18nRegionListResponse.from_dict(data)
|
||
|
||
def get_members(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
mode: Optional[str] = "all_current",
|
||
count: Optional[int] = 5,
|
||
limit: Optional[int] = 5,
|
||
page_token: Optional[str] = None,
|
||
has_access_to_level: Optional[str] = None,
|
||
filter_by_member_channel_id: Optional[Union[str, list, tuple, set]] = None,
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[MemberListResponse, dict]:
|
||
"""
|
||
Retrieve a list of members for a channel.
|
||
|
||
Args:
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for member you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
mode:
|
||
The mode parameter indicates which members will be included in the API response.
|
||
Set the parameter value to one of the following values:
|
||
- all_current (default): List current members, from newest to oldest. When this value is used,
|
||
the end of the list is reached when the API response does not contain a nextPageToken.
|
||
- updates : List only members that joined or upgraded since the previous API call.
|
||
Note: The first call starts a new stream of updates but does not actually return any members.
|
||
To start retrieving the membership updates, you need to poll the endpoint using the
|
||
nextPageToken at your desired frequency.
|
||
Note that when this value is used, the API response always contains a nextPageToken.
|
||
count (int, optional):
|
||
The count will retrieve videos data.
|
||
Default is 5.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For members, this should not be more than 1000.
|
||
Default is 5.
|
||
page_token (str, optional):
|
||
The token of the page of search result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
has_access_to_level (str, optional):
|
||
The hasAccessToLevel parameter value is a level ID that specifies the minimum level
|
||
that members in the result set should have.
|
||
filter_by_member_channel_id ((str,list,tuple,set) optional):
|
||
A list of channel IDs that can be used to check the membership status of specific users.
|
||
A maximum of 100 channels can be specified per call.
|
||
return_json (bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.MemberListResponse instance.
|
||
Returns:
|
||
MemberListResponse or original data
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 1000
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"part": enf_parts(resource="members", value=parts),
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if mode:
|
||
args["mode"] = mode
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
if has_access_to_level:
|
||
args["hasAccessToLevel"] = has_access_to_level
|
||
|
||
if filter_by_member_channel_id:
|
||
args["filterByMemberChannelId"] = enf_parts(
|
||
resource="filterByMemberChannelId",
|
||
value=filter_by_member_channel_id,
|
||
check=False,
|
||
)
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="members",
|
||
args=args,
|
||
count=count,
|
||
)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return MemberListResponse.from_dict(res_data)
|
||
|
||
def get_membership_levels(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[MembershipsLevelListResponse, dict]:
|
||
"""
|
||
Retrieve membership levels for a channel
|
||
|
||
Notes:
|
||
This requires your authorization.
|
||
|
||
Args:
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for membership level you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
return_json (bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.MembershipsLevelListResponse instance.
|
||
|
||
Returns:
|
||
MembershipsLevelListResponse or original data
|
||
"""
|
||
|
||
args = {
|
||
"part": enf_parts(resource="membershipsLevels", value=parts),
|
||
}
|
||
|
||
resp = self._request(resource="membershipsLevels", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return MembershipsLevelListResponse.from_dict(data)
|
||
|
||
def get_playlist_item_by_id(
|
||
self,
|
||
*,
|
||
playlist_item_id: Union[str, list, tuple, set],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve playlist Items info by your given id
|
||
|
||
Args:
|
||
playlist_item_id ((str,list,tuple,set)):
|
||
The id for playlist item that you want to retrieve info.
|
||
You can pass this with single id str, comma-separated id str.
|
||
Or a list,tuple,set of ids.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.PlayListItemApiResponse instance.
|
||
Returns:
|
||
PlaylistItemListResponse or original data
|
||
"""
|
||
|
||
args = {
|
||
"id": enf_comma_separated("playlist_item_id", playlist_item_id),
|
||
"part": enf_parts(resource="playlistItems", value=parts),
|
||
}
|
||
|
||
resp = self._request(resource="playlistItems", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return PlaylistItemListResponse.from_dict(data)
|
||
|
||
def get_playlist_items(
|
||
self,
|
||
*,
|
||
playlist_id: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
video_id: Optional[str] = None,
|
||
count: Optional[int] = 5,
|
||
limit: Optional[int] = 5,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve playlist Items info by your given playlist id
|
||
|
||
Args:
|
||
playlist_id (str):
|
||
The id for playlist that you want to retrieve items data.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
video_id (str, Optional):
|
||
Specifies that the request should return only the playlist items that contain the specified video.
|
||
count (int, optional):
|
||
The count will retrieve playlist items data.
|
||
Default is 5.
|
||
If provide this with None, will retrieve all playlist items.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For playlistItem, this should not be more than 50.
|
||
Default is 5
|
||
page_token(str, optional):
|
||
The token of the page of playlist items result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.PlayListItemApiResponse instance.
|
||
Returns:
|
||
PlaylistItemListResponse or original data
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 50 # for playlistItems the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"playlistId": playlist_id,
|
||
"part": enf_parts(resource="playlistItems", value=parts),
|
||
"maxResults": limit,
|
||
}
|
||
if video_id is not None:
|
||
args["videoId"] = video_id
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="playlistItems", args=args, count=count
|
||
)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return PlaylistItemListResponse.from_dict(res_data)
|
||
|
||
def get_playlist_by_id(
|
||
self,
|
||
*,
|
||
playlist_id: Union[str, list, tuple, set],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve playlist data by given playlist id.
|
||
|
||
Args:
|
||
playlist_id ((str,list,tuple,set)):
|
||
The id for playlist that you want to retrieve data.
|
||
You can pass this with single id str,comma-separated id str, or list, tuple, set of id str.
|
||
parts (str, optional):
|
||
Comma-separated list of one or more playlist resource properties.
|
||
You can also pass this with list, tuple, set of part str.
|
||
If not provided. will use default public properties.
|
||
hl (str, optional):
|
||
If provide this. Will return playlist's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.PlaylistListResponse instance
|
||
Returns:
|
||
PlaylistListResponse or original data
|
||
"""
|
||
args = {
|
||
"id": enf_comma_separated("playlist_id", playlist_id),
|
||
"part": enf_parts(resource="playlists", value=parts),
|
||
"hl": hl,
|
||
}
|
||
|
||
resp = self._request(resource="playlists", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return PlaylistListResponse.from_dict(data)
|
||
|
||
def get_playlists(
|
||
self,
|
||
*,
|
||
channel_id: Optional[str] = None,
|
||
mine: Optional[bool] = None,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
count: Optional[int] = 5,
|
||
limit: Optional[int] = 5,
|
||
hl: Optional[str] = "en_US",
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve channel playlists info from youtube data api.
|
||
|
||
Args:
|
||
channel_id (str, optional):
|
||
If provide channel id, this will return pointed channel's playlist info.
|
||
mine (bool, optional):
|
||
If you have given the authorization. Will return your playlists.
|
||
Must provide the access token.
|
||
parts (str, optional):
|
||
Comma-separated list of one or more playlist resource properties.
|
||
You can also pass this with list, tuple, set of part str.
|
||
If not provided. will use default public properties.
|
||
count (int, optional):
|
||
The count will retrieve playlist data.
|
||
Default is 5.
|
||
If provide this with None, will retrieve all playlists.
|
||
limit (int, optional):
|
||
The maximum number of items each request to retrieve.
|
||
For playlist, this should not be more than 50.
|
||
Default is 5
|
||
hl (str, optional):
|
||
If provide this. Will return playlist's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
page_token(str, optional):
|
||
The token of the page of playlists result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.PlaylistListResponse instance.
|
||
Returns:
|
||
PlaylistListResponse or original data
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 50 # for playlists the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"part": enf_parts(resource="playlists", value=parts),
|
||
"hl": hl,
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if channel_id is not None:
|
||
args["channelId"] = channel_id
|
||
elif mine is not None:
|
||
args["mine"] = mine
|
||
else:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message=f"Specify at least one of channel_id,playlist_id or mine",
|
||
)
|
||
)
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="playlists", args=args, count=count
|
||
)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return PlaylistListResponse.from_dict(res_data)
|
||
|
||
def search(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
for_developer: Optional[bool] = None,
|
||
for_mine: Optional[bool] = None,
|
||
related_to_video_id: Optional[str] = None,
|
||
channel_id: Optional[str] = None,
|
||
channel_type: Optional[str] = None,
|
||
event_type: Optional[str] = None,
|
||
location: Optional[str] = None,
|
||
location_radius: Optional[str] = None,
|
||
count: Optional[int] = 10,
|
||
limit: Optional[int] = 10,
|
||
order: Optional[str] = None,
|
||
published_after: Optional[str] = None,
|
||
published_before: Optional[str] = None,
|
||
q: Optional[str] = None,
|
||
region_code: Optional[str] = None,
|
||
relevance_language: Optional[str] = None,
|
||
safe_search: Optional[str] = None,
|
||
topic_id: Optional[str] = None,
|
||
search_type: Optional[Union[str, list, tuple, set]] = None,
|
||
video_caption: Optional[str] = None,
|
||
video_category_id: Optional[str] = None,
|
||
video_definition: Optional[str] = None,
|
||
video_dimension: Optional[str] = None,
|
||
video_duration: Optional[str] = None,
|
||
video_embeddable: Optional[str] = None,
|
||
video_license: Optional[str] = None,
|
||
video_syndicated: Optional[str] = None,
|
||
video_type: Optional[str] = None,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[SearchListResponse, dict]:
|
||
"""
|
||
Main search api implementation.
|
||
You can find all parameters description at https://developers.google.com/youtube/v3/docs/search/list#parameters
|
||
|
||
Returns:
|
||
SearchListResponse or original data
|
||
"""
|
||
parts = enf_parts(resource="search", value=parts)
|
||
if search_type is None:
|
||
search_type = "video,channel,playlist"
|
||
else:
|
||
search_type = enf_comma_separated(field="search_type", value=search_type)
|
||
|
||
args = {
|
||
"part": parts,
|
||
"maxResults": min(limit, count),
|
||
}
|
||
if for_developer:
|
||
args["forDeveloper"] = for_developer
|
||
if for_mine:
|
||
args["forMine"] = for_mine
|
||
if related_to_video_id:
|
||
args["relatedToVideoId"] = related_to_video_id
|
||
if channel_id:
|
||
args["channelId"] = channel_id
|
||
if channel_type:
|
||
args["channelType"] = channel_type
|
||
if event_type:
|
||
args["eventType"] = event_type
|
||
if location:
|
||
args["location"] = location
|
||
if location_radius:
|
||
args["locationRadius"] = location_radius
|
||
if order:
|
||
args["order"] = order
|
||
if published_after:
|
||
args["publishedAfter"] = published_after
|
||
if published_before:
|
||
args["publishedBefore"] = published_before
|
||
if q:
|
||
args["q"] = q
|
||
if region_code:
|
||
args["regionCode"] = region_code
|
||
if relevance_language:
|
||
args["relevanceLanguage"] = relevance_language
|
||
if safe_search:
|
||
args["safeSearch"] = safe_search
|
||
if topic_id:
|
||
args["topicId"] = topic_id
|
||
if search_type:
|
||
args["type"] = search_type
|
||
if video_caption:
|
||
args["videoCaption"] = video_caption
|
||
if video_category_id:
|
||
args["videoCategoryId"] = video_category_id
|
||
if video_definition:
|
||
args["videoDefinition"] = video_definition
|
||
if video_dimension:
|
||
args["videoDimension"] = video_dimension
|
||
if video_duration:
|
||
args["videoDuration"] = video_duration
|
||
if video_embeddable:
|
||
args["videoEmbeddable"] = video_embeddable
|
||
if video_license:
|
||
args["videoLicense"] = video_license
|
||
if video_syndicated:
|
||
args["videoSyndicated"] = video_syndicated
|
||
if video_type:
|
||
args["videoType"] = video_type
|
||
if page_token:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(resource="search", args=args, count=count)
|
||
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return SearchListResponse.from_dict(res_data)
|
||
|
||
def search_by_keywords(
|
||
self,
|
||
*,
|
||
q: Optional[str],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
search_type: Optional[Union[str, list, tuple, set]] = None,
|
||
count: Optional[int] = 25,
|
||
limit: Optional[int] = 25,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
**kwargs: Optional[dict],
|
||
) -> Union[SearchListResponse, dict]:
|
||
"""
|
||
This is simplest usage for search api. You can only passed the keywords to retrieve data from YouTube.
|
||
And the result will include videos,playlists and channels.
|
||
|
||
Note: A call to this method has a quota cost of 100 units.
|
||
|
||
Args:
|
||
q (str):
|
||
Your keywords can also use the Boolean NOT (-) and OR (|) operators to exclude videos or
|
||
to find videos that are associated with one of several search terms. For example,
|
||
to search for videos matching either "boating" or "sailing",
|
||
set the q parameter value to boating|sailing. Similarly,
|
||
to search for videos matching either "boating" or "sailing" but not "fishing",
|
||
set the q parameter value to boating|sailing -fishing.
|
||
Note that the pipe character must be URL-escaped when it is sent in your API request.
|
||
The URL-escaped value for the pipe character is %7C.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
search_type ((str,list,tuple,set), optional):
|
||
Parameter restricts a search query to only retrieve a particular type of resource.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
The default value is video,channel,playlist
|
||
Acceptable values are:
|
||
- channel
|
||
- playlist
|
||
- video
|
||
count (int, optional):
|
||
The count will retrieve videos data.
|
||
Default is 25.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For search, this should not be more than 50.
|
||
Default is 25.
|
||
page_token (str, optional):
|
||
The token of the page of search result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.SearchListResponse instance.
|
||
kwargs:
|
||
If you want use this pass more args. You can use this.
|
||
|
||
Returns:
|
||
SearchListResponse or original data
|
||
"""
|
||
return self.search(
|
||
parts=parts,
|
||
q=q,
|
||
search_type=search_type,
|
||
count=count,
|
||
limit=limit,
|
||
page_token=page_token,
|
||
return_json=return_json,
|
||
**kwargs,
|
||
)
|
||
|
||
def search_by_developer(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]],
|
||
q: Optional[str] = None,
|
||
count: Optional[int] = 25,
|
||
limit: Optional[int] = 25,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
**kwargs,
|
||
) -> Union[SearchListResponse, dict]:
|
||
"""
|
||
Parameter restricts the search to only retrieve videos uploaded via the developer's application or website.
|
||
|
||
Args:
|
||
parts:
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
q:
|
||
Your keywords can also use the Boolean NOT (-) and OR (|) operators to exclude videos or
|
||
to find videos that are associated with one of several search terms. For example,
|
||
to search for videos matching either "boating" or "sailing",
|
||
set the q parameter value to boating|sailing. Similarly,
|
||
to search for videos matching either "boating" or "sailing" but not "fishing",
|
||
set the q parameter value to boating|sailing -fishing.
|
||
Note that the pipe character must be URL-escaped when it is sent in your API request.
|
||
The URL-escaped value for the pipe character is %7C.
|
||
count:
|
||
The count will retrieve videos data.
|
||
Default is 25.
|
||
limit:
|
||
The maximum number of items each request retrieve.
|
||
For search, this should not be more than 50.
|
||
Default is 25.
|
||
page_token:
|
||
The token of the page of search result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json:
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.SearchListResponse instance.
|
||
kwargs:
|
||
If you want use this pass more args. You can use this.
|
||
|
||
Returns:
|
||
SearchListResponse or original data
|
||
"""
|
||
return self.search(
|
||
for_developer=True,
|
||
search_type="video",
|
||
parts=parts,
|
||
q=q,
|
||
count=count,
|
||
limit=limit,
|
||
page_token=page_token,
|
||
return_json=return_json,
|
||
**kwargs,
|
||
)
|
||
|
||
def search_by_mine(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]],
|
||
q: Optional[str] = None,
|
||
count: Optional[int] = 25,
|
||
limit: Optional[int] = 25,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
**kwargs,
|
||
) -> Union[SearchListResponse, dict]:
|
||
"""
|
||
Parameter restricts the search to only retrieve videos owned by the authenticated user.
|
||
|
||
Note:
|
||
This methods can not use following parameters:
|
||
video_definition, video_dimension, video_duration, video_license,
|
||
video_embeddable, video_syndicated, video_type.
|
||
Args:
|
||
q:
|
||
Your keywords can also use the Boolean NOT (-) and OR (|) operators to exclude videos or
|
||
to find videos that are associated with one of several search terms. For example,
|
||
to search for videos matching either "boating" or "sailing",
|
||
set the q parameter value to boating|sailing. Similarly,
|
||
to search for videos matching either "boating" or "sailing" but not "fishing",
|
||
set the q parameter value to boating|sailing -fishing.
|
||
Note that the pipe character must be URL-escaped when it is sent in your API request.
|
||
The URL-escaped value for the pipe character is %7C.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
count (int, optional):
|
||
The count will retrieve videos data.
|
||
Default is 25.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For search, this should not be more than 50.
|
||
Default is 25.
|
||
page_token (str, optional):
|
||
The token of the page of search result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.SearchListResponse instance.
|
||
kwargs:
|
||
If you want use this pass more args. You can use this.
|
||
|
||
Returns:
|
||
SearchListResponse or original data
|
||
"""
|
||
return self.search(
|
||
for_mine=True,
|
||
search_type="video",
|
||
parts=parts,
|
||
q=q,
|
||
count=count,
|
||
limit=limit,
|
||
page_token=page_token,
|
||
return_json=return_json,
|
||
**kwargs,
|
||
)
|
||
|
||
def search_by_related_video(
|
||
self,
|
||
*,
|
||
related_to_video_id: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
region_code: Optional[str] = None,
|
||
relevance_language: Optional[str] = None,
|
||
safe_search: Optional[str] = None,
|
||
count: Optional[int] = 25,
|
||
limit: Optional[int] = 25,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[SearchListResponse, dict]:
|
||
"""
|
||
Retrieve a list of videos related to that video.
|
||
|
||
Args:
|
||
related_to_video_id:
|
||
A YouTube video ID which result associated with.
|
||
parts:
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
region_code:
|
||
Parameter instructs the API to return search results for videos
|
||
that can be viewed in the specified country.
|
||
relevance_language:
|
||
Parameter instructs the API to return search results that are most relevant to the specified language.
|
||
safe_search:
|
||
Parameter indicates whether the search results should include restricted content
|
||
as well as standard content.
|
||
Acceptable values are:
|
||
- moderate – YouTube will filter some content from search results and, at the least,
|
||
will filter content that is restricted in your locale. Based on their content,
|
||
search results could be removed from search results or demoted in search results.
|
||
This is the default parameter value.
|
||
- none – YouTube will not filter the search result set.
|
||
- strict – YouTube will try to exclude all restricted content from the search result set.
|
||
Based on their content, search results could be removed from search results or
|
||
demoted in search results.
|
||
count:
|
||
The count will retrieve videos data.
|
||
Default is 25.
|
||
limit:
|
||
The maximum number of items each request retrieve.
|
||
For search, this should not be more than 50.
|
||
Default is 25.
|
||
page_token:
|
||
The token of the page of search result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json:
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.SearchListResponse instance.
|
||
Returns:
|
||
If you want use this pass more args. You can use this.
|
||
"""
|
||
|
||
return self.search(
|
||
parts=parts,
|
||
related_to_video_id=related_to_video_id,
|
||
search_type="video",
|
||
region_code=region_code,
|
||
relevance_language=relevance_language,
|
||
safe_search=safe_search,
|
||
count=count,
|
||
limit=limit,
|
||
page_token=page_token,
|
||
return_json=return_json,
|
||
)
|
||
|
||
def get_subscription_by_id(
|
||
self,
|
||
*,
|
||
subscription_id: Union[str, list, tuple, set],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve subscriptions by given subscription id(s).
|
||
|
||
Note:
|
||
This need authorized access token. or you will get no data.
|
||
|
||
Args:
|
||
subscription_id ((str,list,tuple,set)):
|
||
The id for subscription that you want to retrieve data.
|
||
You can pass this with single id str, comma-separated id str, or a list,tuple,set of ids.
|
||
parts ((str,list,tuple,set), optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.SubscriptionListResponse instance.
|
||
Returns:
|
||
SubscriptionListResponse or original data.
|
||
"""
|
||
|
||
args = {
|
||
"id": enf_comma_separated(field="subscription_id", value=subscription_id),
|
||
"part": enf_parts(resource="subscriptions", value=parts),
|
||
}
|
||
|
||
resp = self._request(resource="subscriptions", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return SubscriptionListResponse.from_dict(data)
|
||
|
||
def get_subscription_by_channel(
|
||
self,
|
||
*,
|
||
channel_id: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
for_channel_id: Optional[Union[str, list, tuple, set]] = None,
|
||
order: Optional[str] = "relevance",
|
||
count: Optional[int] = 20,
|
||
limit: Optional[int] = 20,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve the specified channel's subscriptions.
|
||
|
||
Note:
|
||
The API returns a 403 (Forbidden) HTTP response code if the specified channel
|
||
does not publicly expose its subscriptions and the request is not authorized
|
||
by the channel's owner.
|
||
|
||
Args:
|
||
channel_id (str):
|
||
The id for channel which you want to get subscriptions.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for subscription you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
for_channel_id ((str,list,tuple,set) optional):
|
||
The parameter specifies a comma-separated list of channel IDs.
|
||
and will then only contain subscriptions matching those channels.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of channel ids.
|
||
order (str, optional):
|
||
The parameter specifies the method that will be used to sort resources in the API response.
|
||
Acceptable values are:
|
||
alphabetical – Sort alphabetically.
|
||
relevance – Sort by relevance.
|
||
unread – Sort by order of activity.
|
||
Default is relevance
|
||
count (int, optional):
|
||
The count will retrieve subscriptions data.
|
||
Default is 20.
|
||
If provide this with None, will retrieve all subscriptions.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For comment threads, this should not be more than 50.
|
||
Default is 20.
|
||
page_token(str, optional):
|
||
The token of the page of subscriptions result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.SubscriptionListResponse instance.
|
||
Returns:
|
||
SubscriptionListResponse or original data.
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 50 # for subscriptions the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"channelId": channel_id,
|
||
"part": enf_parts(resource="subscriptions", value=parts),
|
||
"order": order,
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if for_channel_id is not None:
|
||
args["forChannelId"] = enf_comma_separated(
|
||
field="for_channel_id", value=for_channel_id
|
||
)
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="subscriptions", args=args, count=count
|
||
)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return SubscriptionListResponse.from_dict(res_data)
|
||
|
||
def get_subscription_by_me(
|
||
self,
|
||
*,
|
||
mine: Optional[bool] = None,
|
||
recent_subscriber: Optional[bool] = None,
|
||
subscriber: Optional[bool] = None,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
for_channel_id: Optional[Union[str, list, tuple, set]] = None,
|
||
order: Optional[str] = "relevance",
|
||
count: Optional[int] = 20,
|
||
limit: Optional[int] = 20,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve your subscriptions.
|
||
|
||
Note:
|
||
This can only used in a properly authorized request.
|
||
And for me test the parameter `recent_subscriber` and `subscriber` maybe not working.
|
||
Use the `mine` first.
|
||
|
||
Args:
|
||
mine (bool, optional):
|
||
Set this parameter's value to True to retrieve a feed of the authenticated user's subscriptions.
|
||
recent_subscriber (bool, optional):
|
||
Set this parameter's value to true to retrieve a feed of the subscribers of the authenticated user
|
||
in reverse chronological order (newest first).
|
||
And this can only get most recent 1000 subscribers.
|
||
subscriber (bool, optional):
|
||
Set this parameter's value to true to retrieve a feed of the subscribers of
|
||
the authenticated user in no particular order.
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for subscription you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
for_channel_id ((str,list,tuple,set) optional):
|
||
The parameter specifies a comma-separated list of channel IDs.
|
||
and will then only contain subscriptions matching those channels.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of channel ids.
|
||
order (str, optional):
|
||
The parameter specifies the method that will be used to sort resources in the API response.
|
||
Acceptable values are:
|
||
alphabetical – Sort alphabetically.
|
||
relevance – Sort by relevance.
|
||
unread – Sort by order of activity.
|
||
Default is relevance
|
||
count (int, optional):
|
||
The count will retrieve subscriptions data.
|
||
Default is 20.
|
||
If provide this with None, will retrieve all subscriptions.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For subscriptions, this should not be more than 50.
|
||
Default is 20.
|
||
page_token(str, optional):
|
||
The token of the page of subscriptions result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.SubscriptionListResponse instance.
|
||
|
||
Returns:
|
||
SubscriptionListResponse or original data.
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 50 # for subscriptions the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"part": enf_parts(resource="subscriptions", value=parts),
|
||
"order": order,
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if mine is not None:
|
||
args["mine"] = mine
|
||
elif recent_subscriber is not None:
|
||
args["myRecentSubscribers"] = recent_subscriber
|
||
elif subscriber is not None:
|
||
args["mySubscribers"] = subscriber
|
||
else:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message=f"Must specify at least one of mine,recent_subscriber,subscriber.",
|
||
)
|
||
)
|
||
|
||
if for_channel_id is not None:
|
||
args["forChannelId"] = enf_comma_separated(
|
||
field="for_channel_id", value=for_channel_id
|
||
)
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(
|
||
resource="subscriptions", args=args, count=count
|
||
)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return SubscriptionListResponse.from_dict(res_data)
|
||
|
||
def get_video_abuse_report_reason(
|
||
self,
|
||
*,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
return_json: Optional[bool] = False,
|
||
) -> Union[VideoAbuseReportReasonListResponse, dict]:
|
||
"""
|
||
Retrieve a list of reasons that can be used to report abusive videos.
|
||
|
||
Notes:
|
||
This requires your authorization.
|
||
|
||
Args:
|
||
parts:
|
||
The resource parts for abuse reason you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
hl:
|
||
If provide this. Will return report reason's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
return_json:
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.VideoAbuseReportReasonListResponse instance.
|
||
Returns:
|
||
VideoAbuseReportReasonListResponse or original data.
|
||
"""
|
||
|
||
args = {
|
||
"part": enf_parts(resource="videoAbuseReportReasons", value=parts),
|
||
"hl": hl,
|
||
}
|
||
|
||
resp = self._request(resource="videoAbuseReportReasons", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return VideoAbuseReportReasonListResponse.from_dict(data)
|
||
|
||
def get_video_categories(
|
||
self,
|
||
*,
|
||
category_id: Optional[Union[str, list, tuple, set]] = None,
|
||
region_code: Optional[str] = None,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve video categories by category id or region code.
|
||
|
||
Args:
|
||
category_id ((str,list,tuple,set), optional):
|
||
The id for video category thread that you want to retrieve data.
|
||
You can pass this with single id str, comma-separated id str, or a list,tuple,set of ids.
|
||
region_code (str, optional):
|
||
The region code that you want to retrieve guide categories.
|
||
The parameter value is an ISO 3166-1 alpha-2 country code.
|
||
Refer: https://www.iso.org/iso-3166-country-codes.html
|
||
parts ((str,list,tuple,set) optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
hl (str, optional):
|
||
If provide this. Will return video category's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
Default is en_US.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.VideoCategoryListResponse instance.
|
||
Returns:
|
||
VideoCategoryListResponse or original data
|
||
"""
|
||
args = {
|
||
"part": enf_parts(resource="videoCategories", value=parts),
|
||
"hl": hl,
|
||
}
|
||
|
||
if category_id is not None:
|
||
args["id"] = enf_comma_separated(field="category_id", value=category_id)
|
||
elif region_code is not None:
|
||
args["regionCode"] = region_code
|
||
else:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.MISSING_PARAMS,
|
||
message="Specify at least one of category_id or region_code",
|
||
)
|
||
)
|
||
|
||
resp = self._request(resource="videoCategories", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return VideoCategoryListResponse.from_dict(data)
|
||
|
||
def get_video_by_id(
|
||
self,
|
||
*,
|
||
video_id: Union[str, list, tuple, set],
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
max_height: Optional[int] = None,
|
||
max_width: Optional[int] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve video data by given video id.
|
||
|
||
Args:
|
||
video_id ((str,list,tuple,set)):
|
||
The id for video that you want to retrieve data.
|
||
You can pass this with single id str, comma-separated id str, or a list,tuple,set of ids.
|
||
parts ((str,list,tuple,set), optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
hl (str, optional):
|
||
If provide this. Will return video's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
max_height (int, optional):
|
||
Specifies the maximum height of the embedded player returned in the player.embedHtml property.
|
||
Acceptable values are 72 to 8192, inclusive.
|
||
max_width (int, optional):
|
||
Specifies the maximum width of the embedded player returned in the player.embedHtml property.
|
||
Acceptable values are 72 to 8192, inclusive.
|
||
If provide max_height at the same time. This will may be shorter than max_height.
|
||
For more https://developers.google.com/youtube/v3/docs/videos/list#parameters.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.VideoListResponse instance.
|
||
|
||
Returns:
|
||
VideoListResponse or original data
|
||
"""
|
||
|
||
args = {
|
||
"id": enf_comma_separated(field="video_id", value=video_id),
|
||
"part": enf_parts(resource="videos", value=parts),
|
||
"hl": hl,
|
||
}
|
||
if max_height is not None:
|
||
args["maxHeight"] = max_height
|
||
if max_width is not None:
|
||
args["maxWidth"] = max_width
|
||
|
||
resp = self._request(resource="videos", method="GET", args=args)
|
||
data = self._parse_response(resp)
|
||
|
||
if return_json:
|
||
return data
|
||
else:
|
||
return VideoListResponse.from_dict(data)
|
||
|
||
def get_videos_by_chart(
|
||
self,
|
||
*,
|
||
chart: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
max_height: Optional[int] = None,
|
||
max_width: Optional[int] = None,
|
||
region_code: Optional[str] = None,
|
||
category_id: Optional[str] = "0",
|
||
count: Optional[int] = 5,
|
||
limit: Optional[int] = 5,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve a list of YouTube's most popular videos.
|
||
|
||
Args:
|
||
chart (str):
|
||
The chart string for you want to retrieve data.
|
||
Acceptable values are: mostPopular
|
||
parts ((str,list,tuple,set), optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
hl (str, optional):
|
||
If provide this. Will return playlist's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
max_height (int, optional):
|
||
Specifies the maximum height of the embedded player returned in the player.embedHtml property.
|
||
Acceptable values are 72 to 8192, inclusive.
|
||
max_width (int, optional):
|
||
Specifies the maximum width of the embedded player returned in the player.embedHtml property.
|
||
Acceptable values are 72 to 8192, inclusive.
|
||
If provide max_height at the same time. This will may be shorter than max_height.
|
||
For more https://developers.google.com/youtube/v3/docs/videos/list#parameters.
|
||
region_code (str, optional):
|
||
This parameter instructs the API to select a video chart available in the specified region.
|
||
Value is an ISO 3166-1 alpha-2 country code.
|
||
category_id (str, optional):
|
||
The id for video category that you want to filter.
|
||
Default is 0.
|
||
count (int, optional):
|
||
The count will retrieve videos data.
|
||
Default is 5.
|
||
If provide this with None, will retrieve all videos.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For videos, this should not be more than 50.
|
||
Default is 5.
|
||
page_token(str, optional):
|
||
The token of the page of videos result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.PlaylistListResponse instance.
|
||
|
||
Returns:
|
||
VideoListResponse or original data
|
||
"""
|
||
|
||
if count is None:
|
||
limit = 50 # for videos the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"chart": chart,
|
||
"part": enf_parts(resource="videos", value=parts),
|
||
"hl": hl,
|
||
"maxResults": limit,
|
||
"videoCategoryId": category_id,
|
||
}
|
||
if max_height is not None:
|
||
args["maxHeight"] = max_height
|
||
if max_width is not None:
|
||
args["maxWidth"] = max_width
|
||
if region_code:
|
||
args["regionCode"] = region_code
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(resource="videos", args=args, count=count)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return VideoListResponse.from_dict(res_data)
|
||
|
||
def get_videos_by_myrating(
|
||
self,
|
||
*,
|
||
rating: str,
|
||
parts: Optional[Union[str, list, tuple, set]] = None,
|
||
hl: Optional[str] = "en_US",
|
||
max_height: Optional[int] = None,
|
||
max_width: Optional[int] = None,
|
||
count: Optional[int] = 5,
|
||
limit: Optional[int] = 5,
|
||
page_token: Optional[str] = None,
|
||
return_json: Optional[bool] = False,
|
||
):
|
||
"""
|
||
Retrieve video data by my ration.
|
||
|
||
Args:
|
||
rating (str):
|
||
The rating string for you to retrieve data.
|
||
Acceptable values are: dislike, like
|
||
parts ((str,list,tuple,set), optional):
|
||
The resource parts for you want to retrieve.
|
||
If not provide, use default public parts.
|
||
You can pass this with single part str, comma-separated parts str or a list,tuple,set of parts.
|
||
hl (str, optional):
|
||
If provide this. Will return video's language localized info.
|
||
This value need https://developers.google.com/youtube/v3/docs/i18nLanguages.
|
||
max_height (int, optional):
|
||
Specifies the maximum height of the embedded player returned in the player.embedHtml property.
|
||
Acceptable values are 72 to 8192, inclusive.
|
||
max_width (int, optional):
|
||
Specifies the maximum width of the embedded player returned in the player.embedHtml property.
|
||
Acceptable values are 72 to 8192, inclusive.
|
||
If provide max_height at the same time. This will may be shorter than max_height.
|
||
For more https://developers.google.com/youtube/v3/docs/videos/list#parameters.
|
||
count (int, optional):
|
||
The count will retrieve videos data.
|
||
Default is 5.
|
||
If provide this with None, will retrieve all videos.
|
||
limit (int, optional):
|
||
The maximum number of items each request retrieve.
|
||
For videos, this should not be more than 50.
|
||
Default is 5.
|
||
page_token(str, optional):
|
||
The token of the page of videos result to retrieve.
|
||
You can use this retrieve point result page directly.
|
||
And you should know about the the result set for YouTube.
|
||
return_json(bool, optional):
|
||
The return data type. If you set True JSON data will be returned.
|
||
False will return a pyyoutube.VideoListResponse instance.
|
||
Returns:
|
||
VideoListResponse or original data
|
||
"""
|
||
|
||
if self._access_token is None:
|
||
raise PyYouTubeException(
|
||
ErrorMessage(
|
||
status_code=ErrorCode.NEED_AUTHORIZATION,
|
||
message="This method can only used with authorization",
|
||
)
|
||
)
|
||
|
||
if count is None:
|
||
limit = 50 # for videos the max limit for per request is 50
|
||
else:
|
||
limit = min(count, limit)
|
||
|
||
args = {
|
||
"myRating": rating,
|
||
"part": enf_parts(resource="videos", value=parts),
|
||
"hl": hl,
|
||
"maxResults": limit,
|
||
}
|
||
|
||
if max_height is not None:
|
||
args["maxHeight"] = max_height
|
||
if max_width is not None:
|
||
args["maxWidth"] = max_width
|
||
|
||
if page_token is not None:
|
||
args["pageToken"] = page_token
|
||
|
||
res_data = self.paged_by_page_token(resource="videos", args=args, count=count)
|
||
if return_json:
|
||
return res_data
|
||
else:
|
||
return VideoListResponse.from_dict(res_data)
|