Skip to content
Merged
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
11 changes: 6 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
FROM python:3.9
FROM python:3.9.20

RUN apt-get update && apt-get install -y gcc build-essential && rm -rf /var/lib/apt/lists/*

ENV PYTHONUNBUFFERED 1


RUN curl -sSL https://install.python-poetry.org | python3 - --version 1.8.3
# Poetry location so future commands (below) work

ENV PATH $PATH:/root/.local/bin
# Want poetry to use system python of docker container
RUN poetry config virtualenvs.create false
RUN poetry config virtualenvs.in-project false

COPY pyproject.toml ./
COPY pyproject.toml poetry.lock ./

# Install dependencies
RUN poetry install

RUN poetry lock
RUN poetry install

WORKDIR /app
3,662 changes: 3,662 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ package-mode = false

[tool.poetry.dependencies]
python = "3.9.20"
django = "2.2.17"
django = "2.2.28"
django-oauth-toolkit = "1.0.0"
django-cors-middleware = "1.5.0"
social-auth-core = "2.0.0"
Expand All @@ -18,9 +18,9 @@ django-extensions = "2.2.6"
channels = "2.4"
channels-redis = "3.2.0"
django-extra-fields = "0.9"
pillow = "8.0.1"
pillow = "10.3.0"
celery = "4.2.1"
gunicorn = "20.0.4"
gunicorn = "22.0.0"
urllib3 = ">=1.21.1,<1.25"
uvicorn = {version = "0.13.3", extras = ["standard"]}
pyyaml = "5.3.1"
Expand Down Expand Up @@ -66,7 +66,9 @@ pytest = "6.2.1"
pytest-django = "4.1.0"
pytest-pythonpath = "0.7.3"
selenium = "3.141.0"
jinja2 = "3.1.4"
requests = "2.32.2"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
build-backend = "poetry.core.masonry.api"
3 changes: 2 additions & 1 deletion src/apps/api/serializers/leaderboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from drf_writable_nested import WritableNestedModelSerializer
from rest_framework import serializers

from api.serializers.submissions import SubmissionLeaderBoardSerializer
from api.serializers.submission_leaderboard import SubmissionLeaderBoardSerializer

from competitions.models import Submission, Phase
from leaderboards.models import Leaderboard, Column

Expand Down
31 changes: 31 additions & 0 deletions src/apps/api/serializers/submission_leaderboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# api/serializers/submission_leaderboard.py
from rest_framework import serializers
from competitions.models import Submission
from leaderboards.models import SubmissionScore
from api.serializers.profiles import SimpleOrganizationSerializer


class SubmissionScoreSerializer(serializers.ModelSerializer):
index = serializers.IntegerField(source='column.index', read_only=True)
column_key = serializers.CharField(source='column.key', read_only=True)

class Meta:
model = SubmissionScore
fields = ('id', 'index', 'score', 'column_key')


class SubmissionLeaderBoardSerializer(serializers.ModelSerializer):
scores = SubmissionScoreSerializer(many=True)
owner = serializers.CharField(source='owner.username')
display_name = serializers.CharField(source='owner.display_name')
slug_url = serializers.CharField(source='owner.slug_url')
organization = SimpleOrganizationSerializer(allow_null=True)
created_when = serializers.DateTimeField(format="%Y-%m-%d %H:%M")

class Meta:
model = Submission
fields = (
'id', 'parent', 'owner', 'leaderboard_id', 'fact_sheet_answers',
'task', 'scores', 'display_name', 'slug_url', 'organization',
'detailed_result', 'created_when'
)
48 changes: 2 additions & 46 deletions src/apps/api/serializers/submissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,17 @@

from api.mixins import DefaultUserCreateMixin
from api.serializers import leaderboards
from api.serializers.profiles import SimpleOrganizationSerializer
# from api.serializers.profiles import SimpleOrganizationSerializer
from api.serializers.tasks import TaskSerializer
from api.serializers.submission_leaderboard import SubmissionScoreSerializer
from competitions.models import Submission, SubmissionDetails, CompetitionParticipant, Phase
from datasets.models import Data
from leaderboards.models import SubmissionScore
from utils.data import make_url_sassy

from tasks.models import Task
from queues.models import Queue


class SubmissionScoreSerializer(serializers.ModelSerializer):
index = serializers.IntegerField(source='column.index', read_only=True)
column_key = serializers.CharField(source='column.key', read_only=True)

class Meta:
model = SubmissionScore
fields = (
'id',
'index',
'score',
'column_key',
)


class SubmissionSerializer(serializers.ModelSerializer):
scores = SubmissionScoreSerializer(many=True)
filename = serializers.SerializerMethodField(read_only=True)
Expand Down Expand Up @@ -92,36 +78,6 @@ def get_can_make_submissions_public(self, instance):
return instance.phase.competition.can_participants_make_submissions_public


class SubmissionLeaderBoardSerializer(serializers.ModelSerializer):
scores = SubmissionScoreSerializer(many=True)
owner = serializers.CharField(source='owner.username')
display_name = serializers.CharField(source='owner.display_name')
slug_url = serializers.CharField(source='owner.slug_url')
organization = SimpleOrganizationSerializer(allow_null=True)
created_when = serializers.DateTimeField(format="%Y-%m-%d %H:%M")

class Meta:
model = Submission
fields = (
'id',
'parent',
'owner',
'leaderboard_id',
'fact_sheet_answers',
'task',
'scores',
'display_name',
'slug_url',
'organization',
'detailed_result',
'created_when'
)
extra_kwargs = {
"scores": {"read_only": True},
"owner": {"read_only": True},
}


class SubmissionCreationSerializer(DefaultUserCreateMixin, serializers.ModelSerializer):
"""Used for creation _and_ status updates..."""
data = serializers.SlugRelatedField(queryset=Data.objects.all(), required=False, allow_null=True, slug_field='key')
Expand Down
8 changes: 6 additions & 2 deletions src/apps/api/views/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,12 @@ def competitions_usage(request):
'datefield'
)
for su in query.order_by("-datefield", "competition__id"):
username = su['competition__created_by__username'] or ("user #" + su['competition__created_by__id']) or "unknown user"
email = su['competition__created_by__email'] or "no email"
competitions_usage.setdefault(su['datefield'].isoformat(), {})[su['competition__id']] = {
'snapshot_id': su['id'],
'title': su['competition__title'],
'organizer': su['competition__created_by__username'] + " (" + su['competition__created_by__email'] + ")",
'organizer': username + " (" + email + ")",
'created_when': su['competition__created_when'],
'datasets': su['datasets_total'],
}
Expand Down Expand Up @@ -275,9 +277,11 @@ def users_usage(request):
'datefield'
)
for su in query.order_by("-datefield", "user__id"):
username = su['user__username'] or ("user #" + su['user__id']) or "unknown user"
email = su['user__email'] or "no email"
users_usage.setdefault(su['datefield'].isoformat(), {})[su['user__id']] = {
'snapshot_id': su['id'],
'name': su['user__username'] + " (" + su['user__email'] + ")",
'name': username + " (" + email + ")",
'date_joined': su['user__date_joined'],
'datasets': su['datasets_total'],
'submissions': su['submissions_total'],
Expand Down
24 changes: 18 additions & 6 deletions src/utils/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,26 @@ def __init__(self, *args, **kwargs):
StorageClass = get_storage_class(settings.DEFAULT_FILE_STORAGE)

if settings.STORAGE_IS_S3:
BundleStorage = StorageClass(bucket=settings.AWS_STORAGE_PRIVATE_BUCKET_NAME)
PublicStorage = StorageClass(bucket=settings.AWS_STORAGE_BUCKET_NAME)
# Create separate instances for Bundle and Public storage
BundleStorage = StorageClass()
BundleStorage.bucket_name = settings.AWS_STORAGE_PRIVATE_BUCKET_NAME # Set the private bucket
PublicStorage = StorageClass()
PublicStorage.bucket_name = settings.AWS_STORAGE_BUCKET_NAME # Set the public bucket

elif settings.STORAGE_IS_GCS:
BundleStorage = StorageClass(bucket_name=settings.GS_PRIVATE_BUCKET_NAME)
PublicStorage = StorageClass(bucket_name=settings.GS_PUBLIC_BUCKET_NAME)
# For GCS
BundleStorage = StorageClass()
BundleStorage.bucket_name = settings.GS_PRIVATE_BUCKET_NAME # Set the private bucket
PublicStorage = StorageClass()
PublicStorage.bucket_name = settings.GS_PUBLIC_BUCKET_NAME # Set the public bucket

elif settings.STORAGE_IS_AZURE:
BundleStorage = StorageClass(azure_container=settings.BUNDLE_AZURE_CONTAINER)
PublicStorage = StorageClass(azure_container=settings.AZURE_CONTAINER)
# For Azure
BundleStorage = StorageClass()
BundleStorage.azure_container = settings.BUNDLE_AZURE_CONTAINER # Set the private container
PublicStorage = StorageClass()
PublicStorage.azure_container = settings.AZURE_CONTAINER # Set the public container

else:
raise NotImplementedError()

Expand Down