mimetypes: detecta tipos MIME de archivos

Publicado el: 20/08/2026
Tempo de leitura: 6 minutos
Carpeta con archivos que representa tipos MIME identificados con mimetypes en Python

El módulo mimetypes de la biblioteca estándar de Python relaciona extensiones de archivo con tipos de medios utilizados por HTTP, correo electrónico, almacenamiento y aplicaciones de escritorio. Permite estimar si un nombre terminado en .png debería usar image/png, si un documento JSON corresponde a application/json y qué valor aplicar cuando una extensión no es reconocida.

El módulo es pequeño y práctico, pero tiene un límite esencial: normalmente infiere el tipo a partir del nombre o de la URL. No inspecciona todos los bytes del contenido. Por eso es útil para metadatos, headers, organización y experiencia de usuario, pero no debe ser la única barrera de seguridad para cargas de archivos.

Qué es un tipo de medio

Un tipo de medio suele tener la forma tipo/subtipo. Algunos ejemplos son text/html, image/jpeg, application/pdf y application/zip. Navegadores, servidores y clientes usan este valor para decidir cómo transferir, mostrar, descargar, almacenar o procesar un recurso.

El nombre MIME surgió en el correo electrónico, pero hoy estos tipos son fundamentales en HTTP y en las APIs. El header Content-Type describe el cuerpo de una respuesta. Las cargas multipart pueden declarar un tipo para cada parte. Los sistemas internos también lo usan para elegir vistas previas, pipelines, políticas de retención y análisis de seguridad.

Primer ejemplo con guess_type

import mimetypes

tipo, codificacion = mimetypes.guess_type("informe.pdf")
print(tipo)          # application/pdf
print(codificacion)  # None

La función devuelve dos valores. El primero es el tipo estimado. El segundo puede indicar una codificación de contenido asociada al sufijo, como gzip. Esa codificación no es un charset: representa una capa de compresión o transformación.

Cuando la extensión es desconocida, el tipo puede ser None. La aplicación debe definir una política: usar application/octet-stream, rechazar el archivo, solicitar una selección del usuario o realizar una inspección adicional.

Nombres de archivo y URLs

El módulo acepta nombres y URLs, pero los parámetros y fragments no deben confundirse con la extensión. Conviene separar primero la ruta. La guía de urllib.parse en Python explica cómo descomponer URLs.

from urllib.parse import urlsplit
import mimetypes

url = "https://example.com/assets/manual.pdf?download=1"
ruta = urlsplit(url).path
tipo, codificacion = mimetypes.guess_type(ruta)

La inferencia del tipo no vuelve confiable una URL. Antes de descargar, valida esquema, origen, redirects, DNS, timeout y tamaño. Consulta urllib.request en Python para aplicar límites.

Definir Content-Type

Un servidor puede usar mimetypes para elegir el header de respuesta. Cuando no reconoce el sufijo, utiliza un fallback conservador.

import mimetypes
from pathlib import Path

def content_type_for(path: Path) -> str:
    tipo, _ = mimetypes.guess_type(path.name)
    return tipo or "application/octet-stream"

No permitas que el cliente seleccione libremente una ruta local. Resuelve la ruta contra una raíz autorizada, bloquea path traversal y comprueba que el resultado permanezca dentro del directorio permitido.

La extensión no demuestra el contenido

Un atacante puede renombrar un ejecutable como foto.jpg. El módulo probablemente devolverá image/jpeg porque solo ve el sufijo. Los bytes todavía pueden pertenecer a un ejecutable, script, archivo comprimido o documento malformado.

Valida las cargas por capas. Limita tamaño, cantidad y frecuencia. Genera un identificador interno en lugar de confiar en el nombre original. Después, inspecciona la firma o procesa el archivo con una biblioteca adecuada. Finalmente, almacena fuera de directorios ejecutables y entrega con headers defensivos.

Usa tempfile en Python para áreas temporales aisladas. Usa hashlib en Python para integridad y deduplicación controlada.

Extensiones compuestas y compresión

Un nombre como backup.tar.gz combina formato y codificación. El resultado puede indicar TAR como tipo y gzip como codificación. No confundas ese segundo valor con el tipo de los archivos después de extraer.

tipo, codificacion = mimetypes.guess_type("backup.tar.gz")
print(tipo)
print(codificacion)

Las cargas comprimidas requieren límites de expansión, cantidad de entradas, profundidad y rutas internas. Las guías de zipfile en Python y tarfile en Python explican estas protecciones.

Registrar tipos personalizados

Las aplicaciones pueden añadir mappings propios con add_type().

import mimetypes

mimetypes.add_type(
    "application/vnd.example.report+json",
    ".rjson",
)
print(mimetypes.guess_type("datos.rjson"))

Registra los tipos críticos al iniciar la aplicación y documenta la decisión. Una biblioteca reutilizable debería evitar cambios globales inesperados. Los tests deben aislar o restaurar el estado.

Modo estricto

Varias funciones aceptan strict. El modo estricto prioriza tipos registrados oficialmente. Con strict=False, Python puede incluir extensiones comunes adicionales conocidas por la plataforma.

tipo, codificacion = mimetypes.guess_type(
    "imagen.webp",
    strict=False,
)

Elige una política estable. Los servicios públicos suelen preferir valores estandarizados. Las herramientas locales pueden aceptar un conjunto más amplio. Registra el tipo final para diagnosticar diferencias.

Diferencias entre sistemas operativos

Las tablas pueden variar porque Python carga información del sistema. Un tipo reconocido en el equipo de desarrollo puede faltar en un contenedor mínimo de producción. Prueba las extensiones relevantes y registra explícitamente los mappings esenciales.

No supongas que Windows, una distribución Linux de escritorio y una imagen Docker exponen exactamente la misma base de datos. Los tests deben confirmar el contrato de tu aplicación.

Del tipo a la extensión

La búsqueda inversa está disponible con guess_extension() y guess_all_extensions().

import mimetypes

print(mimetypes.guess_extension("image/jpeg"))
print(mimetypes.guess_all_extensions("image/jpeg"))

Un mismo tipo puede tener varios sufijos, como .jpg y .jpeg. No uses este resultado para reconstruir el nombre original. Elige una extensión canónica definida por tu política.

Los charsets son independientes

text/plain no indica si los bytes usan UTF-8, Latin-1 u otra codificación. El módulo no detecta charset. Si generas el texto, declara charset=utf-8. Para decodificación incremental y manejo de errores, consulta codecs en Python.

Sniffing del navegador

Algunos navegadores intentan adivinar el contenido cuando el servidor envía un tipo ausente o incorrecto. Esto puede ser peligroso con archivos de usuarios. Cuando corresponda, envía X-Content-Type-Options: nosniff y un Content-Disposition deliberado.

Los recursos que no deben ejecutarse ni mostrarse inline pueden forzarse como descarga. Los nombres dentro de headers también necesitan validación y escape.

Política práctica para APIs

Una API robusta puede comparar tres señales: extensión normalizada, tipo declarado por el cliente e inspección real del contenido. Una divergencia debería causar rechazo, cuarentena o revisión, no una corrección silenciosa.

Para imágenes, decodifica con una biblioteca mantenida y vuelve a codificar si es necesario. Para PDF, valida estructura, tamaño y política de procesamiento. Para texto, impone encoding y límite de bytes. Para archivos comprimidos, inspecciona entradas antes de extraer.

Tests recomendados

Prueba extensiones en mayúsculas y minúsculas, nombres sin extensión, varios puntos, URLs con query, tipos desconocidos, registros personalizados, sufijos comprimidos y distintos sistemas. Incluye casos hostiles como foto.jpg.exe, nombres enormes, caracteres de control y headers engañosos.

Los tests deben verificar la decisión final de la aplicación, no solo el retorno del módulo. Una estimación técnicamente correcta puede representar un formato prohibido por la política.

Errores comunes

Los errores frecuentes son confiar solo en la extensión, tratar la codificación de contenido como charset, ejecutar un archivo porque el tipo parece seguro, usar el nombre original como ruta, aceptar tipos desconocidos sin política, asumir mappings idénticos y olvidar headers defensivos.

Conclusión

mimetypes ofrece una forma rápida y sin dependencias de inferir tipos de medios a partir de nombres y URLs. Es útil para headers, metadatos, vistas previas y validación inicial. Su límite central debe quedar claro: normalmente estudia el nombre, no los bytes.

Úsalo como una capa de metadatos junto con parsing real, límites, almacenamiento seguro y headers defensivos. Consulta la documentación oficial de mimetypes y el registro de tipos de medios de IANA.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Desarrollador configurando un servidor HTTPS y certificado TLS con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    HTTPSServer: crea un servidor HTTPS local en Python

    Aprende HTTPSServer en Python para crear servicios HTTPS locales, configurar certificados, usar hilos y comprender sus límites.

    Ler mais

    Tempo de leitura: 4 minutos
    08/10/2026
    Archivos protegidos que representan extracción segura de TAR con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    tarfile extraction_filter: extrae TAR con seguridad

    Aprende tarfile extraction_filter en Python para extraer archivos TAR con validación, seguridad y control de rutas.

    Ler mais

    Tempo de leitura: 6 minutos
    08/10/2026
    Código Python mostrando avisos controlados con catch_warnings
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    catch_warnings: captura warnings en pruebas Python

    Aprende catch_warnings en Python para capturar, probar y controlar avisos con filtros específicos y alcance seguro.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código Python que representa referencias persistentes de pickle
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    pickle persistent_id: serializa referencias externas

    Aprende pickle persistent_id en Python para referencias externas estables, validación, seguridad, rendimiento y compatibilidad.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código binario que representa buffers y vistas de memoria en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    memoryview.count: cuenta valores sin copiar buffers

    Aprende memoryview.count en Python para contar bytes y valores en buffers sin copias, con formatos, límites y buenas prácticas.

    Ler mais

    Tempo de leitura: 6 minutos
    06/10/2026
    Código Python y anotaciones de tipos
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    annotationlib: evita imports circulares en anotaciones

    Aprende annotationlib en Python para inspeccionar anotaciones diferidas, evitar imports circulares y crear herramientas seguras.

    Ler mais

    Tempo de leitura: 6 minutos
    06/10/2026