APA-URAAS / scripts /seed_ace_units.py
Lordkiki's picture
Deploy URAAS — African Research Archival & Analytics System
dd2635a verified
Raw
History Blame Contribute Delete
4.19 kB
"""
Seed Africa Centres of Excellence (ACE) as Community rows (unit_type="ace"),
each minted a self-assigned persistent ID (PMD) — the same role ROR plays
for institutions, minted locally via ark_generator (deterministic, no
network access, idempotent on re-run).
This script does NOT ship with any hardcoded ACE names — supply the real
list at UNILAG (and any other institution) via a JSON input file:
[
{"name": "ACE for Genomics of Non-Communicable Diseases", "institution": "unilag"},
{"name": "Another ACE Name", "institution": "unilag", "ror_id": "https://ror.org/..."}
]
`institution` must match a short_name known to uraas/config/institutions.py.
`ror_id` is optional — only set it if the ACE has been assigned its own ROR.
Usage:
python scripts/seed_ace_units.py ace_units.json # DRY RUN
python scripts/seed_ace_units.py ace_units.json --apply
"""
import argparse
import json
import os
import sys
from datetime import datetime
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from uraas.config.institutions import get_registry
from uraas.database import Community, SessionLocal
from uraas.utils.ark_generator import ark_generator
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("input_file", help="JSON file listing ACE units to seed")
parser.add_argument("--apply", action="store_true", help="Write changes (default: dry run)")
args = parser.parse_args()
with open(args.input_file, encoding="utf-8") as f:
ace_units = json.load(f)
if not isinstance(ace_units, list) or not ace_units:
print("Input file must contain a non-empty JSON list of ACE units.")
return 1
registry = get_registry()
session = SessionLocal()
try:
planned = []
for entry in ace_units:
name = entry.get("name")
inst_short_name = entry.get("institution")
if not name or not inst_short_name:
print(f"SKIP (missing name/institution): {entry}")
continue
institution_config = registry.get(inst_short_name)
if not institution_config:
print(f"SKIP (unknown institution {inst_short_name!r}): {name}")
continue
existing = session.query(Community).filter_by(name=name).first()
seed = f"ACE|{institution_config.ror}|{name}"
pmd = ark_generator.mint(seed)
planned.append((entry, institution_config, existing, pmd))
print("=" * 64)
for entry, institution_config, existing, pmd in planned:
status = "UPDATE" if existing else "CREATE"
print(f"[{status}] {entry['name']} ({institution_config.name}) -> pmd={pmd}")
print("=" * 64)
print(f"{len(planned)} ACE unit(s) to process")
if not args.apply:
print("[DRY RUN] No writes. Re-run with --apply.")
return 0
now = datetime.utcnow()
created = updated = 0
for entry, institution_config, existing, pmd in planned:
if existing:
existing.unit_type = "ace"
existing.institution = institution_config.name
existing.ror = institution_config.ror
if entry.get("ror_id"):
existing.ror_id = entry["ror_id"]
if not existing.pmd:
existing.pmd = pmd
existing.pmd_assigned_at = now
updated += 1
else:
community = Community(
name=entry["name"],
ror_id=entry.get("ror_id"),
institution=institution_config.name,
ror=institution_config.ror,
unit_type="ace",
pmd=pmd,
pmd_assigned_at=now,
)
session.add(community)
created += 1
session.commit()
print(f"DONE. Created: {created} Updated: {updated}")
return 0
finally:
session.close()
if __name__ == "__main__":
sys.exit(main())