""" Generate test data CSVs, sync_payload.json, and enroll_requests.json. Run from project root: python test_data/generate_test_data.py Outputs (written to test_data/): courses.csv – 5 courses rooms.csv – 3 rooms mentors.csv – 9 mentors students.csv – 200 students batches.csv – 13 batches sync_payload.json – POST to /api/v1/ingest/sync (loads all entities) enroll_requests.json – batch_id → [student_ids] map; use enroll.py to load schedule_requests.json – sample AutoGenerateRequest per batch """ import csv import json import os OUT = os.path.dirname(__file__) # ── Master data ──────────────────────────────────────────────────────────────── COURSES = [ {"id": "course-softskill", "title": "Soft Skills", "type": "Addon", "total_sessions": 4}, {"id": "course-dsa", "title": "Data Structures & Algorithms", "type": "Major", "total_sessions": 30}, {"id": "course-data-analytics", "title": "Data Analytics", "type": "Major", "total_sessions": 15}, {"id": "course-system-design", "title": "System Design", "type": "Major", "total_sessions": 10}, {"id": "course-aiml", "title": "AI / ML", "type": "Major", "total_sessions": 12}, ] ROOMS = [ {"id": "room-40", "name": "Room A", "capacity": 40}, {"id": "room-50", "name": "Room B", "capacity": 50}, {"id": "room-60", "name": "Room C", "capacity": 60}, ] def mentor_email(mentor_id): return f"{mentor_id}@example.com" def mentor_mobile(mentor_id): return f"90000{mentor_id[-2:]}00" MENTOR_COURSE_MAP = { "mentor-ss1": "course-softskill", "mentor-dsa1": "course-dsa", "mentor-dsa2": "course-dsa", "mentor-da1": "course-data-analytics", "mentor-da2": "course-data-analytics", "mentor-sd1": "course-system-design", "mentor-sd2": "course-system-design", "mentor-aiml1": "course-aiml", "mentor-aiml2": "course-aiml", } MENTORS = [ { "id": "mentor-ss1", "name": "Priya Sharma", "email": mentor_email("mentor-ss1"), "mobile_number": mentor_mobile("mentor-ss1"), "expertise_tags": ["Soft Skills", "Communication", "Presentation"], "off_days": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], "course_id": MENTOR_COURSE_MAP["mentor-ss1"], }, { "id": "mentor-dsa1", "name": "Rahul Kumar", "email": mentor_email("mentor-dsa1"), "mobile_number": mentor_mobile("mentor-dsa1"), "off_days": ["Sat", "Sun"], "course_id": MENTOR_COURSE_MAP["mentor-dsa1"], }, { "id": "mentor-dsa2", "name": "Ankit Singh", "email": mentor_email("mentor-dsa2"), "mobile_number": mentor_mobile("mentor-dsa2"), "off_days": ["Mon", "Tue", "Wed", "Thu", "Fri"], "course_id": MENTOR_COURSE_MAP["mentor-dsa2"], }, { "id": "mentor-da1", "name": "Sneha Patel", "email": mentor_email("mentor-da1"), "mobile_number": mentor_mobile("mentor-da1"), "off_days": ["Sat", "Sun"], "course_id": MENTOR_COURSE_MAP["mentor-da1"], }, { "id": "mentor-da2", "name": "Vijay Nair", "email": mentor_email("mentor-da2"), "mobile_number": mentor_mobile("mentor-da2"), "off_days": ["Mon", "Tue", "Wed", "Thu", "Fri"], "course_id": MENTOR_COURSE_MAP["mentor-da2"], }, { "id": "mentor-sd1", "name": "Kavya Reddy", "email": mentor_email("mentor-sd1"), "mobile_number": mentor_mobile("mentor-sd1"), "off_days": ["Sat", "Sun"], "course_id": MENTOR_COURSE_MAP["mentor-sd1"], }, { "id": "mentor-sd2", "name": "Arjun Mehta", "email": mentor_email("mentor-sd2"), "mobile_number": mentor_mobile("mentor-sd2"), "off_days": ["Mon", "Tue", "Wed", "Thu", "Fri"], "course_id": MENTOR_COURSE_MAP["mentor-sd2"], }, { "id": "mentor-aiml1", "name": "Deepa Iyer", "email": mentor_email("mentor-aiml1"), "mobile_number": mentor_mobile("mentor-aiml1"), "off_days": ["Mon", "Tue", "Wed", "Thu", "Fri"], "course_id": MENTOR_COURSE_MAP["mentor-aiml1"], }, { "id": "mentor-aiml2", "name": "Rohan Gupta", "email": mentor_email("mentor-aiml2"), "mobile_number": mentor_mobile("mentor-aiml2"), "off_days": ["Mon", "Tue", "Wed", "Thu", "Fri"], "course_id": MENTOR_COURSE_MAP["mentor-aiml2"], }, ] # Batches – note: days/num_sessions are set at schedule-generation time, not stored here BATCHES = [ # Soft Skills – 1 mentor, 1 batch, Sunday only, 4 sessions {"id": "batch-ss-b1", "name": "SS-B1 (Sun)", "course_id": "course-softskill", "mentor_id": "mentor-ss1", "start_date": "2026-04-19", "status": "Active"}, # DSA – mentor-dsa1: 2 weekday batches (Tue–Fri); mentor-dsa2: 2 weekend batches {"id": "batch-dsa-wd-b1", "name": "DSA-WD-B1 (Tue-Fri)", "course_id": "course-dsa", "mentor_id": "mentor-dsa1", "start_date": "2026-04-14", "status": "Active"}, {"id": "batch-dsa-wd-b2", "name": "DSA-WD-B2 (Tue-Fri)", "course_id": "course-dsa", "mentor_id": "mentor-dsa1", "start_date": "2026-04-14", "status": "Active"}, {"id": "batch-dsa-we-b1", "name": "DSA-WE-B1 (Sat-Sun)", "course_id": "course-dsa", "mentor_id": "mentor-dsa2", "start_date": "2026-04-18", "status": "Active"}, {"id": "batch-dsa-we-b2", "name": "DSA-WE-B2 (Sat-Sun)", "course_id": "course-dsa", "mentor_id": "mentor-dsa2", "start_date": "2026-04-18", "status": "Active"}, # Data Analytics – mentor-da1: 1 weekday batch; mentor-da2: 1 weekend batch {"id": "batch-da-wd-b1", "name": "DA-WD-B1 (Mon-Fri)", "course_id": "course-data-analytics", "mentor_id": "mentor-da1", "start_date": "2026-04-14", "status": "Active"}, {"id": "batch-da-we-b1", "name": "DA-WE-B1 (Sat-Sun)", "course_id": "course-data-analytics", "mentor_id": "mentor-da2", "start_date": "2026-04-18", "status": "Active"}, # System Design – mentor-sd1: 2 weekday batches; mentor-sd2: 2 weekend batches {"id": "batch-sd-wd-b1", "name": "SD-WD-B1 (Mon-Fri)", "course_id": "course-system-design", "mentor_id": "mentor-sd1", "start_date": "2026-04-14", "status": "Active"}, {"id": "batch-sd-wd-b2", "name": "SD-WD-B2 (Mon-Fri)", "course_id": "course-system-design", "mentor_id": "mentor-sd1", "start_date": "2026-04-14", "status": "Active"}, {"id": "batch-sd-we-b1", "name": "SD-WE-B1 (Sat-Sun)", "course_id": "course-system-design", "mentor_id": "mentor-sd2", "start_date": "2026-04-18", "status": "Active"}, {"id": "batch-sd-we-b2", "name": "SD-WE-B2 (Sat-Sun)", "course_id": "course-system-design", "mentor_id": "mentor-sd2", "start_date": "2026-04-18", "status": "Active"}, # AI/ML – 2 mentors, 1 weekend batch each {"id": "batch-aiml-we-b1", "name": "AIML-WE-B1 (Sat-Sun)", "course_id": "course-aiml", "mentor_id": "mentor-aiml1", "start_date": "2026-04-18", "status": "Active"}, {"id": "batch-aiml-we-b2", "name": "AIML-WE-B2 (Sat-Sun)", "course_id": "course-aiml", "mentor_id": "mentor-aiml2", "start_date": "2026-04-18", "status": "Active"}, # Attendance scenario batches – backdated/completed to test rich attendance states {"id": "batch-att-completed", "name": "ATT-Completed (backdated, DSA)", "course_id": "course-dsa", "mentor_id": "mentor-dsa1", "start_date": "2026-01-06", "status": "Completed"}, {"id": "batch-att-active", "name": "ATT-Active (attendance history)", "course_id": "course-data-analytics", "mentor_id": "mentor-da1", "start_date": "2026-03-01", "status": "Active"}, ] # ── Student generation ───────────────────────────────────────────────────────── # 200 students spread across main course batches (one batch per student) # DSA: 60 students (15 × 4 batches) # DA: 40 students (20 × 2 batches) # SD: 60 students (15 × 4 batches) # AIML:40 students (20 × 2 batches) # Total = 200 FIRST_NAMES = [ "Aarav","Aditi","Akash","Ananya","Arjun","Avni","Chirag","Deepika","Divya","Gaurav", "Harsha","Isha","Jay","Kavya","Kiran","Lakshmi","Manish","Megha","Mohit","Neha", "Nikhil","Nisha","Pankaj","Pooja","Pranav","Priya","Rahul","Rajesh","Riya","Rohit", "Sachin","Sandeep","Sanjay","Sara","Shivam","Shreya","Simran","Sneha","Suresh","Tanvi", "Tarun","Usha","Varun","Vidya","Vikram","Vinay","Vivek","Yash","Zara","Amit", ] LAST_NAMES = [ "Sharma","Patel","Kumar","Singh","Gupta","Verma","Joshi","Mehta","Reddy","Nair", "Iyer","Agarwal","Mishra","Rao","Shah","Pillai","Bhat","Kaur","Pandey","Bajaj", "Jain","Malhotra","Khanna","Trivedi","Choudhary","Srivastava","Yadav","Tiwari","Das","Bose", "Sen","Mukherjee","Chatterjee","Banerjee","Ghosh","Roy","Dey","Chakraborty","Biswas","Paul", ] def student_name(idx: int) -> str: first = FIRST_NAMES[idx % len(FIRST_NAMES)] last = LAST_NAMES[(idx // len(FIRST_NAMES)) % len(LAST_NAMES)] return f"{first} {last}" STUDENTS = [ { "id": f"student-{i:03d}", "name": student_name(i - 1), "email": f"student-{i:03d}@example.com", "mobile_number": f"80000{i:03d}" } for i in range(1, 201) ] + [ # Dedicated attendance-scenario students (stable IDs for test_api.py) {"id": "student-att-present", "name": "Test Present Student", "email": "student-att-present@example.com", "mobile_number": "70000001"}, {"id": "student-att-late", "name": "Test Late Student", "email": "student-att-late@example.com", "mobile_number": "70000002"}, {"id": "student-att-absent", "name": "Test Absent Student", "email": "student-att-absent@example.com", "mobile_number": "70000003"}, ] # ── Enrollment map ───────────────────────────────────────────────────────────── # Maps batch_id → list of student ids enrolled in that batch BATCH_ENROLLMENT: dict[str, list[str]] = { # DSA weekday "batch-dsa-wd-b1": [f"student-{i:03d}" for i in range(1, 16)], # 15 students "batch-dsa-wd-b2": [f"student-{i:03d}" for i in range(16, 31)], # 15 students # DSA weekend "batch-dsa-we-b1": [f"student-{i:03d}" for i in range(31, 46)], # 15 students "batch-dsa-we-b2": [f"student-{i:03d}" for i in range(46, 61)], # 15 students # DA weekday "batch-da-wd-b1": [f"student-{i:03d}" for i in range(61, 81)], # 20 students # DA weekend "batch-da-we-b1": [f"student-{i:03d}" for i in range(81, 101)], # 20 students # SD weekday "batch-sd-wd-b1": [f"student-{i:03d}" for i in range(101, 116)], # 15 students "batch-sd-wd-b2": [f"student-{i:03d}" for i in range(116, 131)], # 15 students # SD weekend "batch-sd-we-b1": [f"student-{i:03d}" for i in range(131, 146)], # 15 students "batch-sd-we-b2": [f"student-{i:03d}" for i in range(146, 161)], # 15 students # AIML weekend "batch-aiml-we-b1": [f"student-{i:03d}" for i in range(161, 181)], # 20 students "batch-aiml-we-b2": [f"student-{i:03d}" for i in range(181, 201)], # 20 students # Soft Skills addon – 20% of students (40 students, fits Room A capacity=40) # Picked from 4 different main batches (10 each) "batch-ss-b1": ( [f"student-{i:03d}" for i in range(1, 11)] + # 10 from DSA-WD-B1 [f"student-{i:03d}" for i in range(61, 71)] + # 10 from DA-WD-B1 [f"student-{i:03d}" for i in range(101,111)] + # 10 from SD-WD-B1 [f"student-{i:03d}" for i in range(161,171)] # 10 from AIML-WE-B1 ), # Attendance scenario batches – 3 dedicated test students "batch-att-completed": ["student-att-present", "student-att-late", "student-att-absent"], "batch-att-active": ["student-att-present", "student-att-late", "student-att-absent"], } # ── Schedule generation requests (sample for each batch) ────────────────────── SCHEDULE_REQUESTS = [ {"batch_id": "batch-ss-b1", "start_date": "2026-04-19", "days": ["Sun"], "num_sessions": 4}, {"batch_id": "batch-dsa-wd-b1", "start_date": "2026-04-14", "days": ["Tue","Wed","Thu","Fri"], "num_sessions": 30}, {"batch_id": "batch-dsa-wd-b2", "start_date": "2026-04-14", "days": ["Tue","Wed","Thu","Fri"], "num_sessions": 30}, {"batch_id": "batch-dsa-we-b1", "start_date": "2026-04-18", "days": ["Sat","Sun"], "num_sessions": 30}, {"batch_id": "batch-dsa-we-b2", "start_date": "2026-04-18", "days": ["Sat","Sun"], "num_sessions": 30}, {"batch_id": "batch-da-wd-b1", "start_date": "2026-04-14", "days": ["Mon","Tue","Wed","Thu","Fri"], "num_sessions": 15}, {"batch_id": "batch-da-we-b1", "start_date": "2026-04-18", "days": ["Sat","Sun"], "num_sessions": 15}, {"batch_id": "batch-sd-wd-b1", "start_date": "2026-04-14", "days": ["Mon","Tue","Wed","Thu","Fri"], "num_sessions": 10}, {"batch_id": "batch-sd-wd-b2", "start_date": "2026-04-14", "days": ["Mon","Tue","Wed","Thu","Fri"], "num_sessions": 10}, {"batch_id": "batch-sd-we-b1", "start_date": "2026-04-18", "days": ["Sat","Sun"], "num_sessions": 10}, {"batch_id": "batch-sd-we-b2", "start_date": "2026-04-18", "days": ["Sat","Sun"], "num_sessions": 10}, {"batch_id": "batch-aiml-we-b1", "start_date": "2026-04-18", "days": ["Sat","Sun"], "num_sessions": 12}, {"batch_id": "batch-aiml-we-b2", "start_date": "2026-04-18", "days": ["Sat","Sun"], "num_sessions": 12}, ] # ── Writers ──────────────────────────────────────────────────────────────────── def write_csv(filename: str, rows: list[dict], json_fields: list[str] | None = None): """Write a CSV. JSON fields are serialised as JSON strings.""" path = os.path.join(OUT, filename) flat_rows = [] for row in rows: flat = {} for k, v in row.items(): if json_fields and k in json_fields: flat[k] = json.dumps(v) else: flat[k] = v flat_rows.append(flat) with open(path, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=flat_rows[0].keys()) writer.writeheader() writer.writerows(flat_rows) print(f" wrote {path} ({len(rows)} rows)") def write_json(filename: str, data): path = os.path.join(OUT, filename) with open(path, "w", encoding="utf-8") as f: json.dump(data, f, indent=2) print(f" wrote {path}") # ── Main ─────────────────────────────────────────────────────────────────────── if __name__ == "__main__": print("Generating test data ...") # CSVs (for upload/preview in the UI) write_csv("courses.csv", COURSES) write_csv("rooms.csv", ROOMS) write_csv("mentors.csv", MENTORS, json_fields=["expertise_tags", "off_days"]) write_csv("mentors.csv", MENTORS, json_fields=["off_days"]) write_csv("students.csv", STUDENTS) write_csv("batches.csv", BATCHES) # sync_payload.json – POST body for /api/v1/ingest/sync sync_payload = { "courses": COURSES, "rooms": ROOMS, "mentors": MENTORS, "students": STUDENTS, "batches": BATCHES, } write_json("sync_payload.json", sync_payload) # enroll_requests.json – used by enroll.py write_json("enroll_requests.json", BATCH_ENROLLMENT) # schedule_requests.json – sample schedule generation requests write_json("schedule_requests.json", SCHEDULE_REQUESTS) print("\nDone.") print("\nNext steps:") print(" 1. Load entities: POST /api/v1/ingest/sync with sync_payload.json") print(" 2. Enroll students: python test_data/enroll.py --base-url http://localhost:7861") print(" 3. Schedule: POST /api/v1/schedule/auto-generate (one per batch in schedule_requests.json)")