Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(channel): ✨ support get channel by channel handle #170

Merged
merged 4 commits into from
Feb 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

All notable changes to this project will be documented in this file.


## Version 0.9.4 (development)

### What's New

- Add new parameter `for_handle` to get channel by handle.


## Version 0.9.3 (2023-11-22)

### What's New
Expand Down
10 changes: 9 additions & 1 deletion pyyoutube/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ def get_channel_info(
self,
*,
channel_id: Optional[Union[str, list, tuple, set]] = None,
for_handle: Optional[str] = None,
for_username: Optional[str] = None,
mine: Optional[bool] = None,
parts: Optional[Union[str, list, tuple, set]] = None,
Expand All @@ -744,6 +745,11 @@ def get_channel_info(
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_handle (str, optional):
The parameter specifies a YouTube handle, thereby requesting the channel associated with that handle.
The parameter value can be prepended with an @ symbol. For example, to retrieve the resource for
the "Google for Developers" channel, set the forHandle parameter value to
either GoogleDevelopers or @GoogleDevelopers.
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.
Expand All @@ -768,7 +774,9 @@ def get_channel_info(
"part": enf_parts(resource="channels", value=parts),
"hl": hl,
}
if for_username is not None:
if for_handle is not None:
args["forHandle"] = for_handle
elif for_username is not None:
args["forUsername"] = for_username
elif channel_id is not None:
args["id"] = enf_comma_separated("channel_id", channel_id)
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
New Client for YouTube API
"""

import inspect
import json
from typing import List, Optional, Tuple, Union
Expand Down
7 changes: 4 additions & 3 deletions pyyoutube/media.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Media object to upload.
"""

import mimetypes
import os
from typing import IO, Optional, Tuple
Expand Down Expand Up @@ -180,9 +181,9 @@ def next_chunk(self) -> Tuple[Optional[MediaUploadProgress], Optional[dict]]:
# sending "bytes 0--1/0" results in an invalid request
# Only add header "Content-Range" if chunk_end != -1
if chunk_end != -1:
headers[
"Content-Range"
] = f"bytes {self.resumable_progress}-{chunk_end}/{size}"
headers["Content-Range"] = (
f"bytes {self.resumable_progress}-{chunk_end}/{size}"
)

resp = self.client.request(
path=self.resumable_uri,
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/models/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
These are category related models.
Include VideoCategory
"""

from dataclasses import dataclass, field
from typing import List, Optional

Expand Down
1 change: 1 addition & 0 deletions pyyoutube/models/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

References: https://developers.google.com/youtube/v3/docs/channels#properties
"""

from dataclasses import dataclass, field
from typing import List, Optional

Expand Down
3 changes: 1 addition & 2 deletions pyyoutube/models/channel_section.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,4 @@ class ChannelSectionResponse(BaseApiResponse):


@dataclass
class ChannelSectionListResponse(ChannelSectionResponse):
...
class ChannelSectionListResponse(ChannelSectionResponse): ...
1 change: 1 addition & 0 deletions pyyoutube/models/comment_thread.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
These are comment threads related models.
"""

from dataclasses import dataclass, field
from typing import Optional, List

Expand Down
1 change: 1 addition & 0 deletions pyyoutube/models/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
These are common models for multi resource.
"""

from dataclasses import dataclass, field
from typing import Optional, List

Expand Down
1 change: 1 addition & 0 deletions pyyoutube/models/mixins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
These are some mixin for models
"""

import datetime
from typing import Optional

Expand Down
1 change: 1 addition & 0 deletions pyyoutube/models/playlist.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
These are playlist related models.
"""

from dataclasses import dataclass, field
from typing import Optional, List

Expand Down
1 change: 1 addition & 0 deletions pyyoutube/models/search_result.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
These are search result related models.
"""

from dataclasses import dataclass, field
from typing import Optional, List

Expand Down
1 change: 1 addition & 0 deletions pyyoutube/models/video.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
These are video related models.
"""

from dataclasses import dataclass, field
from typing import Optional, List

Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/activities.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Activities resource implementation
"""

from typing import Optional, Union

from pyyoutube.error import PyYouTubeException, ErrorMessage, ErrorCode
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/base_resource.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Base resource class.
"""

from typing import Optional, TYPE_CHECKING

if TYPE_CHECKING:
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/captions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Captions resource implementation
"""

from typing import Optional, Union

from requests import Response
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/channel_banners.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Channel banners resource implementation.
"""

from typing import Optional

from pyyoutube.resources.base_resource import Resource
Expand Down
11 changes: 10 additions & 1 deletion pyyoutube/resources/channels.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Channel resource implementation.
"""

from typing import Optional, Union

from pyyoutube.error import PyYouTubeException, ErrorMessage, ErrorCode
Expand All @@ -18,6 +19,7 @@ class ChannelsResource(Resource):
def list(
self,
parts: Optional[Union[str, list, tuple, set]] = None,
for_handle: Optional[str] = None,
for_username: Optional[str] = None,
channel_id: Optional[Union[str, list, tuple, set]] = None,
managed_by_me: Optional[bool] = None,
Expand All @@ -36,6 +38,11 @@ def list(
Comma-separated list of one or more channel resource properties.
Accepted values: id,auditDetails,brandingSettings,contentDetails,contentOwnerDetails,
localizations,snippet,statistics,status,topicDetails
for_handle:
The parameter specifies a YouTube handle, thereby requesting the channel associated with that handle.
The parameter value can be prepended with an @ symbol. For example, to retrieve the resource for
the "Google for Developers" channel, set the forHandle parameter value to
either GoogleDevelopers or @GoogleDevelopers.
for_username:
The parameter specifies a YouTube username, thereby requesting
the channel associated with that username.
Expand Down Expand Up @@ -90,7 +97,9 @@ def list(
"pageToken": page_token,
**kwargs,
}
if for_username is not None:
if for_handle is not None:
params["forHandle"] = for_handle
elif for_username is not None:
params["forUsername"] = for_username
elif channel_id is not None:
params["id"] = enf_comma_separated(field="channel_id", value=channel_id)
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/comment_threads.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Comment threads resource implementation.
"""

from typing import Optional, Union

from pyyoutube.error import PyYouTubeException, ErrorMessage, ErrorCode
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/membership_levels.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Membership levels resource implementation.
"""

from typing import Optional, Union

from pyyoutube.models import MembershipsLevelListResponse
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/search.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Search resource implementation.
"""

from typing import Optional, Union

from pyyoutube.resources.base_resource import Resource
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/thumbnails.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Thumbnails resources implementation.
"""

from typing import Optional

from pyyoutube.resources.base_resource import Resource
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/video_abuse_report_reasons.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Video abuse report reasons resource implementation.
"""

from typing import Optional, Union

from pyyoutube.resources.base_resource import Resource
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/resources/watermarks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Watermarks resource implementation.
"""

from typing import Optional, Union

from pyyoutube.resources.base_resource import Resource
Expand Down
1 change: 1 addition & 0 deletions pyyoutube/utils/params_checker.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
function's params checker.
"""

import logging

from typing import Optional, Union
Expand Down
2 changes: 1 addition & 1 deletion testdata/apidata/channel_info_single.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"snippet": {
"title": "Google Developers",
"description": "The Google Developers channel features talks from events, educational series, best practices, tips, and the latest updates across our products and platforms.",
"customUrl": "googledevelopers",
"customUrl": "@googledevelopers",
"publishedAt": "2007-08-23T00:34:43.000Z",
"thumbnails": {
"default": {
Expand Down
8 changes: 8 additions & 0 deletions tests/apis/test_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ def testGetChannelInfo(self) -> None:
)
self.assertEqual(res_by_channel_id.items[0].id, "UC_x5XG1OV2P6uZZ5FSM9Ttw")

res_by_channel_handle = self.api.get_channel_info(
for_handle="googledevelopers", return_json=True
)
self.assertEqual(
res_by_channel_handle["items"][0]["snippet"]["customUrl"],
"@googledevelopers",
)

res_by_channel_name = self.api.get_channel_info(
for_username="GoogleDevelopers", return_json=True
)
Expand Down
1 change: 1 addition & 0 deletions tests/clients/test_captions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Tests for captions resources.
"""

import io

import pytest
Expand Down
1 change: 1 addition & 0 deletions tests/clients/test_channel_banners.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Tests for channel banners
"""

import io

from .base import BaseTestCase
Expand Down
6 changes: 6 additions & 0 deletions tests/clients/test_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ def test_list(self, helpers, authed_cli, key_cli):
assert res.items[0].id == self.channel_id
assert key_cli.channels.api_key == "api key"

res = key_cli.channels.list(
parts="id,snippet",
for_handle="@googledevelopers",
)
assert res.items[0].snippet.customUrl == "@googledevelopers"

res = key_cli.channels.list(
parts=["id", "snippet"], for_username="googledevelopers"
)
Expand Down
1 change: 1 addition & 0 deletions tests/clients/test_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Tests for client.
"""

import pytest

import responses
Expand Down
1 change: 1 addition & 0 deletions tests/clients/test_media.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Tests for media upload.
"""

import io

import pytest
Expand Down
1 change: 1 addition & 0 deletions tests/clients/test_thumbnails.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Tests for thumbnails.
"""

import io

from .base import BaseTestCase
Expand Down
Loading