forked from enviPath/enviPy
[Feature] External Identifier/References
Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#139
This commit is contained in:
@ -16,7 +16,9 @@ from .models import (
|
||||
Node,
|
||||
Edge,
|
||||
Scenario,
|
||||
Setting
|
||||
Setting,
|
||||
ExternalDatabase,
|
||||
ExternalIdentifier
|
||||
)
|
||||
|
||||
|
||||
@ -43,6 +45,7 @@ class EPAdmin(admin.ModelAdmin):
|
||||
class PackageAdmin(EPAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class MLRelativeReasoningAdmin(EPAdmin):
|
||||
pass
|
||||
|
||||
@ -87,6 +90,14 @@ class SettingAdmin(EPAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class ExternalDatabaseAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class ExternalIdentifierAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
|
||||
admin.site.register(User, UserAdmin)
|
||||
admin.site.register(UserPackagePermission, UserPackagePermissionAdmin)
|
||||
admin.site.register(Group, GroupAdmin)
|
||||
@ -103,3 +114,5 @@ admin.site.register(Node, NodeAdmin)
|
||||
admin.site.register(Edge, EdgeAdmin)
|
||||
admin.site.register(Setting, SettingAdmin)
|
||||
admin.site.register(Scenario, ScenarioAdmin)
|
||||
admin.site.register(ExternalDatabase, ExternalDatabaseAdmin)
|
||||
admin.site.register(ExternalIdentifier, ExternalIdentifierAdmin)
|
||||
|
||||
@ -116,7 +116,7 @@ class Command(BaseCommand):
|
||||
'full_name': 'KEGG Reaction Database',
|
||||
'description': 'Database of biochemical reactions',
|
||||
'base_url': 'https://www.genome.jp',
|
||||
'url_pattern': 'https://www.genome.jp/entry/reaction+{id}'
|
||||
'url_pattern': 'https://www.genome.jp/entry/{id}'
|
||||
},
|
||||
{
|
||||
'name': 'UniProt',
|
||||
|
||||
57
epdb/management/commands/import_external_identifiers.py
Normal file
57
epdb/management/commands/import_external_identifiers.py
Normal file
@ -0,0 +1,57 @@
|
||||
from csv import DictReader
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from epdb.models import *
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
STR_TO_MODEL = {
|
||||
'Compound': Compound,
|
||||
'CompoundStructure': CompoundStructure,
|
||||
'Reaction': Reaction,
|
||||
}
|
||||
|
||||
STR_TO_DATABASE = {
|
||||
'ChEBI': ExternalDatabase.objects.get(name='ChEBI'),
|
||||
'RHEA': ExternalDatabase.objects.get(name='RHEA'),
|
||||
'KEGG Reaction': ExternalDatabase.objects.get(name='KEGG Reaction'),
|
||||
'PubChem Compound': ExternalDatabase.objects.get(name='PubChem Compound'),
|
||||
'PubChem Substance': ExternalDatabase.objects.get(name='PubChem Substance'),
|
||||
}
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--data',
|
||||
type=str,
|
||||
help='Path of the ID Mapping file.',
|
||||
required=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--replace-host',
|
||||
type=str,
|
||||
help='Replace https://envipath.org/ with this host, e.g. http://localhost:8000/',
|
||||
)
|
||||
|
||||
@transaction.atomic
|
||||
def handle(self, *args, **options):
|
||||
with open(options['data']) as fh:
|
||||
reader = DictReader(fh)
|
||||
for row in reader:
|
||||
clz = self.STR_TO_MODEL[row['model']]
|
||||
|
||||
url = row['url']
|
||||
if options['replace_host']:
|
||||
url = url.replace('https://envipath.org/', options['replace_host'])
|
||||
|
||||
instance = clz.objects.get(url=url)
|
||||
db = self.STR_TO_DATABASE[row['identifier_type']]
|
||||
|
||||
ExternalIdentifier.objects.create(
|
||||
content_object=instance,
|
||||
database=db,
|
||||
identifier_value=row['identifier_value'],
|
||||
url=db.url_pattern.format(id=row['identifier_value']),
|
||||
is_primary=False
|
||||
)
|
||||
@ -277,6 +277,53 @@ class ExternalDatabase(TimeStampedModel):
|
||||
return self.url_pattern.format(id=identifier_value)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_databases():
|
||||
return {
|
||||
'compound': [
|
||||
{
|
||||
'database': ExternalDatabase.objects.get(name='PubChem Compound'),
|
||||
'placeholder': 'PubChem Compound ID e.g. 12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='PubChem Substance'),
|
||||
'placeholder': 'PubChem Substance ID e.g. 12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='KEGG Reaction'),
|
||||
'placeholder': 'KEGG ID including entity Prefix e.g. C12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='ChEBI'),
|
||||
'placeholder': 'ChEBI ID without prefix e.g. 12345',
|
||||
},
|
||||
],
|
||||
'structure': [
|
||||
{
|
||||
'database': ExternalDatabase.objects.get(name='PubChem Compound'),
|
||||
'placeholder': 'PubChem Compound ID e.g. 12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='PubChem Substance'),
|
||||
'placeholder': 'PubChem Substance ID e.g. 12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='KEGG Reaction'),
|
||||
'placeholder': 'KEGG ID including entity Prefix e.g. C12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='ChEBI'),
|
||||
'placeholder': 'ChEBI ID without prefix e.g. 12345',
|
||||
},
|
||||
],
|
||||
'reaction': [
|
||||
{
|
||||
'database': ExternalDatabase.objects.get(name='KEGG Reaction'),
|
||||
'placeholder': 'KEGG ID including entity Prefix e.g. C12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='RHEA'),
|
||||
'placeholder': 'RHEA ID without Prefix e.g. 12345',
|
||||
}, {
|
||||
'database': ExternalDatabase.objects.get(name='UniProt'),
|
||||
'placeholder': 'Query ID for UniPro e.g. rhea:12345',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
class ExternalIdentifier(TimeStampedModel):
|
||||
uuid = models.UUIDField(default=uuid4, editable=False, unique=True)
|
||||
|
||||
@ -17,7 +17,7 @@ from utilities.misc import HTMLGenerator
|
||||
from .logic import GroupManager, PackageManager, UserManager, SettingManager, SearchManager, EPDBURLParser
|
||||
from .models import Package, GroupPackagePermission, Group, CompoundStructure, Compound, Reaction, Rule, Pathway, Node, \
|
||||
EPModel, EnviFormer, MLRelativeReasoning, RuleBasedRelativeReasoning, Scenario, SimpleAmbitRule, APIToken, \
|
||||
UserPackagePermission, Permission, License, User, Edge
|
||||
UserPackagePermission, Permission, License, User, Edge, ExternalDatabase, ExternalIdentifier
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -194,6 +194,7 @@ def get_base_context(request, for_user=None) -> Dict[str, Any]:
|
||||
'available_settings': SettingManager.get_all_settings(current_user),
|
||||
'enabled_features': s.FLAGS,
|
||||
'debug': s.DEBUG,
|
||||
'external_databases': ExternalDatabase.get_databases(),
|
||||
},
|
||||
}
|
||||
|
||||
@ -249,6 +250,9 @@ def copy_object(current_user, target_package: 'Package', source_object_url: str)
|
||||
# Ensures that source is readable
|
||||
source_package = PackageManager.get_package_by_url(current_user, source_object_url)
|
||||
|
||||
if source_package == target_package:
|
||||
raise ValueError(f"Can't copy object {source_object_url} to the same package!")
|
||||
|
||||
parser = EPDBURLParser(source_object_url)
|
||||
|
||||
# if the url won't contain a package or is a plain package
|
||||
@ -892,7 +896,11 @@ def package(request, package_uuid):
|
||||
if not object_to_copy:
|
||||
return error(request, 'No object to copy', 'There was no object to copy.')
|
||||
|
||||
copied_object = copy_object(current_user, current_package, object_to_copy)
|
||||
try:
|
||||
copied_object = copy_object(current_user, current_package, object_to_copy)
|
||||
except ValueError as e:
|
||||
return JsonResponse({'error': f"Can't copy object {object_to_copy} to the same package!"}, status=400)
|
||||
|
||||
return JsonResponse({'success': copied_object.url})
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
@ -1043,8 +1051,8 @@ def package_compound(request, package_uuid, compound_uuid):
|
||||
set_scenarios(current_user, current_compound, selected_scenarios)
|
||||
return redirect(current_compound.url)
|
||||
|
||||
new_compound_name = request.POST.get('compound-name')
|
||||
new_compound_description = request.POST.get('compound-description')
|
||||
new_compound_name = request.POST.get('compound-name', '').strip()
|
||||
new_compound_description = request.POST.get('compound-description', '').strip()
|
||||
|
||||
if new_compound_name:
|
||||
current_compound.name = new_compound_name
|
||||
@ -1055,6 +1063,20 @@ def package_compound(request, package_uuid, compound_uuid):
|
||||
if any([new_compound_name, new_compound_description]):
|
||||
current_compound.save()
|
||||
return redirect(current_compound.url)
|
||||
|
||||
selected_database = request.POST.get('selected-database', '').strip()
|
||||
external_identifier = request.POST.get('identifier', '').strip()
|
||||
|
||||
if selected_database and external_identifier:
|
||||
db = ExternalDatabase.objects.get(id=int(selected_database))
|
||||
ExternalIdentifier.objects.create(
|
||||
content_object=current_compound,
|
||||
database=db,
|
||||
identifier_value=external_identifier,
|
||||
url=db.url_pattern.format(id=external_identifier),
|
||||
is_primary=False
|
||||
)
|
||||
return redirect(current_compound.url)
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
@ -1146,12 +1168,39 @@ def package_compound_structure(request, package_uuid, compound_uuid, structure_u
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
new_structure_name = request.POST.get('compound-structure-name', '').strip()
|
||||
new_structure_description = request.POST.get('compound-structure-description', '').strip()
|
||||
|
||||
if new_structure_name:
|
||||
current_structure.name = new_structure_name
|
||||
|
||||
if new_structure_description:
|
||||
current_structure.description = new_structure_description
|
||||
|
||||
if any([new_structure_name, new_structure_description]):
|
||||
current_structure.save()
|
||||
return redirect(current_structure.url)
|
||||
|
||||
if 'selected-scenarios' in request.POST:
|
||||
selected_scenarios = request.POST.getlist('selected-scenarios')
|
||||
|
||||
set_scenarios(current_user, current_structure, selected_scenarios)
|
||||
return redirect(current_structure.url)
|
||||
|
||||
selected_database = request.POST.get('selected-database', '').strip()
|
||||
external_identifier = request.POST.get('identifier', '').strip()
|
||||
|
||||
if selected_database and external_identifier:
|
||||
db = ExternalDatabase.objects.get(id=int(selected_database))
|
||||
ExternalIdentifier.objects.create(
|
||||
content_object=current_structure,
|
||||
database=db,
|
||||
identifier_value=external_identifier,
|
||||
url=db.url_pattern.format(id=external_identifier),
|
||||
is_primary=False
|
||||
)
|
||||
return redirect(current_structure.url)
|
||||
|
||||
return HttpResponseBadRequest()
|
||||
else:
|
||||
return HttpResponseNotAllowed(['GET', ])
|
||||
@ -1382,8 +1431,8 @@ def package_reaction(request, package_uuid, reaction_uuid):
|
||||
set_scenarios(current_user, current_reaction, selected_scenarios)
|
||||
return redirect(current_reaction.url)
|
||||
|
||||
new_reaction_name = request.POST.get('reaction-name')
|
||||
new_reaction_description = request.POST.get('reaction-description')
|
||||
new_reaction_name = request.POST.get('reaction-name', '').strip()
|
||||
new_reaction_description = request.POST.get('reaction-description', '').strip()
|
||||
|
||||
if new_reaction_name:
|
||||
current_reaction.name = new_reaction_name
|
||||
@ -1394,8 +1443,22 @@ def package_reaction(request, package_uuid, reaction_uuid):
|
||||
if any([new_reaction_name, new_reaction_description]):
|
||||
current_reaction.save()
|
||||
return redirect(current_reaction.url)
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
selected_database = request.POST.get('selected-database', '').strip()
|
||||
external_identifier = request.POST.get('identifier', '').strip()
|
||||
|
||||
if selected_database and external_identifier:
|
||||
db = ExternalDatabase.objects.get(id=int(selected_database))
|
||||
ExternalIdentifier.objects.create(
|
||||
content_object=current_reaction,
|
||||
database=db,
|
||||
identifier_value=external_identifier,
|
||||
url=db.url_pattern.format(id=external_identifier),
|
||||
is_primary=False
|
||||
)
|
||||
return redirect(current_reaction.url)
|
||||
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
else:
|
||||
return HttpResponseNotAllowed(['GET', 'POST'])
|
||||
|
||||
Reference in New Issue
Block a user