Crea un encurtidor de URL con Python Flask

PythonBeginner
Practicar Ahora

Introducción

En este proyecto, aprenderemos a crear un encurtidor de URL utilizando Python y Flask. Un encurtidor de URL es una herramienta que toma una URL larga y la convierte en una URL más corta y manejable. Esto puede ser útil para compartir enlaces en redes sociales o en correos electrónicos, así como para hacer que las URLs largas sean más amigables para el usuario.

👀 Vista previa

Vista previa de la interfaz del encurtidor de URL

🎯 Tareas

En este proyecto, aprenderás:

  • Cómo configurar una carpeta de proyecto y crear los archivos necesarios para el encurtidor de URL.
  • Cómo configurar una base de datos SQLite para almacenar las URLs originales y sus correspondientes URLs encurtidas.
  • Cómo generar URLs encurtidas utilizando caracteres aleatorios.
  • Cómo crear una página de índice donde los usuarios pueden enviar una URL para que sea encurtida y mostrar la URL encurtida.
  • Cómo redirigir a los usuarios a la URL original cuando ingresan una URL encurtida.
  • Cómo crear una página de historial para mostrar todas las URLs que se han encurtido.
  • Cómo ejecutar el proyecto y probarlo en un navegador web.

🏆 Logros

Después de completar este proyecto, serás capaz de:

  • Comprender cómo configurar un proyecto Flask y crear los archivos necesarios.
  • Utilizar SQLite para crear una base de datos y ejecutar consultas.
  • Generar caracteres aleatorios para las URLs encurtidas.
  • Desarrollar plantillas HTML y extender plantillas base.
  • Manejar envíos de formularios y mostrar contenido dinámico utilizando Flask.
  • Implementar la redirección de URL basada en la entrada del usuario.

Creando los archivos del proyecto

Para comenzar, necesitamos crear una carpeta de proyecto y agregar los siguientes archivos a ella:

  • app.py: Este archivo contendrá todo el código para nuestro encurtidor de URL.
  • templates/index.html: Este archivo contendrá el código HTML para la página de índice de nuestro sitio web.
  • templates/history.html: Este archivo contendrá el código HTML para la página de historial de nuestro sitio web.
  • templates/base.html: Este archivo contendrá el código HTML base que se utilizará tanto en index.html como en history.html.
cd ~/proyecto
touch app.py
mkdir templates
touch templates/index.html templates/history.html templates/base.html
✨ Revisar Solución y Practicar

Configurando la base de datos

Nuestro encurtidor de URL necesitará una base de datos para almacenar las URLs originales y sus correspondientes URLs encurtidas. Utilizaremos SQLite para nuestra base de datos, que es un sistema de gestión de bases de datos ligero y fácil de usar.

Para configurar la base de datos, primero debemos importar los módulos necesarios en app.py:

## app.py
from flask import Flask, render_template, request, redirect
import string
import random
import sqlite3

Luego, necesitamos conectarnos a la base de datos SQLite y crear un objeto cursor:

## Conectarse a la base de datos SQLite
conn = sqlite3.connect("urls.db", check_same_thread=False)
db = conn.cursor()

Luego, podemos crear una tabla en nuestra base de datos para almacenar las URLs:

## Crear la tabla urls si no existe
db.execute(
    """CREATE TABLE IF NOT EXISTS urls
              (id INTEGER PRIMARY KEY AUTOINCREMENT,
               original_url TEXT NOT NULL,
               short_url TEXT NOT NULL,
               created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"""
)
conn.commit()
✨ Revisar Solución y Practicar

Generando URLs cortas

Para generar URLs encurtidas, usaremos una combinación de letras y números aleatorios. Esto se puede lograr utilizando los módulos string y random en Python. Crearemos una función llamada generate_short_url() que devolverá una cadena aleatoria de 6 caracteres:

def generate_short_url():
    characters = string.ascii_letters + string.digits
    short_url = "".join(random.choice(characters) for _ in range(6))
    return short_url
✨ Revisar Solución y Practicar

Creando la página de índice

La página de índice de nuestro sitio web permitirá a los usuarios enviar una URL para que sea encurtida. También mostrará la URL encurtida una vez que se haya generado. El código HTML para esta página se puede encontrar en templates/index.html.

Primero, necesitamos extender la plantilla base.html y crear un formulario para que los usuarios envíen sus URLs:

{% extends "base.html" %} {% block content %}
<div class="text-center">
  <h1 class="text-3xl font-bold text-gray-900 mb-8">Acorta tu URL</h1>
  <form action="/" method="POST" class="w-full max-w-sm mx-auto">
    <div
      class="flex items-center border-2 border-blue-500 rounded overflow-hidden"
    >
      <input
        type="text"
        name="original_url"
        placeholder="Ingrese URL"
        class="appearance-none bg-transparent border-none w-full text-gray-700 py-2 px-4 leading-tight focus:outline-none"
      />
      <button
        type="submit"
        class="bg-blue-500 hover:bg-blue-700 text-white py-2 px-4 rounded-r focus:outline-none"
      >
        Acortar
      </button>
    </div>
  </form>
  {% if short_url %}
  <div class="mt-4">
    <p class="text-lg text-gray-700">
      URL encurtida:
      <a href="{{ request.host_url }}{{ short_url }}" class="text-blue-500"
        >{{ request.host_url }}{{ short_url }}</a
      >
    </p>
  </div>
  {% endif %}
</div>
{% endblock %}

En index.html, tenemos un formulario con un solo campo de entrada para que el usuario ingrese su URL. El formulario se enviará a la misma página, por lo que establecemos el atributo action en /. También establecemos el atributo method en POST para que los datos del formulario se envíen en el cuerpo de la solicitud.

Ahora, necesitamos agregar templates/base.html:

<!doctype html>
<html>
  <head>
    <title>Encurtidor de URL</title>
    <link
      href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <nav class="p-6 bg-white flex justify-between items-center">
      <a href="/" class="text-2xl font-bold text-gray-900">Encurtidor de URL</a>
      <div>
        <a href="/" class="text-gray-800 mr-6">Inicio</a>
        <a href="/history" class="text-gray-800">Historial</a>
      </div>
    </nav>
    <main class="container mx-auto max-w-xl pt-8 min-h-screen">
      {% block content %} {% endblock %}
    </main>
  </body>
</html>

En base.html, tenemos una barra de navegación en la parte superior de la página con enlaces a la página de inicio y la página de historial. También tenemos un elemento main que contendrá el contenido de cada página. El bloque content es donde se insertará el contenido de cada página.

También necesitamos agregar el código necesario en app.py para manejar los envíos de formularios y generar la URL encurtida:

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "POST":
        original_url = request.form["original_url"]
        short_url = generate_short_url()

        ## Insertar las URLs original y encurtida en la base de datos
        db.execute(
            "INSERT INTO urls (original_url, short_url) VALUES (?,?)",
            (original_url, short_url),
        )
        conn.commit()

        return render_template("index.html", short_url=short_url)

    return render_template("index.html")

En index(), verificamos si el método de solicitud es POST. Si es así, obtenemos la URL original de los datos del formulario y generamos una URL encurtida. Luego insertamos las URLs original y encurtida en la base de datos y renderizamos la plantilla index.html con la URL encurtida.

✨ Revisar Solución y Practicar

Redirigiendo a la URL original

Cuando un usuario ingresa una URL encurtida, queremos redirigirlo a la URL original correspondiente. Para hacer esto, necesitamos crear una función que recuperará la URL original de la base de datos basada en la URL encurtida:

@app.route("/<short_url>")
def redirect_to_url(short_url):
    ## Recuperar la URL original de la base de datos basada en la URL corta
    db.execute("SELECT original_url FROM urls WHERE short_url=?", (short_url,))
    result = db.fetchone()

    if result:
        original_url = result[0]
        return redirect(original_url)

    return render_template("index.html")
✨ Revisar Solución y Practicar

Creando la página de historial

La página de historial mostrará todas las URLs que se han encurtido, junto con sus URLs originales y la fecha en que se agregaron. El código HTML para esta página se puede encontrar en templates/history.html.

Primero, necesitamos extender la plantilla base.html y agregar una tabla para mostrar las URLs:

{% extends "base.html" %} {% block content %}
<div class="w-full overflow-x-auto">
  <table class="w-full bg-white rounded shadow overflow-hidden">
    <thead class="bg-gray-200">
      <tr>
        <th
          class="text-left py-3 px-4 uppercase font-semibold text-sm text-gray-700"
        >
          URL original
        </th>
        <th
          class="text-left py-3 px-4 uppercase font-semibold text-sm text-gray-700"
        >
          URL encurtida
        </th>
        <th
          class="text-left py-3 px-4 uppercase font-semibold text-sm text-gray-700"
        >
          Fecha
        </th>
      </tr>
    </thead>
    <tbody>
      {% for result in results %}
      <tr class="hover:bg-gray-100">
        <td class="border-t">
          <p class="py-3 px-4">{{ result[0] }}</p>
        </td>
        <td class="border-t">
          <a
            href="{{ request.host_url }}{{ result[1] }}"
            class="py-3 px-4 text-blue-500 hover:text-blue-700"
            >{{ request.host_url }}{{ result[1] }}</a
          >
        </td>
        <td class="border-t">
          <p class="py-3 px-4">{{ result[2] }}</p>
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
</div>
{% endblock %}

También necesitamos agregar el código necesario en app.py para recuperar las URLs de la base de datos y pasarlas a la plantilla:

@app.route("/history")
def history():
    ## Recuperar todas las URLs de la base de datos, ordenadas por las más recientes
    db.execute(
        "SELECT original_url, short_url, created_at FROM urls ORDER BY created_at DESC"
    )
    results = db.fetchall()
    return render_template("history.html", results=results)
✨ Revisar Solución y Practicar

Ejecutando el proyecto

Agregue el siguiente código al final de app.py:

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=8080)

Una vez que se hayan instalado los módulos, podemos ejecutar nuestro proyecto ejecutando python app.py en nuestra terminal. Esto iniciará el servidor de desarrollo de Flask y nuestro sitio web será accesible en http://localhost:8080.

Cambie a la pestaña 8080 y actualice la página. Debería ver lo siguiente:

Flask server running successfully
✨ Revisar Solución y Practicar

Resumen

En este proyecto, aprendimos cómo crear un encurtidor de URL utilizando Python y Flask. Primero configuramos los archivos y la base de datos necesarios para el proyecto, luego creamos funciones para generar URLs encurtidas y manejar los envíos de formularios. También aprendimos cómo recuperar y mostrar las URLs de la base de datos. Con este proyecto, ahora puedes crear tu propio encurtidor de URL y personalizarlo según tus gustos.