Arquivos temporários aparecem em exportações, uploads, testes, conversões, downloads, processamento de imagens e comunicação com programas externos. Criar esses arquivos manualmente em uma pasta fixa parece simples, mas pode gerar colisões de nomes, permissões incorretas, dados deixados no disco e vulnerabilidades de corrida. O módulo tempfile no Python fornece APIs seguras e portáveis para criar arquivos e diretórios temporários com limpeza automática.
Neste guia, você aprenderá a usar TemporaryFile, NamedTemporaryFile, SpooledTemporaryFile, TemporaryDirectory, mkstemp() e mkdtemp(), além de entender diferenças entre Windows e Unix, modos binário e texto, nomes visíveis, limpeza, testes e segurança. O conteúdo complementa nossos artigos sobre listas em Python, slicing, collections, PermissionError e desempenho em Python.
Por que não criar um nome temporário manualmente
Um código como open('/tmp/arquivo.txt', 'w') pode funcionar em um teste isolado, mas é frágil em produção. Dois processos podem escolher o mesmo nome, um invasor pode criar um arquivo ou link antes do programa, e caminhos fixos podem não existir ou não ter permissão em outro sistema.
tempfile combina escolha de nome e criação segura em uma única operação. Os nomes recebem caracteres aleatórios e as permissões seguem regras adequadas para o usuário que criou o recurso.
TemporaryFile: armazenamento temporário simples
TemporaryFile() retorna um objeto semelhante a um arquivo. Por padrão, ele abre em modo binário de leitura e escrita, w+b, e é removido quando fechado.
from tempfile import TemporaryFile
with TemporaryFile() as arquivo:
arquivo.write(b"resultado temporario")
arquivo.seek(0)
dados = arquivo.read()
print(dados)O bloco with garante fechamento e limpeza mesmo quando uma exceção ocorre. Em sistemas Unix, o arquivo pode não ter um nome visível no diretório. Em outras plataformas, a implementação pode usar um arquivo nomeado. Portanto, não escreva código que dependa da visibilidade do caminho.
Modo texto e codificação
Quando o conteúdo é textual, declare modo, codificação e tratamento de novas linhas.
from tempfile import TemporaryFile
with TemporaryFile(mode="w+t", encoding="utf-8") as arquivo:
arquivo.write("Olá, arquivo temporário!\n")
arquivo.seek(0)
print(arquivo.read())Usar parâmetros explícitos evita diferenças de codificação entre máquinas. Para imagens, PDFs, ZIPs e dados de rede, mantenha o modo binário.
NamedTemporaryFile: quando você precisa do caminho
Algumas bibliotecas e comandos externos exigem um nome de arquivo, não apenas um objeto aberto. NamedTemporaryFile() cria um arquivo com caminho visível e expõe esse caminho em name.
from tempfile import NamedTemporaryFile
with NamedTemporaryFile(suffix=".json") as arquivo:
print(arquivo.name)
arquivo.write(b'{"status": "ok"}')
arquivo.flush()
# passe arquivo.name para outra APIO sufixo é útil quando a ferramenta externa identifica o formato pela extensão. Você também pode definir prefix e dir, preferencialmente por argumentos nomeados.
delete e delete_on_close
Por padrão, o arquivo nomeado é excluído ao ser fechado. Desde o Python 3.12, delete_on_close permite separar o fechamento do objeto da remoção no fim do contexto.
from tempfile import NamedTemporaryFile
with NamedTemporaryFile(
mode="w+b",
suffix=".bin",
delete=True,
delete_on_close=False,
) as arquivo:
caminho = arquivo.name
arquivo.write(b"dados")
arquivo.close()
with open(caminho, "rb") as leitura:
print(leitura.read())
# remoção no fim do with externoEsse padrão ajuda quando uma biblioteca precisa reabrir o arquivo pelo nome. Se delete=False, a aplicação assume responsabilidade total pela remoção.
Diferenças importantes no Windows
No POSIX, um arquivo aberto normalmente pode ser reaberto ou removido enquanto ainda está em uso. No Windows, o compartilhamento e a permissão de exclusão são mais restritos. Reabrir um NamedTemporaryFile ainda aberto pode falhar dependendo de delete, delete_on_close e da forma de abertura adicional.
Uma opção previsível é usar delete_on_close=False, fechar o objeto antes de reabrir pelo nome e garantir que todos os outros descritores estejam fechados antes de sair do contexto. Também teste o comportamento no mesmo sistema operacional usado em produção.
TemporaryDirectory para árvores temporárias
Quando o processamento usa vários arquivos, crie um diretório temporário inteiro.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory(prefix="relatorio-") as pasta:
raiz = Path(pasta)
entrada = raiz / "entrada.csv"
saida = raiz / "saida.json"
entrada.write_text("nome,valor\nA,10\n", encoding="utf-8")
saida.write_text('{"total": 10}', encoding="utf-8")
print(list(raiz.iterdir()))
# pasta e conteúdo removidosO atributo ou valor retornado pelo contexto contém o caminho. A limpeza recursiva acontece ao final. Isso é ideal para testes de importação, descompactação controlada e pipelines de conversão.
Parâmetros delete e ignore_cleanup_errors
TemporaryDirectory aceita ignore_cleanup_errors para limpeza em melhor esforço, especialmente útil diante de arquivos ainda abertos no Windows. Desde o Python 3.12, delete=False pode preservar a pasta ao sair do contexto, o que ajuda na depuração.
from tempfile import TemporaryDirectory
with TemporaryDirectory(delete=False) as pasta:
print("Preservada para análise:", pasta)Não use essa opção permanentemente em produção sem uma política de retenção. Diretórios temporários esquecidos podem consumir todo o disco.
SpooledTemporaryFile: memória antes do disco
SpooledTemporaryFile mantém dados em memória até ultrapassar max_size ou até uma operação como fileno() exigir um arquivo real. Depois, ocorre o rollover para o disco.
from tempfile import SpooledTemporaryFile
with SpooledTemporaryFile(max_size=1024 * 1024) as arquivo:
arquivo.write(b"conteudo pequeno")
arquivo.seek(0)
print(arquivo.read())Essa classe é útil para uploads, respostas geradas e transformações cujo tamanho costuma ser pequeno, mas pode crescer. Ela combina velocidade de memória com uma saída segura para volumes maiores.
Forçando rollover
Quando uma API exige um descritor de arquivo real, chame rollover().
with SpooledTemporaryFile(max_size=10_000) as arquivo:
arquivo.write(b"abc")
arquivo.rollover()
print(arquivo.fileno())Evite acessar o atributo interno _file; ele é detalhe de implementação. Use a interface pública de arquivo.
mkstemp(): API de baixo nível
mkstemp() cria um arquivo de maneira segura e retorna um descritor de sistema operacional e um caminho absoluto.
import os
from tempfile import mkstemp
fd, caminho = mkstemp(suffix=".txt", prefix="processo-")
try:
with os.fdopen(fd, "w", encoding="utf-8") as arquivo:
arquivo.write("conteúdo")
finally:
if os.path.exists(caminho):
os.unlink(caminho)A função não remove o arquivo automaticamente. Fechar apenas o descritor não apaga o caminho. Prefira as APIs de alto nível quando não houver uma necessidade específica.
mkdtemp(): diretório com limpeza manual
mkdtemp() cria um diretório seguro e retorna seu caminho absoluto. A limpeza é responsabilidade da aplicação.
import shutil
from pathlib import Path
from tempfile import mkdtemp
pasta = Path(mkdtemp(prefix="job-"))
try:
(pasta / "resultado.txt").write_text("ok", encoding="utf-8")
finally:
shutil.rmtree(pasta, ignore_errors=False)Se você deseja limpeza automática, TemporaryDirectory normalmente é mais simples e menos propenso a vazamentos.
Nunca use mktemp()
A documentação oficial de tempfile marca mktemp() como obsoleto e inseguro. Ele gera um nome que não existia no momento da chamada, mas não cria o arquivo imediatamente. Outro processo pode ocupar o nome antes da abertura, produzindo uma condição de corrida.
Use NamedTemporaryFile ou mkstemp(), que criam o recurso no mesmo passo em que escolhem o nome.
Escolhendo prefix, suffix e dir
prefix facilita a identificação durante depuração e suffix preserva a extensão esperada por ferramentas externas. dir permite controlar a localização.
with NamedTemporaryFile(
prefix="miniatura-",
suffix=".png",
dir="/caminho/controlado",
) as imagem:
passO diretório deve existir e ser gravável. Evite construir nomes com entrada não confiável. Mesmo quando a função cria a parte aleatória, um prefixo malicioso pode confundir logs ou ferramentas.
Onde os temporários são criados
gettempdir() informa o diretório padrão. A escolha considera variáveis como TMPDIR, TEMP e TMP, além de locais específicos da plataforma.
from tempfile import gettempdir
print(gettempdir())Não presuma que sempre será /tmp. Contêineres, serviços e sistemas corporativos podem direcionar temporários para outro volume. Também não altere globalmente tempfile.tempdir sem forte justificativa; prefira o argumento dir.
Flush, seek e sincronização
Após escrever, reposicione o cursor antes de ler com seek(0). Se outro processo ou biblioteca abrirá o mesmo caminho, execute flush() para enviar buffers do Python ao sistema operacional.
with NamedTemporaryFile() as arquivo:
arquivo.write(b"123")
arquivo.flush()
arquivo.seek(0)
assert arquivo.read() == b"123"Para garantias de persistência física, os.fsync() pode ser necessário, mas isso raramente faz sentido para dados temporários e possui custo maior.
Arquivos temporários em uploads
Uploads não devem ser mantidos integralmente em memória sem limite. Uma estratégia é receber o fluxo em SpooledTemporaryFile, impor tamanho máximo, validar tipo real, processar e remover o conteúdo ao fim.
O fato de um arquivo ser temporário não o torna confiável. Continue aplicando limites, antivírus quando necessário, validação de formato e proteção contra conteúdo malicioso.
Uso com subprocessos
Alguns programas aceitam entrada padrão; essa opção evita criar um caminho. Quando o programa exige arquivo, use NamedTemporaryFile ou TemporaryDirectory, feche e faça flush conforme a plataforma, passe o caminho como argumento separado e nunca monte um comando de shell por concatenação.
Remova resultados no bloco finally quando a limpeza não for automática. Uma falha do processo externo não deve deixar dados sensíveis no disco.
Testes com TemporaryDirectory
Diretórios temporários tornam testes independentes da máquina.
from pathlib import Path
from tempfile import TemporaryDirectory
def salvar(caminho, texto):
Path(caminho).write_text(texto, encoding="utf-8")
with TemporaryDirectory() as pasta:
destino = Path(pasta) / "teste.txt"
salvar(destino, "valor")
assert destino.read_text(encoding="utf-8") == "valor"Cada teste recebe uma área isolada, reduz colisões e não polui o repositório. Frameworks como pytest oferecem fixtures equivalentes, mas entender tempfile ajuda em scripts e testes sem dependências.
Segurança e dados sensíveis
As funções criam nomes de forma segura, porém a aplicação ainda precisa controlar permissões do diretório, tempo de retenção e exposição em logs. Não registre caminhos contendo identificadores sensíveis. Evite temporários em volumes compartilhados sem isolamento e considere criptografia quando o modelo de ameaça exigir.
Em POSIX, uma interrupção abrupta com SIGKILL pode impedir a limpeza de arquivos nomeados. Serviços de longa duração devem ter monitoramento de espaço e uma rotina de remoção por idade para resíduos legítimos.
Erros frequentes
- Usar nomes fixos em diretórios compartilhados.
- Escolher
mktemp()apenas porque retorna um caminho. - Esquecer
seek(0)antes de ler. - Não executar
flush()antes de passar o arquivo a outro processo. - Confiar em comportamento POSIX no Windows.
- Usar
delete=Falsesem remover depois. - Guardar uploads ilimitados em memória.
- Presumir que o diretório temporário sempre é
/tmp.
Boas práticas
- Prefira context managers e APIs de alto nível.
- Use
TemporaryFilequando não precisa do caminho. - Use
NamedTemporaryFilequando outra API precisa do nome. - Use
TemporaryDirectorypara múltiplos artefatos. - Use
SpooledTemporaryFilepara conteúdo pequeno com limite. - Teste explicitamente no Windows quando houver reabertura.
- Defina limites de tamanho e política de retenção.
- Consulte também a documentação oficial de pathlib.
Conclusão
O módulo tempfile no Python elimina grande parte do trabalho perigoso envolvido na criação de arquivos temporários. Ele gera nomes sem colisão, cria recursos com segurança, oferece limpeza automática e funciona em diferentes sistemas operacionais.
A escolha depende da integração: TemporaryFile para um objeto descartável, NamedTemporaryFile para APIs que exigem caminho, SpooledTemporaryFile para equilibrar memória e disco e TemporaryDirectory para pipelines com vários arquivos. Com context managers, limites, testes multiplataforma e limpeza previsível, os temporários deixam de ser uma fonte de vazamentos, falhas de permissão e riscos de segurança.







