Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • Brody
  • James
  • Kacper
  • Michael
  • brodybranch
  • hamid
  • main
7 results

Target

Select target project
  • kj2-drupisz/desd
1 result
Select Git revision
  • Brody
  • James
  • Kacper
  • Michael
  • brodybranch
  • hamid
  • main
7 results
Show changes
{% extends "_base.html" %}
{% block content %}
<div class="container mx-auto px-4">
<h1 class="text-2xl font-bold mb-4">Model Performance</h1>
{% if metrics %}
<div class="bg-white shadow-md rounded p-6">
<p><strong>Request Count:</strong> {{ metrics.request_count }}</p>
<p><strong>Average Request Latency:</strong> {{ metrics.avg_request_latency|floatformat:6 }} seconds</p>
<p><strong>Average Runtime Latency:</strong> {{ metrics.avg_runtime_latency|floatformat:6 }} seconds</p>
<p><strong>Model Load Latency:</strong> {{ metrics.model_load_latency|floatformat:6 }} seconds</p>
</div>
{% else %}
<p>Failed to retrieve model performance metrics.</p>
{% endif %}
</div>
{% endblock content %}
\ No newline at end of file
......@@ -7,7 +7,19 @@
User settings
</h1>
<h3 class="mb-4 text-xl font-semibold dark:text-white">
User type: {{ user_profile.user_type }}
{% if user_profile.is_superuser %}
User type: Superuser
{% elif user_profile.user_type == 0 %}
User type: User
{% elif user_profile.user_type == 1 %}
User type: Admin
{% elif user_profile.user_type == 2 %}
User type: ML Engineer
{% elif user_profile.user_type == 3 %}
User type: Accountant
{% else %}
User type: Unknown
{% endif %}
</h3>
</div>
<!-- Right Content -->
......@@ -23,7 +35,7 @@
</div>
{% if user_profile.user_type == 3 %}
{% if user_profile.user_type == 3 or user.is_superuser or user_profile.user_type == 1%}
<div
class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"
>
......@@ -76,7 +88,7 @@
{% comment %} REPLACE WITH LOGIC TO CHECK PROPER USER {% endcomment %}
</div>
{% endif %}
{% if 1 %}
{% if user_profile.user_type == 2 or user.is_superuser or user_profile.user_type == 1%}
<div
class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"
......@@ -115,8 +127,13 @@
</div>
{% comment %} AI content {% endcomment %} {% endif%}
</div>
<div class="col-span-2">
{% if user_profile.user_type == 2 or user.is_superuser %}
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<h3 class="mb-4 text-xl font-semibold dark:text-white">Model Performance</h3>
<a href="{% url 'model_performance' %}" class="text-blue-500 hover:underline">View Model Performance</a>
</div>
{% endif %}
<div
class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"
>
......@@ -137,8 +154,12 @@
class="shadow-sm bg-gray-50 border border-gray-300 text-grey-300 sm:text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="example@gmail.com"
required
>{{ user.email }}</span
>
{% if user.email %}
<span>{{ user.email }}</span>
{% else %}
<span>No email address on record.</span>
{% endif %}
</div>
<div class="col-span-6 sm:col-span-3">
<label
......@@ -158,6 +179,17 @@
</div>
</div>
</div>
<!-- Modal -->
<div id="myModal" class="hidden fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
<!-- Modal content with scrolling enabled -->
<div class="modal-body bg-white dark:bg-gray-800 rounded-lg p-4 md:p-6 w-full max-w-2xl">
<h3 class="text-2xl font-bold mb-4">Predictions:</h3>
<ul id="predictionList" class="space-y-2"></ul>
<button onclick="closeModal()" class="mt-4 px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600">Close</button>
</div>
</div>
<div
class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"
>
......@@ -192,61 +224,147 @@
class="font-medium text-blue-600 dark:text-blue-500 hover:underline"
>{{entry.file}}</a
>
{% if entry.description %}
<button type="button" class="ml-4 px-2 py-1 bg-blue-500 text-white rounded-md hover:bg-blue-600" onclick="showModal('{{entry.description|join:'\n'}}')">
Show Results
</button>
{% endif %}
</td>
</tr>
{%endfor%}
</tbody>
</table>
</div>
{% if 1 %} {% comment %} REPLACE WITH LOGIC TO CHECK PROPER USER
{%endcomment %}
{% if user_profile.user_type == 2 %}
<div
class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"
>
<h3 class="mb-4 text-xl font-semibold dark:text-white">
Application Logs
</h3>
<table
class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400"
>
<thead
class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"
>
{% if 1 %} {% comment %} REPLACE WITH LOGIC TO CHECK PROPER USER {% endcomment %}
{% if user_profile.user_type == 2 or user.is_superuser %}
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<h3 class="mb-4 text-xl font-semibold dark:text-white">Application Logs</h3>
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" class="px-6 py-3">Date</th>
<th scope="col" class="px-6 py-3">Action</th>
<th scope="col" class="px-6 py-3">User ID</th>
<th scope="col" class="px-6 py-3">status</th>
<th scope="col" class="px-6 py-3">Status</th>
<th scope="col" class="px-6 py-3">Feedback</th>
</tr>
</thead>
<tbody>
{% for entry in admin_data %}
<tr
class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700"
>
<td
scope="row"
class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
>
{{entry.date}} </td>
<tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700">
<td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{entry.date}}
</td>
<td class="px-6 py-4">
<a
href="#"
class="font-medium text-blue-600 dark:text-blue-500 hover:underline"
>{{entry.action}}</a
>
<a href="#" class="font-medium text-blue-600 dark:text-blue-500 hover:underline">{{entry.action}}</a>
{% if entry.description %}
<button type="button" class="ml-4 px-2 py-1 bg-blue-500 text-white rounded-md hover:bg-blue-600" onclick="showModal('{{entry.description|join:'\n'}}')">
Show Results
</button>
{% endif %}
</td>
<td class="px-6 py-4">{{entry.user}}</td>
<td class="px-6 py-4">{{entry.status}}</td>
<td class="px-6 py-4">
{{entry.status}}</td>
{% if entry.feedback is not None %}
{% if entry.feedback %}
<span class="text-green-500">Liked</span>
{% else %}
<span class="text-red-500">Disliked</span>
{% endif %}
{% else %}
N/A
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% if user.is_superuser or user_profile.user_type == 1 %}
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<h3 class="mb-4 text-xl font-semibold dark:text-white">
User Management
</h3>
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" class="px-6 py-3">Username</th>
<th scope="col" class="px-6 py-3">User Type</th>
<th scope="col" class="px-6 py-3">Actions</th>
</tr>
</thead>
<tbody>
{% for user_profile in all_user_profiles %}
<tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700">
<td class="px-6 py-4">{{ user_profile.user.username }}</td>
<td class="px-6 py-4">
{% if user_profile.is_superuser %}
Superuser
{% elif user_profile.user_type == 1 %}
Admin
{% elif user_profile.user_type == 2 %}
ML Engineer
{% elif user_profile.user_type == 3 %}
Accountant
{% else %}
User
{% endif %}
</td>
<td class="px-6 py-4">
<form action="{% url 'change_user_type' user_profile.user.id %}" method="post">
{% csrf_token %}
<select name="user_type">
<option value="0">User</option>
<option value="1">Admin</option>
<option value="2">ML Engineer</option>
<option value="3">Accountant</option>
</select>
<button type="submit" class="p-2 bg-blue-500 text-white rounded-md hover:bg-blue-600">
Change User Type
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% endif %} {% comment %} Admin page functionality end {% endcomment %}
</div>
</div>
{% endblock content %}
{% block scripts %}
<script>
function showModal(predictions, action) {
var predictionList = document.getElementById('predictionList');
predictionList.innerHTML = '';
// Split the predictions string into an array
var predictionsArray = predictions.split(', ');
// Iterate over the predictionsArray and create list items
predictionsArray.forEach(function(prediction) {
var li = document.createElement('li');
li.innerHTML = prediction;
li.className = 'bg-gray-100 dark:bg-gray-700 px-4 py-2 rounded-md';
predictionList.appendChild(li);
});
document.getElementById('myModal').classList.remove('hidden');
}
function closeModal() {
document.getElementById('myModal').classList.add('hidden');
}
</script>
{% endblock scripts %}
from django.urls import path
from .views import InstrumentDetectionView, index, users, maintenance, handler404, handler500, terms_conditions, privacy_policy, handling_music_file, pricing, generate_pdf, admin_table
from .views import InstrumentDetectionView, ModelPerformanceView, index, log_fileupload, users, maintenance, \
handler404, handler500, terms_conditions, privacy_policy, pricing, generate_pdf, admin_table,\
change_user_type, submit_feedback
from .payments import create_payment, execute_payment, payment_cancelled, payment_success
from django.contrib.auth import views as auth_views
......@@ -18,19 +20,21 @@ urlpatterns = [
path('terms_conditions/', terms_conditions, name='terms_conditions'),
path('pricay_policy/', privacy_policy, name='privacy_policy'),
path('pricing/', pricing, name='pricing'),
path('uploading_file/', handling_music_file, name='uploading_file'),
path('submit_feedback/', submit_feedback, name='submit_feedback'),
path('generate_pdf/', generate_pdf, name='generate_pdf'),
path('pricing/', pricing, name='pricing'),
path('generate_pdf/', generate_pdf, name='generate_pdf'),
path('admin_table/', admin_table, name='admin_table'),
path('instrument_detection/', InstrumentDetectionView.as_view(), name='instrument_detection'),
path('model_performance/', ModelPerformanceView.as_view(), name='model_performance'),
path('password_change/', auth_views.PasswordChangeView.as_view(template_name='password_change_form.html'), name='password_change'),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(template_name='password_change_done.html'), name='password_change_done'),
# path('user_logout/', auth_views.LogoutView.as_view(next_page='index'), name='user_logout'),
path('payment/create/', create_payment, name='create_payment'),
path('payment/execute/', execute_payment, name='execute_payment'),
path('payment/cancel/', payment_cancelled, name='payment_cancelled'),
path('payment_success/', payment_success, name='success'),
# Logging
path('log_fileupload', log_fileupload, name='log_fileupload'),
# Admin
path('change_user_type/<int:user_id>/', change_user_type, name='change_user_type'),
path('admin_table/', admin_table, name='admin_table'),
# Authentication
path('login/', CustomLoginView.as_view(), name='login'),
......@@ -42,4 +46,5 @@ urlpatterns = [
path('payment/execute/', execute_payment, name='execute_payment'),
path('payment/cancel/', payment_cancelled, name='payment_cancelled'),
path('payment_success/', payment_success, name='success')
]
......@@ -4,7 +4,7 @@ from django.contrib.auth.models import User
from django.contrib import messages
from django.http import HttpResponse
from django.utils import timezone
from django.shortcuts import render, redirect
from django.shortcuts import render, redirect, get_object_or_404
from django.template import RequestContext
import logging
from reportlab.pdfgen import canvas
......@@ -12,7 +12,7 @@ import json
from datetime import datetime
from .forms import InstrumentDetectionForm
from .models import Log, Action, User, UserTokenCount
from .models import Log, Action, User, UserTokenCount, Profile
from django.http import JsonResponse
from django.db import connection
......@@ -30,38 +30,71 @@ from django.views import generic
from .models import Profile
from .forms import UserRegisterForm, LoginAuthenticationForm
from django.contrib.auth.views import LoginView
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.mixins import UserPassesTestMixin
from django.views.generic import TemplateView
import re
logger = logging.getLogger(__name__)
def get_log_data(action, status='success', file=None, description=None):
def get_log_data(user, action, status='success', file=None, description=None, feedback=None):
log_data = {
'action': action.value,
'username': user.username,
'action': action.value.format(username=user.username),
'status': status,
'file': file,
'description': description,
'feedback': feedback, # Add the feedback field
}
return log_data
def create_log(user, log_data):
Log.objects.create(user=user, log=log_data)
Log.objects.create(user=user, log=log_data, feedback=log_data.get('feedback'))
def handling_music_file(request):
@csrf_exempt
def log_fileupload(request):
if request.method == 'POST':
if 'audio_file' in request.FILES:
log_data = {
'action': 'File uploaded',
'file': request.FILES['audio_file'].name,
}
log_data = get_log_data(Action.UPLOAD_FILE, 'success', file=request.FILES['audio_file'].name)
create_log(request.user if request.user.is_authenticated else None, log_data)
return HttpResponse('File uploaded successfully!',log_data)
log_data = get_log_data(Action.invalid_file, 'error')
create_log(None, log_data)
return HttpResponse('File invalid',log_data)
data = json.loads(request.body)
status = data.get('status')
file = data.get('file')
if request.user.is_authenticated:
log_data = get_log_data(request.user, Action.UPLOAD_FILE, status, file)
create_log(request.user, log_data)
return JsonResponse({'message': 'Log created successfully'}, status=201)
return JsonResponse({'error': 'Invalid request'}, status=400)
def submit_feedback(request):
if request.method == 'POST' and request.user.is_authenticated:
prediction = request.POST.get('prediction')
liked = request.POST.get('feedback') == 'true'
file_name = request.POST.get('file_name') # Get the filename from the form data
# Create log data using the get_log_data function
log_data = get_log_data(
user=request.user,
action=Action.FEEDBACK_SUBMITTED,
status='success',
file=file_name, # Use the filename obtained from the form
description=prediction,
feedback=liked
)
# Create the Log entry using the create_log function
create_log(request.user, log_data)
return redirect('index')
return redirect('index')
def admin_table(request):
if request.user.is_authenticated:
if request.user.profile.user_type != 0 or request.user.is_superuser:
# Execute the query and fetch all rows
query = """SELECT date, user, log FROM myapp_log ORDER BY date DESC"""
query = """SELECT date, log, user_id, feedback FROM myapp_log ORDER BY date DESC"""
with connection.cursor() as cursor:
cursor.execute(query)
rows = cursor.fetchall()
......@@ -70,21 +103,30 @@ def admin_table(request):
data = []
for row in rows:
# Parse the JSON string into a dictionary
log = json.loads(row[2])
# Create a dictionary with the date, user, and JSON fields
log = json.loads(row[1])
# Get the user object based on the user_id
user_id = row[2]
# Get the feedback value
feedback = row[3]
# Create a dictionary with the date, user, JSON fields, and feedback
date = row[0].strftime('%Y-%m-%d %H:%M:%S')
entry = {'date': date, 'user': row[1], 'file': log['file'], 'action': log['action'], 'status': log['status']}
entry = {'date': date, 'user': user_id, 'file': log['file'], 'action': log['action'], 'status': log['status'],
'description': log['description'], 'feedback': feedback}
data.append(entry)
# Return the data as a JSON response
return JsonResponse({'data': data}, safe=False)
else:
messages.info(request, 'Must be logged in as a non-basic user to access this page.')
return redirect('index')
else:
messages.info(request, 'Must be logged in as a non-basic user to access this page.')
return redirect('login')
def user_table(request):
# Execute the query and fetch all rows
query = """SELECT date, user, log FROM myapp_log ORDER BY date DESC"""
if request.user.is_authenticated:
user_id = request.user.id
# Only display user logs code below
# query = """SELECT date, user, log FROM myapp_log WHERE user = '{}' ORDER BY date DESC""".format(request.user)
query = """SELECT date, log, user_id, feedback FROM myapp_log WHERE user_id = {} ORDER BY date DESC""".format(user_id)
with connection.cursor() as cursor:
cursor.execute(query)
rows = cursor.fetchall()
......@@ -93,43 +135,54 @@ def user_table(request):
data = []
for row in rows:
# Parse the JSON string into a dictionary
log = json.loads(row[2])
# Create a dictionary with the date, user, and JSON fields
log = json.loads(row[1])
# Get the user object based on the user_id
user_id = row[2]
# Get the feedback value
feedback = row[3]
# Create a dictionary with the date, user, JSON fields, and feedback
date = row[0].strftime('%Y-%m-%d %H:%M:%S')
entry = {'date': date, 'user': row[1], 'file': log['file'], 'action': log['action'], 'status': log['status']}
entry = {'date': date, 'user': user_id, 'file': log['file'], 'action': log['action'], 'status': log['status'],
'description': log['description'], 'feedback': feedback}
data.append(entry)
# Return the data as a JSON response
return JsonResponse({'data': data}, safe=False)
else:
messages.info(request, 'Must be logged in as a user to access this page.')
return redirect('login')
def index(request):
# Initialize default context
context = {'form': InstrumentDetectionForm(),
'predictions': [],
'file_name': None
}
context = {'form': InstrumentDetectionForm(), 'predictions': [], 'file_name': None}
# Handle authenticated users
if request.user.is_authenticated:
token_count = UserTokenCount.objects.get(user=request.user).token_count
context['token_count'] = token_count
if request.method == 'POST':
form = InstrumentDetectionForm(request.POST, request.FILES)
if form.is_valid() and 'audio_file' in request.FILES:
uploaded_file = request.FILES['audio_file']
context['file_name'] = uploaded_file.name
# Make a request to the InstrumentDetectionView to get the predictions
view = InstrumentDetectionView().as_view()
response = view(request)
# Ensure there's a response and it contains predictions before updating context
if response and hasattr(response, 'data') and 'predictions' in response.data:
context['predictions'] = response.data['predictions']
if request.user.is_authenticated:
feedback = request.POST.get('feedback') # Get the user's feedback from the form
predictions_string = ', '.join(response.data['predictions'])
log_data = get_log_data(request.user, Action.RUN_ALGORITHM, 'success', file=uploaded_file.name,
description=predictions_string, feedback=feedback)
create_log(request.user, log_data)
else:
context['form'] = form
# For GET requests or if form is not valid, render the page with the default or updated context
return render(request, 'index1.html', context)
# Handle unauthenticated users
else:
if request.method == 'POST':
# Assuming you want to do something specific with the file if it's uploaded
......@@ -137,8 +190,11 @@ def index(request):
if uploaded_file:
# Process the uploaded file as needed
pass
# For now, just render the main page again, potentially after handling the uploaded file
# For GET requests or if POST doesn't involve a file, just show the main page
# For GET requests or if form is not valid, render the page with the default or updated context
if request.user.is_authenticated:
return render(request, 'index1.html', context)
else:
return render(request, 'index2.html')
......@@ -146,24 +202,34 @@ def index(request):
def users(request):
if request.user.is_authenticated:
# Make a request to the admin_table view to get the data
context = {}
data_admin = admin_table(request)
data_user = user_table(request)
admin_dict = json.loads(data_admin.content)
user_dict = json.loads(data_user.content)
token_count = UserTokenCount.objects.get(user=request.user).token_count
user_profile = request.user.profile
user = request.user
all_user_profiles = Profile.objects.all() # Retrieve all Profile objects
# Pass the data as a context variable to the template
# !!! ADMIN DATA ONLY DISPLAYED AND GET IF USER IS ADMIN !!!
if request.user.profile.user_type != 0 or request.user.is_superuser:
data_admin = admin_table(request)
admin_dict = json.loads(data_admin.content)
context['admin_data'] = admin_dict['data']
context['user_data'] = user_dict['data']
context['token_count'] = token_count
context['user_profile'] = user_profile
context['user'] = user
context['all_user_profiles'] = all_user_profiles # Add all_user_profiles to the context
return render(request, 'user_page.html', context)
else:
messages.info(request, 'Must be logged in as a user to access this page.')
return redirect('login')
def handler404(request, *args, **kwargs):
response = render(request, '404.html', {})
......@@ -178,54 +244,34 @@ def handler500(request, *args, **kwargs):
def maintenance(request):
return render(request, 'maintenance.html')
# def user_login(request):
# if request.method == 'POST':
# form = LoginForm(request.POST)
# if form.is_valid():
# username = form.cleaned_data.get('username')
# password = form.cleaned_data.get('password')
# user = authenticate(request, username=username, password=password) # Passing request along with username and password
# if user:
# login(request, user=user) # Passing request along with user
# return redirect('users')
# else:
# messages.error(request, 'Invalid username or password.')
# else:
# pass
# else:
# form = LoginForm()
# return render(request, 'login.html', {'form': form})
# def register(request):
# if request.method == 'POST':
# form = CustomRegistrationForm(request.POST)
# if form.is_valid():
# form.save()
# return redirect('user_login')
# else:
# form = CustomRegistrationForm()
# return render(request, 'register.html', {'form': form})
# def user_logout(request):
# logout(request)
# return redirect('user_login')
# Authentication
class RegisterView(generic.CreateView):
form_class = UserRegisterForm
success_url = reverse_lazy('login')
success_url = reverse_lazy('index')
template_name = 'registration/register.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
messages.info(request, 'You are already logged in.')
return redirect('index')
return super().dispatch(request, *args, **kwargs)
def form_valid(self, form):
response = super().form_valid(form)
Profile.objects.create(user=self.object, user_type=0) # Default user type as Basic User
user = self.object # Grab the user instance
# Ensure the user is active; this line might be redundant if you're sure users are active by default
user.is_active = True
user.save()
# Check if the Profile exists, and if not, create it
if not Profile.objects.filter(user=user).exists():
Profile.objects.create(user=user, user_type=0) # Default user type as Basic User
# Log the user in
login(self.request, user)
return response
......@@ -233,6 +279,23 @@ class CustomLoginView(LoginView):
authentication_form = LoginAuthenticationForm
template_name = 'registration/login.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
messages.info(request, 'You are already logged in.')
return redirect('index')
return super().dispatch(request, *args, **kwargs)
def form_valid(self, form):
# Create log if user is authenticated
login(self.request, form.get_user())
log_data = get_log_data(form.get_user(), Action.LOGIN, 'success')
create_log(form.get_user(), log_data)
return super().form_valid(form)
def terms_conditions(request):
return render(request, 'terms_conditions.html')
......@@ -257,7 +320,25 @@ def generate_pdf(request):
# Running the audio file through the model
class InstrumentDetectionView(APIView):
def dispatch(self, request, *args, **kwargs):
user_token_count = UserTokenCount.objects.get(user=request.user)
if request.user.is_anonymous:
messages.info(request, 'Must be logged in as a user to access this page.')
return redirect('login')
elif user_token_count.token_count < 1:
messages.info(request, 'You do not have enough tokens to make a prediction.')
return redirect('pricing')
else: return super().dispatch(request, *args, **kwargs)
def post(self, request):
# Get the user's token count
user_token_count = UserTokenCount.objects.get(user=request.user)
# Decrease the user's token count by one
user_token_count.token_count -= 1
user_token_count.save()
serializer = InstrumentDetectionSerializer(data=request.data)
if serializer.is_valid():
audio_file = serializer.validated_data['audio_file']
......@@ -288,26 +369,84 @@ class InstrumentDetectionView(APIView):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def convert_to_percentages(self, predictions):
# Assuming predictions is a list of lists
percentage_predictions = []
for prediction in predictions:
total = sum(prediction)
# Convert each number to a percentage of the total, rounded to 2 decimal places
percentages = [round((number / total) * 100, 2) for number in prediction]
percentage_predictions.append(percentages)
return percentage_predictions
def format_predictions(self, predictions):
instruments = ['Guitar', 'Drum', 'Violin', 'Piano']
formatted_predictions = []
instrument_windows = {instrument: [] for instrument in instruments}
for window_index, prediction in enumerate(predictions, start=1):
formatted_window = f"<strong>Window {window_index}</strong><br>"
formatted_scores = "<br>".join([f"{instruments[i]} - {score:.2f}" for i, score in enumerate(prediction)])
formatted_predictions.append(f"{formatted_window}{formatted_scores}")
highest_score_index = prediction.index(max(prediction))
highest_score_instrument = instruments[highest_score_index]
instrument_windows[highest_score_instrument].append(window_index)
formatted_predictions = []
for instrument, windows in instrument_windows.items():
if windows:
window_list = ', '.join(map(str, windows))
formatted_predictions.append(f"{instrument} - Windows: {window_list}")
return formatted_predictions
class ModelPerformanceView(UserPassesTestMixin, TemplateView):
template_name = 'model_performance.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_anonymous:
messages.info(request, 'Must be logged in as an ML Engineer or Admin to access this page.')
return redirect('login')
elif request.user.profile.user_type != 2 and not request.user.is_superuser:
messages.info(request, 'Must be logged in as an ML Engineer or Admin to access this page.')
return redirect('users')
else:
return super().dispatch(request, *args, **kwargs)
def test_func(self):
return self.request.user.is_authenticated and (self.request.user.is_superuser or self.request.user.profile.user_type == 2)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
metrics_url = 'http://tensorflow_serving:8501/monitoring/prometheus/metrics'
response = requests.get(metrics_url)
if response.status_code == 200:
metrics_data = response.text
# Extract metrics using regular expressions
request_count = re.search(r':tensorflow:serving:request_count{model_name="instrument_model",status="OK"} (\d+)', metrics_data)
request_latency_sum = re.search(r':tensorflow:serving:request_latency_sum{model_name="instrument_model",API="predict",entrypoint="REST"} ([\d\.e\+]+)', metrics_data)
request_latency_count = re.search(r':tensorflow:serving:request_latency_count{model_name="instrument_model",API="predict",entrypoint="REST"} (\d+)', metrics_data)
runtime_latency_sum = re.search(r':tensorflow:serving:runtime_latency_sum{model_name="instrument_model",API="Predict",runtime="TF1"} ([\d\.e\+]+)', metrics_data)
runtime_latency_count = re.search(r':tensorflow:serving:runtime_latency_count{model_name="instrument_model",API="Predict",runtime="TF1"} (\d+)', metrics_data)
model_load_latency = re.search(r':tensorflow:cc:saved_model:load_latency{model_path="/models/instrument_model/2"} (\d+)', metrics_data)
# Calculate average latencies in seconds
avg_request_latency = float(request_latency_sum.group(1)) / float(request_latency_count.group(1)) / 1e6 if request_latency_sum and request_latency_count else None
avg_runtime_latency = float(runtime_latency_sum.group(1)) / float(runtime_latency_count.group(1)) / 1e6 if runtime_latency_sum and runtime_latency_count else None
model_load_latency_seconds = float(model_load_latency.group(1)) / 1e6 if model_load_latency else None
context['metrics'] = {
'request_count': request_count.group(1) if request_count else None,
'avg_request_latency': avg_request_latency,
'avg_runtime_latency': avg_runtime_latency,
'model_load_latency': model_load_latency_seconds
}
else:
context['metrics'] = None
return context
def change_user_type(request, user_id):
if request.method == 'POST':
user_type = request.POST.get('user_type')
user_profile = get_object_or_404(Profile, user__id=user_id) # Get the user profile
user_profile.user_type = user_type
user_profile.save()
return redirect('users') # Redirect to the users page
def user_has_credits():
has_credits = False
......
No preview for this file type
No preview for this file type
......@@ -26,7 +26,7 @@ SECRET_KEY = 'django-insecure-t%k1f1!c4_9f#x@r_z_k69oz21@0eadh2qb_k3pm3=gknej9f@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["*"]
ALLOWED_HOSTS = ['*']
# Application definition
......@@ -173,10 +173,10 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
IMAGE_URL = 'static/src/images/'
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'
#PayPal API settings
PAYPAL_MODE = 'sandbox'
PAYPAL_CLIENT_ID = 'AYpHxonrFMrgnqmjii46SeNsQidn2PjJtEoIgVK0Nrda1iQFUbX28zyuMvUiJk67o_cHII3c8vCMWY-y'
PAYPAL_CLIENT_SECRET = 'EPXXK3Z7xDr4Gy_kt4OkPLbJRXd9tP62q1Dpbmj5QiwaFh7twcSUalHDRBbFRwxdX_rmHk_F6YStXa95'
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'tensorflow_serving'
scrape_interval: 5s
metrics_path: /monitoring/prometheus/metrics
static_configs:
- targets: ['tensorflow_serving:8501']
\ No newline at end of file
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
WAITFORIT_cmdname=${0##*/}
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()
{
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
fi
WAITFORIT_start_ts=$(date +%s)
while :
do
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
WAITFORIT_result=$?
else
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
WAITFORIT_result=$?
fi
if [[ $WAITFORIT_result -eq 0 ]]; then
WAITFORIT_end_ts=$(date +%s)
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
break
fi
sleep 1
done
return $WAITFORIT_result
}
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
WAITFORIT_hostport=(${1//:/ })
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
shift 1
;;
--child)
WAITFORIT_CHILD=1
shift 1
;;
-q | --quiet)
WAITFORIT_QUIET=1
shift 1
;;
-s | --strict)
WAITFORIT_STRICT=1
shift 1
;;
-h)
WAITFORIT_HOST="$2"
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
WAITFORIT_HOST="${1#*=}"
shift 1
;;
-p)
WAITFORIT_PORT="$2"
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
WAITFORIT_PORT="${1#*=}"
shift 1
;;
-t)
WAITFORIT_TIMEOUT="$2"
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
WAITFORIT_TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
WAITFORIT_CLI=("$@")
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-30}
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
# Check to see if timeout is from busybox?
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
WAITFORIT_BUSYTIMEFLAG=""
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
WAITFORIT_ISBUSY=1
# Check if busybox timeout uses -t flag
# (recent Alpine versions don't support -t anymore)
if timeout &>/dev/stdout | grep -q -e '-t '; then
WAITFORIT_BUSYTIMEFLAG="-t"
fi
else
WAITFORIT_ISBUSY=0
fi
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
wait_for
WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for
WAITFORIT_RESULT=$?
fi
fi
if [[ $WAITFORIT_CLI != "" ]]; then
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT
fi
\ No newline at end of file