Megacurso programación en Python3 | 1. Wrapper para la API de Youtube

in #spanish7 years ago (edited)

En esta clase aprenderemos a crear un wrapper para hacer llamadas a la API pública de Youtube. En la carpeta del proyecto puedes encontrar todo el código explicado a continuación.

Carpeta del proyecto

En la carpeta del curso encontrarás el índice con las clases publicadas.

Los endpoints

Lo primero que debemos hacer es añadir las URLs base a las que haremos las llamadas. Creamos un archivo .py y añadimos el siguiente código:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

YOUTUBE_COMMENT_URL = 'https://www.googleapis.com/youtube/v3/commentThreads'
YOUTUBE_SEARCH_URL = 'https://www.googleapis.com/youtube/v3/search'

El objeto YoutubeApi

Luego creamos una clase la cual usaremos para llamar a la API de Youtube. Usaremos la biblioteca urllib para abrir las URLs, que se incluye entre las bibliotecas de python3, así tendremos un código más portable.

Desde aquí puedes acceder a la documentación de urllib.

Si no sabes cómo obtener tu clave para la API de Youtube puedes leer este artículo.

class YoutubeApi(object):
    def __init__(self, API_KEY):
        self.api_key = API_KEY

    def _openURL(self, url, parms):
        from urllib.request import urlopen
        from urllib.parse import urlencode
        f = urlopen(url + '?' + urlencode(parms))
        data = f.read()
        f.close()
        matches = data.decode("utf-8")
        return matches

El parámetro url tomará la url base de la llamada y parms será un diccionario con los parámetros de la llamada. La función urlencode se encarga de formatear la parte de los parámetros.

Si no entiendes qué significa pasar parámetros a una URL puedes leer este artículo.

Los métodos

Entonces comenzamos a añadir la funcionalidad a nuestro objeto. Para empezar vamos a crear un método que tome el ID de un canal de Youtube y nos devuelva la información de tantos vídeos de un canal como máximo le indiquemos.

    def channel_videos(self, channel_id, max_res=50):
        ''' Toma una id de canal y devuelve todos los vídeos
        con su información en un diccionario. Se le puede pasar
        un número para indicar el límite máximo de resultados'''
        from json import loads
        parms = {
                   'part': 'id,snippet',
                   'channelId': channel_id,
                   'maxResults': max_res,
                   'key': self.api_key
                }

        matches = self._openURL(YOUTUBE_SEARCH_URL, parms)
        search_response = loads(matches)

        videos = []
        for search_result in search_response.get('items', []):
            if search_result["id"]["kind"] == "youtube#video":
                videos.append(search_result['snippet'])
        return videos

Lo que hace el método anterior es crear un diccionario de parámetros para la llamada. Luego llamamos a la función que creamos antes y le pasamos la URL base y los parámetros.

Para acceder a todos los posibles parámetros podemos ir a la documentación de la API de Youtube.

Luego lo cargamos en JSON gracias a la función loads que importamos al principio y de los resultados obtenidos rescatamos los que son del tipo "youtube#video" mediante un bucle.


Construyendo las llamadas

Si somos capaces de entender este tipo de código, podemos crear el resto de llamadas fácilmente. Aquí puedes ver todas las que he diseñado yo:

Puedes ver el código completo desde aquí

Contáctame

Cualquier duda o sugerencia házmelo saber en un comentario o envíame un correo a mondejar1994@gmail.com. ¡Un saludo y hasta la próxima!

Sort:  

Buen post! He escuchado mucho sobre python...

No me queda muy claro qué hace o qué es snippet. Podrías aclararlo?

Y tengo otra duda, yo personalmente suelo hacer los import de manera global al principio del documento, por qué prefieres hacerlo dentro de la definición de los métodos? Es sólo costumbre, o existe alguna ventaja? :)

Excelente post, me gusta tu contenido!

Hola me alegro de que te guste. Snippet significa "fragmento", es el diccionario donde la API de youtube trae la parte de información del elemento que estés buscando. Entiendo que es una buena práctica hacer las importaciones locales para cada función para que así sólo se importe la parte de las bilibotecas que vayas a usar en ese momento y consumes menos memoria. Un saludo!

me interesa aprender Python.. te sigo..