O módulo mimetypes da biblioteca padrão do Python ajuda a relacionar extensões de arquivo com tipos de mídia usados em HTTP, e-mail e armazenamento. Ele responde perguntas como: um arquivo terminado em .png provavelmente é image/png? Um nome terminado em .json deve usar application/json? A resposta é útil para servidores web, APIs, uploads, downloads e ferramentas de automação.
Apesar de simples, o módulo precisa ser usado com cuidado. Ele normalmente trabalha a partir do nome ou da URL, não examina o conteúdo binário real. Portanto, mimetypes é excelente para inferência, configuração e experiência do usuário, mas não deve ser tratado como uma barreira de segurança isolada.
O que é um MIME type
Um tipo de mídia descreve a natureza de um recurso. Ele costuma ter a forma tipo/subtipo, como text/html, image/jpeg, application/pdf ou application/zip. Navegadores, clientes HTTP, servidores, proxies e sistemas de armazenamento usam essa informação para decidir como entregar, exibir ou processar o conteúdo.
O nome histórico MIME veio do e-mail, mas os tipos de mídia hoje aparecem em vários protocolos. Em HTTP, o header Content-Type informa o formato do corpo. Em uploads multipart, cada parte também pode declarar um tipo. Em sistemas internos, o tipo ajuda a escolher visualizadores, pipelines e regras de retenção.
Primeiro exemplo com guess_type
import mimetypes
mime_type, encoding = mimetypes.guess_type("relatorio.pdf")
print(mime_type) # application/pdf
print(encoding) # None
guess_type() retorna uma tupla. O primeiro valor é o tipo estimado. O segundo indica uma codificação de conteúdo associada ao sufixo, como gzip em certos nomes terminados em .gz. Essa codificação não é charset. Ela representa uma camada de compressão ou transformação.
Quando a extensão não é conhecida, o tipo pode ser None. O código deve ter uma política explícita para esse caso, por exemplo usar application/octet-stream, rejeitar o arquivo ou exigir inspeção adicional.
URLs e nomes de arquivo
O módulo consegue analisar nomes e URLs. Entretanto, strings com query string, fragments ou nomes pouco convencionais podem exigir normalização antes da inferência. Não remova partes arbitrariamente sem entender o contexto. Para decompor URLs, consulte o guia de urllib.parse no Python.
from urllib.parse import urlsplit
import mimetypes
url = "https://exemplo.com/assets/manual.pdf?download=1"
path = urlsplit(url).path
mime_type, encoding = mimetypes.guess_type(path)
Use apenas o caminho para inferir pela extensão. Ainda assim, não faça download automático de qualquer URL. A validação de origem, redirects, DNS, timeout e tamanho continua necessária. O artigo sobre urllib.request no Python mostra como aplicar limites ao buscar recursos externos.
Content-Type em respostas HTTP
Um servidor simples pode usar mimetypes para escolher o header da resposta. Se o tipo não for reconhecido, use um fallback conservador.
import mimetypes
from pathlib import Path
def content_type_for(path: Path) -> str:
mime_type, _ = mimetypes.guess_type(path.name)
return mime_type or "application/octet-stream"
Não permita que o cliente controle livremente o caminho local. Resolva a rota contra um diretório permitido, bloqueie path traversal e confirme que o arquivo final está dentro da raiz. A extensão correta não torna um caminho seguro.
Uploads: extensão não prova conteúdo
Um usuário pode renomear um executável para foto.jpg. Nesse caso, guess_type() provavelmente retornará image/jpeg, embora os bytes não representem uma imagem. Por isso, valide uploads em camadas:
Primeiro, limite tamanho, quantidade e frequência. Depois, normalize o nome, gere um identificador interno e não use o nome original como caminho. Em seguida, verifique a assinatura ou faça parsing com uma biblioteca adequada ao formato. Finalmente, armazene fora de diretórios executáveis e sirva com headers seguros.
Para criar nomes temporários e áreas isoladas durante a validação, veja tempfile no Python. Para calcular integridade e deduplicação, o guia de hashlib no Python apresenta SHA-256 e BLAKE2.
Extensões compostas e compressão
Arquivos como backup.tar.gz combinam formato e codificação. Dependendo da tabela disponível, o retorno pode indicar um tipo para TAR e uma codificação gzip. Não confunda esse segundo valor com o tipo final do conteúdo descompactado.
import mimetypes
mime_type, encoding = mimetypes.guess_type("backup.tar.gz")
print(mime_type)
print(encoding)
Ao aceitar arquivos compactados, também aplique limites de expansão, número de entradas, profundidade e caminhos internos. Os artigos sobre zipfile no Python e tarfile no Python explicam esses riscos.
Adicionar tipos personalizados
Aplicações podem registrar extensões próprias com add_type().
import mimetypes
mimetypes.add_type("application/vnd.exemplo.relatorio+json", ".reljson")
print(mimetypes.guess_type("dados.reljson"))
Faça esse registro na inicialização e documente a decisão. Evite alterar mappings globais de forma inesperada em bibliotecas reutilizáveis. Em testes, isole o estado ou reinicialize as tabelas quando necessário.
Modo estrito
Algumas funções aceitam o parâmetro strict. Em modo estrito, o módulo tende a considerar apenas tipos registrados oficialmente. Com strict=False, pode incluir extensões comuns adicionais conhecidas pela plataforma.
mime_type, encoding = mimetypes.guess_type("imagem.webp", strict=False)
Escolha uma política coerente. Sistemas interoperáveis podem preferir tipos padronizados. Ferramentas locais podem aceitar mappings mais amplos. Registre o tipo efetivamente enviado para facilitar diagnóstico.
Dependência do sistema operacional
As tabelas podem variar entre ambientes porque o módulo pode carregar informações do sistema. Um tipo reconhecido no computador do desenvolvedor pode não existir no contêiner de produção. Por isso, teste as extensões relevantes e registre explicitamente mappings críticos.
Em imagens Docker mínimas, não presuma que o banco de tipos será idêntico ao de uma distribuição desktop. Use testes automatizados para confirmar os tipos que sua aplicação realmente suporta.
guess_extension e ambiguidades
O caminho inverso também existe: obter uma extensão provável a partir de um tipo.
import mimetypes
print(mimetypes.guess_extension("image/jpeg"))
print(mimetypes.guess_all_extensions("image/jpeg"))
Vários sufixos podem representar o mesmo tipo, como .jpg e .jpeg. Não use o retorno para preservar o nome original. Prefira uma extensão canônica definida pela aplicação.
Charsets não vêm automaticamente
text/plain não informa por si só se os bytes estão em UTF-8, Latin-1 ou outra codificação. O módulo não detecta charset. Se você controla a geração do texto, declare explicitamente charset=utf-8. Para decodificação incremental e tratamento de erros, consulte codecs no Python.
Sniffing do navegador
Alguns navegadores tentam adivinhar o conteúdo quando o tipo parece incorreto. Isso pode criar riscos, especialmente em uploads enviados de volta ao usuário. Quando apropriado, envie X-Content-Type-Options: nosniff e um Content-Disposition coerente.
Arquivos que não devem ser executados ou exibidos inline podem ser servidos como download. Mesmo assim, nomes e headers precisam de escape e validação.
Política prática para APIs
Uma API segura pode comparar três sinais: extensão normalizada, tipo declarado pelo cliente e inspeção real do conteúdo. Divergências devem gerar rejeição ou revisão, não correção silenciosa. O tipo informado pelo cliente é apenas uma dica.
Para imagens, abra o arquivo com uma biblioteca que decodifique o formato e regrave quando necessário. Para PDFs, valide estrutura, tamanho e política de processamento. Para arquivos de texto, limite bytes, detecte ou imponha encoding e rejeite conteúdo inesperado.
Testes recomendados
Teste extensões em maiúsculas e minúsculas, nomes sem extensão, múltiplos pontos, URLs com query, tipos desconhecidos, extensões personalizadas, arquivos compactados e diferenças entre sistemas. Inclua também casos maliciosos como foto.jpg.exe, nomes muito longos e caracteres de controle.
Os testes devem verificar a decisão final da aplicação, não apenas o retorno do módulo. Um tipo estimado corretamente ainda pode ser proibido pela política de upload.
Erros comuns
Os erros mais frequentes são confiar apenas na extensão, tratar encoding como charset, executar arquivos porque o tipo parece seguro, usar nomes originais como caminhos, aceitar tipos desconhecidos sem política, presumir mappings idênticos em todos os sistemas e esquecer headers de download.
Conclusão
mimetypes oferece uma forma rápida e portátil de inferir tipos de mídia a partir de nomes e URLs. Ele é útil para definir Content-Type, organizar arquivos, escolher visualizadores e validar regras iniciais. Seu limite central é importante: ele normalmente analisa o nome, não os bytes.
Use o módulo como uma camada de metadados, combinado com validação de conteúdo, limites, armazenamento seguro e headers defensivos. Consulte a documentação oficial de mimetypes e o registro de media types da IANA.







