This commit is contained in:
Tim Lorsbach
2026-02-12 14:03:10 +01:00
parent 58ab5b33e3
commit 93390b349b
27 changed files with 495 additions and 1871 deletions

0
bayer/__init__.py Normal file
View File

3
bayer/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
bayer/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class BayerConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'bayer'

View File

@ -0,0 +1,35 @@
# Generated by Django 5.2.7 on 2026-02-12 12:36
import django.utils.timezone
import model_utils.fields
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Package',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('reviewed', models.BooleanField(default=False, verbose_name='Reviewstatus')),
('classification_level', models.IntegerField(choices=[(0, 'Internal'), (10, 'Restricted'), (20, 'Secret')], default=10)),
],
options={
'db_table': 'epdb_package',
},
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 5.2.7 on 2026-02-12 12:36
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('bayer', '0001_initial'),
('epdb', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='package',
name='license',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.license', verbose_name='License'),
),
]

View File

95
bayer/models.py Normal file
View File

@ -0,0 +1,95 @@
from typing import List
from django.conf import settings as s
from django.db import models
from django.db.models import QuerySet
from epdb.models import (
EnviPathModel,
ParallelRule,
SequentialRule,
SimpleAmbitRule,
SimpleRDKitRule,
)
class Package(EnviPathModel):
reviewed = models.BooleanField(verbose_name="Reviewstatus", default=False)
license = models.ForeignKey(
"epdb.License", on_delete=models.SET_NULL, blank=True, null=True, verbose_name="License"
)
class Classification(models.IntegerChoices):
INTERNAL = 0, "Internal"
RESTRICTED = 10 , "Restricted"
SECRET = 20, "Secret"
classification_level = models.IntegerField(
choices=Classification,
default=Classification.RESTRICTED,
)
def delete(self, *args, **kwargs):
# explicitly handle related Rules
for r in self.rules.all():
r.delete()
super().delete(*args, **kwargs)
def __str__(self):
return f"{self.name} (pk={self.pk})"
@property
def compounds(self) -> QuerySet:
return self.compound_set.all()
@property
def rules(self) -> QuerySet:
return self.rule_set.all()
@property
def reactions(self) -> QuerySet:
return self.reaction_set.all()
@property
def pathways(self) -> QuerySet:
return self.pathway_set.all()
@property
def scenarios(self) -> QuerySet:
return self.scenario_set.all()
@property
def models(self) -> QuerySet:
return self.epmodel_set.all()
def _url(self):
return "{}/package/{}".format(s.SERVER_URL, self.uuid)
def get_applicable_rules(self) -> List["Rule"]:
"""
Returns a ordered set of rules where the following applies:
1. All Composite will be added to result
2. All SimpleRules will be added if theres no CompositeRule present using the SimpleRule
Ordering is based on "url" field.
"""
rules = []
rule_qs = self.rules
reflected_simple_rules = set()
for r in rule_qs:
if isinstance(r, ParallelRule) or isinstance(r, SequentialRule):
rules.append(r)
for sr in r.simple_rules.all():
reflected_simple_rules.add(sr)
for r in rule_qs:
if isinstance(r, SimpleAmbitRule) or isinstance(r, SimpleRDKitRule):
if r not in reflected_simple_rules:
rules.append(r)
rules = sorted(rules, key=lambda x: x.url)
return rules
class Meta:
db_table = "epdb_package"

View File

@ -0,0 +1,97 @@
{% extends "framework_modern.html" %}
{% block content %}
{% block action_modals %}
{% include "modals/objects/edit_package_modal.html" %}
{% include "modals/objects/edit_package_permissions_modal.html" %}
{% include "modals/objects/publish_package_modal.html" %}
{% include "modals/objects/set_license_modal.html" %}
{% include "modals/objects/export_package_modal.html" %}
{% include "modals/objects/generic_delete_modal.html" %}
{% endblock action_modals %}
<div class="space-y-2 p-4">
<!-- Header Section -->
<div class="card bg-base-100">
<div class="card-body">
<div class="flex items-center justify-between">
<h2 class="card-title text-2xl">{{ package.name }} - <i>{{ package.get_classification_level_display }}</i></h2>
<div id="actionsButton" class="dropdown dropdown-e nd hidden">
<div tabindex="0" role="button" class="btn btn-ghost btn-sm">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-wrench"
>
<path
d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"
/>
</svg>
Actions
</div>
<ul
tabindex="-1"
class="dropdown-content menu bg-base-100 rounded-box z-50 w-52 p-2"
>
{% block actions %}
{% include "actions/objects/package.html" %}
{% endblock %}
</ul>
</div>
</div>
<p class="mt-2">{{ package.description|safe }}</p>
<ul class="menu bg-base-200 rounded-box mt-4 w-full">
<li>
<a href="{{ package.url }}/pathway" class="hover:bg-base-300"
>Pathways ({{ package.pathways.count }})</a
>
</li>
<li>
<a href="{{ package.url }}/rule" class="hover:bg-base-300"
>Rules ({{ package.rules.count }})</a
>
</li>
<li>
<a href="{{ package.url }}/compound" class="hover:bg-base-300"
>Compounds ({{ package.compounds.count }})</a
>
</li>
<li>
<a href="{{ package.url }}/reaction" class="hover:bg-base-300"
>Reactions ({{ package.reactions.count }})</a
>
</li>
<li>
<a href="{{ package.url }}/model" class="hover:bg-base-300"
>Models ({{ package.models.count }})</a
>
</li>
<li>
<a href="{{ package.url }}/scenario" class="hover:bg-base-300"
>Scenarios ({{ package.scenarios.count }})</a
>
</li>
</ul>
</div>
</div>
</div>
<script>
// Show actions button if there are actions
document.addEventListener("DOMContentLoaded", function () {
const actionsButton = document.getElementById("actionsButton");
const actionsList = actionsButton?.querySelector("ul");
if (actionsList && actionsList.children.length > 0) {
actionsButton?.classList.remove("hidden");
}
});
</script>
{% endblock content %}

3
bayer/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
bayer/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View File

@ -53,6 +53,7 @@ INSTALLED_APPS = [
"epapi", # API endpoints (v1, etc.)
"epdb",
"migration",
"bayer",
]
TENANT = os.environ.get("TENANT", "public")
@ -93,10 +94,15 @@ if os.environ.get("REGISTRATION_MANDATORY", False) == "True":
ROOT_URLCONF = "envipath.urls"
TEMPLATE_DIRS = [
os.path.join(BASE_DIR, "bayer", "templates"),
os.path.join(BASE_DIR, "templates"),
]
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": (os.path.join(BASE_DIR, "templates"),),
"DIRS": TEMPLATE_DIRS,
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [

View File

@ -1,6 +1,5 @@
# Generated by Django 5.2.1 on 2025-07-22 20:58
# Generated by Django 5.2.7 on 2026-02-12 12:36
import datetime
import django.contrib.auth.models
import django.contrib.auth.validators
import django.contrib.postgres.fields
@ -19,11 +18,12 @@ class Migration(migrations.Migration):
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('contenttypes', '0002_remove_content_type_name'),
migrations.swappable_dependency(settings.EPDB_PACKAGE_MODEL),
]
operations = [
migrations.CreateModel(
name='Compound',
name='ApplicabilityDomain',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
@ -31,9 +31,33 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('num_neighbours', models.IntegerField(default=5)),
('reliability_threshold', models.FloatField(default=0.5)),
('local_compatibilty_threshold', models.FloatField(default=0.5)),
('functional_groups', models.JSONField(blank=True, default=dict, null=True)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Edge',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='EPModel',
@ -44,7 +68,9 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Package')),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')),
],
options={
@ -52,6 +78,27 @@ class Migration(migrations.Migration):
'base_manager_name': 'objects',
},
),
migrations.CreateModel(
name='ExternalDatabase',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('name', models.CharField(max_length=100, unique=True, verbose_name='Database Name')),
('full_name', models.CharField(blank=True, max_length=255, verbose_name='Full Database Name')),
('description', models.TextField(blank=True, verbose_name='Description')),
('base_url', models.URLField(blank=True, null=True, verbose_name='Base URL')),
('url_pattern', models.CharField(blank=True, help_text="URL pattern with {id} placeholder, e.g., 'https://pubchem.ncbi.nlm.nih.gov/compound/{id}'", max_length=500, verbose_name='URL Pattern')),
('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
],
options={
'verbose_name': 'External Database',
'verbose_name_plural': 'External Databases',
'db_table': 'epdb_external_database',
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Permission',
fields=[
@ -65,6 +112,7 @@ class Migration(migrations.Migration):
name='License',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('cc_string', models.TextField(verbose_name='CC string')),
('link', models.URLField(verbose_name='link')),
('image_link', models.URLField(verbose_name='Image link')),
],
@ -78,8 +126,11 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Package')),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')),
],
options={
'abstract': False,
@ -101,6 +152,9 @@ class Migration(migrations.Migration):
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('email', models.EmailField(max_length=254, unique=True)),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('is_reviewer', models.BooleanField(default=False)),
('default_package', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Default Package')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
@ -117,11 +171,34 @@ class Migration(migrations.Migration):
name='APIToken',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hashed_key', models.CharField(max_length=128, unique=True)),
('created', models.DateTimeField(auto_now_add=True)),
('expires_at', models.DateTimeField(blank=True, default=datetime.datetime(2025, 10, 20, 20, 58, 48, 351675, tzinfo=datetime.timezone.utc), null=True)),
('name', models.CharField(blank=True, help_text='Optional name for the token', max_length=100)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('hashed_key', models.CharField(help_text='SHA-256 hash of the token key', max_length=128, unique=True)),
('expires_at', models.DateTimeField(blank=True, help_text='Token expiration time (null for no expiration)', null=True)),
('name', models.CharField(help_text='Descriptive name for this token', max_length=100)),
('is_active', models.BooleanField(default=True, help_text='Whether this token is active')),
('user', models.ForeignKey(help_text='User who owns this token', on_delete=django.db.models.deletion.CASCADE, related_name='api_tokens', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'API Token',
'verbose_name_plural': 'API Tokens',
'db_table': 'epdb_api_token',
'ordering': ['-created'],
},
),
migrations.CreateModel(
name='Compound',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Package')),
],
),
migrations.CreateModel(
@ -133,6 +210,7 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
('smiles', models.TextField(verbose_name='SMILES')),
@ -150,36 +228,6 @@ class Migration(migrations.Migration):
name='default_structure',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='compound_default_structure', to='epdb.compoundstructure', verbose_name='Default Structure'),
),
migrations.CreateModel(
name='Edge',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
),
migrations.CreateModel(
name='EnviFormer',
fields=[
('epmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='epdb.epmodel')),
('threshold', models.FloatField(default=0.5)),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
bases=('epdb.epmodel',),
),
migrations.CreateModel(
name='PluginModel',
fields=[
@ -191,17 +239,6 @@ class Migration(migrations.Migration):
},
bases=('epdb.epmodel',),
),
migrations.CreateModel(
name='RuleBaseRelativeReasoning',
fields=[
('epmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='epdb.epmodel')),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
bases=('epdb.epmodel',),
),
migrations.CreateModel(
name='Group',
fields=[
@ -209,10 +246,11 @@ class Migration(migrations.Migration):
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('name', models.TextField(verbose_name='Group name')),
('public', models.BooleanField(default=False, verbose_name='Public Group')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('group_member', models.ManyToManyField(related_name='groups_in_group', to='epdb.group', verbose_name='Group member')),
('group_member', models.ManyToManyField(blank=True, related_name='groups_in_group', to='epdb.group', verbose_name='Group member')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Group Owner')),
('user_member', models.ManyToManyField(related_name='users_in_group', to=settings.AUTH_USER_MODEL, verbose_name='User members')),
],
@ -225,6 +263,41 @@ class Migration(migrations.Migration):
name='default_group',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_group', to='epdb.group', verbose_name='Default Group'),
),
migrations.CreateModel(
name='JobLog',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('task_id', models.UUIDField(unique=True)),
('job_name', models.TextField()),
('status', models.CharField(choices=[('INITIAL', 'Initial'), ('SUCCESS', 'Success'), ('FAILURE', 'Failure'), ('REVOKED', 'Revoked'), ('IGNORED', 'Ignored')], default='INITIAL', max_length=20)),
('done_at', models.DateTimeField(blank=True, default=None, null=True)),
('task_result', models.TextField(blank=True, default=None, null=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Package',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('reviewed', models.BooleanField(default=False, verbose_name='Reviewstatus')),
('license', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.license', verbose_name='License')),
],
options={
'swappable': 'EPDB_PACKAGE_MODEL',
},
),
migrations.CreateModel(
name='Node',
fields=[
@ -234,9 +307,11 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
('depth', models.IntegerField(verbose_name='Node depth')),
('stereo_removed', models.BooleanField(default=False)),
('default_node_label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='default_node_structure', to='epdb.compoundstructure', verbose_name='Default Node Label')),
('node_labels', models.ManyToManyField(related_name='node_structures', to='epdb.compoundstructure', verbose_name='All Node Labels')),
('out_edges', models.ManyToManyField(to='epdb.edge', verbose_name='Outgoing Edges')),
@ -255,38 +330,6 @@ class Migration(migrations.Migration):
name='start_nodes',
field=models.ManyToManyField(related_name='edge_educts', to='epdb.node', verbose_name='Start Nodes'),
),
migrations.CreateModel(
name='Package',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('reviewed', models.BooleanField(default=False, verbose_name='Reviewstatus')),
('license', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.license', verbose_name='License')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='epmodel',
name='package',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Package'),
),
migrations.AddField(
model_name='compound',
name='package',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Package'),
),
migrations.AddField(
model_name='user',
name='default_package',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.package', verbose_name='Default Package'),
),
migrations.CreateModel(
name='SequentialRule',
fields=[
@ -309,16 +352,6 @@ class Migration(migrations.Migration):
},
bases=('epdb.rule',),
),
migrations.AddField(
model_name='rule',
name='package',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Package'),
),
migrations.AddField(
model_name='rule',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype'),
),
migrations.CreateModel(
name='Pathway',
fields=[
@ -328,9 +361,11 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Package')),
('predicted', models.BooleanField(default=False)),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Package')),
],
options={
'abstract': False,
@ -355,12 +390,13 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('aliases', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), default=list, size=None, verbose_name='Aliases')),
('multi_step', models.BooleanField(verbose_name='Multistep Reaction')),
('medline_references', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), null=True, size=None, verbose_name='Medline References')),
('educts', models.ManyToManyField(related_name='reaction_educts', to='epdb.compoundstructure', verbose_name='Educts')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Package')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Package')),
('products', models.ManyToManyField(related_name='reaction_products', to='epdb.compoundstructure', verbose_name='Products')),
('rules', models.ManyToManyField(related_name='reaction_rule', to='epdb.rule', verbose_name='Rule')),
],
@ -368,6 +404,28 @@ class Migration(migrations.Migration):
'abstract': False,
},
),
migrations.CreateModel(
name='EnzymeLink',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('ec_number', models.TextField(verbose_name='EC Number')),
('classification_level', models.IntegerField(verbose_name='Classification Level')),
('linking_method', models.TextField(verbose_name='Linking Method')),
('edge_evidence', models.ManyToManyField(to='epdb.edge')),
('rule', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.rule')),
('reaction_evidence', models.ManyToManyField(to='epdb.reaction')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='edge',
name='edge_label',
@ -382,11 +440,12 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('scenario_date', models.CharField(default='No date', max_length=256)),
('scenario_type', models.CharField(default='Not specified', max_length=256)),
('additional_information', models.JSONField(verbose_name='Additional Information')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Package')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Package')),
('parent', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='epdb.scenario')),
],
options={
@ -437,14 +496,16 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('url', models.TextField(null=True, unique=True, verbose_name='URL')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('public', models.BooleanField(default=False)),
('global_default', models.BooleanField(default=False)),
('max_depth', models.IntegerField(default=5, verbose_name='Setting Max Depth')),
('max_nodes', models.IntegerField(default=30, verbose_name='Setting Max Number of Nodes')),
('model_threshold', models.FloatField(blank=True, default=0.25, null=True, verbose_name='Setting Model Threshold')),
('expansion_scheme', models.CharField(choices=[('BFS', 'Breadth First Search'), ('DFS', 'Depth First Search'), ('GREEDY', 'Greedy')], default='BFS', max_length=20)),
('model', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.epmodel', verbose_name='Setting EPModel')),
('rule_packages', models.ManyToManyField(blank=True, related_name='setting_rule_packages', to='epdb.package', verbose_name='Setting Rule Packages')),
('rule_packages', models.ManyToManyField(blank=True, related_name='setting_rule_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Setting Rule Packages')),
],
options={
'abstract': False,
@ -461,39 +522,86 @@ class Migration(migrations.Migration):
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.setting', verbose_name='The users default settings'),
),
migrations.CreateModel(
name='MLRelativeReasoning',
name='EnviFormer',
fields=[
('epmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='epdb.epmodel')),
('threshold', models.FloatField(default=0.5)),
('model_status', models.CharField(choices=[('INITIAL', 'Initial'), ('INITIALIZING', 'Model is initializing.'), ('BUILDING', 'Model is building.'), ('BUILT_NOT_EVALUATED', 'Model is built and can be used for predictions, Model is not evaluated yet.'), ('EVALUATING', 'Model is evaluating'), ('FINISHED', 'Model has finished building and evaluation.'), ('ERROR', 'Model has failed.')], default='INITIAL')),
('eval_results', models.JSONField(blank=True, default=dict, null=True)),
('data_packages', models.ManyToManyField(related_name='data_packages', to='epdb.package', verbose_name='Data Packages')),
('eval_packages', models.ManyToManyField(related_name='eval_packages', to='epdb.package', verbose_name='Evaluation Packages')),
('rule_packages', models.ManyToManyField(related_name='rule_packages', to='epdb.package', verbose_name='Rule Packages')),
('multigen_eval', models.BooleanField(default=False)),
('model_status', models.CharField(choices=[('INITIAL', 'Initial'), ('INITIALIZING', 'Model is initializing.'), ('BUILDING', 'Model is building.'), ('BUILT_NOT_EVALUATED', 'Model is built and can be used for predictions, Model is not evaluated yet.'), ('EVALUATING', 'Model is evaluating'), ('FINISHED', 'Model has finished building and evaluation.'), ('ERROR', 'Model has failed.')], default='INITIAL')),
('app_domain', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.applicabilitydomain')),
('data_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_data_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Data Packages')),
('eval_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_eval_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Evaluation Packages')),
('rule_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_rule_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Rule Packages')),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
bases=('epdb.epmodel',),
),
migrations.CreateModel(
name='ApplicabilityDomain',
name='MLRelativeReasoning',
fields=[
('epmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='epdb.epmodel')),
('threshold', models.FloatField(default=0.5)),
('eval_results', models.JSONField(blank=True, default=dict, null=True)),
('multigen_eval', models.BooleanField(default=False)),
('model_status', models.CharField(choices=[('INITIAL', 'Initial'), ('INITIALIZING', 'Model is initializing.'), ('BUILDING', 'Model is building.'), ('BUILT_NOT_EVALUATED', 'Model is built and can be used for predictions, Model is not evaluated yet.'), ('EVALUATING', 'Model is evaluating'), ('FINISHED', 'Model has finished building and evaluation.'), ('ERROR', 'Model has failed.')], default='INITIAL')),
('app_domain', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.applicabilitydomain')),
('data_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_data_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Data Packages')),
('eval_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_eval_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Evaluation Packages')),
('rule_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_rule_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Rule Packages')),
],
options={
'abstract': False,
},
bases=('epdb.epmodel',),
),
migrations.AddField(
model_name='applicabilitydomain',
name='model',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.mlrelativereasoning'),
),
migrations.CreateModel(
name='RuleBasedRelativeReasoning',
fields=[
('epmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='epdb.epmodel')),
('threshold', models.FloatField(default=0.5)),
('eval_results', models.JSONField(blank=True, default=dict, null=True)),
('multigen_eval', models.BooleanField(default=False)),
('model_status', models.CharField(choices=[('INITIAL', 'Initial'), ('INITIALIZING', 'Model is initializing.'), ('BUILDING', 'Model is building.'), ('BUILT_NOT_EVALUATED', 'Model is built and can be used for predictions, Model is not evaluated yet.'), ('EVALUATING', 'Model is evaluating'), ('FINISHED', 'Model has finished building and evaluation.'), ('ERROR', 'Model has failed.')], default='INITIAL')),
('min_count', models.IntegerField(default=10)),
('max_count', models.IntegerField(default=0)),
('app_domain', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.applicabilitydomain')),
('data_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_data_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Data Packages')),
('eval_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_eval_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Evaluation Packages')),
('rule_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_rule_packages', to=settings.EPDB_PACKAGE_MODEL, verbose_name='Rule Packages')),
],
options={
'abstract': False,
},
bases=('epdb.epmodel',),
),
migrations.CreateModel(
name='ExternalIdentifier',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')),
('name', models.TextField(default='no name', verbose_name='Name')),
('description', models.TextField(default='no description', verbose_name='Descriptions')),
('kv', models.JSONField(blank=True, default=dict, null=True)),
('num_neighbours', models.FloatField(default=5)),
('reliability_threshold', models.FloatField(default=0.5)),
('local_compatibilty_threshold', models.FloatField(default=0.5)),
('model', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.mlrelativereasoning')),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('object_id', models.IntegerField()),
('identifier_value', models.CharField(max_length=255, verbose_name='Identifier Value')),
('url', models.URLField(blank=True, null=True, verbose_name='Direct URL')),
('is_primary', models.BooleanField(default=False, help_text='Mark this as the primary identifier for this database', verbose_name='Is Primary')),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
('database', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.externaldatabase', verbose_name='External Database')),
],
options={
'abstract': False,
'verbose_name': 'External Identifier',
'verbose_name_plural': 'External Identifiers',
'db_table': 'epdb_external_identifier',
'indexes': [models.Index(fields=['content_type', 'object_id'], name='epdb_extern_content_b76813_idx'), models.Index(fields=['database', 'identifier_value'], name='epdb_extern_databas_486422_idx')],
'unique_together': {('content_type', 'object_id', 'database', 'identifier_value')},
},
),
migrations.CreateModel(
@ -558,7 +666,7 @@ class Migration(migrations.Migration):
('permission_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, to='epdb.permission')),
('uuid', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='UUID of this object')),
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.group', verbose_name='Permission to')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Permission on')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Permission on')),
],
options={
'unique_together': {('package', 'group')},
@ -570,7 +678,7 @@ class Migration(migrations.Migration):
fields=[
('permission_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, to='epdb.permission')),
('uuid', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='UUID of this object')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.package', verbose_name='Permission on')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.EPDB_PACKAGE_MODEL, verbose_name='Permission on')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Permission to')),
],
options={

View File

@ -40,7 +40,7 @@ def set_cc(apps, schema_editor):
row["cc_string"]: (row["lowest_pk"], row["all_pks"]) for row in license_lookup_qs
}
Packages = apps.get_model("epdb", "Package")
Packages = apps.get_model("bayer", "Package")
for k, v in license_lookup.items():
# Set min pk to all packages pointing to any of the duplicates
@ -53,7 +53,7 @@ def set_cc(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
("epdb", "0010_license_cc_string"),
("epdb", "0001_initial"),
]
operations = [migrations.RunPython(set_cc)]

View File

@ -1,128 +0,0 @@
# Generated by Django 5.2.1 on 2025-08-25 18:07
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('epdb', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='ExternalDatabase',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('name', models.CharField(max_length=100, unique=True, verbose_name='Database Name')),
('full_name', models.CharField(blank=True, max_length=255, verbose_name='Full Database Name')),
('description', models.TextField(blank=True, verbose_name='Description')),
('base_url', models.URLField(blank=True, null=True, verbose_name='Base URL')),
('url_pattern', models.CharField(blank=True, help_text="URL pattern with {id} placeholder, e.g., 'https://pubchem.ncbi.nlm.nih.gov/compound/{id}'", max_length=500, verbose_name='URL Pattern')),
('is_active', models.BooleanField(default=True, verbose_name='Is Active')),
],
options={
'verbose_name': 'External Database',
'verbose_name_plural': 'External Databases',
'db_table': 'epdb_external_database',
'ordering': ['name'],
},
),
migrations.AlterModelOptions(
name='apitoken',
options={'ordering': ['-created'], 'verbose_name': 'API Token', 'verbose_name_plural': 'API Tokens'},
),
migrations.AlterModelOptions(
name='edge',
options={},
),
migrations.RemoveField(
model_name='edge',
name='polymorphic_ctype',
),
migrations.AddField(
model_name='apitoken',
name='is_active',
field=models.BooleanField(default=True, help_text='Whether this token is active'),
),
migrations.AddField(
model_name='apitoken',
name='modified',
field=model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified'),
),
migrations.AddField(
model_name='applicabilitydomain',
name='functional_groups',
field=models.JSONField(blank=True, default=dict, null=True),
),
migrations.AddField(
model_name='mlrelativereasoning',
name='app_domain',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.applicabilitydomain'),
),
migrations.AlterField(
model_name='apitoken',
name='created',
field=model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created'),
),
migrations.AlterField(
model_name='apitoken',
name='expires_at',
field=models.DateTimeField(blank=True, help_text='Token expiration time (null for no expiration)', null=True),
),
migrations.AlterField(
model_name='apitoken',
name='hashed_key',
field=models.CharField(help_text='SHA-256 hash of the token key', max_length=128, unique=True),
),
migrations.AlterField(
model_name='apitoken',
name='name',
field=models.CharField(help_text='Descriptive name for this token', max_length=100),
),
migrations.AlterField(
model_name='apitoken',
name='user',
field=models.ForeignKey(help_text='User who owns this token', on_delete=django.db.models.deletion.CASCADE, related_name='api_tokens', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='applicabilitydomain',
name='num_neighbours',
field=models.IntegerField(default=5),
),
migrations.AlterModelTable(
name='apitoken',
table='epdb_api_token',
),
migrations.CreateModel(
name='ExternalIdentifier',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('object_id', models.IntegerField()),
('identifier_value', models.CharField(max_length=255, verbose_name='Identifier Value')),
('url', models.URLField(blank=True, null=True, verbose_name='Direct URL')),
('is_primary', models.BooleanField(default=False, help_text='Mark this as the primary identifier for this database', verbose_name='Is Primary')),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
('database', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='epdb.externaldatabase', verbose_name='External Database')),
],
options={
'verbose_name': 'External Identifier',
'verbose_name_plural': 'External Identifiers',
'db_table': 'epdb_external_identifier',
'indexes': [models.Index(fields=['content_type', 'object_id'], name='epdb_extern_content_b76813_idx'), models.Index(fields=['database', 'identifier_value'], name='epdb_extern_databas_486422_idx')],
'unique_together': {('content_type', 'object_id', 'database', 'identifier_value')},
},
),
]

View File

@ -1,228 +0,0 @@
# Generated by Django 5.2.1 on 2025-08-26 17:05
from django.db import migrations, models
def populate_url(apps, schema_editor):
MODELS = [
'User',
'Group',
'Package',
'Compound',
'CompoundStructure',
'Pathway',
'Edge',
'Node',
'Reaction',
'SimpleAmbitRule',
'SimpleRDKitRule',
'ParallelRule',
'SequentialRule',
'Scenario',
'Setting',
'MLRelativeReasoning',
'EnviFormer',
'ApplicabilityDomain',
]
for model in MODELS:
obj_cls = apps.get_model("epdb", model)
for obj in obj_cls.objects.all():
obj.url = assemble_url(obj)
if obj.url is None:
raise ValueError(f"Could not assemble url for {obj}")
obj.save()
def assemble_url(obj):
from django.conf import settings as s
match obj.__class__.__name__:
case 'User':
return '{}/user/{}'.format(s.SERVER_URL, obj.uuid)
case 'Group':
return '{}/group/{}'.format(s.SERVER_URL, obj.uuid)
case 'Package':
return '{}/package/{}'.format(s.SERVER_URL, obj.uuid)
case 'Compound':
return '{}/compound/{}'.format(obj.package.url, obj.uuid)
case 'CompoundStructure':
return '{}/structure/{}'.format(obj.compound.url, obj.uuid)
case 'SimpleAmbitRule':
return '{}/simple-ambit-rule/{}'.format(obj.package.url, obj.uuid)
case 'SimpleRDKitRule':
return '{}/simple-rdkit-rule/{}'.format(obj.package.url, obj.uuid)
case 'ParallelRule':
return '{}/parallel-rule/{}'.format(obj.package.url, obj.uuid)
case 'SequentialRule':
return '{}/sequential-rule/{}'.format(obj.compound.url, obj.uuid)
case 'Reaction':
return '{}/reaction/{}'.format(obj.package.url, obj.uuid)
case 'Pathway':
return '{}/pathway/{}'.format(obj.package.url, obj.uuid)
case 'Node':
return '{}/node/{}'.format(obj.pathway.url, obj.uuid)
case 'Edge':
return '{}/edge/{}'.format(obj.pathway.url, obj.uuid)
case 'MLRelativeReasoning':
return '{}/model/{}'.format(obj.package.url, obj.uuid)
case 'EnviFormer':
return '{}/model/{}'.format(obj.package.url, obj.uuid)
case 'ApplicabilityDomain':
return '{}/model/{}/applicability-domain/{}'.format(obj.model.package.url, obj.model.uuid, obj.uuid)
case 'Scenario':
return '{}/scenario/{}'.format(obj.package.url, obj.uuid)
case 'Setting':
return '{}/setting/{}'.format(s.SERVER_URL, obj.uuid)
case _:
raise ValueError(f"Unknown model {obj.__class__.__name__}")
class Migration(migrations.Migration):
dependencies = [
('epdb', '0002_externaldatabase_alter_apitoken_options_and_more'),
]
operations = [
migrations.AddField(
model_name='applicabilitydomain',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='compound',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='compoundstructure',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='edge',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='epmodel',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='group',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='node',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='package',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='pathway',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='reaction',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='rule',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='scenario',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='setting',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.AddField(
model_name='user',
name='url',
field=models.TextField(null=True, unique=False, verbose_name='URL'),
),
migrations.RunPython(populate_url, reverse_code=migrations.RunPython.noop),
migrations.AlterField(
model_name='applicabilitydomain',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='compound',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='compoundstructure',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='edge',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='epmodel',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='group',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='node',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='package',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='pathway',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='reaction',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='rule',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='scenario',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='setting',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
migrations.AlterField(
model_name='user',
name='url',
field=models.TextField(null=True, unique=True, verbose_name='URL'),
),
]

View File

@ -1,55 +0,0 @@
# Generated by Django 5.2.1 on 2025-09-09 09:21
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('epdb', '0001_squashed_0003_applicabilitydomain_url_compound_url_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='mlrelativereasoning',
options={},
),
migrations.AlterField(
model_name='mlrelativereasoning',
name='data_packages',
field=models.ManyToManyField(related_name='%(app_label)s_%(class)s_data_packages', to='epdb.package', verbose_name='Data Packages'),
),
migrations.AlterField(
model_name='mlrelativereasoning',
name='eval_packages',
field=models.ManyToManyField(related_name='%(app_label)s_%(class)s_eval_packages', to='epdb.package', verbose_name='Evaluation Packages'),
),
migrations.AlterField(
model_name='mlrelativereasoning',
name='rule_packages',
field=models.ManyToManyField(related_name='%(app_label)s_%(class)s_rule_packages', to='epdb.package', verbose_name='Rule Packages'),
),
migrations.CreateModel(
name='RuleBasedRelativeReasoning',
fields=[
('epmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='epdb.epmodel')),
('threshold', models.FloatField(default=0.5)),
('eval_results', models.JSONField(blank=True, default=dict, null=True)),
('model_status', models.CharField(choices=[('INITIAL', 'Initial'), ('INITIALIZING', 'Model is initializing.'), ('BUILDING', 'Model is building.'), ('BUILT_NOT_EVALUATED', 'Model is built and can be used for predictions, Model is not evaluated yet.'), ('EVALUATING', 'Model is evaluating'), ('FINISHED', 'Model has finished building and evaluation.'), ('ERROR', 'Model has failed.')], default='INITIAL')),
('min_count', models.IntegerField(default=10)),
('max_count', models.IntegerField(default=0)),
('app_domain', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.applicabilitydomain')),
('data_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_data_packages', to='epdb.package', verbose_name='Data Packages')),
('eval_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_eval_packages', to='epdb.package', verbose_name='Evaluation Packages')),
('rule_packages', models.ManyToManyField(related_name='%(app_label)s_%(class)s_rule_packages', to='epdb.package', verbose_name='Rule Packages')),
],
options={
'abstract': False,
},
bases=('epdb.epmodel',),
),
migrations.DeleteModel(
name='RuleBaseRelativeReasoning',
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2.1 on 2025-09-11 06:21
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('epdb', '0004_alter_mlrelativereasoning_options_and_more'),
]
operations = [
migrations.AlterField(
model_name='group',
name='group_member',
field=models.ManyToManyField(blank=True, related_name='groups_in_group', to='epdb.group', verbose_name='Group member'),
),
]

View File

@ -1,23 +0,0 @@
# Generated by Django 5.2.1 on 2025-09-18 06:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('epdb', '0005_alter_group_group_member'),
]
operations = [
migrations.AddField(
model_name='mlrelativereasoning',
name='multigen_eval',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='rulebasedrelativereasoning',
name='multigen_eval',
field=models.BooleanField(default=False),
),
]

View File

@ -1,53 +0,0 @@
# Generated by Django 5.2.1 on 2025-10-07 08:19
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('epdb', '0006_mlrelativereasoning_multigen_eval_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='enviformer',
options={},
),
migrations.AddField(
model_name='enviformer',
name='app_domain',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.applicabilitydomain'),
),
migrations.AddField(
model_name='enviformer',
name='data_packages',
field=models.ManyToManyField(related_name='%(app_label)s_%(class)s_data_packages', to='epdb.package', verbose_name='Data Packages'),
),
migrations.AddField(
model_name='enviformer',
name='eval_packages',
field=models.ManyToManyField(related_name='%(app_label)s_%(class)s_eval_packages', to='epdb.package', verbose_name='Evaluation Packages'),
),
migrations.AddField(
model_name='enviformer',
name='eval_results',
field=models.JSONField(blank=True, default=dict, null=True),
),
migrations.AddField(
model_name='enviformer',
name='model_status',
field=models.CharField(choices=[('INITIAL', 'Initial'), ('INITIALIZING', 'Model is initializing.'), ('BUILDING', 'Model is building.'), ('BUILT_NOT_EVALUATED', 'Model is built and can be used for predictions, Model is not evaluated yet.'), ('EVALUATING', 'Model is evaluating'), ('FINISHED', 'Model has finished building and evaluation.'), ('ERROR', 'Model has failed.')], default='INITIAL'),
),
migrations.AddField(
model_name='enviformer',
name='multigen_eval',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='enviformer',
name='rule_packages',
field=models.ManyToManyField(related_name='%(app_label)s_%(class)s_rule_packages', to='epdb.package', verbose_name='Rule Packages'),
),
]

View File

@ -1,64 +0,0 @@
# Generated by Django 5.2.7 on 2025-10-10 06:58
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("epdb", "0007_alter_enviformer_options_enviformer_app_domain_and_more"),
]
operations = [
migrations.CreateModel(
name="EnzymeLink",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
(
"created",
model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, editable=False, verbose_name="created"
),
),
(
"modified",
model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, editable=False, verbose_name="modified"
),
),
(
"uuid",
models.UUIDField(
default=uuid.uuid4, unique=True, verbose_name="UUID of this object"
),
),
("name", models.TextField(default="no name", verbose_name="Name")),
(
"description",
models.TextField(default="no description", verbose_name="Descriptions"),
),
("url", models.TextField(null=True, unique=True, verbose_name="URL")),
("kv", models.JSONField(blank=True, default=dict, null=True)),
("ec_number", models.TextField(verbose_name="EC Number")),
("classification_level", models.IntegerField(verbose_name="Classification Level")),
("linking_method", models.TextField(verbose_name="Linking Method")),
("edge_evidence", models.ManyToManyField(to="epdb.edge")),
("reaction_evidence", models.ManyToManyField(to="epdb.reaction")),
(
"rule",
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="epdb.rule"),
),
],
options={
"abstract": False,
},
),
]

View File

@ -1,66 +0,0 @@
# Generated by Django 5.2.7 on 2025-10-27 09:39
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("epdb", "0008_enzymelink"),
]
operations = [
migrations.CreateModel(
name="JobLog",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
(
"created",
model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, editable=False, verbose_name="created"
),
),
(
"modified",
model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, editable=False, verbose_name="modified"
),
),
("task_id", models.UUIDField(unique=True)),
("job_name", models.TextField()),
(
"status",
models.CharField(
choices=[
("INITIAL", "Initial"),
("SUCCESS", "Success"),
("FAILURE", "Failure"),
("REVOKED", "Revoked"),
("IGNORED", "Ignored"),
],
default="INITIAL",
max_length=20,
),
),
("done_at", models.DateTimeField(blank=True, default=None, null=True)),
("task_result", models.TextField(blank=True, default=None, null=True)),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
options={
"abstract": False,
},
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2.7 on 2025-11-11 14:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("epdb", "0009_joblog"),
]
operations = [
migrations.AddField(
model_name="license",
name="cc_string",
field=models.TextField(default="by-nc-sa", verbose_name="CC string"),
preserve_default=False,
),
]

View File

@ -1,22 +0,0 @@
# Generated by Django 5.2.7 on 2025-12-02 13:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("epdb", "0011_auto_20251111_1413"),
]
operations = [
migrations.AddField(
model_name="node",
name="stereo_removed",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="pathway",
name="predicted",
field=models.BooleanField(default=False),
),
]

View File

@ -1,25 +0,0 @@
# Generated by Django 5.2.7 on 2025-12-14 11:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("epdb", "0012_node_stereo_removed_pathway_predicted"),
]
operations = [
migrations.AddField(
model_name="setting",
name="expansion_schema",
field=models.CharField(
choices=[
("BFS", "Breadth First Search"),
("DFS", "Depth First Search"),
("GREEDY", "Greedy"),
],
default="BFS",
max_length=20,
),
),
]

View File

@ -1,17 +0,0 @@
# Generated by Django 5.2.7 on 2025-12-14 16:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("epdb", "0013_setting_expansion_schema"),
]
operations = [
migrations.RenameField(
model_name="setting",
old_name="expansion_schema",
new_name="expansion_scheme",
),
]

View File

@ -1,17 +0,0 @@
# Generated by Django 5.2.7 on 2026-01-19 19:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("epdb", "0014_rename_expansion_schema_setting_expansion_scheme"),
]
operations = [
migrations.AddField(
model_name="user",
name="is_reviewer",
field=models.BooleanField(default=False),
),
]