5月11日に札幌で開催されたPyCon mini Sapporo 2019で登壇した。
PyCon mini Sapporo 2019 札幌市産業
— PyCon mini Sapporo 2019 (@pyconminisap) May 11, 2019
13:35A 「Simple-Spotify: Pythonでシンプルに楽曲データを扱うライブラリ」by @NaoY_py 横山 直敬 氏#pyconsap pic.twitter.com/vprg2vF3xS
写真撮る人がめっちゃ上手くて影とかいい感じになっててすごい。正装(オサカナTシャツ)もばっちり写っている。
テーマは3ヶ月くらい前から作っていたSpotify Web APIのラッパーライブラリSimple-Spotify。懇親会ではUKロック好きな@shinyorkeとSimple-Spotifyのいい感じな使い方の話で盛り上がった。興味を持ってもらえてとても嬉しかった。
Spotify Web APIのラッパーライブラリとしてはSpotipyがあるが、requests
に依存しているそれとは異なりSimple-SpotifyはPure Pythonで実装している。
また、SpotipyがAPIのレスポンスを辞書形式で扱っているのに対してSimple-Spotifyではクラスとして扱っている。
Simple-SpotifyとSpotipyの違いを見比べてみる。ここからは発表にはない話になる。
Spotipy
import spotipy sp = spotipy.Spotify() results = sp.search(q='weezer', limit=20) for i, t in enumerate(results['tracks']['items']): print ' ', i, t['name']
Simple-Spotify
from simple_spotify.api import Spotify from simple_spotify.authorization import ClientCredentialsFlow res = ClientCredentialsFlow.token_request(CLIENT ID, CLIENT_SECRET) auth = ClientCredentialsFlow(**res) sp = Spotify(auth) results = sp.search(q='sora tob sakana', market='JP') for album in results.albums.items: print(album.name)
sora tob sakana World Fragment Tour New Stranger alight ep cocoon ep 魔法の言葉 夜空を全部 アルファルド
sora tob sakanaはいいぞ。
Spotipyでは認証を行っていないんだけど、Web APIのドキュメントにはすべてのリクエストは認証が必要、と書いてあるのでサンプルコードが古い可能性がある。
Authentication
All requests to Web API require authentication.
https://developer.spotify.com/documentation/web-api/
認証を含めなければ行数はほぼ同じ。 検索結果(results)オブジェクトにアルバム(albums)属性があって、さらにそれぞれのアルバム(items)がある、というのはそこそこ直感的でないかと思っている。
認証について言えば、認証用のエンドポイントからのレスポンスを一度受け取ってから、それをアンパックして認証クラスに渡すというのはちょっとわかりにくい流れになってしまった。 本当のところを言えば、認証用クラスにClient IDとClient Secretを渡せばOKという風にしたかったのだけど、もう一つの認証をWebアプリ上で使えるようにする関係でそれと同じ流れにした。
これがFlaskで作成したSimple-Spotifyを使った簡単なWebアプリ。
@app.route('/') def top(): if 'response' in session.keys(): auth = AuthorizationCodeFlow(**session['response']) sp = Spotify(auth) user = sp.get_current_user_profile() top_artists = sp.get_users_top('artists', time_range='medium_term') artists = top_artists.items top_tracks = sp.get_users_top('tracks', time_range='medium_term') tracks = top_tracks.items return render_template('index.html', name=user.display_name, artists=artists, tracks=tracks) else: seed = ''.join(random.choices(string.ascii_letters + string.digits, k=32)) url = access_authorize_page(CLIENT_ID, REDIRECT_URI, SCOPES, seed) return render_template('index.html', auth_url=url) @app.route('/callback/') def callback(): """ callback """ session['response'] = AuthorizationCodeFlow.token_request( CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, request.args['code']) return redirect(url_for('top'))
Spotifyへのログインをしてからアクセストークンを受け取るのだけど、アクセストークンの取得をtop()
で行ってしまうとリロードやページ遷移の度にトークンを取りに行こうとしてAPIからエラーが返ってきてしまった。これを避けるためにコールバックでアクセストークンなどを受け取って、セッションに格納。top()
でそれを使うという流れにした。
これには認証方法によってSimple-Spotifyの使い方に違いが出てしまうのを避けたかったという思いがある。
と言い訳めいたことを書いてから、実際にSimple-Spotifyの使い方などを書きたいと思うのだけど寒いのでしばらくしてから続きを書く。 なにしろこんなところで書いているので風が冷たい。
ビール部自主練です pic.twitter.com/ApYOoacAkK
— nao_y (@NaoY_py) 2019年5月12日