from database.database import db from models.LabelStudioProject import LabelStudioProject from models.Images import Image from models.Annotation import Annotation from services.fetch_labelstudio import fetch_label_studio_project, fetch_project_ids_and_titles update_status = {"running": False} def seed_label_studio(): """Seed database with Label Studio project data""" update_status["running"] = True print('Seeding started') try: projects = fetch_project_ids_and_titles() for project in projects: print(f"Processing project {project['id']} ({project['title']})") # Upsert project in DB existing_project = LabelStudioProject.query.filter_by(project_id=project['id']).first() if existing_project: existing_project.title = project['title'] else: new_project = LabelStudioProject(project_id=project['id'], title=project['title']) db.session.add(new_project) db.session.commit() # Fetch project data (annotations array) data = fetch_label_studio_project(project['id']) if not isinstance(data, list) or len(data) == 0: print(f"No annotation data for project {project['id']}") continue # Remove old images and annotations for this project old_images = Image.query.filter_by(project_id=project['id']).all() old_image_ids = [img.image_id for img in old_images] if old_image_ids: Annotation.query.filter(Annotation.image_id.in_(old_image_ids)).delete(synchronize_session=False) Image.query.filter_by(project_id=project['id']).delete() db.session.commit() print(f"Deleted {len(old_image_ids)} old images and their annotations for project {project['id']}") # Prepare arrays images_bulk = [] anns_bulk = [] for ann in data: # Extract width/height width = None height = None if isinstance(ann.get('label_rectangles'), list) and len(ann['label_rectangles']) > 0: width = ann['label_rectangles'][0].get('original_width') height = ann['label_rectangles'][0].get('original_height') elif isinstance(ann.get('label'), list) and len(ann['label']) > 0: if ann['label'][0].get('original_width') and ann['label'][0].get('original_height'): width = ann['label'][0]['original_width'] height = ann['label'][0]['original_height'] # Only process if width and height are valid if width and height: image_data = { 'project_id': project['id'], 'image_path': ann.get('image'), 'width': int(width), # Ensure integer 'height': int(height) # Ensure integer } images_bulk.append(image_data) # Handle multiple annotations per image if isinstance(ann.get('label_rectangles'), list): for ann_detail in ann['label_rectangles']: # Get label safely rectanglelabels = ann_detail.get('rectanglelabels', []) if isinstance(rectanglelabels, list) and len(rectanglelabels) > 0: label = rectanglelabels[0] elif isinstance(rectanglelabels, str): label = rectanglelabels else: label = 'unknown' ann_data = { 'image_path': ann.get('image'), 'x': (ann_detail['x'] * width) / 100, 'y': (ann_detail['y'] * height) / 100, 'width': (ann_detail['width'] * width) / 100, 'height': (ann_detail['height'] * height) / 100, 'Label': label } anns_bulk.append(ann_data) elif isinstance(ann.get('label'), list): for ann_detail in ann['label']: # Get label safely rectanglelabels = ann_detail.get('rectanglelabels', []) if isinstance(rectanglelabels, list) and len(rectanglelabels) > 0: label = rectanglelabels[0] elif isinstance(rectanglelabels, str): label = rectanglelabels else: label = 'unknown' ann_data = { 'image_path': ann.get('image'), 'x': (ann_detail['x'] * width) / 100, 'y': (ann_detail['y'] * height) / 100, 'width': (ann_detail['width'] * width) / 100, 'height': (ann_detail['height'] * height) / 100, 'Label': label } anns_bulk.append(ann_data) # Insert images and get generated IDs inserted_images = [] for img_data in images_bulk: new_image = Image(**img_data) db.session.add(new_image) db.session.flush() # Flush to get the ID inserted_images.append(new_image) db.session.commit() # Map image_path -> image_id image_map = {img.image_path: img.image_id for img in inserted_images} # Assign correct image_id to each annotation for ann_data in anns_bulk: ann_data['image_id'] = image_map.get(ann_data['image_path']) del ann_data['image_path'] # Insert annotations for ann_data in anns_bulk: new_annotation = Annotation(**ann_data) db.session.add(new_annotation) db.session.commit() print(f"Inserted {len(images_bulk)} images and {len(anns_bulk)} annotations for project {project['id']}") print('Seeding done') return {'success': True, 'message': 'Data inserted successfully!'} except Exception as error: print(f'Error inserting data: {error}') db.session.rollback() return {'success': False, 'message': str(error)} finally: update_status["running"] = False print('updateStatus.running set to false')