"""Upload RAG artifacts (FAISS index, metadata DB) to Modal Volume. Carica i file dell'indice RAG sul Volume 'boccaccio-rag-data' usato da modal_app.py. Di default carica solo l'indice FAISS; con --metadata carica anche metadata.db. Uso: python scripts/upload_index_modal.py python scripts/upload_index_modal.py --input rag/index/faiss/index.faiss python scripts/upload_index_modal.py --metadata """ from __future__ import annotations import argparse from pathlib import Path import modal VOLUME_NAME = "boccaccio-rag-data" def parse_args() -> argparse.Namespace: p = argparse.ArgumentParser(description="Upload RAG index to Modal Volume.") p.add_argument("--input", default="rag/index/faiss/index.faiss", help="Path locale dell'indice FAISS da caricare.") p.add_argument("--remote-name", default="index.faiss", help="Nome del file sul Volume.") p.add_argument("--metadata", action="store_true", help="Carica anche metadata.db.") p.add_argument("--metadata-input", default="rag/index/faiss/metadata.db", help="Path locale di metadata.db.") return p.parse_args() def main() -> None: args = parse_args() local = Path(args.input) if not local.exists(): raise FileNotFoundError(f"File not found: {local}") size_gb = local.stat().st_size / 1024**3 print(f"Uploading {local} ({size_gb:.2f} GB) -> Volume '{VOLUME_NAME}'/{args.remote_name}") vol = modal.Volume.from_name(VOLUME_NAME, create_if_missing=True) with vol.batch_upload(force=True) as batch: batch.put_file(str(local), args.remote_name) print(f" index uploaded ({size_gb:.2f} GB).") if args.metadata: meta = Path(args.metadata_input) if not meta.exists(): raise FileNotFoundError(f"File not found: {meta}") m_gb = meta.stat().st_size / 1024**3 print(f"Uploading {meta} ({m_gb:.2f} GB) -> Volume '{VOLUME_NAME}'/metadata.db") with vol.batch_upload(force=True) as batch: batch.put_file(str(meta), "metadata.db") print(f" metadata uploaded ({m_gb:.2f} GB).") print("Done.") if __name__ == "__main__": main()