| | import json |
| | from urllib import request |
| | from fastapi import FastAPI |
| | from starlette.middleware.sessions import SessionMiddleware |
| | from starlette.responses import HTMLResponse, RedirectResponse |
| | from starlette.requests import Request |
| | import gradio as gr |
| | import uvicorn |
| | from fastapi.responses import HTMLResponse |
| | from fastapi.responses import RedirectResponse |
| | import pandas as pd |
| |
|
| | import spotipy |
| | from spotipy import oauth2 |
| |
|
| | import heatmap |
| |
|
| | import numpy as np |
| |
|
| | import matplotlib.pyplot as plt |
| | from matplotlib.patches import Circle, RegularPolygon |
| | from matplotlib.path import Path |
| | from matplotlib.projections.polar import PolarAxes |
| | from matplotlib.projections import register_projection |
| | from matplotlib.spines import Spine |
| | from matplotlib.transforms import Affine2D |
| | import matplotlib |
| |
|
| | matplotlib.use('SVG') |
| |
|
| |
|
| | def get_features2(spotify): |
| | features = [] |
| | for index in range(0, 10): |
| | results = spotify.current_user_saved_tracks(offset=index*50, limit=50) |
| | track_ids = [item['track']['id'] for item in results['items']] |
| | features.extend(spotify.audio_features(track_ids)) |
| |
|
| | df = pd.DataFrame(data=features) |
| | names = [ |
| | 'danceability', |
| | 'energy', |
| | |
| | 'speechiness', |
| | 'acousticness', |
| | 'instrumentalness', |
| | 'liveness', |
| | 'valence', |
| | ] |
| | features_means = df[names].mean() |
| | return names, features_means.values |
| |
|
| |
|
| | def radar_factory(num_vars, frame='circle'): |
| | """ |
| | Create a radar chart with `num_vars` axes. |
| | |
| | This function creates a RadarAxes projection and registers it. |
| | |
| | Parameters |
| | ---------- |
| | num_vars : int |
| | Number of variables for radar chart. |
| | frame : {'circle', 'polygon'} |
| | Shape of frame surrounding axes. |
| | |
| | """ |
| | |
| | theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False) |
| |
|
| | class RadarTransform(PolarAxes.PolarTransform): |
| |
|
| | def transform_path_non_affine(self, path): |
| | |
| | |
| | |
| | if path._interpolation_steps > 1: |
| | path = path.interpolated(num_vars) |
| | return Path(self.transform(path.vertices), path.codes) |
| |
|
| | class RadarAxes(PolarAxes): |
| |
|
| | name = 'radar' |
| | PolarTransform = RadarTransform |
| |
|
| | def __init__(self, *args, **kwargs): |
| | super().__init__(*args, **kwargs) |
| | |
| | self.set_theta_zero_location('N') |
| |
|
| | def fill(self, *args, closed=True, **kwargs): |
| | """Override fill so that line is closed by default""" |
| | return super().fill(closed=closed, *args, **kwargs) |
| |
|
| | def plot(self, *args, **kwargs): |
| | """Override plot so that line is closed by default""" |
| | lines = super().plot(*args, **kwargs) |
| | for line in lines: |
| | self._close_line(line) |
| |
|
| | def _close_line(self, line): |
| | x, y = line.get_data() |
| | |
| | if x[0] != x[-1]: |
| | x = np.append(x, x[0]) |
| | y = np.append(y, y[0]) |
| | line.set_data(x, y) |
| |
|
| | def set_varlabels(self, labels): |
| | self.set_thetagrids(np.degrees(theta), labels) |
| |
|
| | def _gen_axes_patch(self): |
| | |
| | |
| | if frame == 'circle': |
| | return Circle((0.5, 0.5), 0.5) |
| | elif frame == 'polygon': |
| | return RegularPolygon((0.5, 0.5), num_vars, |
| | radius=.5, edgecolor="k") |
| | else: |
| | raise ValueError("Unknown value for 'frame': %s" % frame) |
| |
|
| | def _gen_axes_spines(self): |
| | if frame == 'circle': |
| | return super()._gen_axes_spines() |
| | elif frame == 'polygon': |
| | |
| | spine = Spine(axes=self, |
| | spine_type='circle', |
| | path=Path.unit_regular_polygon(num_vars)) |
| | |
| | |
| | |
| | spine.set_transform(Affine2D().scale(.5).translate(.5, .5) |
| | + self.transAxes) |
| | return {'polar': spine} |
| | else: |
| | raise ValueError("Unknown value for 'frame': %s" % frame) |
| |
|
| | register_projection(RadarAxes) |
| | return theta |
| |
|
| | def get_spider_plot(request: gr.Request): |
| | token = request.request.session.get('token') |
| | sp = spotipy.Spotify(token) |
| | names, data = get_features2(sp) |
| |
|
| | theta = radar_factory(len(names), frame='polygon') |
| |
|
| | fig = plt.figure(figsize=(9, 9)) |
| | ax = fig.add_axes([0, 0, 1, 1], projection='radar') |
| |
|
| | |
| | title = 'test' |
| | ax.set_rgrids([0.2, 0.4, 0.6, 0.8]) |
| | ax.set_title(title, weight='bold', size='medium', position=(0.5, 1.1), |
| | horizontalalignment='center', verticalalignment='center') |
| |
|
| | ax.plot(theta, data) |
| | ax.fill(theta, data, alpha=0.25, label='_nolegend_') |
| |
|
| | ax.set_varlabels(names) |
| |
|
| | return fig |
| |
|
| |
|
| | PORT_NUMBER = 8080 |
| | SPOTIPY_CLIENT_ID = 'c087fa97cebb4f67b6f08ba841ed8378' |
| | SPOTIPY_CLIENT_SECRET = 'ae27d6916d114ac4bb948bb6c58a72d9' |
| | SPOTIPY_REDIRECT_URI = 'https://hf-hackathon-2023-01-spotify.hf.space' |
| | SCOPE = 'ugc-image-upload user-read-playback-state user-modify-playback-state user-read-currently-playing app-remote-control streaming playlist-read-private playlist-read-collaborative playlist-modify-private playlist-modify-public user-follow-modify user-follow-read user-read-playback-position user-top-read user-read-recently-played user-library-modify user-library-read user-read-email user-read-private' |
| |
|
| | sp_oauth = oauth2.SpotifyOAuth(SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET, SPOTIPY_REDIRECT_URI, scope=SCOPE) |
| |
|
| | app = FastAPI() |
| | app.add_middleware(SessionMiddleware, secret_key="w.o.w") |
| |
|
| | @app.get('/', response_class=HTMLResponse) |
| | async def homepage(request: Request): |
| | token = request.session.get('token') |
| | if token: |
| | return RedirectResponse("/gradio") |
| |
|
| | url = str(request.url) |
| | code = sp_oauth.parse_response_code(url) |
| | if code != url: |
| | token_info = sp_oauth.get_access_token(code) |
| | request.session['token'] = token_info['access_token'] |
| | return RedirectResponse("/gradio") |
| |
|
| | auth_url = sp_oauth.get_authorize_url() |
| | return "<a href='" + auth_url + "'>Login to Spotify</a>" |
| |
|
| |
|
| |
|
| | from vega_datasets import data |
| |
|
| | iris = data.iris() |
| |
|
| |
|
| | def scatter_plot_fn_energy(request: gr.Request): |
| |
|
| | token = request.request.session.get('token') |
| | if token: |
| | sp = spotipy.Spotify(token) |
| | results = sp.current_user() |
| | print(results) |
| | df = get_features(sp) |
| | return gr.ScatterPlot( |
| | value=df, |
| | x="danceability", |
| | y="energy" |
| | ) |
| |
|
| | def scatter_plot_fn_liveness(request: gr.Request): |
| | token = request.request.session.get('token') |
| | if token: |
| | sp = spotipy.Spotify(token) |
| | results = sp.current_user() |
| | print(results) |
| | df = get_features(sp) |
| | print(df) |
| | return gr.ScatterPlot( |
| | value=df, |
| | x="acousticness", |
| | y="liveness" |
| | ) |
| |
|
| | def heatmap_plot_fn(request: gr.Request): |
| | token = request.request.session.get('token') |
| | if token: |
| | sp = spotipy.Spotify(token) |
| | data = heatmap.build_heatmap(heatmap.fetch_recent_songs(sp)) |
| | fig, ax = heatmap.plot(data) |
| | return fig |
| |
|
| |
|
| | def get_features(spotify): |
| | features = [] |
| | for index in range(0, 10): |
| | results = spotify.current_user_saved_tracks(offset=index*50, limit=50) |
| | track_ids = [item['track']['id'] for item in results['items']] |
| | features.extend(spotify.audio_features(track_ids)) |
| |
|
| | df = pd.DataFrame(data=features) |
| | names = [ |
| | 'danceability', |
| | 'energy', |
| | 'loudness', |
| | 'speechiness', |
| | 'acousticness', |
| | 'instrumentalness', |
| | 'liveness', |
| | 'valence', |
| | 'tempo', |
| | ] |
| |
|
| | |
| | return df |
| |
|
| |
|
| | def get_features(spotify): |
| | features = [] |
| | for index in range(0, 10): |
| | results = spotify.current_user_saved_tracks(offset=index*50, limit=50) |
| | track_ids = [item['track']['id'] for item in results['items']] |
| | features.extend(spotify.audio_features(track_ids)) |
| |
|
| | df = pd.DataFrame(data=features) |
| | names = [ |
| | 'danceability', |
| | 'energy', |
| | 'loudness', |
| | 'speechiness', |
| | 'acousticness', |
| | 'instrumentalness', |
| | 'liveness', |
| | 'valence', |
| | 'tempo', |
| | ] |
| | features_means = df[names].mean() |
| | |
| | return features_means |
| |
|
| |
|
| | |
| | def get_started(): |
| | |
| | |
| | return |
| |
|
| | with gr.Blocks() as demo: |
| | gr.Markdown(" ## Spotify Analyzer 🥳🎉") |
| | gr.Markdown("This app analyzes how cool your music taste is. We dare you to take this challenge!") |
| | with gr.Row(): |
| | get_started_btn = gr.Button("Get Started") |
| | with gr.Row(): |
| | spider_plot = gr.Plot() |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | with gr.Row(): |
| | gr.Markdown(" ### We have recommendations for you!") |
| | with gr.Row(): |
| | heatmap_plot = gr.Plot() |
| | with gr.Row(): |
| | gr.Markdown(" ### We have recommendations for you!") |
| | with gr.Row(): |
| | gr.Dataframe( |
| | headers=["Song", "Album", "Artist"], |
| | datatype=["str", "str", "str"], |
| | label="Reccomended Songs", |
| | value=[["Fired Up", "Fired Up", "Randy Houser"], ["Something Just Like This", "Memories... Do Not Open", "The Chainsmokers"]] |
| | ) |
| | |
| | demo.load(fn=get_spider_plot, outputs = spider_plot) |
| | demo.load(fn=heatmap_plot_fn, outputs = heatmap_plot) |
| | |
| | |
| |
|
| |
|
| | gradio_app = gr.mount_gradio_app(app, demo, "/gradio") |
| | uvicorn.run(app, host="0.0.0.0", port=7860) |
| |
|