No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

17 Días
5 Hrs
31 Min
32 Seg

Obteniendo los albums

24/30
Recursos

Aportes 14

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

¡Reto completado 😉!

def obtener_tracks(album_id, token, return_name=False, page_limit=50, market=None):
"""Función que devuelve una lista con los tracks de un album determinado"""

    url = f'https://api.spotify.com/v1/albums/{album_id}/tracks'
    header = {'Authorization': f'Bearer {token}'}
    params = {
        'limit': page_limit,
        'offset': 0,
    }
    lista = []
    r = requests.get(url, params=params, headers=header)
    if r.status_code != 200:
        print('Error en la request.', r.json())
        return None
    if return_name:
        lista += [(item['id'], item['name']) for item in r.json()['items']]
    else:
        lista += [item['id'] for item in r.json()['items']]
        
    while r.json()['next']:
        r = requests.get(r.json()['next'], headers=header)
        if r.status_code == 200:
            if return_name:
                lista += [(item['id'], item['name']) for item in r.json()['items']]
            else:
                lista += [item['id'] for item in r.json()['items']]
        else:
            print('Error:', r.status_code, '\n', r.json())
    return lista

En mi caso, dejaría la verificación del status code en una función externa debido a que se está comprobando muy seguido la misma. De esta manera puedo disminuir las líneas de código y mantenimiento, sumando a esto que el código se hace más legible.

Solución usando decoradores

def comprobation_request(request_func):
    
    def comprobation(*args, **kwargs):
        list_components = []
        data_components = []
        response = request_func(*args, **kwargs)
        
        if response.status_code == 200:
            
            list_components.append(response.json()['items']) 

            while response.json()['next']:
                next_url = response.json()['next']
                
                temp = list(args)
                temp[0] = next_url
                args = tuple(temp)
                
                
                response = request_func(*args)
                list_components.append(response.json()['items'])
            
            for component in list_components:
                for data in component:
                    
                    data_components.append((data['id'], data['name']))
    
                
            return data_components
        
        else:
            print('==== ERROR IN REQUEST ==== ' )
            print(response.json())
            return None 
    
    return comprobation


@comprobation_request
def get_albums_id(url_albums, artist_id, header, market, page_limit = 50):
    params = {'country': market,
              'limit': page_limit,}
    
    try:
        albums_id = requests.get(url_albums.format(artist_id), headers = header, params = params)
    except:
        albums_id = requests.get(url_albums)
        
    
    
        
    return albums_id
    


@comprobation_request
def get_album_data(url_album_data, album_id,header, market):  
    params = {'market':market}
    
    try:
        album_data = requests.get(url_album_data.format(album_id), headers = header, params = params)
    except:
        album_data = requests.get(url_album_data)
        
    
    return album_data


Yo hice mi codigo por modulos, se que hay algunas partes que quedaron poco esteticas pero quedo funcional y sin consumir tantos recursos, me paso una vez que creaba un objeto tan trande que superaba el tamaño de la ram.

import requests, base64, pandas, os


URL_SPOTYFY_SRCH = 'https://api.spotify.com/v1/search'
TOKEN = 'https://accounts.spotify.com/api/token'


def encoding():
    clien_id = "4e3aad51b12e4608bb932adb19a240d1:b08d5cebc0f345e0b7d64320a388c4a8"
    msg_bytes = clien_id.encode("UTF-8")
    msg_base64 = base64.b64encode(msg_bytes)
    msg_decode = msg_base64.decode("UTF-8")
    return msg_decode
        

def token_spotify():
    try:  
        params = {'grant_type': 'client_credentials'}
        headers = {'Authorization': 'Basic ' + encoding()}
        token_spoty = requests.post(TOKEN, headers=headers, data=params).json()["access_token"]
        return token_spoty
    except Exception as erre:
        print(f"Error al requerir el token:  \n {erre}")


def srch_albms_spotify(artist, page_limit = 50):
    try:
        header = {'Authorization': f'Bearer {token_spotify()}'}
        srch_params = {'county' : 'CO', 'limit' : page_limit, "offset": 0}
        get_url_albums = requests.get(f'https://api.spotify.com/v1/artists/{artist}/albums', headers= header, params= srch_params )
        next_l = get_url_albums.json()["next"]
        print(get_url_albums.json()["total"])
        albums =[]
        for i in get_url_albums.json()["items"]:
                albums.append(i['id']) 
        try:             
            while requests.get(next_l, headers=header).status_code == 200:
                next = requests.get(next_l, headers=header) 
                for ii in next.json()["items"]:
                    albums.append(ii["id"])
                next_l = next.json()["next"]
        except:
            pass
        return albums
    except Exception as erre:
        print(f"Error en la rch_sngs_spotify:  \n {erre}")
  

def api_spotify(inp):
    try:
        header = {'Authorization': f'Bearer {token_spotify()}'}
        srch_params = {'q' : inp, 'type' : 'artist', 'market' : 'CO'}
        get_url = requests.get(URL_SPOTYFY_SRCH, headers=header, params=srch_params)
        data_frame = pandas.DataFrame(get_url.json() ['artists']['items'])
        artist = data_frame.sort_values(by="popularity", ascending=False).iloc[0]["id"]
        return srch_albms_spotify(artist)  
    except Exception as erre:
        print(f"Error en api_spotify:  \n {erre}")


def main():
    inp = input("Que artista desaea buscar?: ")
    albums_list = api_spotify(inp)
    print(len(albums_list))

    

if __name__ == "__main__":
    os.system("cls")
    main()

🚀

def obtener_tracks(album_id, token, return_name = False, page_limit = 50, country = None):
    url = f'https://api.spotify.com/v1/albums/{album_id}/tracks'
    header = {'Authorization': f'Bearer {token}'}
    params = {'limit':page_limit,
             'offset': 0,
             'country': country}
    lista = []
    r = requests.get(url,params=params,headers=header)
    if r.status_code != 200:
        print('Error en la request. ',r.json())
        return None
    if return_name:
        lista += [(item['id'],item['name']) for item in r.json()['items']]
    else:
        lista += [item['id'] for item in r.json()['items']]
    
    while r.json()['next']:
        r = requests.get(r.json()['next'], headers=header)
        
        if r.status_code == 200:
            if return_name:
                lista += [(item['id'],item['name']) for item in r.json()['items']]
            else:
                lista += [item['id'] for item in r.json()['items']]
        else:
            print('Error en la request. ', r.json())
    
    return lista

Les dejo el codigo como lo llevo

import base64
import requests
import pandas as pd


def get_token(client_id, client_secret):

    client_str = '{client_id}:{client_secret}'.format(client_id=client_id, client_secret=client_secret)
    client_encode = base64.b64encode(client_str.encode("utf-8"))  # Codificado en Bytes
    client_encode = str(client_encode, "utf-8")  # Codificado en String

    token_url = 'https://accounts.spotify.com/api/token'
    params = {'grant_type': 'client_credentials'}
    headers= {'Authorization' : 'Basic {client_encode}'.format(client_encode=client_encode)}

    r = requests.post(token_url, data=params, headers = headers)

    if r.status_code != 200:
        print('Error en la request.', r.json())
        return None
    print('Token valido por {} segundos.'.format(r.json()['expires_in']))
    return r.json()['access_token']


def obtener_discografia(artist_id, token, return_name = False, page_limit = 50, country = None):
    url = f'https://api.spotify.com/v1/artists/{artist_id}/albums'
    header = {'authorization': f'Bearer {token}'}
    params = {'limit': page_limit,
              'offset': 0,
              'country': country}

    lista = []
    r = requests.get(url, params = params, headers = header)

    if r.status_code != 200:
        print('Error en la request', r.json())
        return None

    if return_name:
        lista += [(item['id'], item['name']) for item in r.json()['items']]
    else:
        lista += [item['id'] for item in r.json()['items']]

    while r.json()['next']:
        r = requests.get(r.json()['next'], headers = header)

        if r.status_code != 200:
            print('Error en la request', r.json())
        else:
            if return_name:
                lista += [(item['id'], item['name']) for item in r.json()['items']]
            else:
                lista += [item['id'] for item in r.json()['items']]

    return lista
    

def obtener_tracks(album_id, token, return_name = False, page_limit = 50, country = None):
    url = f'https://api.spotify.com/v1/albums/{album_id}/tracks'
    header = {'authorization': f'Bearer {token}'}
    params = {'limit': page_limit,
              'offset': 0,
              'country': country}

    lista = []
    r = requests.get(url, params = params, headers = header)

    if r.status_code != 200:
        print('Error en la request', r.json())
        return None

    if return_name:
        lista += [(item['id'], item['name']) for item in r.json()['items']]
    else:
        lista += [item['id'] for item in r.json()['items']]

    while r.json()['next']:
        r = requests.get(r.json()['next'], headers = header)

        if r.status_code != 200:
            print('Error en la request', r.json())
        else:
            if return_name:
                lista += [(item['id'], item['name']) for item in r.json()['items']]
            else:
                lista += [item['id'] for item in r.json()['items']]

    return lista

def main():
 
    id_blink = '6FBDaR13swtiWwGhX1WQsP'
    client_id = 'your_id'
    client_secret = 'your_secret_id'

    token = get_token(client_id, client_secret)

    print(token)

    lista_albums = obtener_discografia(id_blink, token, True, country = 'CO')

    discography = {}
    for album in lista_albums:
        lista_tracks = obtener_tracks(album[0], token, True, country = 'CO')
        tracks_name = [tracks[1] for tracks in lista_tracks]
        discography[f'{album[1]}'] = tracks_name

    df = pd.DataFrame({key:pd.Series(value) for key, value in discography.items()})
    pd.set_option('display.max_rows', None)
    pd.set_option('display.max_colwidth', 30)

    df.to_excel('Discography.xlsx', sheet_name='Hoja_1')

if __name__ == "__main__":
    main()

Aqui mi pequeño aporte realice la funcion haciendo uso del concepto Generator de Python asi retornar un objeto iterador y reutilizar el mismo codigo para leer varios endpoind de ese tipo del api de Spotify.
.
Función generator:

def generator(endpoint_url, access_token, params, return_name=False):
    '''
    Retorna un objeto iterable con los datos de la propiedad "items" que es retornado
    al hacer un request a un endpoint del api de Spotify
    '''
    headers = dict(Authorization=f'Bearer {access_token}')
    url = endpoint_url
    total = 0
    while url:
        req = requests.get(url, headers=headers, params=params)
        json = req.json()
        if req.status_code != 200:
            print('Error al ejecutar el request.', json)
            return None
        url = json['next']
        total = json['total']
        if return_name:
            for item in json['items']:
                yield (item['id'], item['name'])
        else:
            for item in json['items']:
                yield item['id']
    print('Total of items:', total)

Función que retorna la discografía:

def get_discography(artist_id, access_token, return_name=False, market='DO'):
    '''
    Retorna la discografia de un artista
    '''
    params = dict(market=market)
    url = f'https://api.spotify.com/v1/artists/{artist_id}/albums'

    return [album for album in generator(url, access_token, params, return_name)]

Función que retorna la lista de canciones(tracks):

def get_tracks(album_id, access_token, return_name=True, market='DO'):
    '''
    Retorna las canciones de un album
    '''    
    params = dict(market=market)
    url = f'https://api.spotify.com/v1/albums/{album_id}/tracks'

    return [track for track in generator(url, access_token, params, return_name)]

El reto me quedo de la siguiente manera:

def obtener_tracks(album_id, token, return_name=False, page_limit=50, market=None):
    url = f'https://api.spotify.com/v1/albums/{album_id}/tracks'
    header = {'authorization': f'Bearer {token}'}
    
    # En los paramétros es donde específicamos el limit, el offset y country.
    params = {'limit' : page_limit, 
              'offset': 0, 
              'market': market}
    
    lista = []
    r = requests.get(url, params=params, headers=header)

    if r.status_code != 200:
        print('Error en la request.', r.json())
        return None
    
    if return_name:
        lista += [(item['id'], item['name']) for item in r.json()['items']]
    else:
        lista += [item['id'] for item in r.json()['items']]
        

    while r.json()['next']:
        r = requests.get(r.json()['next'], headers=header)
        
        if return_name:
            lista += [(item['id'], item['name']) for item in r.json()['items']]
        else:
            lista += [item['id'] for item in r.json()['items']]
            
    return lista

Solución al reto:

Output:

no sabia de la existencia de next por lo que hice este código para resolver el reto

def get_tracks(albuns_ids,headers,page_limit=50,return_name=False,ofset=0,):
    id_tracks = []
    name_tacks = []
    params = {'ofset':ofset}
    
    for albun_id in albuns_ids:
        url = base_url + '/albums/{id}/tracks'.format(id=albun_id)
        albun_info = requests.get(url,headers=headers,params=params)
        
        if (albun_info.status_code != 200): raise Exception(f"error geting info for albun_id: {albun_id} -details: {albun_info.json()}")                  
        albun_info_j = albun_info.json()
        
        if (albun_info_j['limit'] < albun_info_j['total']):
            return_data = get_tracks(albuns_ids,headers,page_limit,return_name,ofset=albun_info_j['limit'])
            
            if return_name:
                name_tracks += return_data[0]
                id_tracks += return_data[1]
            else:
                id_tracks += return_data
                
        id_tracks += [item['id'] for item in albun_info_j['items']]
        
        if return_name:
            name_tacks += [item['name'] for item in albun_info_j['items']]
            
    if return_name:
        return name_tacks,id_tracks
    else:
        return id_tracks

def get_albuns_ids(artist_id,headers,page_limit=50, country=None, types_albun=['single'],ofset=0):
    
    #get alvund
    
    url = base_url + '/artists/{id}/albums'.format(id=artist_id)
    params = {'limit':page_limit,'ofset':ofset}
    
    if types_albun != None:
        params['include_groups'] = types_albun
    if country != None:
        params['market'] = country
        
    albuns = requests.get(url,headers=headers,params=params)
    albuns_j = albuns.json()
    if (albuns.status_code != 200): raise Exception(f"error {albuns.status_code} geting albuns from artist id: {artist_id}-details: {albuns.json()}")         
    
    albuns_ids = [item['id'] for item in albuns.json()['items']]
    
    if (albuns_j['limit'] < albuns_j['total']):
        albuns_ids += get_albuns_ids(artist_id,headers,page_limit, country, types_albun,ofset=albuns_j['limit'])
        
    return albuns_ids

def get_tracks_for_artist(artist_id,token,return_name=False,page_limit=50, country=None, types_albun=['single'],ofset=0):
    base_url = 'https://api.spotify.com/v1'    
    headers = {'Authorization' : 'Bearer '+ token,
           'Content-Type' : 'application/json',
           'Accept': 'application/json'
          }
    
    albuns_ids = get_albuns_ids(artist_id,headers,page_limit, country, types_albun,ofset)
    result = get_tracks(albuns_ids,headers,page_limit,return_name,ofset)
    
    if return_name:
        return dict(zip(result[0],result[1]))
    else:
        return result

Consejo:
Si te sale el error 400 con el Bearer, revisa bien tu header. Si no encuentras el typo, busca en el código cómo estaba escrito.

Creeme que querrás probar el bonus de la siguiente clase

Mi implementacion de obtener tracks

album_id = '0SmIkzc7YgxqBV0V5RcbPt'

def obtener_tracks(album_id, token, return_name=False, page_limit=50, country=None):
    url = f'https://api.spotify.com/v1/albums/{album_id}/tracks'
    
    header = header = {'Authorization': f'Bearer {token}'}
    params = {'limit': page_limit,
              'offset': 0,
              'country': country}
    
    lista = []
    r = requests.get(url, params=params, headers=header)

    if r.status_code != 200:
        print('Error en la request.', json())
        return None

    if return_name:
        lista += [(item['id'], item['name']) for item in r.json()['items']]
    else:
         lista += [item['id'] for item in r.json()['items']] 

    while r.json()['next']:
        r = requests.get(r.json()['next'], headers=header)

        if return_name:
            lista += [(item['id'], item['name']) for item in r.json()['items']]
        else:
             lista += [item['id'] for item in r.json()['items']]   

    return lista   

tracks = obtener_tracks(album_id, token, True, 50, 'AR')
tracks