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

    Código HTML en una pantalla que representa análisis con html.parser en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    html.parser en Python: analiza HTML

    Aprende html.parser en Python para extraer texto, enlaces y metadatos, procesar HTML por bloques y no confundir parsing con sanitización.

    Ler mais

    Tempo de leitura: 4 minutos
    20/08/2026
    Persona usando un portátil en una sesión web que representa cookies con http.cookiejar en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    http.cookiejar en Python: gestiona cookies

    Aprende http.cookiejar en Python para mantener sesiones, aplicar políticas, persistir cookies de forma segura e integrar urllib.request.

    Ler mais

    Tempo de leitura: 5 minutos
    20/08/2026
    Rack de servidores que representa conexiones HTTP de bajo nivel con http.client en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    http.client en Python: HTTP de bajo nivel

    Aprende http.client en Python para controlar conexiones HTTP y HTTPS, streaming, headers, TLS, reutilización, límites y errores.

    Ler mais

    Tempo de leitura: 4 minutos
    20/08/2026
    Teclas formando HTTP que representan solicitudes con urllib.request en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    urllib.request en Python: HTTP nativo

    Aprende urllib.request en Python para GET, POST, JSON y descargas con timeout, TLS, redirects, proxies, límites y manejo de errores.

    Ler mais

    Tempo de leitura: 4 minutos
    19/08/2026
    Cables Ethernet conectados que representan servidores de red con socketserver en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    socketserver en Python: crea servidores

    Aprende socketserver en Python para crear servidores TCP y UDP con handlers, concurrencia, límites, timeouts y apagado seguro.

    Ler mais

    Tempo de leitura: 5 minutos
    19/08/2026
    Sala de servidores iluminada que representa conexiones TLS seguras con ssl en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ssl en Python: conexiones TLS seguras

    Aprende ssl en Python para crear clientes y servidores TLS, validar certificados y hostname, configurar CA, versiones mínimas y mTLS.

    Ler mais

    Tempo de leitura: 5 minutos
    19/08/2026