shutil provides high-level filesystem operations for copying, moving, removing trees, and creating archives. Convenience does not remove risk: existing destinations may be overwritten and metadata is not fully portable.

from pathlib import Path
from shutil import copy2, make_archive

origem = Path("relatorios")
backup = Path("backup")
backup.mkdir(exist_ok=True)

for arquivo in origem.glob("*.csv"):
    copy2(arquivo, backup / arquivo.name)

make_archive("backup-relatorios", "zip", root_dir=backup)

copy2() attempts to retain more metadata than copy(), but ownership, ACLs, and platform attributes may still be lost. make_archive() builds ZIP or tar formats from a root directory. Verify the result and test restoration because creating a backup does not prove recoverability.

Practical guidance

Resolve and validate paths before destructive operations. Never pass user-controlled destinations directly to rmtree(), move(), or extraction. Inspect untrusted archive members and use safe extraction filters supported by your runtime. For atomic replacement, write to a temporary destination and then replace the final file.

Use pathlib to construct paths and the Python automation guide to structure repeatable scripts.

The official shutil documentation, accessed July 22, 2026, documents the API and its constraints.