Skip to content

Commit

Permalink
fix(release): fixes and updates (#1613)
Browse files Browse the repository at this point in the history
  • Loading branch information
elmessary authored Apr 24, 2024
2 parents e255e2c + 710c7e5 commit d38c1c5
Show file tree
Hide file tree
Showing 113 changed files with 7,894 additions and 1,266 deletions.
5 changes: 5 additions & 0 deletions CodeListLibrary_project/clinicalcode/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
from .models.EntityClass import EntityClass
from .models.GenericEntity import GenericEntity
from .models.Template import Template
from .models.OntologyTag import OntologyTag
from .models.DMD_CODES import DMD_CODES
from .forms.TemplateForm import TemplateAdminForm
from .forms.EntityClassForm import EntityAdminForm

@admin.register(OntologyTag)
class OntologyTag(admin.ModelAdmin):
list_display = ['id', 'name', 'type_id', 'atlas_id']


@admin.register(CodingSystemFilter)
class CodingSystemFilterAdmin(admin.ModelAdmin):
Expand Down
27 changes: 21 additions & 6 deletions CodeListLibrary_project/clinicalcode/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

from .views import Concept, GenericEntity, Template, DataSource, Tag, Collection
from .views import (
Concept, GenericEntity,
Template, DataSource,
Tag, Collection, Ontology
)

""" Router
Use the default REST API router to access the API details explicitly. These paths will
Expand Down Expand Up @@ -135,19 +139,30 @@ def get_schema(self, request=None, public=False):

# Tags
url(r'^tags/$',
Tag.get_tags,
Tag.get_tags,
name='tag_list'),
url(r'^tags/(?P<tag_id>\d+)/detail/$',
Tag.get_tag_detail,
Tag.get_tag_detail,
name='tag_list_by_id'),

# Collections
url(r'^collections/$',
Collection.get_collections,
Collection.get_collections,
name='collection_list'),
url(r'^collections/(?P<collection_id>\d+)/detail/$',
Collection.get_collection_detail,
name='collections_list_by_id'),
Collection.get_collection_detail,
name='collections_list_by_id'),

# Ontology
url(r'^ontology/$',
Ontology.get_ontologies,
name='ontology_list'),
url(r'^ontology/type/(?P<ontology_id>\d+)/$',
Ontology.get_ontology_detail,
name='ontology_list_by_type'),
url(r'^ontology/node/(?P<node_id>\d+)/$',
Ontology.get_ontology_node,
name='ontology_node_by_id'),
]

""" Create/Update urls """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def get_entity_detail(request, phenotype_id, version_id=None, field=None):
historical_entity,
user_authed,
target_field=field,
return_data=True
return_data=False
)

if field == 'codes':
Expand Down
81 changes: 81 additions & 0 deletions CodeListLibrary_project/clinicalcode/api/views/Ontology.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from rest_framework.decorators import (api_view, permission_classes)
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework import status
from django.db.models import F

from ...entity_utils import api_utils
from ...entity_utils import gen_utils
from ...entity_utils import constants

from ...models.OntologyTag import OntologyTag

@api_view(['GET'])
@permission_classes([IsAuthenticatedOrReadOnly])
def get_ontologies(request):
"""
Get all ontology categories and their root nodes, incl. associated data
"""
result = OntologyTag.get_groups([x.value for x in constants.ONTOLOGY_TYPES], default=[])
return Response(
data=list(result),
status=status.HTTP_200_OK
)

@api_view(['GET'])
@permission_classes([IsAuthenticatedOrReadOnly])
def get_ontology_detail(request, ontology_id):
"""
Get specified ontology group detail by the ontology_id type, including associated
data e.g. root nodes, children etc
"""
ontology_id = gen_utils.parse_int(ontology_id, default=None)
if not isinstance(ontology_id, int):
return Response(
data={
'message': 'Invalid ontology id, expected valid integer'
},
content_type='json',
status=status.HTTP_400_BAD_REQUEST
)

result = OntologyTag.get_group_data(ontology_id, default=None)
if not isinstance(result, dict):
return Response(
data={
'message': f'Ontology of id {ontology_id} does not exist'
},
content_type='json',
status=status.HTTP_404_NOT_FOUND
)

return Response(
data=result,
status=status.HTTP_200_OK
)

@api_view(['GET'])
@permission_classes([IsAuthenticatedOrReadOnly])
def get_ontology_node(request, node_id):
"""
Get the element details of the specified ontology element by its
node_id including associated data
e.g. tree-related information
"""
node_id = gen_utils.parse_int(node_id, default=None)
if not isinstance(node_id, int):
return Response(
data={
'message': 'Invalid node id, expected valid integer'
},
content_type='json',
status=status.HTTP_400_BAD_REQUEST
)

result = OntologyTag.get_node_data(node_id, default=None)
return Response(
data=result,
status=status.HTTP_200_OK
)
11 changes: 6 additions & 5 deletions CodeListLibrary_project/clinicalcode/entity_utils/api_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,14 @@ def get_entity_detail_from_layout(
validation = template_utils.get_field_item(
constants.metadata, field, 'validation', {}
)
is_source = validation.get('source')

is_source = validation.get('source')
if is_source:
value = template_utils.get_metadata_value_from_source(
entity, field, default=None
)
if value is None:
if template_utils.is_metadata(entity, field=field):
value = template_utils.get_metadata_value_from_source(
entity, field, default=None
)
else:
value = template_utils.get_entity_field(entity, field)

result[field] = value
Expand Down
27 changes: 14 additions & 13 deletions CodeListLibrary_project/clinicalcode/entity_utils/concept_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

from django.db import connection
from django.db.models import ForeignKey
from django.http.request import HttpRequest
Expand Down Expand Up @@ -745,8 +746,8 @@ def get_clinical_concept_data(concept_id, concept_history_id, include_reviewed_c
aggregate_component_codes=False, include_component_codes=True,
include_attributes=False, strippable_fields=None,
remove_userdata=False, hide_user_details=False,
derive_access_from=None, format_for_api=False,
include_source_data=False):
derive_access_from=None, requested_entity_id=None,
format_for_api=False, include_source_data=False):
"""
[!] Note: This method ignores permissions to derive data - it should only be called from a
a method that has previously considered accessibility
Expand Down Expand Up @@ -878,21 +879,21 @@ def get_clinical_concept_data(concept_id, concept_history_id, include_reviewed_c
concept_data['code_attribute_header'] = attribute_headers

# Set phenotype owner
phenotype_owner = concept.phenotype_owner
phenotype_owner = concept.phenotype_owner
if phenotype_owner:
concept_data['phenotype_owner'] = phenotype_owner.id
entity_from_concept = GenericEntity.history.filter(
id=phenotype_owner.id
)
template_data = entity_from_concept.values_list('template_data',flat=True)

#Iterate through the concept_information to find the phenotype owner history
for index, value in enumerate(template_data):
history_ids_concept = [j['concept_version_id'] for j in value['concept_information']]
if concept_history_id in history_ids_concept:
concept_data['phenotype_owner_history_id'] = entity_from_concept.values_list('history_id',flat=True)[index]

latest_version_id = permission_utils.get_latest_owner_version_from_concept(
phenotype_id=phenotype_owner.id,
concept_id=historical_concept.id,
concept_version_id=historical_concept.history_id
)

if latest_version_id is not None:
concept_data['phenotype_owner_history_id'] = latest_version_id

# Set the requested entity id
concept_data['requested_entity_id'] = requested_entity_id

# Set base
if not format_for_api:
Expand Down
33 changes: 32 additions & 1 deletion CodeListLibrary_project/clinicalcode/entity_utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,26 @@ class FORM_METHODS(int, enum.Enum, metaclass=IterableMeta):
CREATE = 1
UPDATE = 2

class ONTOLOGY_TYPES(int, enum.Enum, metaclass=IterableMeta):
"""
Defines the ontology internal type id,
which describes the ontology type
"""
CLINICAL_DISEASE = 0
CLINICAL_DOMAIN = 1
CLINICAL_FUNCTIONAL_ANATOMY = 2

"""
Used to define the labels for each
known ontology type
"""
ONTOLOGY_LABELS = {
ONTOLOGY_TYPES.CLINICAL_DOMAIN: 'Clinical Domain',
ONTOLOGY_TYPES.CLINICAL_DISEASE: 'Clinical Disease Category (ICD-10)',
ONTOLOGY_TYPES.CLINICAL_FUNCTIONAL_ANATOMY: 'Functional Anatomy',
}

"""
The excepted X-Requested-With header if a fetch request is made
Expand Down Expand Up @@ -476,7 +496,7 @@ class FORM_METHODS(int, enum.Enum, metaclass=IterableMeta):
"citation_requirements": {
"title": "Citation Requirements",
"description": "A request for how this phenotype is referenced if used in other work.",
"field_type": "textarea_markdown",
"field_type": "citation_requirements",
"active": True,
"validation": {
"type": "string",
Expand Down Expand Up @@ -699,6 +719,12 @@ class FORM_METHODS(int, enum.Enum, metaclass=IterableMeta):
'output_type': 'list_of_inputboxes'
},

'citation_requirements': {
'data_type': 'string',
'input_type': 'markdown',
'output_type': 'citation_requirements'
},

'enum': {
'data_type': 'int',
'input_type': 'dropdown-list',
Expand All @@ -712,6 +738,11 @@ class FORM_METHODS(int, enum.Enum, metaclass=IterableMeta):
'apply_badge_style': True
},

'ontology': {
'input_type': 'generic/ontology',
'output_type': 'generic/ontology'
},

'enum_radio_badge': {
'data_type': 'int',
'input_type': 'radiobutton',
Expand Down
Loading

0 comments on commit d38c1c5

Please sign in to comment.