Skip to content

Commit

Permalink
ab tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pplonski committed Nov 4, 2019
1 parent e02b403 commit 2611a22
Show file tree
Hide file tree
Showing 10 changed files with 566 additions and 41 deletions.
22 changes: 18 additions & 4 deletions backend/server/apps/endpoints/migrations/0001_initial.py
@@ -1,4 +1,4 @@
# Generated by Django 2.2.4 on 2019-10-31 15:10
# Generated by Django 2.2.4 on 2019-11-04 10:01

from django.db import migrations, models
import django.db.models.deletion
Expand Down Expand Up @@ -39,8 +39,9 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('input_data', models.CharField(max_length=10000)),
('full_response', models.CharField(max_length=10000)),
('response', models.CharField(max_length=10000)),
('feedback', models.CharField(max_length=10000)),
('feedback', models.CharField(blank=True, max_length=10000, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('parent_mlalgorithm', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endpoints.MLAlgorithm')),
],
Expand All @@ -50,10 +51,23 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(max_length=128)),
('active', models.BooleanField()),
('created_by', models.CharField(max_length=128)),
('created_at', models.DateTimeField(auto_now_add=True)),
('parent_endpoint', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endpoints.Endpoint')),
('parent_mlalgorithm', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='endpoints.MLAlgorithm')),
('parent_mlalgorithm', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status', to='endpoints.MLAlgorithm')),
],
),
migrations.CreateModel(
name='ABTest',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=10000)),
('created_by', models.CharField(max_length=128)),
('created_at', models.DateTimeField(auto_now_add=True)),
('ended_at', models.DateTimeField(blank=True, null=True)),
('summary', models.CharField(blank=True, max_length=10000, null=True)),
('parent_mlalgorithm_1', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parent_mlalgorithm_1', to='endpoints.MLAlgorithm')),
('parent_mlalgorithm_2', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parent_mlalgorithm_2', to='endpoints.MLAlgorithm')),
],
),
]
47 changes: 35 additions & 12 deletions backend/server/apps/endpoints/models.py
Expand Up @@ -36,34 +36,57 @@ class MLAlgorithm(models.Model):

class MLAlgorithmStatus(models.Model):
'''
The MLAlgorithmStatus represent the status of the MLAlgorithm which can change during the time.
The MLAlgorithmStatus represent status of the MLAlgorithm which can change during the time.
Attributes:
status: The status of the algorithm in the endpoint. It can be: testing, staging, production, ab_testing.
created_by: The name of the creator.
status: The status of algorithm in the endpoint. Can be: testing, staging, production, ab_testing.
created_by: The name of creator.
created_at: The date of status creation.
parent_mlalgorithm: The reference to the corresponding MLAlgorithm.
parent_endpoint: The reference to corresponding Endpoint.
parent_mlalgorithm: The reference to corresponding MLAlgorithm.
parent_endpoint: The reference to corresonding Endpoint.
'''
status = models.CharField(max_length=128)
active = models.BooleanField()
created_by = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
parent_mlalgorithm = models.ForeignKey(MLAlgorithm, on_delete=models.CASCADE)
parent_endpoint = models.ForeignKey(Endpoint, on_delete=models.CASCADE)
parent_mlalgorithm = models.ForeignKey(MLAlgorithm, on_delete=models.CASCADE, related_name = "status")

class MLRequest(models.Model):
'''
The MLRequest will keep information about all requests to ML algorithms.
Attributes:
input_data: The input data to the ML algorithm in JSON format.
input_data: The input data to ML algorithm in JSON format.
response: The response of the ML algorithm in JSON format.
feedback: Feedback about the response in JSON format.
created_at: The date when the request was created.
parent_mlalgorithm: The reference to MLAlgorithm used to compute the response.
feedback: The feedback about the response in JSON format.
created_at: The date when request was created.
parent_mlalgorithm: The reference to MLAlgorithm used to compute response.
'''
input_data = models.CharField(max_length=10000)
full_response = models.CharField(max_length=10000)
response = models.CharField(max_length=10000)
feedback = models.CharField(max_length=10000)
feedback = models.CharField(max_length=10000, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
parent_mlalgorithm = models.ForeignKey(MLAlgorithm, on_delete=models.CASCADE)


class ABTest(models.Model):
'''
The ABTest will keep information about A/B tests.
Attributes:
title: The title of test.
created_by: The name of creator.
created_at: The date of test creation.
ended_at: The date of test stop.
summary: The description with test summary, created at test stop.
parent_mlalgorithm_1: The reference to the first corresponding MLAlgorithm.
parent_mlalgorithm_2: The reference to the second corresponding MLAlgorithm.
'''
title = models.CharField(max_length=10000)
created_by = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
ended_at = models.DateTimeField(blank=True, null=True)
summary = models.CharField(max_length=10000, blank=True, null=True)

parent_mlalgorithm_1 = models.ForeignKey(MLAlgorithm, on_delete=models.CASCADE, related_name="parent_mlalgorithm_1")
parent_mlalgorithm_2 = models.ForeignKey(MLAlgorithm, on_delete=models.CASCADE, related_name="parent_mlalgorithm_2")
39 changes: 35 additions & 4 deletions backend/server/apps/endpoints/serializers.py
Expand Up @@ -3,6 +3,7 @@
from apps.endpoints.models import MLAlgorithm
from apps.endpoints.models import MLAlgorithmStatus
from apps.endpoints.models import MLRequest
from apps.endpoints.models import ABTest


class EndpointSerializer(serializers.ModelSerializer):
Expand All @@ -13,7 +14,9 @@ class Meta:


class MLAlgorithmSerializer(serializers.ModelSerializer):

current_status = serializers.SerializerMethodField(read_only=True)

def get_current_status(self, mlalgorithm):
return MLAlgorithmStatus.objects.filter(parent_mlalgorithm=mlalgorithm).latest('created_at').status

Expand All @@ -23,12 +26,12 @@ class Meta:
"version", "owner", "created_at",
"parent_endpoint", "current_status")
fields = read_only_fields

class MLAlgorithmStatusSerializer(serializers.ModelSerializer):
class Meta:
model = MLAlgorithmStatus
read_only_fields = ("id", "created_by", "parent_endpoint")
fields = ("id", "status", "created_by", "created_at",
read_only_fields = ("id", "active")
fields = ("id", "active", "status", "created_by", "created_at",
"parent_mlalgorithm")

class MLRequestSerializer(serializers.ModelSerializer):
Expand All @@ -37,9 +40,37 @@ class Meta:
read_only_fields = (
"id",
"input_data",
"full_response",
"response",
"created_at",
"parent_mlalgorithm",
)
fields = (
"id",
"input_data",
"full_response",
"response",
"feedback",
"created_at",
"parent_mlalgorithm",
)
fields = read_only_fields

class ABTestSerializer(serializers.ModelSerializer):
class Meta:
model = ABTest
read_only_fields = (
"id",
"ended_at",
"created_at",
"summary",
)
fields = (
"id",
"title",
"created_by",
"created_at",
"ended_at",
"summary",
"parent_mlalgorithm_1",
"parent_mlalgorithm_2",
)
11 changes: 9 additions & 2 deletions backend/server/apps/endpoints/urls.py
Expand Up @@ -3,18 +3,25 @@

from apps.endpoints.views import EndpointViewSet
from apps.endpoints.views import MLAlgorithmViewSet
from apps.endpoints.views import MLAlgorithmStatusViewSet
from apps.endpoints.views import MLRequestViewSet
from apps.endpoints.views import PredictView # import PredictView
from apps.endpoints.views import PredictView
from apps.endpoints.views import ABTestViewSet
from apps.endpoints.views import StopABTestView

router = DefaultRouter(trailing_slash=False)
router.register(r"endpoints", EndpointViewSet, basename="endpoints")
router.register(r"mlalgorithms", MLAlgorithmViewSet, basename="mlalgorithms")
router.register(r"mlalgorithmstatuses", MLAlgorithmStatusViewSet, basename="mlalgorithmstatuses")
router.register(r"mlrequests", MLRequestViewSet, basename="mlrequests")
router.register(r"abtests", ABTestViewSet, basename="abtests")

urlpatterns = [
url(r"^api/v1/", include(router.urls)),
# add predict url
url(
r"^api/v1/(?P<endpoint_name>.+)/predict$", PredictView.as_view(), name="predict"
),
url(
r"^api/v1/stop_ab_test/(?P<ab_test_id>.+)", StopABTestView.as_view(), name="stop_ab"
),
]

0 comments on commit 2611a22

Please sign in to comment.