Skip to content
Open
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
6 changes: 4 additions & 2 deletions apps/analytics/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
name="get_submission_count",
),
re_path(
r"^challenge/(?P<challenge_pk>[0-9]+)/challenge_phase/(?P<challenge_phase_pk>[0-9]+)/analytics$",
r"^challenge/(?P<challenge_pk>[0-9]+)/challenge_phase/"
r"(?P<challenge_phase_pk>[0-9]+)/analytics$",
views.get_challenge_phase_submission_analysis,
name="get_challenge_phase_submission_analysis",
),
re_path(
r"^challenge/(?P<challenge_pk>[0-9]+)/challenge_phase/(?P<challenge_phase_pk>[0-9]+)/count$",
r"^challenge/(?P<challenge_pk>[0-9]+)/challenge_phase/"
r"(?P<version>(v1|v2))/(?P<challenge_phase_pk_or_slug>[-a-zA-Z0-9_]+)/count$",
views.get_challenge_phase_submission_count_by_team,
name="get_challenge_phase_submission_count_by_team",
),
Expand Down
14 changes: 12 additions & 2 deletions apps/analytics/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from datetime import timedelta

from accounts.permissions import HasVerifiedEmail
from challenges.models import ChallengePhase
from challenges.permissions import IsChallengeCreator
from challenges.utils import get_challenge_model, get_challenge_phase_model
from django.http import HttpResponse
Expand Down Expand Up @@ -140,14 +141,23 @@ def get_submission_count(request, challenge_pk, duration):
)
@authentication_classes((JWTAuthentication, ExpiringTokenAuthentication))
def get_challenge_phase_submission_count_by_team(
request, challenge_pk, challenge_phase_pk
request, challenge_pk, challenge_phase_pk_or_slug, version
):
"""
Returns number of submissions done by a participant team in a challenge phase
"""
challenge = get_challenge_model(challenge_pk)

challenge_phase = get_challenge_phase_model(challenge_phase_pk)
if version == "v2":
try:
challenge_phase = ChallengePhase.objects.get(
slug=challenge_phase_pk_or_slug, challenge=challenge
)
except ChallengePhase.DoesNotExist:
response_data = {"error": "Challenge Phase does not exist"}
return Response(response_data, status=status.HTTP_400_BAD_REQUEST)
else:
challenge_phase = get_challenge_phase_model(challenge_phase_pk_or_slug)

participant_team = get_participant_team_id_of_user_for_a_challenge(
request.user, challenge.pk
Expand Down
15 changes: 10 additions & 5 deletions apps/challenges/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@


class ChallengeSerializer(serializers.ModelSerializer):

is_active = serializers.ReadOnlyField()
domain_name = serializers.SerializerMethodField()

Expand Down Expand Up @@ -100,7 +99,6 @@ class Meta:


class ChallengePhaseSerializer(serializers.ModelSerializer):

is_active = serializers.ReadOnlyField()

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -177,6 +175,8 @@ class ChallengePhaseSplitSerializer(serializers.ModelSerializer):
dataset_split_name = serializers.SerializerMethodField()
challenge_phase_name = serializers.SerializerMethodField()
leaderboard_schema = serializers.SerializerMethodField()
challenge_phase_slug = serializers.SerializerMethodField()
dataset_split_codename = serializers.SerializerMethodField()

class Meta:
model = ChallengePhaseSplit
Expand All @@ -186,6 +186,8 @@ class Meta:
"challenge_phase",
"challenge_phase_name",
"dataset_split_name",
"challenge_phase_slug",
"dataset_split_codename",
"visibility",
"show_leaderboard_by_latest_submission",
"show_execution_time",
Expand All @@ -202,6 +204,12 @@ def get_dataset_split_name(self, obj):
def get_challenge_phase_name(self, obj):
return obj.challenge_phase.name

def get_challenge_phase_slug(self, obj):
return obj.challenge_phase.slug

def get_dataset_split_codename(self, obj):
return obj.dataset_split.codename


class ChallengeConfigSerializer(serializers.ModelSerializer):
"""
Expand Down Expand Up @@ -354,7 +362,6 @@ class Meta:


class ChallengePhaseCreateSerializer(serializers.ModelSerializer):

is_active = serializers.ReadOnlyField()

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -412,7 +419,6 @@ class Meta:


class StarChallengeSerializer(serializers.ModelSerializer):

count = serializers.SerializerMethodField()

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -502,7 +508,6 @@ class Meta:


class PWCChallengeLeaderboardSerializer(serializers.ModelSerializer):

challenge_id = serializers.SerializerMethodField()
leaderboard = serializers.SerializerMethodField()
leaderboard_decimal_precision = serializers.SerializerMethodField()
Expand Down
8 changes: 5 additions & 3 deletions apps/challenges/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
),
# `A-Za-z` because it accepts either of `all, future, past or present` in either case
url(
r"^challenge/(?P<challenge_time>[A-Za-z]+)/(?P<challenge_approved>[A-Za-z]+)/(?P<challenge_published>[A-Za-z]+)$",
r"^challenge/(?P<challenge_time>[A-Za-z]+)/(?P<challenge_approved>[A-Za-z]+)/"
r"(?P<challenge_published>[A-Za-z]+)$",
views.get_all_challenges,
name="get_all_challenges",
),
Expand Down Expand Up @@ -90,12 +91,13 @@
name="create_challenge_using_zip_file",
),
url(
r"^(?P<challenge_pk>[0-9]+)/challenge_phase/(?P<challenge_phase_pk>[0-9]+)/submissions$",
r"^(?P<challenge_pk>[0-9]+)/challenge_phase/(?P<version>(v1|v2))"
r"/(?P<challenge_phase_pk_or_slug>[-a-zA-Z0-9_]+)/submissions$",
views.get_all_submissions_of_challenge,
name="get_all_submissions_of_challenge",
),
url(
r"^(?P<challenge_pk>[0-9]+)/phase/(?P<challenge_phase_pk>[0-9]+)"
r"^(?P<challenge_pk>[0-9]+)/phase/(?P<version>(v1|v2))/(?P<challenge_phase_pk_or_slug>[-a-zA-Z0-9_]+)"
r"/download_all_submissions/(?P<file_type>[A-Za-z]+)/$",
views.download_all_submissions,
name="download_all_submissions",
Expand Down
102 changes: 63 additions & 39 deletions apps/challenges/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,6 @@ def get_participant_teams_for_challenge(request, challenge_pk):
def add_participant_team_to_challenge(
request, challenge_pk, participant_team_pk
):

try:
challenge = Challenge.objects.get(pk=challenge_pk)
except Challenge.DoesNotExist:
Expand Down Expand Up @@ -1423,9 +1422,8 @@ def create_challenge_using_zip_file(request, challenge_host_team_pk):
):
options = attribute.get("options")
if not options or not len(options):
message = "Please include at least one option in attribute for challenge_phase {}".format(
data["id"]
)
message = "Please include at least one option in attribute"
"for challenge_phase {}".format(data["id"])
response_data = {"error": message}
return Response(
response_data,
Expand Down Expand Up @@ -1464,7 +1462,10 @@ def create_challenge_using_zip_file(request, challenge_host_team_pk):
)
else:
missing_keys_string = ", ".join(missing_keys)
message = "Please enter the following to the default submission meta attribute in phase {}: {}.".format(
message = (
"Please enter the following to the default submission"
)
" meta attribute in phase {}: {}.".format(
data["id"], missing_keys_string
)
response_data = {"error": message}
Expand Down Expand Up @@ -2088,7 +2089,7 @@ def create_challenge_using_zip_file(request, challenge_host_team_pk):
@permission_classes((permissions.IsAuthenticated, HasVerifiedEmail))
@authentication_classes((JWTAuthentication, ExpiringTokenAuthentication))
def get_all_submissions_of_challenge(
request, challenge_pk, challenge_phase_pk
request, challenge_pk, challenge_phase_pk_or_slug, version
):
"""
Returns all the submissions for a particular challenge
Expand All @@ -2098,24 +2099,26 @@ def get_all_submissions_of_challenge(

# To check for the corresponding challenge phase from the
# challenge_phase_pk and challenge.
try:
challenge_phase = ChallengePhase.objects.get(
pk=challenge_phase_pk, challenge=challenge
)
except ChallengePhase.DoesNotExist:
response_data = {
"error": "Challenge Phase {} does not exist".format(
challenge_phase_pk
if version == "v2":
try:
challenge_phase = ChallengePhase.objects.get(
slug=challenge_phase_pk_or_slug, challenge=challenge
)
}
return Response(response_data, status=status.HTTP_404_NOT_FOUND)
except ChallengePhase.DoesNotExist:
response_data = {
"error": "Challenge Phase {} does not exist".format(
challenge_phase_pk_or_slug
)
}
return Response(response_data, status=status.HTTP_404_NOT_FOUND)
else:
challenge_phase = get_challenge_phase_model(challenge_phase_pk_or_slug)

# To check for the user as a host of the challenge from the request and
# challenge_pk.
if is_user_a_host_of_challenge(
user=request.user, challenge_pk=challenge_pk
):

# Filter submissions on the basis of challenge for host for now. Later on, the support for query
# parameters like challenge phase, date is to be added.
submissions = Submission.objects.filter(
Expand All @@ -2138,7 +2141,6 @@ def get_all_submissions_of_challenge(
elif has_user_participated_in_challenge(
user=request.user, challenge_id=challenge_pk
):

# get participant team object for the user for a particular challenge.
participant_team_pk = get_participant_team_id_of_user_for_a_challenge(
request.user, challenge_pk
Expand Down Expand Up @@ -2245,7 +2247,7 @@ def get_all_submissions_of_challenge(
@permission_classes((permissions.IsAuthenticated, HasVerifiedEmail))
@authentication_classes((JWTAuthentication, ExpiringTokenAuthentication))
def download_all_submissions(
request, challenge_pk, challenge_phase_pk, file_type
request, challenge_pk, challenge_phase_pk_or_slug, file_type, version
):
"""
API endpoint to download all the submissions for a particular challenge as a csv
Expand All @@ -2264,18 +2266,20 @@ def download_all_submissions(

# To check for the corresponding challenge phase from the
# challenge_phase_pk and challenge.
try:
challenge_phase = ChallengePhase.objects.get(
pk=challenge_phase_pk, challenge=challenge
)
except ChallengePhase.DoesNotExist:
response_data = {
"error": "Challenge Phase {} does not exist".format(
challenge_phase_pk
if version == "v2":
try:
challenge_phase = ChallengePhase.objects.get(
slug=challenge_phase_pk_or_slug, challenge=challenge
)
}
return Response(response_data, status=status.HTTP_404_NOT_FOUND)

except ChallengePhase.DoesNotExist:
response_data = {
"error": "Challenge Phase {} does not exist".format(
challenge_phase_pk_or_slug
)
}
return Response(response_data, status=status.HTTP_404_NOT_FOUND)
else:
challenge_phase = get_challenge_phase_model(challenge_phase_pk_or_slug)
if request.method == "GET":
if file_type == "csv":
if is_user_a_host_of_challenge(
Expand Down Expand Up @@ -2370,7 +2374,6 @@ def download_all_submissions(
elif has_user_participated_in_challenge(
user=request.user, challenge_id=challenge_pk
):

# get participant team object for the user for a particular
# challenge.
participant_team_pk = (
Expand Down Expand Up @@ -2924,7 +2927,6 @@ def get_aws_credentials_for_participant_team(request, phase_pk):
@permission_classes((permissions.IsAuthenticated, HasVerifiedEmail))
@authentication_classes((JWTAuthentication, ExpiringTokenAuthentication))
def invite_users_to_challenge(request, challenge_pk):

challenge = get_challenge_model(challenge_pk)

if not challenge.is_active or not challenge.approved_by_admin:
Expand Down Expand Up @@ -4173,7 +4175,12 @@ def create_or_update_github_challenge(request, challenge_host_team_pk):
if serializer.is_valid():
serializer.save()
else:
error_messages = f"challenge phase split (phase:{data['challenge_phase_id']}, leaderboard:{data['leaderboard_id']}, dataset split: {data['dataset_split_id']}):{str(serializer.errors)}"
error_messages = (
f"challenge phase split"
f" (phase:{data['challenge_phase_id']},"
f" leaderboard:{data['leaderboard_id']},"
f" dataset split: {data['dataset_split_id']}):{str(serializer.errors)}"
)
raise RuntimeError()

zip_config = ChallengeConfiguration.objects.get(
Expand Down Expand Up @@ -4363,7 +4370,6 @@ def create_or_update_github_challenge(request, challenge_host_team_pk):
challenge_phases_data,
files["challenge_test_annotation_files"],
):

# Override the submission_meta_attributes when they are
# missing
submission_meta_attributes = data.get(
Expand Down Expand Up @@ -4552,7 +4558,12 @@ def create_or_update_github_challenge(request, challenge_host_team_pk):
if serializer.is_valid():
serializer.save()
else:
error_messages = f"challenge phase split update (phase:{data['challenge_phase_id']}, leaderboard:{data['leaderboard_id']}, dataset split: {data['dataset_split_id']}):{str(serializer.errors)}"
error_messages = (
f"challenge phase split update"
f"(phase:{data['challenge_phase_id']},"
f"leaderboard:{data['leaderboard_id']},"
f"dataset split: {data['dataset_split_id']}):{str(serializer.errors)}"
)
raise RuntimeError()

response_data = {
Expand Down Expand Up @@ -4607,7 +4618,11 @@ def pwc_task_dataset(request):
return Response(response_data, status=status.HTTP_200_OK)
else:
response_data = {
"error": "You are not authorized to make this request. Please ask EvalAI admin to add you as a staff user for accessing this API."
"error": (
"You are not authorized "
"to make this request. Please ask EvalAI admin to "
"add you as a staff user for accessing this API."
)
}
return Response(response_data, status=status.HTTP_406_NOT_ACCEPTABLE)

Expand Down Expand Up @@ -4833,7 +4848,10 @@ def request_challenge_approval_by_pk(request, challenge_pk):
unfinished_phases.append(challenge_phase.name)

if unfinished_phases:
error_message = f"The following challenge phases do not have finished submissions: {', '.join(unfinished_phases)}"
error_message = (
"The following challenge phases do not have finished submissions: "
f"{', '.join(unfinished_phases)}"
)
return Response(
{"error": error_message}, status=status.HTTP_406_NOT_ACCEPTABLE
)
Expand Down Expand Up @@ -4899,13 +4917,19 @@ def request_challenge_approval_by_pk(request, challenge_pk):
}
return Response(response_data, status=status.HTTP_200_OK)
else:
error_message = f"Sorry, there was an error sending approval request: {str(webhook_response.content.decode('utf-8'))}. Please try again."
error_message = (
f"Sorry, there was an error sending approval request:"
f" {str(webhook_response.content.decode('utf-8'))}. Please try again."
)
return Response(
{"error": error_message},
status=status.HTTP_406_NOT_ACCEPTABLE,
)
else:
error_message = "Sorry, there was an error sending approval request: No response received. Please try again."
error_message = (
"Sorry, there was an error sending approval request:"
" No response received. Please try again."
)
return Response(
{"error": error_message}, status=status.HTTP_406_NOT_ACCEPTABLE
)
Expand Down
Loading