Hi,
I want to build an app that analyzes Spotify data. However, I want to let users use their own Spotify client id and client secret to access the Spotify API. Therefore, I have created input areas for the client id and client secret in the app. Then, there is an "Authenticate" button, which triggers the authentication of the id and secret. In the script, I have written an authentication function, which is run when I click the "Authenticate" button.
However, when I run the app and enter my client id and secret, and then try to fetch some data, I get the error message below in my console:
Listening on http://127.0.0.1:3991
Request failed [400]. Retrying in 1.7 seconds...
Request failed [400]. Retrying in 1.8 seconds...
Warning: Error in get_spotify_access_token:
167: stop
166: get_spotify_access_token
165: get_related_artists
164: artists_popularity [C:\Users\IFEANYI\Documents\SpotifyNet\testAPP/app.R#58]
163: <reactive:bar_plot> [C:\Users\IFEANYI\Documents\SpotifyNet\testAPP/app.R#199]
147: bar_plot
146: eventReactiveValueFunc [C:\Users\IFEANYI\Documents\SpotifyNet\testAPP/app.R#201]
102: plot_react
101: renderPlotly [C:\Users\IFEANYI\Documents\SpotifyNet\testAPP/app.R#206]
100: func
97: shinyRenderWidget
96: func
83: renderFunc
82: output$plot
1: runApp
But when, as a default, I include my Spotify client id and secret in the Shiny app script, it works just fine. But that way, users will be using my API credentials, which I do not want. I want users to be able to use their own client id and client secret to access the Spotify API. I have included here a reprex of the app, in case anyone is willing and kindhearted enough to help me troubleshoot this problem. Thanks in advance of your help:
library(shiny)
library(spotifyr)
library(plotly)
ui <- fluidPage(title = "Bar Plot",
#h2(p(id = "question","What does this app do?")),
#actionButton("button","Answer"),
# javascript code to answer question
# includeScript("Answer.js"),
# add css
# includeCSS("styles.css"),
sidebarLayout(
sidebarPanel(textInput("id","Enter Client ID"),
textInput("secret","Enter Client Secret"),
actionButton("auth","Authenticate"),br(),hr(),
textInput("text","Enter Artist's ID"),id = "sidebar",
actionButton("click","Get data"),
width = 3),
mainPanel(fluidRow(column(6,plotlyOutput("plot",width = "105%",height = "400px")))
)))
server <- function(input,output,session){
#set up Spotify API credentials environment
authentication <- function(id, secret) {
client_ID <- as.character(id)
client_secret <- as.character(secret)
# authenticate the spotify client side
Sys.setenv(SPOTIFY_CLIENT_ID = client_ID)
Sys.setenv(SPOTIFY_CLIENT_SECRET = client_secret)
access_token <- get_spotify_access_token(client_id = client_ID,
client_secret = client_secret)
return(access_token)
}
#validate API credentials
authenticate <- reactive(authentication(input$id,input$secret))
validation <- eventReactive(input$auth,{
authenticate()})
artists_popularity <- function(artist_id){
# get related artists
related_artists <- get_related_artists(id = artist_id,
include_meta_info = TRUE)
# get other artists that are related to the
# artists that are related to the main artist
other_related <- c()
for(i in 1:nrow(related_artists$artists)){
result <- get_related_artists(id = related_artists$artists[["id"]][i],
include_meta_info = TRUE)
other_related <- append(other_related,result)
}
# create nodes data.frame
nodes <- data.frame(
id = c(1:400),
node = c(other_related[[1]]$name,
other_related[[2]]$name,
other_related[[3]]$name,
other_related[[4]]$name,
other_related[[5]]$name,
other_related[[6]]$name,
other_related[[7]]$name,
other_related[[8]]$name,
other_related[[9]]$name,
other_related[[10]]$name,
other_related[[11]]$name,
other_related[[12]]$name,
other_related[[13]]$name,
other_related[[14]]$name,
other_related[[15]]$name,
other_related[[16]]$name,
other_related[[17]]$name,
other_related[[18]]$name,
other_related[[19]]$name,
other_related[[20]]$name),
label = c(other_related[[1]]$name,
other_related[[2]]$name,
other_related[[3]]$name,
other_related[[4]]$name,
other_related[[5]]$name,
other_related[[6]]$name,
other_related[[7]]$name,
other_related[[8]]$name,
other_related[[9]]$name,
other_related[[10]]$name,
other_related[[11]]$name,
other_related[[12]]$name,
other_related[[13]]$name,
other_related[[14]]$name,
other_related[[15]]$name,
other_related[[16]]$name,
other_related[[17]]$name,
other_related[[18]]$name,
other_related[[19]]$name,
other_related[[20]]$name),
popularity = c(c(other_related[[1]]$popularity,
other_related[[2]]$popularity,
other_related[[3]]$popularity,
other_related[[4]]$popularity,
other_related[[5]]$popularity,
other_related[[6]]$popularity,
other_related[[7]]$popularity,
other_related[[8]]$popularity,
other_related[[9]]$popularity,
other_related[[10]]$popularity,
other_related[[11]]$popularity,
other_related[[12]]$popularity,
other_related[[13]]$popularity,
other_related[[14]]$popularity,
other_related[[15]]$popularity,
other_related[[16]]$popularity,
other_related[[17]]$popularity,
other_related[[18]]$popularity,
other_related[[19]]$popularity,
other_related[[20]]$popularity)),
followers = c(c(other_related[[1]]$followers.total,
other_related[[2]]$followers.total,
other_related[[3]]$followers.total,
other_related[[4]]$followers.total,
other_related[[5]]$followers.total,
other_related[[6]]$followers.total,
other_related[[7]]$followers.total,
other_related[[8]]$followers.total,
other_related[[9]]$followers.total,
other_related[[10]]$followers.total,
other_related[[11]]$followers.total,
other_related[[12]]$followers.total,
other_related[[13]]$followers.total,
other_related[[14]]$followers.total,
other_related[[15]]$followers.total,
other_related[[16]]$followers.total,
other_related[[17]]$followers.total,
other_related[[18]]$followers.total,
other_related[[19]]$followers.total,
other_related[[20]]$followers.total))
)
# remove duplicate nodes and labels in data frame
nodes <- distinct(nodes,node,label,popularity,followers,.keep_all = T)
# create new data.frame for bar plot tooltip
nodes_df <- data.frame(
Artist = reorder(nodes$node,+nodes$popularity),
Popularity = nodes$popularity
)
# select top twenty most popular nodes
nodes_df <- head(nodes_df,20)
# create random color fill options
fill <- c("A","B","C","D","E","F","G","H")
rand_fill <- sample(fill,size = 1)
# plot top twenty most popular nodes
ggnodes <- nodes_df |>
ggplot()+aes(x = Artist,y = Popularity,fill = Artist)+
geom_bar(stat = "identity")+coord_flip()+
ggtitle("Top 20 Most Popular Artists")+
labs(x = "Artists")+scale_fill_viridis(discrete = T,option = rand_fill)+
scale_y_continuous(expand = c(0,0))+
theme(axis.ticks = element_blank(),
legend.position = "none",
axis.text = element_text(size = 10,face = "bold"),
plot.title = element_text(size = 12,face = "bold",hjust = 0.5),
axis.title.x = element_text(size = 12,face = "bold"),
axis.title.y = element_text(hjust = 0.8,size = 12,face = "bold"))
g <- ggnodes |> ggplotly(tooltip = c("x","y")) # show only x and y aesthetic values
return(g)
}
id_input <- reactive({as.character(input$text)})
bar_plot <- reactive({artists_popularity(id_input())})
related_network <- reactive({related_artists_network(id_input())})
plot_react <- eventReactive(input$click,{bar_plot()})
network_react <- eventReactive(input$click,{related_network()})
output$plot <- renderPlotly({
plot_react()
})
}
shinyApp(ui = ui,server = server)