API Django para procesamiento de imágenes

René Silva Valdés
Python Data Science
4 min readApr 25, 2024

Al momento de trabajar con imágenes, o datos en general, existen ocasiones en las que la máquina en la cual trabajamos es distinta de aquella en donde realizamos el procesamiento(un servidor on-premise o cloud, por ejemplo). Si no deseamos trabajar directamente en el servidor, con todo lo que ello implica, podemos optar por configurar este último como una API para el procesamiento. En este articulo lo haremos utilizando el framework Django en lenguaje Python.

Django

Django

Django es un framework de Python para el desarrollo web. Adicionalmente, haremos uso del Django REST Framework (DRF), el cual en un toolkit para el desarrollo de APIs. Algunos conceptos importantes a conocer son serializers, vistas y urls:

  • Serializer: Es una herramienta de DRF que facilita el intercambio de datos entre cliente y servidor al asegurar que la entrada y la salida de datos estén en el formato correcto y sean adecuadas para su consumo en diferentes contextos.
  • Vistas: Funcionan como el puente entre los modelos de datos y los templates, manejando la lógica necesaria para procesar las peticiones de los usuarios y devolver las respuestas correctas.
  • URLS: Actúan como el mapeador entre las peticiones HTTP que recibe un sitio web y el código Python que las maneja. Este mapeo se define en lo que Django llama el “sistema de enrutamiento de URL”, que utiliza expresiones regulares o rutas de estilo de ruta para capturar patrones de URL y dirigirlos a las vistas adecuadas.

Con estos conceptos claros, podemos comenzar el desarrollo.

Paso 1: Instalar Django, crear proyecto y aplicacion

Primero instalamos Django y DRF con:

pip install django djangorestframework Pillow

Luego creamos nuesto proyecto (ImageAPI) ejecutando:

django-admin startproject ImageAPI

A continuación, en la carpeta de nuestro proyecto, creamos nuestra aplicación (imageapp) con:

python manage.py startapp imageapp

Luego creamos/modificamos el archivo ImageAPI/settings.py para agregar los elementos rest_framework e imageapp a la lista INSTALLED_APPS. Aquí cabe destacar que un proyecto puede tener multiples aplicaciones.

INSTALLED_APPS = ['rest_framework',
'imageapp',]

Paso 2: Definir serializer, vista y url

Comenzamos por el serializer, el cual se encargará de estandarizar la comunicación entre cliente y servidor. Para esto editamos nuestro archivo imageapp/serializers.py y agregamos:

from rest_framework import serializers

class ImageUploadSerializer(serializers.Serializer):
image = serializers.ImageField()

Notamos que nuestro ImageUploadSerializer utiliza serializers.ImageField(), lo que nos permite verificar que el archivo cargado sea un tipo de archivo de imagen válido, también asegura que se respeten los límites de tamaño de archivo (si están configurados) y valida que el archivo no esté corrupto y pueda ser procesado correctamente.

A continuación definimos nuestra vista, la cual usara nuestro serializer para cargar una imagen, procesarla y luego devolver un resultado. Para definirla editamos el archivo imageapp/views.py agregando:

from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from .serializers import ImageUploadSerializer

def process_image(image_file):
# Lógica para procesar la imagen
# Por ejemplo, calcular el tamaño de la imagen
return {'details': f'Processed image size: {image_file.size} bytes'}

class ImageProcessView(APIView):
parser_classes = [MultiPartParser, FormParser]

def post(self, request, *args, **kwargs):
serializer = ImageUploadSerializer(data=request.data)
if serializer.is_valid():
image_file = serializer.validated_data['image']
result = process_image(image_file)
return Response(result)
return Response(serializer.errors, status=400)

Como podemos ver, la vista ImageProcessView hereda de APIView, que es una clase nativa de DRF diseñada para manejar vistas relacionadas con APIs. Utilizar APIView nos ayuda a tener un manejo claro y estructurado de diferentes métodos HTTP. En nuestro caso, estamos implementando el método post para manejar las cargas de imágenes.

Por ultimo definimos nuestras urls. Aquí es importante distinguir entre dos archivos urls.py:

  • urls.py del Proyecto: Funciona como el nivel más alto de configuración de URL, que enruta las solicitudes a las aplicaciones correspondientes usando include().
  • urls.py de la Aplicación: Define rutas específicamente para los recursos y funcionalidades ofrecidas por una aplicación individual.

Con esto, editamos el archivo ImageAPI//urls.py para que incluya lo siguiente:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('imageapp.urls')), # Incluye las rutas de la aplicación imageapp
]

Luego editamos el archivo imageapp/urls.py de la siguiente manera:

from django.urls import path
from .views import ImageProcessView

urlpatterns = [
path('process/', ImageProcessView.as_view(), name='image-process'),
]

Aqui utilizamos la función path para definir una ruta URL. path toma un string que define el patrón de la URL, una vista que manejará las solicitudes a esa URL, y opcionalmente, un nombre que se puede utilizar para referenciar la URL en otras partes del código, como en las plantillas de Django.

Con todo esto listo, podemos probar nuestra API

Paso 3: Desplegar y testear

Para probar nuestra API con solicitudes desde localhost ejecutamos:

python manage.py runserver

O alternativamente, si deseamos hacer las solicitudes desde otro dispositivo en la red:

python manage.py runserver 0.0.0.0:8000

Si este último es el caso, también debemos asegurarnos de que el dispositivo que hará las solicitudes se encuentre en la lista de ALLOWED_HOSTS , esto lo haremos editando el archivo settings.py del proyecto agregando:

ALLOWED_HOSTS = [DEVICE_IP, ‘localhost’, ‘127.0.0.1’]

Ahora, para efectuar una prueba, debemos enviar una imagen a nuestro servidor, para lo cual nos ayudaremos de una imágen cualquiera y el comando curl . En la consola ejecutaremos:

curl -X POST -F “image=@PATH_TO_IMAGE.png” http://localhost:8000/api/process/

Deberíamos recibir un output similar al siguiente:

{“details”:”Processed image size: 95262 bytes”}

Con esto hemos creado una aplicación básica de Django la cual nos permite procesar imágenes en el servidor con la función process_image .

Espero que este post te haya sido de ayuda, te envío un abrazo y nos vemos en el siguiente :)

--

--