Skip to content

Commit

Permalink
Merge branch 'main' into 1867-delete_video_api
Browse files Browse the repository at this point in the history
  • Loading branch information
GresilleSiffle committed May 6, 2024
2 parents b825e0f + ce94b0b commit e00991b
Show file tree
Hide file tree
Showing 32 changed files with 678 additions and 137 deletions.
5 changes: 5 additions & 0 deletions backend/dev-env/settings-tournesol.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# This configuration file is intended for development environment only
# (see instructions in /dev-env/README.md).
# Find more information regarding the configuration and a detailed example
# in /backend/documentation/settings-tournesol.yaml

DEBUG: True
SECRET_KEY: g&*0o49mk(t&*vvdsfsdgfsdgsgesqdg5n*e7ars&$qz*lpi^s$k*
ALLOWED_HOSTS:
Expand Down
17 changes: 14 additions & 3 deletions backend/documentation/settings-tournesol.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# This file is an example settings file for Tournesol backend.
# It should NOT be deployed as is.
# Follow the instructions below to adapt the configuration
# and generate secret values.

# to be set to False in production
DEBUG: True
# to be changed in production

# TO BE CHANGED IN PRODUCTION
# Can be generated (for example) with the command below:
# `openssl rand -base64 48`
SECRET_KEY: g&*0o49mk(t&*vvdsfsdgfsdgsgesqdg5n*e7ars&$qz*lpi^s$k*

# to be set to the actual hosts on which the API in served in production
ALLOWED_HOSTS:
- localhost
Expand Down Expand Up @@ -35,8 +44,10 @@ LOGIN_URL: /admin/login
OIDC_ENABLED: true
# to be set to the actual IDP URI in production
OIDC_ISS_ENDPOINT: http://localhost:8000/o
# test key generated with the command below (change it in production)
# openssl genrsa 4096

# TO BE CHANGED IN PRODUCTION
# The key can be generated with the command below:
# `openssl genrsa 4096`
OIDC_RSA_PRIVATE_KEY: |
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEAx0m1CHyJjkjCQW3f9pRDXHDWkmJtEGTPLqoxug8TRi6baRKs
Expand Down
6 changes: 5 additions & 1 deletion backend/ml/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def get_comparisons(self, criteria=None, user_id=None) -> pd.DataFrame:

values = scores_queryset.values(
"score",
"score_max",
"criteria",
"weight",
entity_a=F("comparison__entity_1_id"),
Expand All @@ -78,7 +79,9 @@ def get_comparisons(self, criteria=None, user_id=None) -> pd.DataFrame:
)
if len(values) > 0:
dtf = pd.DataFrame(values)
return dtf[["user_id", "entity_a", "entity_b", "criteria", "score", "weight"]]
return dtf[
["user_id", "entity_a", "entity_b", "criteria", "score", "score_max", "weight"]
]

return pd.DataFrame(
columns=[
Expand All @@ -87,6 +90,7 @@ def get_comparisons(self, criteria=None, user_id=None) -> pd.DataFrame:
"entity_b",
"criteria",
"score",
"score_max",
"weight",
]
)
Expand Down
3 changes: 1 addition & 2 deletions backend/ml/mehestan/parameters.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from solidago.pipeline.legacy2023.parameters import PipelineParameters

from tournesol.utils.constants import COMPARISON_MAX, MEHESTAN_MAX_SCALED_SCORE
from tournesol.utils.constants import MEHESTAN_MAX_SCALED_SCORE


class MehestanParameters(PipelineParameters):
r_max = COMPARISON_MAX
max_squashed_score = MEHESTAN_MAX_SCALED_SCORE
26 changes: 10 additions & 16 deletions backend/settings/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@
with open(SETTINGS_FILE, "r") as f:
server_settings = yaml.full_load(f)
except FileNotFoundError:
print("No local settings.")
pass
print("WARNING: no local settings.")

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/

# For guidelines related to settings in production
# see https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING
# Do not commit any secret used in staging or production.
SECRET_KEY = server_settings.get(
"SECRET_KEY", "django-insecure-(=8(97oj$3)!#j!+^&bh_+5v5&1pfpzmaos#z80c!ia5@9#jz1"
)
if "SECRET_KEY" in server_settings:
SECRET_KEY = server_settings["SECRET_KEY"]
else:
print("WARNING: using default secret key, as none was found in local settings.")
# The default key generated by Django is only be used for testing purposes.
SECRET_KEY = "django-insecure-(=8(97oj$3)!#j!+^&bh_+5v5&1pfpzmaos#z80c!ia5@9#jz1" # nosec B105

# SECURITY WARNING
# Don't set DEBUG to True in staging or production.
Expand Down Expand Up @@ -209,13 +212,6 @@
},
}

DRF_RECAPTCHA_PUBLIC_KEY = server_settings.get(
"DRF_RECAPTCHA_PUBLIC_KEY", "dsfsdfdsfsdfsdfsdf"
)
DRF_RECAPTCHA_SECRET_KEY = server_settings.get(
"DRF_RECAPTCHA_SECRET_KEY", "dsfsdfdsfsdf"
)


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
Expand Down Expand Up @@ -327,8 +323,6 @@
'entertaining_relaxing',
]

# maximal weight to assign to a rating for a particular feature, see #41
MAX_FEATURE_WEIGHT = 8

SPECTACULAR_SETTINGS = {
# Split data components into 2 distinct schemas for request and response.
Expand Down
12 changes: 11 additions & 1 deletion backend/tournesol/lib/public_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def get_comparisons_data(poll_name: str, until_: datetime) -> QuerySet:
comparisoncriteriascore.criteria,
comparisoncriteriascore.weight,
comparisoncriteriascore.score,
comparisoncriteriascore.score_max,
DATE(DATE_TRUNC('week', datetime_add)) AS week_date
FROM tournesol_comparison
Expand Down Expand Up @@ -283,7 +284,15 @@ def write_comparisons_file(

# If we want this function to be generic, the specific video_a and video_b
# columns should be renamed entity_a and entity_b.
fieldnames = ["public_username", "video_a", "video_b", "criteria", "score", "week_date"]
fieldnames = [
"public_username",
"video_a",
"video_b",
"criteria",
"score",
"score_max",
"week_date"
]
writer = csv.DictWriter(write_target, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(
Expand All @@ -293,6 +302,7 @@ def write_comparisons_file(
"video_b": comparison.uid_b.split(UID_DELIMITER)[1],
"criteria": comparison.criteria,
"score": int(round(comparison.score)),
"score_max": comparison.score_max,
"week_date": comparison.week_date,
}
for comparison in get_comparisons_data(poll_name, until_).iterator()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def handle(self, *args, **options):
comparison=comparison,
criteria=values["criteria"],
score=values["score"],
score_max=values["score_max"],
)
nb_comparisons += 1
print(f"Created {nb_comparisons} comparisons")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.11 on 2024-05-02 09:05

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("tournesol", "0060_remove_entity_tournesol_score"),
]

operations = [
migrations.AddField(
model_name="comparisoncriteriascore",
name="score_max",
field=models.IntegerField(
default=10,
help_text="The absolute value of the maximum score.",
validators=[django.core.validators.MinValueValidator(1)],
),
preserve_default=False,
),
migrations.AlterField(
model_name="comparisoncriteriascore",
name="score",
field=models.FloatField(help_text="Score for the given comparison"),
),
]
22 changes: 19 additions & 3 deletions backend/tournesol/models/comparisons.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
import uuid

import computed_property
from django.core.validators import MaxValueValidator, MinValueValidator
from django.core.validators import MinValueValidator
from django.db import models
from django.db.models import F, ObjectDoesNotExist, Q

from core.models import User
from tournesol.utils.constants import COMPARISON_MAX

from .poll import Poll

Expand Down Expand Up @@ -129,7 +128,10 @@ class ComparisonCriteriaScore(models.Model):
)
score = models.FloatField(
help_text="Score for the given comparison",
validators=[MinValueValidator(-COMPARISON_MAX), MaxValueValidator(COMPARISON_MAX)],
)
score_max = models.IntegerField(
help_text="The absolute value of the maximum score.",
validators=[MinValueValidator(1)],
)
# TODO: ask Lê if weights should be in a certain range (maybe always > 0)
# and add validation if required
Expand All @@ -144,3 +146,17 @@ class Meta:

def __str__(self):
return f"{self.comparison}/{self.criteria}/{self.score}"

def save(self, *args, **kwargs):
if self.score_max is None:
raise TypeError("The value of score_max cannot be None.")

if self.score_max <= 0:
raise ValueError("The value of score_max must be greater than or equal to 1.")

if abs(self.score) > self.score_max:
raise ValueError(
f"The absolute value of the score {self.score} given to the criterion "
f"{self.criteria} can't be greater than the value of score_max {self.score_max}."
)
return super().save(*args, **kwargs)
13 changes: 9 additions & 4 deletions backend/tournesol/resources/export_readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,15 @@ List of columns:

- score:

The score is an integer between -10 and +10. Negative values indicate that
the user considers the video_a better, and positive values indicate that
they prefer the video_b. A score of 0 or close to 0 means that they find the
two videos similar.
The score is an integer in the range [-score_max, +score_max]. Negative
values indicate that the user considers the video_a better, and positive
values indicate that they prefer the video_b. A score of 0 or close to 0
means that they find the two videos similar.

- score_max:

The absolute value of the minimum and maximum score. 10 means the user could
have given a score between -10 and +10 for the criterion.

- week_date:

Expand Down
32 changes: 23 additions & 9 deletions backend/tournesol/serializers/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class ComparisonCriteriaScoreSerializer(ModelSerializer):
class Meta:
model = ComparisonCriteriaScore
fields = ["criteria", "score", "weight"]
fields = ["criteria", "score", "score_max", "weight"]

def validate_criteria(self, value):
current_poll = self.context["poll"]
Expand All @@ -37,11 +37,15 @@ def reverse_criteria_scores(self, criteria_scores):

def validate_criteria_scores(self, value):
current_poll = self.context["poll"]
missing_criterias = set(current_poll.required_criterias_list) - set(
score["criteria"] for score in value
)
if missing_criterias:
raise ValidationError(f"Missing required criteria: {','.join(missing_criterias)}")
partial_update = self.context.get("partial_update")

if not partial_update:
missing_criterias = set(current_poll.required_criterias_list) - set(
score["criteria"] for score in value
)
if missing_criterias:
raise ValidationError(f"Missing required criteria: {','.join(missing_criterias)}")

return value


Expand Down Expand Up @@ -193,9 +197,19 @@ def update(self, instance, validated_data):
instance.duration_ms = validated_data.get("duration_ms")

instance.save()
instance.criteria_scores.all().delete()

for criteria_score in validated_data.pop("criteria_scores"):
instance.criteria_scores.create(**criteria_score)
partial_update = self.context.get("partial_update")

if partial_update:
for criteria_score in validated_data.pop("criteria_scores"):
instance.criteria_scores.update_or_create(
criteria=criteria_score["criteria"],
defaults={**criteria_score}
)
else:
instance.criteria_scores.all().delete()

for criteria_score in validated_data.pop("criteria_scores"):
instance.criteria_scores.create(**criteria_score)

return instance
1 change: 1 addition & 0 deletions backend/tournesol/serializers/inconsistencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ScoreInconsistencySerializer(Serializer):
entity_1_rating = serializers.FloatField()
entity_2_rating = serializers.FloatField()
comparison_score = serializers.FloatField()
comparison_score_max = serializers.IntegerField()
expected_comparison_score = serializers.FloatField()


Expand Down
1 change: 1 addition & 0 deletions backend/tournesol/tests/factories/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ class Meta:
comparison = factory.SubFactory(ComparisonFactory)
criteria = "better_habits"
score = fuzzy.FuzzyDecimal(-10, 10)
score_max = 10
Loading

0 comments on commit e00991b

Please sign in to comment.