Setup base API module models to record and track ml algorithms and api requests
diff --git a/api/migrations/0001_initial.py b/api/migrations/0001_initial.py
index 0a81080..1d4bb37 100644
--- a/api/migrations/0001_initial.py
+++ b/api/migrations/0001_initial.py
@@ -1,6 +1,7 @@
-# Generated by Django 3.2.1 on 2021-05-27 03:52
+# Generated by Django 3.2.1 on 2021-06-07 10:55
 
 from django.db import migrations, models
+import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
@@ -12,17 +13,96 @@
 
     operations = [
         migrations.CreateModel(
+            name='Endpoint',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=128)),
+                ('classifier', models.CharField(max_length=128)),
+                ('created_by', models.CharField(max_length=128)),
+                ('created_at', models.DateTimeField(auto_now_add=True)),
+            ],
+            options={
+                'ordering': ['created_at'],
+            },
+        ),
+        migrations.CreateModel(
             name='GermanDataModel',
             fields=[
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('age', models.IntegerField(blank=True)),
+                ('created', models.DateTimeField(auto_now_add=True)),
+                ('age', models.IntegerField()),
                 ('sex', models.CharField(blank=True, choices=[(1, 'Female')], max_length=10)),
                 ('job', models.CharField(max_length=100)),
                 ('housing', models.CharField(max_length=50)),
-                ('credit_amount', models.FloatField(blank=True, max_length=50)),
-                ('duration', models.IntegerField(blank=True)),
+                ('credit_amount', models.FloatField(max_length=50)),
+                ('duration', models.IntegerField()),
                 ('purpose', models.CharField(blank=True, max_length=50)),
                 ('risk', models.CharField(blank=True, choices=[(1, 'Bad')], max_length=10)),
             ],
+            options={
+                'ordering': ['created'],
+            },
+        ),
+        migrations.CreateModel(
+            name='MLAlgorithm',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=128)),
+                ('description', models.CharField(max_length=1000)),
+                ('code', models.CharField(max_length=50000)),
+                ('version', models.CharField(max_length=128)),
+                ('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='api.endpoint')),
+            ],
+            options={
+                'ordering': ['created_at'],
+            },
+        ),
+        migrations.CreateModel(
+            name='MLRequest',
+            fields=[
+                ('id', models.BigAutoField(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(blank=True, max_length=10000, null=True)),
+                ('created_by', models.CharField(max_length=128)),
+                ('created_at', models.DateTimeField(auto_now_add=True)),
+                ('parent_mlalgorithm', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.mlalgorithm')),
+            ],
+            options={
+                'ordering': ['created_at'],
+            },
+        ),
+        migrations.CreateModel(
+            name='MLAlgorithmStatus',
+            fields=[
+                ('id', models.BigAutoField(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_mlalgorithm', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='status', to='api.mlalgorithm')),
+            ],
+            options={
+                'ordering': ['created_at'],
+            },
+        ),
+        migrations.CreateModel(
+            name='ABTest',
+            fields=[
+                ('id', models.BigAutoField(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='api.mlalgorithm')),
+                ('parent_mlalgorithm_2', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parent_mlalgorithm_2', to='api.mlalgorithm')),
+            ],
+            options={
+                'ordering': ['created_at'],
+            },
         ),
     ]
diff --git a/api/migrations/0002_auto_20210529_1147.py b/api/migrations/0002_auto_20210529_1147.py
deleted file mode 100644
index 5f9f312..0000000
--- a/api/migrations/0002_auto_20210529_1147.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Generated by Django 3.2.1 on 2021-05-29 11:47
-
-from django.db import migrations, models
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('api', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AlterModelOptions(
-            name='germandatamodel',
-            options={'ordering': ['created']},
-        ),
-        migrations.AddField(
-            model_name='germandatamodel',
-            name='created',
-            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
-            preserve_default=False,
-        ),
-        migrations.AlterField(
-            model_name='germandatamodel',
-            name='age',
-            field=models.IntegerField(),
-        ),
-        migrations.AlterField(
-            model_name='germandatamodel',
-            name='credit_amount',
-            field=models.FloatField(max_length=50),
-        ),
-        migrations.AlterField(
-            model_name='germandatamodel',
-            name='duration',
-            field=models.IntegerField(),
-        ),
-    ]
diff --git a/api/models.py b/api/models.py
index 08e7012..86c5321 100644
--- a/api/models.py
+++ b/api/models.py
@@ -13,7 +13,10 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-#
+# =============================================================================
+"""
+API Models module
+"""
 
 from django.db import models
 
@@ -36,3 +39,117 @@
     
     class Meta:
         ordering = ['created']
+
+class Endpoint(models.Model):
+    '''
+    The Endpoint object represents ML API endpoint.
+
+    Attributes
+    ----------
+        name: The name of the endpoint, it will be used in API URL,
+        created_by: The string with owner name,
+        created_at: The date when endpoint was created.
+    '''
+    name = models.CharField(max_length=128)
+    classifier = models.CharField(max_length=128)
+    created_by = models.CharField(max_length=128)
+    created_at = models.DateTimeField(auto_now_add=True, blank=True)
+
+    class Meta:
+        ordering = ['created_at']
+        
+class MLAlgorithm(models.Model):
+    '''
+    The MLAlgorithm represent the ML algorithm object.
+
+    Attributes
+    ----------
+        name: The name of the algorithm.
+        description: The short description of how the algorithm works.
+        code: The code of the algorithm.
+        version: The version of the algorithm similar to software versioning.
+        created_by: The name of the owner.
+        created_at: The date when MLAlgorithm was added.
+        parent_endpoint: The reference to the Endpoint.
+    '''
+    name = models.CharField(max_length=128)
+    description = models.CharField(max_length=1000)
+    code = models.CharField(max_length=50000)
+    version = models.CharField(max_length=128)
+    created_by = models.CharField(max_length=128)
+    created_at = models.DateTimeField(auto_now_add=True, blank=True)
+    parent_endpoint = models.ForeignKey(Endpoint, on_delete=models.CASCADE)
+
+    class Meta:
+        ordering = ['created_at']
+        
+class MLAlgorithmStatus(models.Model):
+    '''
+    The MLAlgorithmStatus represent status of the MLAlgorithm which can change during the time.
+
+    Attributes
+    ----------
+        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 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, related_name = "status")
+    
+    class Meta:
+        ordering = ['created_at']
+
+class MLRequest(models.Model):
+    '''
+    The MLRequest will keep information about all requests to ML algorithms.
+
+    Attributes
+    ----------
+        input_data: The input data to ML algorithm in JSON format.
+        response: The response of the ML algorithm in JSON format.
+        feedback: The feedback about the response in JSON format.
+        created_by: The name of creator.
+        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, blank=True, null=True)
+    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)
+    
+    class Meta:
+        ordering = ['created_at']
+
+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")
+    
+    class Meta:
+        ordering = ['created_at']