mimetypes en Python: tipos MIME

Publicado el: 08/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

    Búsqueda binaria y listas ordenadas con bisect en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    bisect en Python: listas ordenadas

    Aprende bisect en Python para búsqueda binaria, inserción ordenada, duplicados, rangos y diseño seguro de listas.

    Ler mais

    Tempo de leitura: 5 minutos
    08/08/2026
    Código y archivos empaquetados con importlib.resources en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    importlib.resources en Python: guía práctica

    Aprende importlib.resources en Python para acceder a archivos empaquetados con seguridad en wheels y aplicaciones instaladas.

    Ler mais

    Tempo de leitura: 5 minutos
    07/08/2026
    Teclado y flujo de datos que representa el procesamiento de varios archivos con fileinput en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    fileinput en Python: lee varios archivos

    Aprende fileinput en Python para leer varios archivos o stdin, rastrear líneas, abrir archivos comprimidos y reescribir contenido con backups.

    Ler mais

    Tempo de leitura: 7 minutos
    07/08/2026
    Editor de código con líneas numeradas que representa el módulo linecache en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    linecache en Python: lee líneas por número

    Aprende linecache en Python para leer líneas por número, administrar la caché, actualizar archivos modificados e integrar traceback y loaders.

    Ler mais

    Tempo de leitura: 7 minutos
    07/08/2026
    Datos binarios que representan serialización interna con marshal en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    marshal en Python: serialización interna

    Aprende marshal en Python para serializar tipos internos, controlar versiones y bloquear objetos de código cuando no sean necesarios.

    Ler mais

    Tempo de leitura: 6 minutos
    06/08/2026
    Monitor con código binario que representa personalización de pickle con copyreg en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    copyreg en Python: personaliza pickle

    Aprende copyreg en Python para registrar funciones de reducción, personalizar pickle y preservar compatibilidad de objetos.

    Ler mais

    Tempo de leitura: 6 minutos
    06/08/2026