Upload File dari Cloudflare R2 ke AWS S3 Pakai Python Parallel
Catatan praktis bikin script Python untuk download dari Cloudflare R2 lalu upload ke AWS S3, sambil hapus URL yang sukses dari list.
Masalahnya gini
Gue punya list file MP4 yang disimpan di Cloudflare R2, isinya ada di listmp4.txt. Targetnya, file-file itu mau dipindahin ke AWS S3. Jadi alurnya simpel: download dari R2, upload ke S3, lalu URL yang sukses dihapus dari list biar next run tinggal lanjut sisanya.
Kalau dikerjain manual, jelas capek. Apalagi kalau file-nya banyak. Jadi yang paling enak ya bikin script yang jalan otomatis, bisa parallel, dan aman buat diulang kalau ada yang gagal.
Solusi yang gue pakai
Gue bikin script Python yang:
- ambil URL dari
listmp4.txt - download file dari R2 pakai streaming
- langsung upload ke S3 tanpa simpan file full di disk
- jalan parallel biar lebih cepat
- hapus URL yang sukses dari list
Ini enak karena hemat RAM, nggak bikin storage lokal penuh, dan kalau gagal tinggal rerun aja.
Install dependency
pip install boto3 requestsScript Python
Ganti dulu credential AWS dan sesuaikan bucket, folder, serta endpoint kalau perlu.
import os
import sys
import time
import boto3
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.parse import urlparse
# ================== CONFIG ==================
AWS_ACCESS_KEY = 'MASUKKAN_ACCESS_KEY_KAMU'
AWS_SECRET_KEY = 'MASUKKAN_SECRET_KEY_KAMU'
BUCKET_NAME = 'dramaku'
S3_FOLDER = 'dramabox/'
LIST_FILE = 'listmp4.txt'
MAX_WORKERS = 5 # Bisa dinaikkan jadi 8-10 kalau stabil
TIMEOUT = 300 # 5 menit
# ===========================================
s3_client = boto3.client(
's3',
aws_access_key_id=AWS_ACCESS_KEY,
aws_secret_access_key=AWS_SECRET_KEY,
endpoint_url='https://s3.dualstack.us-east-1.amazonaws.com'
)
def get_filename_from_url(url):
return os.path.basename(urlparse(url).path)
def download_and_upload(url):
filename = get_filename_from_url(url)
try:
s3_key = S3_FOLDER + filename
print(f'[{filename}] Download dan upload mulai...')
with requests.get(url, stream=True, timeout=TIMEOUT) as r:
r.raise_for_status()
s3_client.upload_fileobj(
r.raw,
BUCKET_NAME,
s3_key,
ExtraArgs={'ContentType': 'video/mp4'}
)
print(f'BERHASIL: {filename}')
return url, True
except Exception as e:
print(f'GAGAL: {filename} | {str(e)}')
return url, False
def main():
if not os.path.exists(LIST_FILE):
print(f'File {LIST_FILE} tidak ditemukan!')
sys.exit(1)
with open(LIST_FILE, 'r') as f:
urls = [line.strip() for line in f if line.strip() and not line.startswith('#')]
if not urls:
print('List kosong, tidak ada yang perlu diupload.')
return
print(f'Mulai proses {len(urls)} file dengan {MAX_WORKERS} worker...')
successful = []
start_time = time.time()
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
future_to_url = {executor.submit(download_and_upload, url): url for url in urls}
for future in as_completed(future_to_url):
url, success = future.result()
if success:
successful.append(url)
if successful:
remaining = [u for u in urls if u not in successful]
with open(LIST_FILE, 'w') as f:
for u in remaining:
f.write(u + '\n')
print('SELESAI')
print(f'Berhasil: {len(successful)} file')
print(f'Sisa di list: {len(remaining)} file')
else:
print('Tidak ada file yang berhasil diupload.')
elapsed = time.time() - start_time
print(f'Total waktu: {elapsed/60:.1f} menit')
if __name__ == '__main__':
main()Cara pakai
- Simpan script misalnya dengan nama
download_and_upload_parallel.py - Isi credential AWS di bagian config
- Pastikan
listmp4.txtada di folder yang sama - Jalankan script
python3 download_and_upload_parallel.pyCatatan penting
- Kalau file besar dan koneksi stabil,
MAX_WORKERSbisa dinaikkan ke 8 atau 10. - Kalau sering gagal, turunin worker biar lebih aman.
- Script ini cocok buat file yang memang mau dipindah bertahap, bukan sekali jalan terus lupa.
- Karena yang sukses langsung dihapus dari list, rerun script jadi gampang.
Kalau mau lebih praktis
Kalau file-nya sebenarnya sudah bisa diakses publik dan cuma mau dipindah antar storage, script model begini sudah cukup praktis. Tapi kalau workflow-nya sering dipakai, ada beberapa upgrade yang bisa bikin hidup lebih enak:
- tambahin retry otomatis kalau upload gagal
- log hasil ke file biar gampang audit
- cek dulu apakah object sudah ada di S3 sebelum upload
- pakai progress bar kalau jumlah file banyak
Kalau gue pribadi, versi parallel + hapus URL sukses dari list itu udah paling balance: simpel, cepat, dan gampang diulang.
Masalah yang mungkin muncul
1. Credential AWS salah
Biasanya upload langsung gagal. Cek lagi access key dan secret key-nya.
2. Endpoint S3 keliru
Pastikan endpoint yang dipakai sesuai bucket dan region tujuan.
3. File gagal di tengah jalan
Turunin jumlah worker atau tambah retry biar lebih tahan banting.
4. List tidak berkurang
Pastikan script memang menulis ulang listmp4.txt setelah proses selesai.
Penutup
Intinya, kalau lu punya banyak URL file di R2 dan mau dipindah ke S3, jangan dikerjain manual. Bikin script yang streaming, parallel, dan bisa lanjut dari sisa list. Jauh lebih waras, bro.
Kalau mau, next step bisa gue bantu bikinin versi yang ada retry, progress bar, atau cek file duplikat sebelum upload.
Tags: Catatan Teknis, Python, AWS S3, Cloudflare R2, upload file