import json from django.conf import settings as s from django.core.management.base import BaseCommand from django.db import transaction from epdb.logic import UserManager, GroupManager, PackageManager, SettingManager from epdb.models import ( UserSettingPermission, MLRelativeReasoning, EnviFormer, Permission, User, ExternalDatabase, License, ) class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument("-ol", "--only-licenses", action="store_true", help="Only create licenses.") def create_users(self): # Anonymous User if not User.objects.filter(email="anon@envipath.com").exists(): anon = UserManager.create_user( "anonymous", "anon@envipath.com", "SuperSafe", is_active=True, add_to_group=False, set_setting=False, ) else: anon = User.objects.get(email="anon@envipath.com") # Admin User if not User.objects.filter(email="admin@envipath.com").exists(): admin = UserManager.create_user( "admin", "admin@envipath.com", "SuperSafe", is_active=True, add_to_group=False, set_setting=False, ) admin.is_staff = True admin.is_superuser = True admin.save() else: admin = User.objects.get(email="admin@envipath.com") # System Group g = GroupManager.create_group(admin, "enviPath Users", "All enviPath Users") g.public = True g.save() g.user_member.add(anon) g.save() anon.default_group = g anon.save() admin.default_group = g admin.save() if not User.objects.filter(email="user0@envipath.com").exists(): user0 = UserManager.create_user( "user0", "user0@envipath.com", "SuperSafe", is_active=True, add_to_group=False, set_setting=False, ) user0.is_staff = True user0.is_superuser = True user0.save() else: user0 = User.objects.get(email="user0@envipath.com") g.user_member.add(user0) g.save() user0.default_group = g user0.save() return anon, admin, g, user0 def create_licenses(self): """Create the six default licenses supported by enviPath""" cc_strings = ["by", "by-nc", "by-nc-nd", "by-nc-sa", "by-nd", "by-sa"] for cc_string in cc_strings: new_license = License() new_license.cc_string = cc_string new_license.link = f"https://creativecommons.org/licenses/{cc_string}/4.0/" new_license.image_link = f"https://licensebuttons.net/l/{cc_string}/4.0/88x31.png" new_license.save() def import_package(self, data, owner): return PackageManager.import_legacy_package( data, owner, keep_ids=True, add_import_timestamp=False, trust_reviewed=True ) def create_default_setting(self, owner, packages): s = SettingManager.create_setting( owner, name="Global Default Setting", description="Global Default Setting containing BBD Rules and Max 30 Nodes and Max Depth of 8", max_nodes=30, max_depth=5, rule_packages=packages, model=None, model_threshold=None, ) return s def populate_common_external_databases(self): """ Helper function to populate common external databases. This can be called from a Django management command. """ databases = [ { "name": "PubChem Compound", "full_name": "PubChem Compound Database", "description": "Chemical database of small organic molecules", "base_url": "https://pubchem.ncbi.nlm.nih.gov", "url_pattern": "https://pubchem.ncbi.nlm.nih.gov/compound/{id}", }, { "name": "PubChem Substance", "full_name": "PubChem Substance Database", "description": "Database of chemical substances", "base_url": "https://pubchem.ncbi.nlm.nih.gov", "url_pattern": "https://pubchem.ncbi.nlm.nih.gov/substance/{id}", }, { "name": "ChEBI", "full_name": "Chemical Entities of Biological Interest", "description": "Dictionary of molecular entities", "base_url": "https://www.ebi.ac.uk/chebi", "url_pattern": "https://www.ebi.ac.uk/chebi/searchId.do?chebiId=CHEBI:{id}", }, { "name": "RHEA", "full_name": "RHEA Reaction Database", "description": "Comprehensive resource of biochemical reactions", "base_url": "https://www.rhea-db.org", "url_pattern": "https://www.rhea-db.org/rhea/{id}", }, { "name": "KEGG Reaction", "full_name": "KEGG Reaction Database", "description": "Database of biochemical reactions", "base_url": "https://www.genome.jp", "url_pattern": "https://www.genome.jp/entry/{id}", }, { "name": "UniProt", "full_name": "MetaCyc Metabolic Pathway Database", "description": "UniProt is a freely accessible database of protein sequence and functional information", "base_url": "https://www.uniprot.org", "url_pattern": 'https://www.uniprot.org/uniprotkb?query="{id}"', }, ] for db_info in databases: ExternalDatabase.objects.get_or_create(name=db_info["name"], defaults=db_info) @transaction.atomic def handle(self, *args, **options): # Create users self.create_licenses() if options.get("only_licenses", False): return anon, admin, g, user0 = self.create_users() self.populate_common_external_databases() # Import Packages packages = [ "EAWAG-BBD.json", "EAWAG-SOIL.json", "EAWAG-SLUDGE.json", "EAWAG-SEDIMENT.json", ] mapping = {} for p in packages: print(f"Importing {p}...") package_data = json.loads( open( s.BASE_DIR / "fixtures" / "packages" / "2025-07-18" / p, encoding="utf-8" ).read() ) imported_package = self.import_package(package_data, admin) mapping[p.replace(".json", "")] = imported_package setting = self.create_default_setting(admin, [mapping["EAWAG-BBD"]]) setting.public = True setting.save() setting.make_global_default() for u in [anon, user0]: u.default_setting = setting u.save() usp = UserSettingPermission() usp.user = u usp.setting = setting usp.permission = Permission.READ[0] usp.save() # Create Model Package pack = PackageManager.create_package( admin, "Public Prediction Models", "Package to make Prediction Models publicly available", ) pack.reviewed = True pack.save() # Create RR ml_model = MLRelativeReasoning.create( package=pack, rule_packages=[mapping["EAWAG-BBD"]], data_packages=[mapping["EAWAG-BBD"]], eval_packages=[], threshold=0.5, name="ECC - BBD - T0.5", description="ML Relative Reasoning", ) ml_model.build_dataset() ml_model.build_model() # If available, create EnviFormerModel if s.ENVIFORMER_PRESENT: EnviFormer.create(pack, "EnviFormer - T0.5", "EnviFormer Model with Threshold 0.5", 0.5)