├── .gitignore ├── MANIFEST.in ├── PKG-INFO ├── README.md ├── requirements.txt ├── setup.cfg ├── setup.py └── youtube ├── __init__.py ├── api.py └── exceptions.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | /youtube_python.egg-info 4 | /dist -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt -------------------------------------------------------------------------------- /PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.1 2 | Name: youtube-python 3 | Version: 1.0.13 4 | Summary: Python Youtube Data API v3 5 | Home-page: https://github.com/rohitkhatri/youtube-python 6 | Author: Rohit Khatri 7 | Author-email: developer.rohitkhatri@gmail.com 8 | License: GPL 9 | Description: # youtube-python 10 | =================== 11 | #### Python - Youtube Data API v3 12 | 13 | **youtube-python** is a simple client for youtube api. It uses [Youtube Data API v3](https://developers.google.com/youtube/v3/). 14 | 15 | ## Installation 16 | ``` 17 | sudo pip install youtube-python 18 | ``` 19 | 20 | ## Using 21 | ```python 22 | from youtube import YouTube 23 | api = youtube.YouTube(api_key='') 24 | ``` 25 | 26 | ## References https://developers.google.com/youtube/v3/docs/videos 27 | ```python 28 | video = api.get('videos', id='B7FJV9KIn58') 29 | ``` 30 | 31 | ## References https://developers.google.com/youtube/v3/docs/channels/list 32 | ```python 33 | video = api.get('channels', id='UCLFZ5qAH-l_WiRd_EOzX2og') 34 | ``` 35 | 36 | 37 | ## Contributing 38 | [https://github.com/rohitkhatri/youtube-python](https://github.com/rohitkhatri/youtube-python) 39 | 40 | ## Youtube Data API v3 41 | [Youtube Data API v3 Doc](https://developers.google.com/youtube/v3/) 42 | 43 | Keywords: youtube data api python v3 44 | Platform: UNKNOWN 45 | Classifier: Development Status :: 4 - Beta 46 | Classifier: Intended Audience :: Developers 47 | Classifier: Operating System :: OS Independent 48 | Classifier: Programming Language :: Python :: 3.5 49 | Classifier: Operating System :: OS Independent 50 | Classifier: Topic :: Software Development :: Libraries :: Python Modules 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # youtube-python 2 | =================== 3 | #### Python - Youtube Data API v3 4 | 5 | **youtube-python** is a simple client for youtube api. It uses [Youtube Data API v3](https://developers.google.com/youtube/v3/). 6 | 7 | ## Installation 8 | ``` 9 | sudo pip install youtube-python 10 | ``` 11 | 12 | ## Using 13 | ```python 14 | from youtube import API 15 | api = API(client_id='', client_secret='', api_key='', access_token='optional') 16 | ``` 17 | 18 | ## References https://developers.google.com/youtube/v3/docs/videos 19 | ```python 20 | video = api.get('videos', id='B7FJV9KIn58') 21 | ``` 22 | 23 | ## References https://developers.google.com/youtube/v3/docs/channels/list 24 | ```python 25 | video = api.get('channels', id='UCLFZ5qAH-l_WiRd_EOzX2og') 26 | ``` 27 | 28 | 29 | ## Contributing 30 | [https://github.com/rohitkhatri/youtube-python](https://github.com/rohitkhatri/youtube-python) 31 | 32 | ## Youtube Data API v3 33 | [Youtube Data API v3 Doc](https://developers.google.com/youtube/v3/) 34 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.12.1 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 3 | 4 | [egg_info] 5 | tag_build = 6 | tag_date = 0 7 | 8 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | except ImportError: 4 | from distutils.core import setup 5 | 6 | try: 7 | long_description = open('README.md').read() 8 | except IOError: 9 | long_description = "" 10 | 11 | setup( 12 | name='youtube-python', 13 | version='1.0.13', 14 | description='Python Youtube Data API v3', 15 | long_description=long_description, 16 | url='https://github.com/rohitkhatri/youtube-python', 17 | author='Rohit Khatri', 18 | author_email='developer.rohitkhatri@gmail.com', 19 | license='GPL', 20 | classifiers=[ 21 | "Development Status :: 4 - Beta", 22 | "Intended Audience :: Developers", 23 | "Operating System :: OS Independent", 24 | 'Programming Language :: Python :: 3.5', 25 | "Operating System :: OS Independent", 26 | 'Topic :: Software Development :: Libraries :: Python Modules' 27 | ], 28 | keywords="youtube data api python v3", 29 | packages=['youtube'], 30 | install_requires=['requests'] 31 | ) 32 | -------------------------------------------------------------------------------- /youtube/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '1.0.13' 2 | __author__ = 'Rohit Khatri' 3 | __license__ = 'MIT' 4 | 5 | 6 | from youtube.exceptions import * 7 | from youtube.api import API 8 | -------------------------------------------------------------------------------- /youtube/api.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from urllib.parse import urlencode 3 | from youtube.exceptions import YouTubeException 4 | 5 | 6 | class API: 7 | _client_id = None 8 | _client_secret = None 9 | _api_key = None 10 | _access_token = None 11 | _api_base_url = 'https://www.googleapis.com/youtube/v3/' 12 | _auth_url = 'https://accounts.google.com/o/oauth2/auth' 13 | _exchange_code_url = 'https://accounts.google.com/o/oauth2/token' 14 | _scope = [ 15 | 'https://www.googleapis.com/auth/youtube', 16 | 'https://www.googleapis.com/auth/userinfo.profile' 17 | ] 18 | _part = 'id,snippet' 19 | 20 | def __init__(self, client_id, client_secret, api_key, access_token=None, api_url=None): 21 | self._client_id = client_id 22 | self._client_secret = client_secret 23 | self._api_key = api_key 24 | self._access_token = access_token 25 | 26 | if api_url: 27 | self.api_url = api_url 28 | 29 | def get(self, endpoint, **kwargs): 30 | if self._access_token: 31 | kwargs['access_token'] = self._access_token 32 | else: 33 | kwargs['key'] = self._api_key 34 | 35 | if 'part' not in kwargs: 36 | kwargs['part'] = self._part 37 | 38 | return self.response(self._get(self._api_base_url+endpoint, params=kwargs)) 39 | 40 | def post(self, endpoint, **kwargs): 41 | if self._access_token: 42 | kwargs['access_token'] = self._access_token 43 | else: 44 | kwargs['key'] = self._api_key 45 | 46 | return self.response(self._post(self._api_base_url + endpoint, params=kwargs)) 47 | 48 | def get_auth_url(self, redirect_uri, **kwargs): 49 | kwargs = {**{ 50 | 'response_type': 'code', 51 | 'redirect_uri': redirect_uri, 52 | 'client_id': self._client_id, 53 | 'access_type': 'offline', 54 | 'approval_prompt': 'force' 55 | }, **kwargs} 56 | 57 | if 'scope' not in kwargs: 58 | kwargs['scope'] = self._scope 59 | 60 | kwargs['scope'] = ' '.join(kwargs['scope']) 61 | 62 | return self._auth_url+'?'+urlencode(kwargs) 63 | 64 | def exchange_code(self, code, redirect_uri): 65 | params = { 66 | 'code': code, 'client_id': self._client_id, 'client_secret': self._client_secret, 67 | 'redirect_uri': redirect_uri, 'grant_type': 'authorization_code' 68 | } 69 | headers = {'Content-Type': 'application/x-www-form-urlencoded'} 70 | response = self.response(self._post(self._exchange_code_url, params=params, headers=headers)) 71 | 72 | if response and 'access_token' in response: 73 | self._access_token = response['access_token'] 74 | 75 | return response 76 | 77 | def refresh_token(self, refresh_token): 78 | params = { 79 | 'client_id': self._client_id, 'client_secret': self._client_secret, 'refresh_token': refresh_token, 80 | 'grant_type': 'refresh_token' 81 | } 82 | headers = {'Content-Type': 'application/x-www-form-urlencoded'} 83 | response = self.response(self._post(self._exchange_code_url, params=params, headers=headers)) 84 | 85 | if response and 'access_token' in response: 86 | self._access_token = response['access_token'] 87 | 88 | return response 89 | 90 | def get_profile(self): 91 | return self.response(self._get( 92 | 'https://www.googleapis.com/oauth2/v1/userinfo', 93 | {'access_token': self._access_token} 94 | )) 95 | 96 | @staticmethod 97 | def _get(url, params=None, **kwargs): 98 | result = requests.get(url, params=params, **kwargs) 99 | _response = result.json() 100 | 101 | if _response and 'error' in _response: 102 | raise YouTubeException(_response['error']['code'], _response['error']['message'], result) 103 | 104 | if result.status_code != 200: 105 | raise YouTubeException(result.status_code, result.reason, result) 106 | 107 | return result 108 | 109 | @staticmethod 110 | def _post(url, params=None, **kwargs): 111 | result = requests.post(url, data=params, **kwargs) 112 | _response = result.json() 113 | 114 | if _response and 'error' in _response: 115 | if isinstance(_response['error'], str): 116 | raise YouTubeException(result.status_code, _response['error'], result) 117 | else: 118 | raise YouTubeException(_response['error']['code'], _response['error']['message'], result) 119 | 120 | if result.status_code != 200: 121 | raise YouTubeException(result.status_code, result.reason, result) 122 | 123 | return result 124 | 125 | @staticmethod 126 | def response(response): 127 | return response.json() 128 | -------------------------------------------------------------------------------- /youtube/exceptions.py: -------------------------------------------------------------------------------- 1 | class YouTubeException(Exception): 2 | def __init__(self, code, message, response): 3 | self.status_code = code 4 | self.error_type = message 5 | self.message = message 6 | self.response = response 7 | self.get_error_type() 8 | 9 | def get_error_type(self): 10 | json_response = self.response.json() 11 | 12 | if 'error' in json_response and 'errors' in json_response['error']: 13 | self.error_type = json_response['error']['errors'][0]['reason'] 14 | --------------------------------------------------------------------------------