import subprocess import os import tarfile import datetime from fastapi import HTTPException from starlette.responses import FileResponse class BackupService: def __init__(self, db_url: str, app_files_dir: str, backup_dir: str, pg_dump_path: str): self.db_url = db_url self.app_files_dir = app_files_dir self.backup_dir = backup_dir self.pg_dump_path = pg_dump_path os.makedirs(backup_dir, exist_ok=True) async def create_backup(self) -> FileResponse: try: timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") backup_name = f"backup_{timestamp}" backup_path = os.path.join(self.backup_dir, backup_name) db_dump_path = f"{os.getcwd()}/{backup_path}.sql" dump_cmd = f'"{self.pg_dump_path}" -Fc -d {self.db_url} -f "{db_dump_path}"' subprocess.run(dump_cmd, shell=True, check=True) with tarfile.open(f"{backup_path}.tar.gz", "w:gz") as tar: tar.add(self.app_files_dir, arcname=self.app_files_dir) tar.add(db_dump_path, arcname="db_dump.sql") os.remove(db_dump_path) return FileResponse( f"{backup_path}.tar.gz", media_type="application/gzip", filename=backup_name, ) except subprocess.CalledProcessError as e: print(e) raise HTTPException(500, f"Ошибка создания бэкапа: {e}")