No tienes acceso a esta clase

¬°Contin√ļa aprendiendo! √önete y comienza a potenciar tu carrera

Aprende Inglés, Programación, AI, Ciberseguridad y más a precio especial.

Antes: $249

Currency
$209
Suscríbete

Termina en:

1 Días
12 Hrs
4 Min
19 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