Python: Creación de una API REST

Guía paso a paso para construir una API REST con Flask en Python

👋 ¡Bienvenido a la documentación de Stackhero!

Stackhero ofrece una solución Python en la nube lista para usar, diseñada para agilizar su proceso de despliegue:

  • Despliegue su aplicación en producción en segundos con un simple git push.
  • Utilice su propio nombre de dominio, con configuración automática del certificado HTTPS para conexiones seguras gestionadas por nosotros.
  • Cuente con copias de seguridad automáticas, actualizaciones con un solo clic y precios predecibles, para que pueda centrarse en su código y no en la gestión de la infraestructura.
  • Disfrute de un alto nivel de rendimiento y seguridad en una infraestructura privada y dedicada. Su entorno está aislado y protegido.

Ahorre tiempo y simplifique su flujo de trabajo: puede tener su código funcionando con el hosting Python en la nube de Stackhero en solo 5 minutos.

Esta guía le muestra cómo crear una API REST sencilla utilizando Python y Flask. Flask es un micro-framework ligero que facilita la creación rápida de aplicaciones web y APIs.

Antes de empezar, asegúrese de tener instaladas las siguientes herramientas:

  1. Python
  2. pip
  3. git
  4. asdf

Si necesita ayuda para configurar su entorno, consulte la guía Development platform. Alternativamente, puede empezar a programar al instante con la plataforma online Code-Hero. Code-Hero proporciona un IDE y terminal online, con todas las herramientas esenciales ya instaladas. Así podrá centrarse en su código en lugar de en la instalación y configuración.

API REST de Python ejecutándose en Code-Hero, accesible directamente desde el navegadorAPI REST de Python ejecutándose en Code-Hero, accesible directamente desde el navegador

Comience creando un nuevo directorio para el proyecto. En este ejemplo, el proyecto se llama myRestApi:

mkdir myRestApi
cd myRestApi

Establezca la versión de Python a la más reciente disponible con asdf e inicialice un repositorio Git:

asdf install python latest \
  && asdf local python latest

echo "__pycache__/" >> .gitignore

git init
git add -A .
git commit -m "First commit"

Para este ejemplo solo necesita una dependencia principal: Flask.

Flask está diseñado para ser simple y rápido, permitiéndole crear y desplegar APIs web sin sobrecarga adicional. Incluye soporte integrado para enrutamiento, plantillas y gestión de peticiones HTTP, lo que le ayuda a pasar de la idea a una API funcional en cuestión de minutos.

Puede instalar Flask y python-dotenv usando pip:

pip install Flask python-dotenv

Incluimos python-dotenv para gestionar las variables de entorno de forma segura y cómoda. Verá su uso en los siguientes pasos.

Después de instalar, congele sus dependencias en un archivo requirements.txt:

pip freeze > requirements.txt

Congelar las dependencias garantiza que todos utilicen las mismas versiones de los paquetes. Este pequeño paso puede ahorrarle horas de resolución de problemas más adelante.

Ahora está listo para escribir el código de su API.

Cree un archivo llamado app.py y añada este código:

import os
from dotenv import load_dotenv
from flask import Flask, jsonify, request

# Cargar variables de entorno desde .env para entornos que no sean de producción
if os.environ.get('ENV') != 'production':
    load_dotenv()

app = Flask(__name__)

# Datos de ejemplo para tareas
tasks = [
    {
        'id': 1,
        'title': 'Buy groceries',
        'description': 'Milk, Cheese, Pizza, Fruits',
        'done': False
    },
    {
        'id': 2,
        'title': 'Learn Python',
        'description': 'Learn Python programming basics',
        'done': False
    }
]

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})

@app.route('/api/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if not task:
        return jsonify({'error': 'Task not found'}), 404
    return jsonify({'task': task[0]})

@app.route('/api/tasks', methods=['POST'])
def create_task():
    if not request.json or 'title' not in request.json:
        return jsonify({'error': 'Title is required'}), 400
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

if __name__ == '__main__':
    if os.environ.get('ENV') == 'production':
        app.run()
    else:
        app.run(host='0.0.0.0', port=8080, debug=True)

Puede iniciar el servidor con:

python app.py

Con host='0.0.0.0', su API es accesible desde el navegador cuando utiliza Code-Hero. Visite http://<XXXXXX>.stackhero-network.com:8080/api/tasks, sustituyendo <XXXXXX> por su dominio de Code-Hero.

Una vez que el servidor esté en funcionamiento, puede interactuar con su API usando cURL. Aquí tiene algunos comandos de ejemplo:

  • Obtener todas las tareas:

    curl -s http://localhost:8080/api/tasks
    # Output:
    # {
    #   "tasks": [
    #     ...
    #   ]
    # }
    
  • Obtener una tarea específica (ID 2):

    curl -s http://localhost:8080/api/tasks/2
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    
  • Crear una nueva tarea:

    curl -s -X POST -H "Content-Type: application/json" \
    -d '{"title": "New task", "description": "Created with cURL"}' \
    http://localhost:8080/api/tasks
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    

Consejo: Para una salida más legible, puede canalizar el resultado a jq. Por ejemplo, curl -s http://localhost:8080/api/tasks/2 | jq hace que el JSON sea más fácil de leer.

Ejemplo de API REST de Python con Flask, ejecutándose en Stackhero Code-Hero, con el servidor (1) y el cliente usando cURL (2)Ejemplo de API REST de Python con Flask, ejecutándose en Stackhero Code-Hero, con el servidor (1) y el cliente usando cURL (2)

Las variables de entorno le ayudan a proteger secretos como credenciales de bases de datos o claves API. Su uso mantiene los datos sensibles fuera de su código fuente y del historial de Git, y facilita el uso de configuraciones diferentes para cada entorno.

Para gestionar variables de entorno, puede utilizar el módulo python-dotenv. Si omitió el paso de instalación anterior, puede instalarlo ahora:

pip install python-dotenv
pip freeze > requirements.txt

Cree un archivo .env en la raíz de su proyecto y añada sus variables de entorno de desarrollo:

ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"

Añada .env a su .gitignore para evitar que se suba a Git:

echo ".env" >> .gitignore

Puede acceder a estas variables en Python usando os.environ.get():

import os

print(os.environ.get('ENV'))

El archivo .env es solo para desarrollo. Para producción o preproducción, puede definir las variables de entorno directamente en el panel de Stackhero, en la configuración de su servicio Python.

El servidor integrado de Flask es ideal para desarrollo. Para producción, es recomendable utilizar un servidor WSGI robusto como Gunicorn. Así puede prepararlo:

  1. Instale Gunicorn:

    pip install gunicorn
    pip freeze > requirements.txt
    
  2. Inicie su aplicación con Gunicorn:

    ENV=production gunicorn app:app \
      --error-logfile - \
      -b 0.0.0.0:8080
    

    Aquí, app:app hace referencia a su archivo (app.py) y a la instancia de la aplicación Flask (app).

  3. Puede añadir un Makefile para alternar fácilmente entre los modos de desarrollo y producción:

    .DEFAULT_GOAL := dev
    
    # Stackhero for Python ejecuta la regla "run" por defecto. La sobrescribimos para lanzar 'prod'.
    run: prod
    
    prod:
    	ENV=production gunicorn app:app \
    	  --error-logfile - \
    	  -b 0.0.0.0:8080
    
    dev:
    	python app.py
    

Puede iniciar el servidor en modo desarrollo con make dev (o simplemente make), o en modo producción con make prod.

Stackhero facilita y asegura el despliegue en la nube. Puede desplegar su proyecto Python utilizando el servicio Python cloud hosting. Entre sus características se incluyen:

  • Despliegue con un simple git push
  • TLS (HTTPS) automático con dominios personalizables
  • Infraestructura dedicada para mayor seguridad
  • Soporte para HTTP/2, TLS 1.3, WebSockets, GZIP & Brotli, ETag y acceso a puertos TCP/UDP

Para desplegar, siga estos pasos:

  1. Obtenga su clave pública SSH:

    cat ~/.ssh/id_*.pub
    
  2. En el panel de Stackhero, abra su servicio "Stackhero for Python" y seleccione "Configure".

  3. Pegue su clave pública en el campo "SSH public keys" o "Key".

  4. Haga clic en "Validate" para confirmar la configuración.

Configuración de clave pública para "Stackhero for Python"Configuración de clave pública para "Stackhero for Python"

Si aún no tiene claves SSH, puede generarlas con:

ssh-keygen -t ed25519

Añada un remoto Git a su proyecto usando el comando proporcionado en su servicio Stackhero (sustituya <XXXXXX> por el dominio de su servicio):

git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git

Comando Git remoteComando Git remote

Cuando esté listo para desplegar, suba su código con:

git push stackhero main

Recuerde hacer commit de sus cambios antes de desplegar. En Stackhero Code-Hero, puede usar la Command Palette (Ctrl+Shift+P o Cmd+Shift+P) y escribir Git: Commit para realizar commits rápidamente.

Tras el despliegue, su API estará disponible en https://<XXXXXX>.stackhero-network.com/api/tasks. Sustituya <XXXXXX> por el dominio de su servicio para acceder a su API Flask.

Ahora dispone de una API REST funcional construida con Flask. Con esta base, es sencillo ampliar su aplicación, conectarla a bases de datos o integrarla con otros servicios. Flask le ofrece la flexibilidad necesaria para evolucionar desde un simple prototipo hasta una API de producción completa.