✕
用 Python
帶你輕鬆玩 KKBOX Open API
John Liu 劉炘武
- Partner Engineer @
- 協助Partner介接KKBOX服務
- 撰寫文件及Sample Code
- Linux and Vim lover
- <3 Python
@johnliu55tw
在開始之前…
-
不要客氣,請隨時發問
-
已安裝 Python ≥ 3
-
已安裝 pip
-
安裝 pipenv
-
$ pip install pipenv
-
-
git clone https://github.com/johnliu55tw/InnovationChat-20
-
投影片連結:https://goo.gl/GtAc8o
-
Wifi: 'K_Square_guest', '12345678'
Agenda
- 為什麼是 Python?
- 探索KKBOX Open API
- KKBOX Open API 認證機制
- Let's code!
- 使用Search API,使用 Python
- 串接KKBOX Widget
- Playlist Search web app
- Summary
為什麼是 Python?
- 因為我喜歡。
- 語法乾淨,像在寫英文
- IPython rocks!
- 多種編程範型 (Programming Paradigms)
- OOP、Functional
- 內建 Asynchronous IO (Since 3.4)
- 資料科學及大數據模組
探索KKBOX Open API
- 取得 KKBOX 平台的高品質音樂資料
- 歌手、專輯、歌曲
- 排行榜、電台、主題歌單
- HTTP RESTful API
- JSON 編碼
What is KKBOX Open API?
探索KKBOX Open API
- 教學及文件
- API Reference
- SDKs
- API Console
- 開發者作品集
- 使用條款
- …
KKBOX Open API 認證機制
- 所有 Endpoints 都需要認證
- OAuth 2.0 - Client Credentials Flow
- Client 使用 ID 及 Secret 向認證伺服器請求認證
- 認證伺服器核發 Access Token 給Client
- Client 使用 Access Token 向 KKBOX Open API 請求資源
- 一旦 Access Token 過期,必須重新要求 Access Token
Client Credentials
-
Client ID
-
Client Secret
KKBOX Open API 認證機制
KKBOX Open API 認證機制
from kkbox_developer_sdk.auth_flow import KKBOXOAuth
# Replace CLIENT_ID and CLIENT_SECRET with yours
auth = KKBOXOAuth(CLIENT_ID, CLIENT_SECRET)
token = auth.fetch_access_token_by_client_credentials()
print(token.access_token)
BQfUdNXcFWiTliaSiTovbQ==
使用 SDK 取得Access Token
$ pip install kkbox_developer_sdk
KKBOX Open API 認證機制
Token access helper function
import pickle
def get_token(token_file, client_id, client_secret):
"""Helper function for getting the token.
If the specified file exists, try to load it with pickle.
Else use the given client ID and Secret to request a token.
"""
if path.exists(token_file):
with open(token_file, 'rb') as f:
return pickle.load(f)
else:
auth = KKBOXOAuth(client_id, client_secret)
token = auth.fetch_access_token_by_client_credentials()
with open(token_file, 'wb') as f:
pickle.dump(token, f)
return token
Let's code 1: 使用Search API
目標:搜尋與「運動」有關的歌單
- 請求方法及 URL
- 資源 ID
- Query 參數
- 資料回傳格式
Let's code 1: 使用Search API
目標:搜尋與「運動」有關的歌單
from kkbox_developer_sdk.api import KKBOXAPI
kkboxapi = KKBOXAPI(token)
search_results = kkboxapi.search_fetcher.search(
'運動',
types=['playlist'],
terr='TW')
playlists = search_results['playlists']['data']
first = playlists[0]
from pprint import pprint
pprint(first, depth=2)
目標:搜尋與「運動」有關的歌單
{'description': '在做有氧運動時...'
'id': 'KnqLLVliEedzFEen54',
'images': [{...}, {...}, {...}],
'owner': {'description': 'House是現今流行樂壇中最重要的樂種...',
'id': 'DZHpWKlqBsC81LL8oy',
'images': [...],
'name': 'DJ Rainbowchild',
'url': 'https://www.kkbox.com/tw/profile/DZHpWKlqBsC81LL8oy'},
'title': '世大運動一動:有氧運動專用勸世舞曲(8.11更新)',
'updated_at': '2017-08-11T12:51:22+00:00',
'url': 'https://event.kkbox.com/content/playlist/KnqLLVliEedzFEen54'}
Let's code 1: 使用Search API
Playlist search helper function
def search_playlists(token, keyword):
"""Search playlists using the given keyword.
This function returns a list of playlist object directly.
"""
kkboxapi = KKBOXAPI(token)
data = kkboxapi.search_fetcher.search(
keyword,
types=['playlist'],
terr='TW')
return data['playlists']['data']
Let's code 1: 使用Search API
Let's code 2: KKBOX Widget
-
id
-
type
-
terr
-
lang
-
autoplay
-
loop
https://widget.kkbox.com/v1/?param1=value¶m2=value
<iframe width="320" height="470"
src="https://widget.kkbox.com/v1/?id=KnqLLVliEedzFEen54&type=playlist"
</iframe>
Embed with <iframe>
Let's code 2: KKBOX Widget
Let's code 3: Playlist Search
-
播放清單搜尋器
-
Python + Flask + Jinja2 HTML template engine
-
No JavaScript!
Jinja2 HTML Template - Form
<div class="w-100 mb-3">
<form action="/" method="get">
<div class="input-group">
<input type="text" name="question" class="form-control"
placeholder="Ask me something about music...">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="submit">
Search
</button>
</div>
</div>
</form>
</div>
Let's code 3: Playlist Search
Jinja2 HTML Template - Search History
<div class="w-100 mb-3 border border-info rounded"
style="height: 80px; overflow: scroll;">
<ul>
{% for record in search_history|reverse %}
<li><b>{{ record.q }}</b>:
{% if record.id %}
<a target="_blank"
href="https://www.kkbox.com/tw/tc/playlist/{{ record.id }}">
{{ record.title }}
</a>
{% else %}
<span>Found nothing...</span>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
Let's code 3: Playlist Search
Jinja2 HTML Template - Widget
<div class="d-flex justify-content-center">
{% if playlist_id %}
<iframe width="320" height="470" frameborder="0" scrolling="no"
src="https://widget.kkbox.com/v1/?id={{playlist_id}}&type=playlist&terr=tw&lang=tc&autoplay=true&loop=true">
</iframe>
{% endif %}
</div>
Let's code 3: Playlist Search
Flask Application
-
Configurations
-
SECRET_KEY
-
TOKEN_FILE
-
KKBOX_CLIENT_ID
-
KKBOX_CLIENT_SECRET
-
-
Endpoints
-
GET /
-
GET /?question=<value>
-
Let's code 3: Playlist Search
Flask Application - Configurations
Let's code 3: Playlist Search
app.config.update(SECRET_KEY=urandom(24),
KKBOX_CLIENT_ID='The Client ID',
KKBOX_CLIENT_SECRET='The Client Secret',
TOKEN_FILE='./token.pkl')
Flask Application - Endpoints
@app.route('/', methods=['GET'])
def index():
history = session.setdefault('history', list())
question = request.args.get('question')
if question:
token = get_token(app.config['TOKEN_FILE'],
app.config['KKBOX_CLIENT_ID'],
app.config['KKBOX_CLIENT_SECRET'])
results = search_playlists(token, question)
record = {'q': question,
'title': results[0]['title'] if results else None,
'id': results[0]['id'] if results else None}
history.append(record)
# Manually set to True since list.append won't be a update.
session.modified = True
return render_template('index.html',
search_history=history,
playlist_id=record['id'])
else:
return render_template('index.html',
search_history=history)
Let's code 3: Playlist Search
Summary
- 探索KKBOX Open API - KKBOX 開發者網站
- KKBOX Open API 認證機制
- 使用KKBOX Python SDK
- 使用KKBOX HTML Widget
- 在Web app中使用KKBOX Open API
Thank you!
用 Python,帶你輕鬆玩 KKBOX Open API
By Hsin-Wu Liu (John)
用 Python,帶你輕鬆玩 KKBOX Open API
用 Python,帶你輕鬆玩 KKBOX Open API
- 2,342