Aprende cómo enviar backups a través de nuestra API
https://backup-server.x10.mx/backup?key=<API_KEY>
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/octet-stream" \
--data-binary @file.backup.txt
Descripción: Crea un backup usando el estándar OAuth 2.0 Bearer Token, compatible con frameworks modernos y aplicaciones empresariales.
Parámetros:
-X POST: Método HTTP POSTAuthorization: Bearer: Header estándar OAuth 2.0Content-Type: Tipo de contenido del archivo--data-binary: Envía archivo sin modificarEstándar empresarial: Compatible con OAuth 2.0, ideal para integraciones con sistemas corporativos y aplicaciones cloud-native.
Nota: Si usas un token temporal, asegúrate de renovarlo antes de que expire.
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
--data-binary @data.json
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/zip" \
--data-binary @backup.zip
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/gzip" \
--data-binary @data.tar.gz
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: text/plain" \
--data-binary @error.log
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/octet-stream" \
--data-binary @data.bin
Content-Types comunes:
application/json: Archivos .jsontext/plain: .txt, .logapplication/zip: .zipapplication/gzip: .gz, .tar.gzapplication/octet-stream: Binarios genéricos
Importante: Para archivos binarios usa siempre --data-binary.
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/octet-stream" \
--data-binary "@file.backup.txt" \
--retry 3 \
--retry-delay 5 \
--retry-max-time 60 \
--retry-connrefused
Opciones de reintento:
--retry 3: Número de reintentos--retry-delay 5: Segundos entre intentos--retry-max-time 60: Tiempo máximo total--retry-connrefused: Reintentar si conexión rechazadacurl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/octet-stream" \
-H "X-Backup-Name: MiBackup-$(date +%Y%m%d)" \
--data-binary "@file.backup.txt"
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/octet-stream" \
-H "X-Backup-Name: Backup-Produccion" \
-H "X-Backup-Description: Backup automático diario" \
-H "X-Backup-Tags: produccion,automatico,diario" \
--data-binary "@file.backup.txt"
curl -X POST "https://backup-server.x10.mx/backup" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/octet-stream" \
-H "X-Backup-Name: DB-$(hostname)-$(date +%Y%m%d-%H%M%S)" \
-H "X-Backup-Source: $(hostname)" \
-H "X-Backup-Timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--data-binary "@file.backup.txt"
Descripción: Añade metadata personalizada a tus backups usando headers adicionales para mejor organización y trazabilidad.
Headers personalizados útiles:
X-Backup-Name: Nombre del backupX-Backup-Description: DescripciónX-Backup-Tags: Tags separados por comasX-Backup-Source: Origen del backupX-Backup-Timestamp: Fecha/hora ISO 8601import requests
import os
# Configuración
api_url = "https://backup-server.x10.mx/backup"
api_key = "<API_KEY>"
backup_file = "file.backup.txt"
if not os.path.exists(backup_file):
print(f"Error: Archivo no encontrado: {backup_file}")
exit(1)
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/octet-stream"
}
try:
with open(backup_file, 'rb') as f:
response = requests.post(api_url, headers=headers, data=f)
if response.status_code in [200, 201]:
print("Backup creado exitosamente")
print(response.json())
else:
print(f"Error: HTTP {response.status_code}")
print(response.text)
except Exception as e:
print(f"Error: {str(e)}")
Descripción: Versión simple y directa. Lee el archivo completo y lo envía en una sola petición.
Instalación:
pip install requests
backup_basico.py (nunca uses nombres como logging.py, requests.py, os.py, etc.)
import requests
from tqdm import tqdm
import os
api_url = "https://backup-server.x10.mx/backup"
api_key = "<API_KEY>"
backup_file = "file.backup.txt"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/octet-stream"
}
file_size = os.path.getsize(backup_file)
with open(backup_file, 'rb') as f:
with tqdm(total=file_size, unit='B', unit_scale=True, desc='Subiendo backup') as pbar:
class ProgressWrapper:
def __init__(self, file_obj, progress_bar):
self.file_obj = file_obj
self.progress_bar = progress_bar
def read(self, size=-1):
chunk = self.file_obj.read(size)
self.progress_bar.update(len(chunk))
return chunk
wrapped_file = ProgressWrapper(f, pbar)
response = requests.post(api_url, headers=headers, data=wrapped_file)
if response.status_code in [200, 201]:
print("\nBackup creado exitosamente")
print(response.json())
else:
print(f"\nError: HTTP {response.status_code}")
print(response.text)
Descripción: Muestra una bonita barra de progreso con velocidad y ETA. Perfecta para archivos grandes.
Instalación:
pip install requests tqdm
backup_con_progreso.py
import requests
import os
import logging
from datetime import datetime
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# Configuración de logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('backup.log', encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
API_URL = "https://backup-server.x10.mx/backup"
API_KEY = "<API_KEY>"
BACKUP_FILE = "file.backup.txt"
def create_backup(file_path):
if not os.path.exists(file_path):
logger.error(f"Archivo no encontrado: {file_path}")
return False
session = requests.Session()
retry = Retry(total=3, backoff_factor=2, status_forcelist=[500,502,503,504], allowed_methods=["POST"])
session.mount('http://', HTTPAdapter(max_retries=retry))
session.mount('https://', HTTPAdapter(max_retries=retry))
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/octet-stream"}
try:
logger.info(f"Iniciando backup de {file_path} ({os.path.getsize(file_path):,} bytes)")
with open(file_path, 'rb') as f:
r = session.post(API_URL, headers=headers, data=f, timeout=600)
if r.status_code in [200, 201]:
logger.info("Backup creado exitosamente")
return True
else:
logger.error(f"Error HTTP {r.status_code}: {r.text}")
return False
except Exception as e:
logger.error(f"Excepción: {e}")
return False
if __name__ == "__main__":
logger.info(f"=== Backup iniciado {datetime.now():%Y-%m-%d %H:%M:%S} ===")
create_backup(BACKUP_FILE) and logger.info("=== Backup completado con éxito ===") or logger.error("=== Backup fallido ===")
Descripción: Versión profesional con logs detallados, reintentos automáticos y registro en archivo.
Instalación:
pip install requests
backup_con_logging.py o upload_backup.pylogging.py → causaría error de importación circular.
import requests
from pathlib import Path
from datetime import datetime
API_URL = "https://backup-server.x10.mx/backup"
API_KEY = "<API_KEY>"
BACKUP_DIR = "./backups" # Cambia por tu directorio
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/octet-stream"
}
total = success = errors = total_size = 0
print(f"=== Backup Masivo - {datetime.now():%Y-%m-%d %H:%M:%S} ===\n")
for file_path in Path(BACKUP_DIR).glob("*.sql.gz"): # o "*.*"
if not file_path.is_file(): continue
total += 1
size = file_path.stat().st_size
total_size += size
print(f"[{total:3d}] {file_path.name} ({size/1024/1024:.2f} MB) ... ", end="")
try:
with open(file_path, 'rb') as f:
r = requests.post(API_URL, headers=headers, data=f, timeout=1800)
print("OK" if r.status_code in [200,201] else f"Error {r.status_code}")
success if r.status_code in [200,201] else errors.__iadd__(1)
except Exception as e:
print(f"Excepción: {e}")
errors += 1
print("\n" + "="*60)
print(f"Total: {total} | Éxitos: {success} | Errores: {errors} | Tamaño: {total_size/1024/1024:.2f} MB")
print("="*60)
Descripción: Sube todos los archivos de un directorio de forma automática con resumen final.
Instalación:
pip install requests
backup_masivo.py o upload_folder.py
import axios from 'axios';
import { readFile } from 'fs/promises';
const API_URL = 'https://backup-server.x10.mx/backup';
const API_KEY = '<API_KEY>';
const FILE = "file.backup.txt";
async function uploadBackup() {
try {
const data = await readFile(FILE);
const sizeMB = (data.length / (1024 * 1024)).toFixed(2);
console.log('Enviando ' + FILE + ' (' + sizeMB + ' MB)...');
const response = await axios.post(API_URL, data, {
headers: {
'Authorization': 'Bearer ' + API_KEY,
'Content-Type': 'application/octet-stream'
}
});
console.log(JSON.stringify(response.data, null, 2));
} catch (err) {
if (err.response) {
console.error('\nError del servidor:');
console.error(' ' + err.response.status + ' ' + err.response.statusText);
console.error(JSON.stringify(err.response.data, null, 2));
} else {
console.error('\nError:', err.message);
}
process.exit(1);
}
}
uploadBackup();
Instalación:
npm install axios
Ideal para archivos pequeños (< 500 MB)
import axios from 'axios';
import fs from 'fs';
import cliProgress from 'cli-progress';
const API_URL = 'https://backup-server.x10.mx/backup';
const API_KEY = '<API_KEY>';
const FILE = "file.backup.txt";
async function uploadBackup() {
const { size } = fs.statSync(FILE);
const totalMB = Number((size / (1024 * 1024)).toFixed(2));
const displayMB = totalMB === 0 ? 0.01 : totalMB;
console.log('Archivo: ' + FILE);
console.log('Tamaño: ' + totalMB.toFixed(2) + ' MB\n');
const bar = new cliProgress.SingleBar({
format: 'Progreso |{bar}| {percentage}% | {value}/{total} MB',
barCompleteChar: '█',
barIncompleteChar: '░',
hideCursor: true
});
bar.start(displayMB, 0);
const stream = fs.createReadStream(FILE);
try {
const response = await axios.post(API_URL, stream, {
headers: {
'Authorization': 'Bearer ' + API_KEY,
'Content-Type': 'application/octet-stream',
'Content-Length': size
},
maxBodyLength: Infinity,
maxContentLength: Infinity,
onUploadProgress: (e) => {
const loaded = Number((e.loaded / (1024 * 1024)).toFixed(2));
bar.update(loaded);
}
});
bar.update(displayMB);
bar.stop();
console.log(JSON.stringify(response.data, null, 2));
} catch (err) {
bar.stop();
console.error('\nError en la subida');
if (err.response) {
console.error(' ' + err.response.status + ' ' + err.response.statusText);
console.error(JSON.stringify(err.response.data, null, 2));
} else if (err.request) {
console.error(' Error de red: no se recibió respuesta');
} else {
console.error(' ' + err.message);
}
process.exit(1);
}
}
uploadBackup();
Instalación:
npm install axios cli-progress
import axios from 'axios';
import axiosRetry from 'axios-retry';
import fs from 'fs';
import cliProgress from 'cli-progress';
axiosRetry(axios, {
retries: 5,
retryDelay: axiosRetry.exponentialDelay,
retryCondition: (err) => axiosRetry.isNetworkOrIdempotentRequestError(err) || (err.response?.status ?? 0) >= 500,
onRetry: (count, err) => console.log('Reintentando ' + count + '/5 tras: ' + err.message)
});
const API_URL = 'https://backup-server.x10.mx/backup';
const API_KEY = '<API_KEY>';
const FILE = "file.backup.txt";
async function uploadBackup() {
const { size } = fs.statSync(FILE);
const totalMB = Number((size / (1024 * 1024)).toFixed(2));
const displayMB = totalMB === 0 ? 0.01 : totalMB;
console.log('Archivo: ' + FILE + ' (' + totalMB.toFixed(2) + ' MB)\n');
const bar = new cliProgress.SingleBar({
format: 'Progreso |{bar}| {percentage}% | {value}/{total} MB',
barCompleteChar: '█',
barIncompleteChar: '░',
hideCursor: true
});
bar.start(displayMB, 0);
const stream = fs.createReadStream(FILE);
try {
const response = await axios.post(API_URL, stream, {
headers: {
'Authorization': 'Bearer ' + API_KEY,
'Content-Type': 'application/octet-stream',
'Content-Length': size
},
maxBodyLength: Infinity,
maxContentLength: Infinity,
onUploadProgress: (e) => {
const loaded = Number((e.loaded / (1024 * 1024)).toFixed(2));
bar.update(loaded);
}
});
bar.update(displayMB);
bar.stop();
console.log(JSON.stringify(response.data, null, 2));
} catch (err) {
bar.stop();
console.error('\nFalló tras todos los reintentos');
if (err.response) {
console.error('\nCódigo: ' + err.response.status + ' ' + err.response.statusText);
console.error('Respuesta del servidor:');
console.error(JSON.stringify(err.response.data, null, 2));
} else if (err.request) {
console.error('Error de red: el servidor no respondió');
} else {
console.error('Error:', err.message);
}
process.exit(1);
}
}
uploadBackup();
Instalación:
npm install axios cli-progress axios-retry
text/plain para enviar el contenido del backup.
--data-binary en lugar de -d para preservar el formato.
Crea tu primer backup ahora o explora la documentación completa