Aplicación Flask NEWS usando Newsapi

En este artículo, crearemos una aplicación web de noticias utilizando Flask y NewsAPI. La página web mostrará los principales titulares y una barra de búsqueda donde el usuario puede ingresar una consulta, después de procesar la consulta, la página web mostrará todos los artículos relevantes (hasta un máximo de 100 titulares). Crearemos una interfaz de usuario simple usando HTML y bootstrap. Puede usar cualquier IDE de su elección, por ejemplo. Código VS o texto sublime, etc.

Introducción a Flask y NewsAPI

Flask: Flask es un marco web escrito en python que nos permite crear puntos finales del lado del servidor. Puede obtener más información sobre el matraz en este enlace: https://www.geeksforgeeks.org/python-introduction-to-web-development-using-flask/.

NewsAPI: News API es una API Rest simple para recuperar artículos en vivo de toda la web. Con News API, podemos obtener los principales titulares de un país de una fuente en particular, como Times of India, Hindustan Times, BBC News y muchos más. También podemos buscar artículos relacionados con un tema en particular. visite https://newsapi.org/ para obtener más información.

Generación de claves API

Para utilizar News API en nuestra aplicación, debemos generar una clave de API única desde https://newsapi.org/. Visite este sitio web y cree su cuenta gratuita, en el registro exitoso y la verificación por correo electrónico obtendrá su clave API en la pantalla. Al registrarse, es posible que deba elegir un plan de desarrollador (elija según sus requisitos). Guarde esta clave API en algún lugar para que pueda usarse más.

Instalación de Flask y NewsAPI

Simplemente instalaremos Flask usando el comando pip:

pip install flask 

Después de una instalación exitosa, cree una carpeta para el nombre de la aplicación, esta carpeta matraz_noticias o cualquier otra cosa de su elección. Dentro de esta carpeta crea un nuevo archivo llamado app.py. Escribiremos todo nuestro código de back-end en este archivo en los próximos pasos.

Para instalar NewsAPI usaremos un comando pip como este:

pip install newsapi-python

Puede obtener más información sobre la biblioteca newsapi-python aquí: https://newsapi.org/docs/client-libraries/python

Creación de puntos finales de back-end

Hay dos cosas que queremos de nuestra aplicación:

  • Muestra los titulares principales cuando se abre la aplicación web.
  • Mostrar resultados basados ​​en una consulta de búsqueda.

En primer lugar, importaremos el matraz y newsapi en el archivo app.py. 

Python3

# import libraries
from flask import Flask, render_template, request
from newsapi import NewsApiClient
  
# init flask app
app = Flask(__name__)
  
# Init news api
newsapi = NewsApiClient(api_key='YOUR_API_KEY')

Para obtener los principales titulares, usaremos la función get_top_headlines de la biblioteca newsapi . Podemos pasar parámetros a esta función como país, idioma, fuentes, etc. En esta aplicación, pasaremos un parámetro adicional llamado page_size para obtener todos los titulares. La función de la biblioteca newsapi solo devuelve los 20 artículos principales, pero también tiene un campo llamado totalResults en el objeto de respuesta JSON. Modificaremos nuestra llamada de función para obtener todos los resultados usando el parámetro page_size . Esta parte del código se ve así:

Python3

# this function returns a JSON object
top_headlines = newsapi.get_top_headlines(country="in", language="en")
total_results = top_headlines['totalResults']
  
# the maximum value for page_size parameter is 100
# so we need to keep it at max 100
if total_results > 100:
    total_results = 100
  
# fetch articles where no. of articles=total_results
# this returns a list of articles
all_headlines = newsapi.get_top_headlines(country="in",
                                          language="en",
                                          page_size=total_results)['articles']

Enviaremos esta lista de artículos al código HTML.

Obtener artículos relacionados con una consulta de búsqueda

Esto estará relacionado con una solicitud de publicación. Vamos a utilizar la función get_everything con parámetros como fuentes de consulta, dominios, idioma, clasificación basada en y tamaño de página. Obtendremos todas las fuentes con la ayuda de la función get_sources de newsapi y para obtener todos los dominios usaremos la propiedad ‘URL’ de cada fuente. Aquí está el código que muestra cómo vamos a manejarlo:

Python3

# this function will return sources and domains in str format
# each of them separated by a comma
def get_sources_and_domains():
    all_sources = newsapi.get_sources()['sources']
    sources = []
    domains = []
    for e in all_sources:
        id = e['id']
        domain = e['url'].replace("http://", "")
        domain = domain.replace("https://", "")
        domain = domain.replace("www.", "")
        slash = domain.find('/')
        if slash != -1:
            domain = domain[:slash]
        sources.append(id)
        domains.append(domain)
    sources = ", ".join(sources)
    domains = ", ".join(domains)
    return sources, domains
  
  
# in post request
sources, domains = get_sources_and_domains()
related_news = newsapi.get_everything(q=keyword,
                                      sources=sources,
                                      domains=domains,
                                      language='en',
                                      sort_by='relevancy')
no_of_articles = related_news['totalResults']
  
# the max number of article can be fetched is 100
if no_of_articles > 100:
    no_of_articles = 100
all_articles = newsapi.get_everything(q=keyword,
                                      sources=sources,
                                      domains=domains,
                                      language='en',
                                      sort_by='relevancy',
                                      page_size=no_of_articles)['articles']
  
# we will send this list of articles to the html web page

Ahora podemos modelar todo el programa para obtener los puntos finales requeridos de la API del matraz. Básicamente, necesitamos una forma de manejar las requests GET para obtener todos los titulares y otra para manejar las requests POST para una consulta de búsqueda. Así es como se verá todo el archivo app.py después de agregar la ruta necesaria.

Código completo de app.py:

Python3

# import libraries
from flask import Flask, render_template, request
from newsapi import NewsApiClient
  
# init flask app
app = Flask(__name__)
  
# Init news api 
newsapi = NewsApiClient(api_key='70fdb9ba81ba40b6bda148e672898bd9')
  
# helper function
def get_sources_and_domains():
    all_sources = newsapi.get_sources()['sources']
    sources = []
    domains = []
    for e in all_sources:
        id = e['id']
        domain = e['url'].replace("http://", "")
        domain = domain.replace("https://", "")
        domain = domain.replace("www.", "")
        slash = domain.find('/')
        if slash != -1:
            domain = domain[:slash]
        sources.append(id)
        domains.append(domain)
    sources = ", ".join(sources)
    domains = ", ".join(domains)
    return sources, domains
  
@app.route("/", methods=['GET', 'POST'])
def home():
    if request.method == "POST":
        sources, domains = get_sources_and_domains()
        keyword = request.form["keyword"]
        related_news = newsapi.get_everything(q=keyword,
                                      sources=sources,
                                      domains=domains,
                                      language='en',
                                      sort_by='relevancy')
        no_of_articles = related_news['totalResults']
        if no_of_articles > 100:
            no_of_articles = 100
        all_articles = newsapi.get_everything(q=keyword,
                                      sources=sources,
                                      domains=domains,
                                      language='en',
                                      sort_by='relevancy',
                                      page_size = no_of_articles)['articles']
        return render_template("home.html", all_articles = all_articles, 
                               keyword=keyword)
    else:
        top_headlines = newsapi.get_top_headlines(country="in", language="en")
        total_results = top_headlines['totalResults']
        if total_results > 100:
            total_results = 100
        all_headlines = newsapi.get_top_headlines(country="in",
                                                     language="en", 
                                                     page_size=total_results)['articles']
        return render_template("home.html", all_headlines = all_headlines)
    return render_template("home.html")
  
if __name__ == "__main__":
    app.run(debug = True)

Creación de interfaz de usuario

Crearemos una página HTML que atenderá todas las requests de los usuarios. Cree una carpeta llamada templates en su directorio raíz ( carpeta flass_news ). Cree un archivo llamado «home.html» dentro de la carpeta de plantillas . La estructura de carpetas debería verse así:

 

Ahora agregue el código final en home.html :

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>News application</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
    <div class="container">
      <form action="/" method="post">
        <div class="input-group mb-3">
          <input type="text" class="form-control" name="keyword" placeholder="Enter keyword ...." aria-label="Recipient's username" aria-describedby="button-addon2">
          <button class="btn btn-outline-secondary" type="button" id="button-addon2">Search</button>
        </div>
      </form>
    </div>
    {% if all_headlines %}
      <center><h1>Headlines</h1></center>
      <div class="row row-cols-1 row-cols-md-2 g-4 mx-3 my-3">
        {% for headline in all_headlines %}
          <div class="col">
            <div class="card h-100">
              <img src="{{headline['urlToImage']}}" class="card-img-top" alt="...">
              <div class="card-body">
                <h3 class="card-title">{{headline['title']}}</h3>
                <p class="card-text">{{headline['description']}} <a href="{{headline['url']}}" target="blank">Read More...</a></p>
  
  
              </div>
              <div class="card-footer">
                <small class="text-muted">{{headline['source']['name']}}</small>
              </div>
            </div>
          </div>
        {% endfor %}
      </div>
    {% endif %}
    {% if all_articles %}
      <center><h1>Results for '{{keyword}}'</h1></center>
      <div class="row row-cols-1 row-cols-md-2 g-4 mx-3 my-3">
        {% for article in all_articles %}
          <div class="col">
            <div class="card h-100">
              <img src="{{article['urlToImage']}}" class="card-img-top" alt="...">
              <div class="card-body">
                <h3 class="card-title">{{article['title']}}</h3>
                <p class="card-text">{{article['description']}} <a href="{{article['url']}}" target="blank">Read More...</a></p>
  
  
              </div>
              <div class="card-footer">
                <small class="text-muted">{{article['source']['name']}}</small>
              </div>
            </div>
          </div>
        {% endfor %}
      </div>
    {% endif %}
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
</body>
</html>

Probando la aplicación 

Ejecutemos el servidor y verifiquemos si nuestra aplicación funciona o no. Vaya a la terminal y ejecute el archivo app.py usando este comando:

python .\app.py

La salida en la consola debería verse así:

 

Ahora vaya a http://127.0.0.1:5000 o localhost:5000 y la salida debería ser así:

Publicación traducida automáticamente

Artículo escrito por hvt_16 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *