mimetypes: detecta tipos MIME por extensión

Actualizado el: 20/08/2026
Tempo de leitura: 6 minutos
Icono de archivo digital que representa tipos MIME con mimetypes en Python

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)  # None

La 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/json

La 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)  # gzip

El 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)  # .png

El 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.pict

Es 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-Encoding con 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-stream como fallback.
  • Inspecciona los bytes de las cargas por separado.
  • Utiliza bases MimeTypes aisladas 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.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Documento y bandeja de entrada que representan buzones de correo con mailbox en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    mailbox en Python: buzones de correo

    Aprende mailbox en Python para leer, crear y migrar Maildir, mbox y MH con locking, flags, mensajes y manejo seguro

    Ler mais

    Tempo de leitura: 5 minutos
    12/08/2026
    Editor de texto que representa formato con textwrap en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    textwrap en Python: formatea textos

    Aprende textwrap en Python para dividir, rellenar, acortar, indentar y quitar sangrías con control de ancho, espacios y palabras largas.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Carpeta y lupa que representan filtros de nombres con fnmatch en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    fnmatch en Python: filtra nombres de archivos

    Aprende fnmatch en Python para filtrar nombres de archivos con comodines, controlar mayúsculas, excluir patrones y distinguir glob de regex.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Monitor con datos binarios que representa arrays numéricos compactos en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    array en Python: números compactos

    Aprende array en Python para almacenar números compactos, usar archivos binarios, byte order, memoryview y buffers seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Círculo cromático que representa conversiones RGB, HSV y HLS con colorsys en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    colorsys en Python: RGB, HSV y HLS

    Aprende colorsys en Python para convertir colores entre RGB, HSV, HLS y YIQ, crear paletas y evitar errores de escala

    Ler mais

    Tempo de leitura: 5 minutos
    09/08/2026
    Icono de configuración que representa archivos plist con plistlib en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    plistlib: lee y escribe archivos plist

    Aprende plistlib en Python para leer y escribir archivos plist XML y binarios, validar datos y manejar fechas, bytes y

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026