Authenticating Spotify API in Shiny

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)

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.