LoginSignup
11
11

More than 3 years have passed since last update.

DjangoでSpotify APIを叩いてみる。

Last updated at Posted at 2019-12-01

はじめに

この記事はDjango Advent Calendar 2019の記事です。
対象読者はこれからDjangoを初めて見ようと言う層向けです。

前回の記事は@yuu-eguciさんの500エラーに関する内容でした。
https://qiita.com/yuu-eguci/items/a1e4b0a2f238d5ccc985

今回の記事はDjangoでSpotifyのAPIを実行してみようといった内容です。

事前準備

Spotifyのユーザーアカウントを作成する必要があるのですが、以下のクラスメソッドさんの記事が大変参考になります。
https://dev.classmethod.jp/etc/about-using-of-spotify-api/

記事のサンプルコードを実行したい方は、以下からチャートデータをCSV形式でダウンロードしてください。
https://spotifycharts.com/regional/jp/daily/latest

サーバー側の実装

行儀が大変悪いですが、手軽に動作を確認してほしいのでviews.pyの中で全て纏めています。
違和感を与えてしまったら申し訳ありません。。。


class SpotifySong:
    def __init__(self, song_name, uri):
        self.song_name = song_name
        self.uri = uri

def spotify(request) :
    # SpotifyのClientID,Secretを使って認可を実施
    client_id = ''
    client_secret = ''
    client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)
    # Spotifyインスタンスを作成
    spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

    # SpotifyからダウンロードしたCSVファイルを読み込む
    songs = pd.read_csv(BASE_DIR + '/regional-jp-daily-latest.csv', index_col=0, header=1)

    # Spotifyから曲情報を取得
    spotify_songs_list = []
    for url in songs['URL']:
        spotify_songs_list.extend(spotify.audio_features(url))

    # 曲名をくっ付ける
    response_list = []
    for i,spotify_song in enumerate(spotify_songs_list):
        response_list.append(SpotifySong(songs.iat[i,0],spotify_song['uri']))

    # テンプレートを指定
    template = loader.get_template('spotify/spotify_base.html')
    context = {
        'response_list': response_list,
    }
    return HttpResponse(template.render(context, request))

spotify.audio_featuresで返ってくるレスポンスは以下を参考にしてください。
演奏時間、キーはもちろんその曲がどれだけアコースティックなのか・どれだけ踊れるかといった指標も返ってきます。今回の記事では省きますが、季節によって好まれる曲の傾向を学習するサービスとか作れそうですね!!
https://developer.spotify.com/documentation/web-api/reference/tracks/get-audio-features/

クライアント側の実装


{% if response_list %}
    <h1>デイリーランキング</h1>
    <ul>
    {% for response in response_list %}
    <li><a href="https://embed.spotify.com/?uri={{ response.uri }}"> {{response.song_name}} </a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>Spotifyからの楽曲取得に失敗しました。</p>
{% endif %}

簡素なHTMLですが、以下の様な感じでデイリーランキングが作れます。
クリックしたらSpotifyの曲ページに飛べるシンプルな画面ですが、初学者にとっては作れたら結構嬉しいのではないでしょうか?

スクリーンショット 2019-12-01 19.09.13.png

サンプルコードを理解する上で知っておきたいこと

DjangoでTemplateを扱う際、いくつか注意する事があります。
マニュアルはこちら。
https://docs.djangoproject.com/en/2.2/ref/templates/language/#templates

1.コレクションのサイズを取得したい時

{{ 変数|length }}という書き方で取得する必要があります。変数.lengthといった書き方は出来ません。

スクリーンショット 2019-12-01 19.18.01.png

2.コレクションのインデックスを指定して取得したい時

{{変数.0}}といった様に、直接.インデックス番号を指定するという方法でしか取得出来ません。
{{変数[[0]]}}という書き方は出来ません。

スクリーンショット 2019-12-01 19.19.56.png

上記理由から、今回のサンプルコードは曲名を取得するために独自クラスを定義しています。
SpotifyAPIの戻り値と、CSV読み込みの結果を2つ渡す案も考えられますが、インデックス番号を用いた取得が困難なため、オブジェクトが別れて状態でデータを取り扱うのが面倒になります。

おまけのトラブルシューティング

以下コマンドを打つと、Portが使われていますエラーが起きる場合があります。

python3 manage.py runserver

Django version 2.2.7, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Error: That port is already in use.

上記を解決するためには、以下手順でプロセスをkillする方法が一番簡単です。

1.ポートを調べる

lsof -i -P | grep 8000
Python    71504 user    4u  IPv4 0x2cdb3e922e88888      0t0  TCP localhost:8000 (LISTEN)

2.PIDを指定してkillコマンドを実行

kill -9 71504

終わりに

Django 3.0のfinalリリースの日のハードルは超えられていませんが、誰かの参考になると幸いです。。。
明日の Django アドベント・カレンダーは @shimayu22 さんです。よろしくお願いします!!

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11