diff --git a/ml_models/resnet_model4.h5 b/ml_models/resnet_model4.h5 new file mode 100644 index 0000000000000000000000000000000000000000..9249b0bbe74ef06fa4cc694c0a8fad9883d1bcf3 Binary files /dev/null and b/ml_models/resnet_model4.h5 differ diff --git a/mlaas/__pycache__/__init__.cpython-310.pyc b/mlaas/__pycache__/__init__.cpython-310.pyc index 5f9f80acf89f24c86d2630c27ca57abd24f33742..f2bc6cd3b7de33b9a46fc6e25fe8f36dd89d17e3 100644 Binary files a/mlaas/__pycache__/__init__.cpython-310.pyc and b/mlaas/__pycache__/__init__.cpython-310.pyc differ diff --git a/mlaas/__pycache__/settings.cpython-310.pyc b/mlaas/__pycache__/settings.cpython-310.pyc index 808a682e145f50eb85610c1519b97d6f3228123c..471722be635a3fcca561a3256b3fb155806e55a1 100644 Binary files a/mlaas/__pycache__/settings.cpython-310.pyc and b/mlaas/__pycache__/settings.cpython-310.pyc differ diff --git a/mlaas/__pycache__/urls.cpython-310.pyc b/mlaas/__pycache__/urls.cpython-310.pyc index d1901d71e5ab6b931fda5a92544cc0134df35512..e5f9ca009c49a4556d1c9e37d287c929c155d0d2 100644 Binary files a/mlaas/__pycache__/urls.cpython-310.pyc and b/mlaas/__pycache__/urls.cpython-310.pyc differ diff --git a/mlaas/__pycache__/wsgi.cpython-310.pyc b/mlaas/__pycache__/wsgi.cpython-310.pyc index db38895afcdeb1b87e1860f6c5e52cfbe3bfdd04..41176ff0429c8db57acaf33be2c694d0db1997b7 100644 Binary files a/mlaas/__pycache__/wsgi.cpython-310.pyc and b/mlaas/__pycache__/wsgi.cpython-310.pyc differ diff --git a/mlaas/middleware/__pycache__/__init__.cpython-310.pyc b/mlaas/middleware/__pycache__/__init__.cpython-310.pyc index bcbe742706f165151f7f033dc3481d34f0d83b4c..a3c0930bc7e7604c0ee2b574c56129d8573497dc 100644 Binary files a/mlaas/middleware/__pycache__/__init__.cpython-310.pyc and b/mlaas/middleware/__pycache__/__init__.cpython-310.pyc differ diff --git a/mlaas/middleware/__pycache__/ai_engineer_auth.cpython-310.pyc b/mlaas/middleware/__pycache__/ai_engineer_auth.cpython-310.pyc index 8e8eca8dd83ab58ce1a5b19f41ada518b0cab366..a1366c37d9f748f5ce6c1aaf8ec1d9ecd4d7f2b0 100644 Binary files a/mlaas/middleware/__pycache__/ai_engineer_auth.cpython-310.pyc and b/mlaas/middleware/__pycache__/ai_engineer_auth.cpython-310.pyc differ diff --git a/mlaas/middleware/__pycache__/autologout.cpython-310.pyc b/mlaas/middleware/__pycache__/autologout.cpython-310.pyc index 196236e92d012bf7c390d3ed49b859bb8bd7c743..fe3a529db247c22ba72c90304dc4d0a1a319315a 100644 Binary files a/mlaas/middleware/__pycache__/autologout.cpython-310.pyc and b/mlaas/middleware/__pycache__/autologout.cpython-310.pyc differ diff --git a/prediction_service/__pycache__/__init__.cpython-310.pyc b/prediction_service/__pycache__/__init__.cpython-310.pyc index c94643b1202d4d4057431f19b2317d57848efd62..98ab6f8443d50cb07f8de13b08b76835829e582d 100644 Binary files a/prediction_service/__pycache__/__init__.cpython-310.pyc and b/prediction_service/__pycache__/__init__.cpython-310.pyc differ diff --git a/prediction_service/__pycache__/admin.cpython-310.pyc b/prediction_service/__pycache__/admin.cpython-310.pyc index 3d0aa399fc21517c1e247f49738d44faa3cf2c1c..50aa0f37e655a4e3cbe61002b4008c38c3a1f044 100644 Binary files a/prediction_service/__pycache__/admin.cpython-310.pyc and b/prediction_service/__pycache__/admin.cpython-310.pyc differ diff --git a/prediction_service/__pycache__/apps.cpython-310.pyc b/prediction_service/__pycache__/apps.cpython-310.pyc index e40330c1af2ec3385920d41c872e75c0c57939cd..dc785a10c849cda030cb6295d12ee08f10b1ca6d 100644 Binary files a/prediction_service/__pycache__/apps.cpython-310.pyc and b/prediction_service/__pycache__/apps.cpython-310.pyc differ diff --git a/prediction_service/__pycache__/forms.cpython-310.pyc b/prediction_service/__pycache__/forms.cpython-310.pyc index 6711bb887fe042f75f5e778b10bf1a28b4566bba..a91838fec4117f1cf1667ac32f82d2d676f5b815 100644 Binary files a/prediction_service/__pycache__/forms.cpython-310.pyc and b/prediction_service/__pycache__/forms.cpython-310.pyc differ diff --git a/prediction_service/__pycache__/models.cpython-310.pyc b/prediction_service/__pycache__/models.cpython-310.pyc index fb33c32ae56b34b9ce9a294a115e9424d05195bd..2e05dc7db5702a4c80ed2f3ff043e1581a7874f4 100644 Binary files a/prediction_service/__pycache__/models.cpython-310.pyc and b/prediction_service/__pycache__/models.cpython-310.pyc differ diff --git a/prediction_service/__pycache__/views.cpython-310.pyc b/prediction_service/__pycache__/views.cpython-310.pyc index e0c1dfb4935d4d1280f68d0091410579733f81cb..a73a1ef5f5ea611e8701184b4018def739e79694 100644 Binary files a/prediction_service/__pycache__/views.cpython-310.pyc and b/prediction_service/__pycache__/views.cpython-310.pyc differ diff --git a/prediction_service/forms.py b/prediction_service/forms.py index e504131e70f58f453c5d5d5af948dfb429aad167..7ebca2ea6b47940d3607a74437b2043c38315451 100644 --- a/prediction_service/forms.py +++ b/prediction_service/forms.py @@ -11,9 +11,17 @@ class UserRegisterForm(UserCreationForm): fields = ['username', 'email', 'password1', 'password2', 'role'] from django import forms -from .models import Post +from .models import MLModel, Post class PostForm(forms.ModelForm): class Meta: model = Post - fields = ['title', 'content', 'mlmodel'] + fields = ['title', 'content', 'mlmodel'] # Include the 'mlmodel' field + + def __init__(self, *args, **kwargs): + super(PostForm, self).__init__(*args, **kwargs) + self.fields['title'].widget.attrs.update({'class': 'form-control'}) + self.fields['content'].widget.attrs.update({'class': 'form-control'}) + + # Modify the mlmodel field to be a dropdown list of existing ML models + self.fields['mlmodel'].queryset = MLModel.objects.all() \ No newline at end of file diff --git a/prediction_service/migrations/0010_mlmodel_model_file.py b/prediction_service/migrations/0010_mlmodel_model_file.py new file mode 100644 index 0000000000000000000000000000000000000000..b1cedea8420acf5040b74dc9eba0c3ce1d26219f --- /dev/null +++ b/prediction_service/migrations/0010_mlmodel_model_file.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2024-05-02 00:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('prediction_service', '0009_aiengineer_is_authorized'), + ] + + operations = [ + migrations.AddField( + model_name='mlmodel', + name='model_file', + field=models.FileField(default='', upload_to='ml_models/'), + ), + ] diff --git a/prediction_service/migrations/0011_alter_post_slug.py b/prediction_service/migrations/0011_alter_post_slug.py new file mode 100644 index 0000000000000000000000000000000000000000..5a1f3d99a238f025091bea9e22745ee5e4c4e689 --- /dev/null +++ b/prediction_service/migrations/0011_alter_post_slug.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2024-05-02 01:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('prediction_service', '0010_mlmodel_model_file'), + ] + + operations = [ + migrations.AlterField( + model_name='post', + name='slug', + field=models.SlugField(blank=True, default=''), + ), + ] diff --git a/prediction_service/migrations/0012_alter_post_mlmodel.py b/prediction_service/migrations/0012_alter_post_mlmodel.py new file mode 100644 index 0000000000000000000000000000000000000000..49a96da010a162bc2bae5b93fa216fbed23bb955 --- /dev/null +++ b/prediction_service/migrations/0012_alter_post_mlmodel.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.4 on 2024-05-02 01:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('prediction_service', '0011_alter_post_slug'), + ] + + operations = [ + migrations.AlterField( + model_name='post', + name='mlmodel', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='prediction_service.mlmodel'), + ), + ] diff --git a/prediction_service/migrations/__pycache__/0001_initial.cpython-310.pyc b/prediction_service/migrations/__pycache__/0001_initial.cpython-310.pyc index 9aa0439f8eba863c159d8a535b9b9954d5858878..3b7b6b51c03c4301b3cbeac135463816664c2d5c 100644 Binary files a/prediction_service/migrations/__pycache__/0001_initial.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0001_initial.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0002_remove_aiengineer_trained_models_and_more.cpython-310.pyc b/prediction_service/migrations/__pycache__/0002_remove_aiengineer_trained_models_and_more.cpython-310.pyc index 5e419840ba17e246de8a82027a70aaceeee25484..7303b70dab3d13798511519ee4f943010a00d0f0 100644 Binary files a/prediction_service/migrations/__pycache__/0002_remove_aiengineer_trained_models_and_more.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0002_remove_aiengineer_trained_models_and_more.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0003_post.cpython-310.pyc b/prediction_service/migrations/__pycache__/0003_post.cpython-310.pyc index e3a6267611c5d63465d80b26fd07327deea0fc9f..527c740512e04796a6216c293fb15cfa57b540f9 100644 Binary files a/prediction_service/migrations/__pycache__/0003_post.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0003_post.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0004_alter_userprofile_role.cpython-310.pyc b/prediction_service/migrations/__pycache__/0004_alter_userprofile_role.cpython-310.pyc index fe6e8a2e38e9cf77f98402ffc57f0ad352d9e4f0..6c508d5c27a07710587a2f53ddae2abcc3491342 100644 Binary files a/prediction_service/migrations/__pycache__/0004_alter_userprofile_role.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0004_alter_userprofile_role.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0005_alter_post_id_delete_financeteam.cpython-310.pyc b/prediction_service/migrations/__pycache__/0005_alter_post_id_delete_financeteam.cpython-310.pyc index a5b26f142235ea9facc86c8e169568620fad9ea2..ef9333676ddd8674127e58866b70e8868e91de1d 100644 Binary files a/prediction_service/migrations/__pycache__/0005_alter_post_id_delete_financeteam.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0005_alter_post_id_delete_financeteam.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0006_mlmodel.cpython-310.pyc b/prediction_service/migrations/__pycache__/0006_mlmodel.cpython-310.pyc index bacd82fd32abafc4179758965f95db8e7a203c46..fe4ff51782739ce26b1bdb9ba0e9d8cc728cc0fe 100644 Binary files a/prediction_service/migrations/__pycache__/0006_mlmodel.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0006_mlmodel.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0007_post_mlmodel.cpython-310.pyc b/prediction_service/migrations/__pycache__/0007_post_mlmodel.cpython-310.pyc index 60e56c987d571c764790bf3e927f1fc2364666de..0dfbab7d3237e0f7ad51c9c3774d13cf05af10d2 100644 Binary files a/prediction_service/migrations/__pycache__/0007_post_mlmodel.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0007_post_mlmodel.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0008_post_slug.cpython-310.pyc b/prediction_service/migrations/__pycache__/0008_post_slug.cpython-310.pyc index 269df00d15384796a285a6073ff7316546c3c935..aad31068e1612ededcb6286897c968fc99ece042 100644 Binary files a/prediction_service/migrations/__pycache__/0008_post_slug.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0008_post_slug.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0009_aiengineer_is_authorized.cpython-310.pyc b/prediction_service/migrations/__pycache__/0009_aiengineer_is_authorized.cpython-310.pyc index 32dead685fc5ed858048143e5f4290b3228bde7d..e847c26be1a72baa8ed5e9eba9cc5fa6cac72b88 100644 Binary files a/prediction_service/migrations/__pycache__/0009_aiengineer_is_authorized.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0009_aiengineer_is_authorized.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0010_mlmodel_model_file.cpython-310.pyc b/prediction_service/migrations/__pycache__/0010_mlmodel_model_file.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29367efe2bdd67ff3aa80678cb7d83873e844dc6 Binary files /dev/null and b/prediction_service/migrations/__pycache__/0010_mlmodel_model_file.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0011_alter_post_slug.cpython-310.pyc b/prediction_service/migrations/__pycache__/0011_alter_post_slug.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..546eb4f5089c37424b60adc0af4dae01f47abea2 Binary files /dev/null and b/prediction_service/migrations/__pycache__/0011_alter_post_slug.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/0012_alter_post_mlmodel.cpython-310.pyc b/prediction_service/migrations/__pycache__/0012_alter_post_mlmodel.cpython-310.pyc index 0dca3b20a7cb453671c7f54f4189f2a83fbb5332..d5ee55750abcf3cb15e2d2628cb088db8c36cbf6 100644 Binary files a/prediction_service/migrations/__pycache__/0012_alter_post_mlmodel.cpython-310.pyc and b/prediction_service/migrations/__pycache__/0012_alter_post_mlmodel.cpython-310.pyc differ diff --git a/prediction_service/migrations/__pycache__/__init__.cpython-310.pyc b/prediction_service/migrations/__pycache__/__init__.cpython-310.pyc index 530685db3e01649a821eceb29b96c5bbafbf48e4..c50df215fb18cd49a18709f940ba83a0cf09e19d 100644 Binary files a/prediction_service/migrations/__pycache__/__init__.cpython-310.pyc and b/prediction_service/migrations/__pycache__/__init__.cpython-310.pyc differ diff --git a/prediction_service/models.py b/prediction_service/models.py index d3f147c115c68cb063a33464a78c82b700b6d5b7..166b6d5cee530444d7efa31bc46a3050071dddf3 100644 --- a/prediction_service/models.py +++ b/prediction_service/models.py @@ -31,17 +31,28 @@ class Administrator(models.Model): class MLModel(models.Model): id = models.AutoField(primary_key=True) layers = models.IntegerField(default=1, verbose_name='Number of Layers', validators=[MinValueValidator(1)]) + model_file = models.FileField(upload_to='ml_models/', default='') # Add FileField for storing .h5 files + def __str__(self): + return f"MLModel {self.id}" + +from django.utils.text import slugify + class Post(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length = 100) - slug = models.SlugField(default=None) + slug = models.SlugField(default='', blank=True) content = models.TextField() date_posted = models.DateTimeField(default = timezone.now) author = models.ForeignKey(User, on_delete=models.CASCADE) - mlmodel = models.ForeignKey(MLModel, on_delete=models.CASCADE, default=None) + mlmodel = models.ForeignKey(MLModel, on_delete=models.CASCADE) + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + super().save(*args, **kwargs) def __str__(self) -> str: return self.title \ No newline at end of file diff --git a/prediction_service/templates/prediction_service/create_post.html b/prediction_service/templates/prediction_service/create_post.html index bbeaf38be2165d53b0d76cf6665611153eeeeafd..e7968f397dfb1b9c76213100012b0b5895dde54b 100644 --- a/prediction_service/templates/prediction_service/create_post.html +++ b/prediction_service/templates/prediction_service/create_post.html @@ -3,7 +3,7 @@ {% block content %} <div class="container"> <h2>Create a New Post</h2> - <form method="post"> + <form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit" class="btn btn-primary">Submit</button> diff --git a/prediction_service/templates/prediction_service/home.html b/prediction_service/templates/prediction_service/home.html index 160d3793a66dc192026da5ac9164fc1493a159ac..ec9f56c510587e7995cde19b2810cd852fc567d6 100644 --- a/prediction_service/templates/prediction_service/home.html +++ b/prediction_service/templates/prediction_service/home.html @@ -25,11 +25,13 @@ </div> <!-- Square plus button --> - <div style="position: fixed; bottom: 20px; right: 20px;"> - <a href="{% url 'MLAAS-create_post' %}"> - <button style="width: 50px; height: 50px; border-radius: 50%; background-color: #007bff; color: white; font-size: 24px; border: none;">+</button> - </a> - </div> + {% if request.user.is_superuser or request.user.userprofile.role == 'ai_engineer' %} + <div style="position: fixed; bottom: 20px; right: 20px;"> + <a href="{% url 'MLAAS-create_post' %}"> + <button style="width: 50px; height: 50px; border-radius: 50%; background-color: #007bff; color: white; font-size: 24px; border: none;">+</button> + </a> + </div> + {% endif %} diff --git a/prediction_service/views.py b/prediction_service/views.py index 0e636cbf804e459fac6cc61da3cd5b6f6e1fa4fa..c7361323d24484750cb6c48b735ef657329d5269 100644 --- a/prediction_service/views.py +++ b/prediction_service/views.py @@ -1,5 +1,5 @@ from django.shortcuts import render, redirect -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseForbidden from django.contrib import messages from django.contrib.auth.decorators import login_required # messages.debug @@ -126,12 +126,19 @@ from .models import Post @login_required def create_post(request): + if not request.user.is_superuser and request.user.userprofile.role != 'ai_engineer': + return HttpResponseForbidden("You do not have permission to access this page.") + if request.method == 'POST': - form = PostForm(request.POST) + form = PostForm(request.POST, request.FILES) if form.is_valid(): post = form.save(commit=False) post.author = request.user + # Assign the selected MLModel instance to the post + mlmodel_id = form.cleaned_data.get('mlmodel') + post.mlmodel_id = mlmodel_id + # Check if the user is an AI engineer or an admin if request.user.userprofile.role == 'AI Engineer' or request.user.is_superuser: post.save() @@ -140,6 +147,8 @@ def create_post(request): else: messages.error(request, 'You are not authorized to create posts.') return redirect('MLAAS-home') # Redirect to home or another appropriate page + else: + messages.error(request, 'Failed to create the post. Please check the form data.') else: form = PostForm() return render(request, 'prediction_service/create_post.html', {'form': form})