Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/launch_api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ DJANGO_SUPERUSER_PASSWORD="${DJANGO_ADMIN_PASSWORD}" \
echo "* Collecting static files"
./manage.py collectstatic --noinput

# generate OpenAPI schema
echo "* Generating OpenAPI schema"
./manage.py spectacular --file /data/schema.yaml

# launch the server
if [ "$DJANGO_DEBUG" = "1" ] ; then
echo "* Serving via django runserver (debug mode)"
Expand Down
3 changes: 3 additions & 0 deletions backend/src/api/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
class ApiConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "api"

def ready(self):
import api.schema # noqa
2 changes: 2 additions & 0 deletions backend/src/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ class SearchTerm(models.Model):
)
confidence = models.FloatField()
related_words = models.TextField(null=True, blank=True)
log2_prob_prior = models.FloatField(null=True, blank=True)
prob = models.FloatField(null=True, blank=True)

class Meta:
indexes = [
Expand Down
19 changes: 19 additions & 0 deletions backend/src/api/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
Contains OpenAPI schema definitions in cases where they can't be
simply inferred from the models/serializers/views.
"""

from drf_spectacular.extensions import OpenApiAuthenticationExtension
from api.utils.auth import CsrfExemptSessionAuthentication


class CsrfExemptSessionAuthenticationScheme(OpenApiAuthenticationExtension):
target_class = CsrfExemptSessionAuthentication
name = "csrfExemptCookieAuth"

def get_security_definition(self, auto_schema):
return {
"type": "apiKey",
"in": "cookie",
"name": "sessionid",
}
18 changes: 10 additions & 8 deletions backend/src/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class SearchTermSerializer(serializers.ModelSerializer):

class Meta:
model = SearchTerm
fields = ["id", "term", "series_id", "prob", "log2_prob_prior", "related_words"]
fields = [
"id", "term", "series_id", "prob", "log2_prob_prior", "related_words"
]


# ===========================================================================
Expand Down Expand Up @@ -133,13 +135,13 @@ class GEOSeriesSerializer(serializers.ModelSerializer):

sample_count = serializers.SerializerMethodField(read_only=True)

def get_sample_count(self, obj):
def get_sample_count(self, obj) -> int:
"""Get the number of samples associated with this series."""
return obj.samples_ct if obj.samples_ct is not None else 0

confidence = serializers.SerializerMethodField()

def get_confidence(self, obj):
def get_confidence(self, obj) -> dict:
"""Compute confidence level based on prob."""
if obj.prob is None:
label = "unknown"
Expand All @@ -164,22 +166,22 @@ def get_confidence(self, obj):

platform = serializers.SerializerMethodField()

def get_platform(self, obj):
"""Get the platform name associated with this series."""
def get_platform(self, obj) -> list[str]:
"""Get the platform names associated with this series."""
gse_obj = GEOSeriesToGEOPlatforms.objects.filter(gse=obj.gse).first()
return str(gse_obj.platforms) if gse_obj else ""
return gse_obj.platforms if gse_obj else []

keywords = serializers.SerializerMethodField()

def get_keywords(self, obj):
def get_keywords(self, obj) -> list[str]:
"""Extract keywords from the series summary."""
if obj.keywords:
return [kw.strip() for kw in obj.keywords.split(",")]
return []

classification = serializers.SerializerMethodField()

def get_classification(self, obj):
def get_classification(self, obj) -> str:
"""Returns values Positive or Negative; supposed to represent 'Classification of study in model training'?"""
# FIXME: figure out how to actually determine this
return "Positive"
Expand Down
25 changes: 24 additions & 1 deletion backend/src/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

from drf_spectacular.utils import extend_schema, OpenApiParameter
from drf_spectacular.types import OpenApiTypes


from .models import (
Cart,
CartItem,
Expand Down Expand Up @@ -468,7 +472,26 @@ class SearchTermViewSet(viewsets.ReadOnlyModelViewSet):
# === Ontology search terms from meta-hq
# ===========================================================================


@extend_schema(
parameters=[
OpenApiParameter(
name="query",
type=OpenApiTypes.STR,
location=OpenApiParameter.QUERY,
required=True,
description="Search query string",
),
OpenApiParameter(
name="max_results",
type=OpenApiTypes.INT,
location=OpenApiParameter.QUERY,
required=False,
description="Maximum number of results to return",
default=50,
),
],
responses={200: OntologySearchResultsSerializer(many=True)},
)
@api_view(["GET"])
@permission_classes([AllowAny])
def ontology_search(request):
Expand Down
1 change: 1 addition & 0 deletions backend/src/meta2onto/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,5 @@ def is_truthy(value):
"rest_framework.filters.SearchFilter",
"rest_framework.filters.OrderingFilter",
],
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
Loading