import boto3,hashlib,os B='analyticsdata123'; P='options-ml-platform/data/knowledge/flow-forensics/2026-10-25_lows/'; L='/workspace/research/flow-forensics-2026-10' s3=boto3.client('s3',region_name='ap-south-2') pre=s3.list_objects_v2(Bucket=B,Prefix=P,MaxKeys=5).get('KeyCount',0); print('existing objects under prefix before upload:',pre) files=[os.path.relpath(os.path.join(r,f),L) for r,_,fs in os.walk(L+'/lows') for f in fs if '__pycache__' not in r and not f.endswith('.pyc')] files+=['index.html','scripts/report.py','scripts/publish_vps.py','PROGRESS.md'] def etag(k): try: return s3.head_object(Bucket=B,Key=k)['ETag'].strip('"') except s3.exceptions.ClientError: return None st={'new':0,'skip':0,'versioned':0,'too_big':0} for f in sorted(files): p=f'{L}/{f}' if os.path.getsize(p)>50e6: st['too_big']+=1; continue md=hashlib.md5(open(p,'rb').read()).hexdigest(); base,ext=os.path.splitext(f); v=1 while True: k=P+(f if v==1 else f'{base}-v{v}{ext}'); e=etag(k) if e is None: s3.upload_file(p,B,k); st['new' if v==1 else 'versioned']+=1; break if e==md: st['skip']+=1; break v+=1 print(st,'files',len(files))