Las aplicaciones que reciben archivos, envían adjuntos, sirven descargas o generan respuestas HTTP necesitan describir el formato del contenido. mimetypes en Python ofrece una tabla de asociaciones entre extensiones y tipos MIME, por lo que puede convertir nombres como informe.pdf en application/pdf o mostrar extensiones posibles para un tipo conocido.
El módulo resulta útil en APIs, servidores web, sistemas de almacenamiento, clientes de correo y flujos documentales. Sin embargo, trabaja principalmente con el nombre, la ruta o la URL. No abre el archivo ni demuestra que los bytes coincidan con el tipo declarado. Esta guía explica la API moderna, la diferencia entre tipo y encoding, las bases personalizadas, la portabilidad y el diseño seguro de cargas.
El contenido complementa nuestras guías sobre tempfile en Python, fileinput, importlib.resources, shlex y filecmp.
Qué representa un tipo MIME
Un tipo MIME describe una categoría general y un formato específico. Suele contener dos partes separadas por una barra, como text/plain, image/png, application/json o audio/mpeg. En HTTP normalmente aparece en el encabezado Content-Type.
El valor ayuda al consumidor a decidir cómo interpretar los bytes, pero no constituye una garantía de seguridad. Navegadores, bibliotecas y sistemas operativos pueden aplicar verificaciones adicionales, y un atacante puede asignar una extensión inocente a un archivo peligroso.
Obtener el tipo de una ruta
En versiones modernas utiliza guess_file_type() cuando tienes una ruta de archivo.
import mimetypes
tipo, encoding = mimetypes.guess_file_type("informe.pdf")
print(tipo) # application/pdf
print(encoding) # NoneLa función devuelve una tupla. El primer elemento es el tipo MIME o None cuando el sufijo falta o es desconocido. El segundo identifica un encoding asociado al nombre, como gzip.
guess_type para URLs
guess_type() sigue siendo la interfaz destinada a URLs. Desde Python 3.13, pasar una ruta local está suavemente obsoleto; el código nuevo debe usar guess_file_type() para archivos.
tipo, encoding = mimetypes.guess_type(
"https://ejemplo.com/descargas/datos.json"
)
print(tipo) # application/jsonLa separación evita ambigüedades, especialmente en Windows, donde las letras de unidad, las barras y los esquemas de URL tienen significados distintos.
Tipo MIME y encoding son conceptos distintos
Un nombre compuesto como copia.tar.gz puede producir dos valores.
tipo, encoding = mimetypes.guess_file_type("copia.tar.gz")
print(tipo) # application/x-tar
print(encoding) # gzipEl valor gzip es apropiado para Content-Encoding en HTTP. No es un charset ni equivale a Content-Transfer-Encoding de un mensaje de correo.
Modo estricto y flexible
Las consultas usan strict=True por defecto y priorizan tipos oficialmente registrados. Con strict=False, el módulo también considera asociaciones comunes no estándar.
tipo, encoding = mimetypes.guess_file_type(
"imagen.pict",
strict=False,
)El modo estricto suele ser más estable para APIs públicas. El modo flexible ayuda a herramientas de escritorio, importadores y sistemas que deben reconocer formatos antiguos.
Obtener una extensión
guess_extension() transforma un tipo MIME en una extensión posible.
extension = mimetypes.guess_extension("image/png")
print(extension) # .pngEl resultado representa una convención, no una prueba sobre un flujo de bytes. Algunos tipos tienen varias extensiones válidas y la base del sistema operativo puede influir.
Listar todas las extensiones
extensiones = mimetypes.guess_all_extensions("image/jpeg")
print(extensiones)Esta función sirve para filtros de selectores, reglas de importación y validadores de configuración. No dependas de un orden universal en la lista.
Registrar un tipo personalizado
Los formatos privados pueden añadirse con add_type().
mimetypes.add_type(
"application/vnd.empresa.informe+json",
".minforme",
)
tipo, _ = mimetypes.guess_file_type("mensual.minforme")Una extensión válida empieza con punto. La documentación de Python 3.14 advierte que las extensiones inválidas sin punto generarán ValueError en Python 3.16, por lo que conviene corregir registros antiguos.
Estado global y bases aisladas
mimetypes.add_type() modifica tablas globales del proceso. En aplicaciones con plugins, clientes distintos o pruebas paralelas, el cambio puede filtrarse entre componentes.
Crea una instancia de MimeTypes cuando necesites una base independiente.
base = mimetypes.MimeTypes()
base.add_type("application/x-proyecto", ".proj")
print(base.guess_file_type("datos.proj"))Las instancias aisladas facilitan las pruebas y evitan que una integración cambie silenciosamente las consultas posteriores.
Inicialización y sistema operativo
El módulo puede combinar sus asociaciones internas con archivos mime.types instalados y, en Windows, información del registro. Por ello, un mismo sufijo puede devolver resultados diferentes en dos equipos.
mimetypes.init(files=[])Una lista vacía evita cargar valores del sistema y conserva únicamente la base interna conocida. Esta opción mejora la reproducibilidad en containers, pruebas y servidores controlados.
Cargar un archivo mime.types
mimetypes.init(files=["config/mime.types"])Los archivos posteriores tienen prioridad. Trata esta configuración como código confiable, controla su versión y revisa colisiones antes del despliegue.
Leer asociaciones y manejar fallos
read_mime_types() analiza un archivo y devuelve un diccionario.
mapa = mimetypes.read_mime_types("config/mime.types")
if mapa is None:
raise RuntimeError("archivo de tipos MIME no disponible")None indica que el archivo no existe o no pudo leerse. No es lo mismo que un diccionario vacío.
Cargas: la extensión no valida los bytes
Un atacante puede renombrar programa.exe como foto.jpg. El módulo responderá basándose en el nombre y podría indicar image/jpeg. Por eso, una carga segura requiere varias capas:
- límites estrictos de tamaño;
- una lista permitida de formatos de negocio;
- inspección de los bytes con una biblioteca adecuada;
- nombres generados por el servidor;
- almacenamiento fuera de la raíz pública;
- antivirus o sandbox cuando corresponda;
- encabezados de respuesta seguros.
El tipo enviado por el navegador también es entrada controlada por el cliente.
Servir descargas con seguridad
tipo, encoding = mimetypes.guess_file_type(ruta)
content_type = tipo or "application/octet-stream"application/octet-stream es un fallback razonable para bytes desconocidos. Si el contenido debe descargarse, utiliza también Content-Disposition: attachment con un nombre normalizado y sin caracteres de control.
No inventar un charset
Un resultado como text/plain no revela si el texto usa UTF-8, Latin-1, UTF-16 u otra codificación. Añade charset=utf-8 solamente cuando la aplicación controle o haya detectado de forma fiable el encoding.
Nombres comprimidos
Para datos.json.gz, el módulo puede separar el tipo original de la compresión. Esto ayuda a crear metadatos HTTP, pero la aplicación todavía debe verificar el formato y limitar la expansión para evitar bombas de compresión.
URLs con parámetros
Extrae la ruta de la URL antes de consultar cuando existan parámetros o fragments.
from urllib.parse import urlparse
url = "https://ejemplo.com/imagen.png?version=2"
ruta = urlparse(url).path
tipo, encoding = mimetypes.guess_type(ruta)Así evitas que la query se interprete como parte del sufijo.
Adjuntos de correo
La consulta MIME ayuda a separar el tipo principal y el subtipo de un adjunto.
tipo, _ = mimetypes.guess_file_type("contrato.pdf")
principal, subtipo = (tipo or "application/octet-stream").split("/", 1)Abre los archivos en modo binario, bloquea rutas arbitrarias y recuerda que el destinatario sigue necesitando protección contra contenido malicioso.
Pruebas reproducibles
Como el sistema puede ampliar las tablas, las pruebas deben controlar la inicialización o verificar únicamente tipos garantizados. Incluye archivos sin extensión, sufijos en mayúsculas, nombres compuestos como .tar.gz, tipos personalizados, valores desconocidos y nombres Unicode.
Interfaz de línea de comandos
El módulo puede ejecutarse directamente.
python -m mimetypes imagen.png
python -m mimetypes --extension application/json
python -m mimetypes --lenient imagen.pictEs una herramienta práctica para diagnóstico en servidores, containers, CI y soporte técnico.
Errores frecuentes
- Tratar la extensión como validación del contenido.
- Confundir
Content-Encodingcon charset. - Usar
guess_type()para nuevas rutas locales. - Ignorar resultados
None. - Modificar las tablas globales en cada petición.
- Suponer respuestas idénticas en todos los sistemas.
- Registrar extensiones sin punto inicial.
- Mostrar contenido desconocido inline en el navegador.
Buenas prácticas
- Usa
guess_file_type()para rutas. - Define
application/octet-streamcomo fallback. - Inspecciona los bytes de las cargas por separado.
- Utiliza bases
MimeTypesaisladas para políticas diferentes. - Versiona los archivos de asociaciones.
- Prueba todos los sistemas soportados.
- No deduzcas el charset únicamente del tipo.
- Genera nombres en el servidor y aplica listas permitidas.
Conclusión
mimetypes en Python es una utilidad enfocada en mapear nombres, rutas, URLs, extensiones y tipos MIME. Simplifica adjuntos, descargas, respuestas HTTP e interfaces de configuración cuando el código distingue correctamente el tipo del encoding.
Su limitación es intencional: responde mediante tablas y nombres, no mediante análisis de bytes. Úsalo para metadatos y comodidad, combinado con validación real del formato, políticas de carga y encabezados seguros. Consulta la documentación oficial de mimetypes y el registro oficial de media types de IANA al definir formatos públicos o privados.







