From bfdc5453c4e6675cc71ad9509e32dafaf1e66564 Mon Sep 17 00:00:00 2001 From: ayobi Date: Thu, 7 Mar 2024 22:11:09 -0500 Subject: [PATCH 01/13] add barcodes to existing kits --- microsetta_admin/server.py | 129 ++++++++++++++ .../templates/add_barcode_to_kit.html | 160 ++++++++++++++++++ microsetta_admin/templates/sitebase.html | 8 +- microsetta_admin/tests/test_routes.py | 33 ++++ 4 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 microsetta_admin/templates/add_barcode_to_kit.html diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index e6993e9..3da99e8 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -1,3 +1,5 @@ +import csv +import tempfile import jwt from flask import render_template, Flask, request, session, send_file import secrets @@ -556,6 +558,133 @@ def new_kits(): mimetype='text/csv') +@app.route('/add_barcode_to_kit', methods=['GET', 'POST']) +def new_barcode_kit(): + + if request.method == 'GET': + return render_template('add_barcode_to_kit.html', + **build_login_variables()) + + elif request.method == 'POST': + project_id = int(request.form['project_id']) + num_kits = int(request.form['num_kits']) + num_samples = int(request.form['num_samples']) + user_barcode = request.form['user_barcode'] + kit_id = request.form['kit_id'] + generate_barcode_payload = {'number_of_kits': num_kits, + 'number_of_samples': num_samples} + + status, result = APIRequest.post( + '/api/admin/create/barcodes', + json=generate_barcode_payload) + if status == 500: + title = result[5:result.index('\n\n\n')].strip() + raise Exception(f"500 error: {title}") + + for key, file in request.files.items(): + if key == 'upload_csv': + uploaded_csv_contents = file.read().decode('utf-8') + + # If the user is generating more than one barcode + total_barcodes = num_kits * num_samples + if total_barcodes > 1: + # Write the barcodes to a temporary CSV file + with tempfile.NamedTemporaryFile(mode='w', + delete=False, + newline='') as file: + writer = csv.writer(file) + writer.writerow(['Kit IDs', 'Barcode']) + + # To build the barcode, kit id pairs + barcode_pairs = [] + + if uploaded_csv_contents: + uploaded_csv_reader = csv.reader(io.StringIO + (uploaded_csv_contents), + skipinitialspace=True) + check_columns = next(uploaded_csv_reader, None) + + # Check to see if the uploaded csv has only one column + # If so, we know they're just providing kit ids + if len(check_columns) == 1: + for row, barcode in zip(uploaded_csv_reader, result): + row.append(barcode) + writer.writerow(row) + barcode_pairs.append([row[0], row[-1]]) + else: + # If the uploaded csv has two columns, + # we know they're providing barcode, kit id pairs + # We can just use the uploaded csv as is + for row in uploaded_csv_reader: + barcode_pairs.append(row) + + else: + for barcode in result: + writer.writerow([kit_id, barcode]) + barcode_pairs.append([kit_id, barcode]) + + filename = file.name + + csv_payload = { + "barcodes": barcode_pairs, + "kit_id": uploaded_csv_contents, + "project_id": project_id + } + + status, results = APIRequest.post('/api/admin/insert_barcodes', + json=csv_payload) + + if status == 500: + title = results[5:results.index('\n\n\n')].strip() + raise Exception(f"500 error: {title}") + + return send_file(filename, + as_attachment=True, + download_name='barcodes.csv') + + elif user_barcode: + # If the user is providing a single barcode + user_barcode_payload = { + "barcodes": [[kit_id, user_barcode]], + "kit_id": kit_id, + "project_id": project_id + } + + status, results = APIRequest.post('/api/admin/insert_barcodes', + json=user_barcode_payload) + + # Provide a 500 error if the API request fails + # Most likely due to duplicate barcode + if status == 500: + title = results[5:results.index('\n\n\n')].strip() + raise Exception(f"500 error: {title}") + + return render_template('add_barcode_to_kit.html', + barcodes=[user_barcode], + kit_id=kit_id, + **build_login_variables()) + else: + # If the user is only generating a single barcode + single_barcode_generated_payload = { + "barcodes": [[kit_id, result[0]]], + "kit_id": kit_id, + "project_id": project_id + } + + status, results = \ + APIRequest.post('/api/admin/insert_barcodes', + json=single_barcode_generated_payload) + + if status == 500: + title = results[5:results.index('\n\n\n')].strip() + raise Exception(f"500 error: {title}") + + return render_template('add_barcode_to_kit.html', + barcodes=result, + kit_id=kit_id, + **build_login_variables()) + + def _check_sample_status(extended_barcode_info): warning = None in_microsetta_project = any( diff --git a/microsetta_admin/templates/add_barcode_to_kit.html b/microsetta_admin/templates/add_barcode_to_kit.html new file mode 100644 index 0000000..a86274b --- /dev/null +++ b/microsetta_admin/templates/add_barcode_to_kit.html @@ -0,0 +1,160 @@ +{% extends "sitebase.html" %} +{% block head %} + + + + + +{% endblock %} +{% block content %} +

Add Barcode to Kit(s)

+ +
+ {% if error_message %} +

+ {{ error_message |e }} +

+ {% endif %} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ {% if barcodes %} +
    + {% for barcode in barcodes %} + You added {{ barcode }} to Kit ID {{ kit_id }}
    + {% endfor %} +
+ {% endif %} + {% if search_error %} +

+ {{search_error |e}} +

+ {% endif %} + + +
+
+{% endblock %} diff --git a/microsetta_admin/templates/sitebase.html b/microsetta_admin/templates/sitebase.html index 50e24ac..38ac8bd 100644 --- a/microsetta_admin/templates/sitebase.html +++ b/microsetta_admin/templates/sitebase.html @@ -47,11 +47,17 @@

Microsetta Utilities

  • Manage Projects
  • Account Summaries
  • Create Kit
  • +
  • Add Barcode to Kit
  • Scan Barcode
  • Retrieve Metadata
  • Sample Summaries
  • Submit Daklapack Order
  • -
  • Log Out
    ({{email |e}})
  • +
  • + + Log Out ({{email |e}}) + +
  • {% else %}
  • Log In
  • {% endif %} diff --git a/microsetta_admin/tests/test_routes.py b/microsetta_admin/tests/test_routes.py index 43fed19..0cfd2ee 100644 --- a/microsetta_admin/tests/test_routes.py +++ b/microsetta_admin/tests/test_routes.py @@ -1,5 +1,7 @@ +import csv import json from copy import deepcopy +import tempfile from microsetta_admin.tests.base import TestBase @@ -354,6 +356,37 @@ def test_create_project_fail(self): self.assertEqual(response.status_code, 200) self.assertIn(b'Unable to create project.', response.data) + def test_create_insert_barcode_success(self): + self.mock_post.return_value = DummyResponse(201, {}) + + response = self.app.post('/add_barcode_to_kit', + data={'project_id': '1', + 'num_kits': '1', + 'kit_id': 'FBGBs', + 'num_samples': '1', + 'user_barcode': 'X11204416'}, + follow_redirects=True) + self.assertEqual(response.status_code, 200) + self.assertIn(b'You added X11204416 to Kit ID FBGBs', response.data) + + def test_create_insert_barcode_from_csv(self): + self.mock_post.return_value = DummyResponse(201, {}) + + with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_file: + csv_writer = csv.writer(temp_file) + csv_writer.writerow(['FBGBs']) + + with open(temp_file.name, 'rb') as f: + response = self.app.post('/add_barcode_to_kit', + data={'project_id': '1', + 'num_kits': '1', + 'kit_id': 'FBGBs', + 'num_samples': '3', + 'user_barcode': 'X11204416', + 'upload_csv': (f, 'test.csv')}, + follow_redirects=True) + self.assertEqual(response.status_code, 200) + def test_update_project_success(self): self.mock_put.return_value = DummyResponse(204, {}) self.mock_get.return_value = DummyResponse(200, self.PROJ_LIST) From 94020c2450ccd55b6b8c9e33fbdeca4aa28958ea Mon Sep 17 00:00:00 2001 From: ayobi Date: Mon, 25 Mar 2024 20:53:25 -0300 Subject: [PATCH 02/13] added user barcode for create kits --- microsetta_admin/server.py | 20 ++++++++++ microsetta_admin/templates/create_kits.html | 43 ++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index 74ae7b4..0569aea 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -518,11 +518,31 @@ def new_kits(): num_samples = int(request.form['num_samples']) prefix = request.form['prefix'] selected_project_ids = request.form.getlist('project_ids') + + barcodes = [] + + barcode_file = request.files.get('upload_csv') + + if barcode_file: + barcode_file = barcode_file.read().decode('utf-8') + barcodes = [line.split(',')[0].strip('\ufeff\r') + for line in barcode_file.split('\n') + if line.strip()] + else: + # Process text input + for i in range(1, num_samples + 1): + barcode = request.form.get(f'barcode_{i}') + if barcode: + barcodes.append(barcode) + payload = {'number_of_kits': num_kits, 'number_of_samples': num_samples, 'project_ids': selected_project_ids} + if prefix: payload['kit_id_prefix'] = prefix + if barcodes: + payload['user_barcodes'] = barcodes status, result = APIRequest.post( '/api/admin/create/kits', diff --git a/microsetta_admin/templates/create_kits.html b/microsetta_admin/templates/create_kits.html index 90ede1a..dd0a506 100644 --- a/microsetta_admin/templates/create_kits.html +++ b/microsetta_admin/templates/create_kits.html @@ -3,6 +3,10 @@ @@ -34,14 +62,14 @@

    Microsetta Create Kits

    margin: 10px; } -
    +
    {% if error_message %}

    {{ error_message |e }}

    {% endif %} -
    + @@ -80,6 +108,17 @@

    Microsetta Create Kits

    + +
    +

    Or you can add your barcodes below

    +
    +
    + + + + +
    + {{blob}} From a2f7b2db4f566043572bbcebfebad19996f8b416 Mon Sep 17 00:00:00 2001 From: ayobi Date: Fri, 21 Jun 2024 19:33:49 -0400 Subject: [PATCH 03/13] improvements per suggestions --- microsetta_admin/server.py | 208 ++++++++---------- .../templates/add_barcode_to_kit.html | 149 +++++-------- microsetta_admin/templates/create_kits.html | 83 ++----- 3 files changed, 179 insertions(+), 261 deletions(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index 0569aea..6b2ecd4 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -514,8 +514,6 @@ def new_kits(): **build_login_variables()) elif request.method == 'POST': - num_kits = int(request.form['num_kits']) - num_samples = int(request.form['num_samples']) prefix = request.form['prefix'] selected_project_ids = request.form.getlist('project_ids') @@ -528,25 +526,18 @@ def new_kits(): barcodes = [line.split(',')[0].strip('\ufeff\r') for line in barcode_file.split('\n') if line.strip()] - else: - # Process text input - for i in range(1, num_samples + 1): - barcode = request.form.get(f'barcode_{i}') - if barcode: - barcodes.append(barcode) - payload = {'number_of_kits': num_kits, - 'number_of_samples': num_samples, - 'project_ids': selected_project_ids} + payload = { + 'action': 'create' if not barcodes else 'insert', + 'project_ids': selected_project_ids + } if prefix: payload['kit_id_prefix'] = prefix if barcodes: - payload['user_barcodes'] = barcodes + payload['barcodes'] = barcodes - status, result = APIRequest.post( - '/api/admin/create/kits', - json=payload) + status, result = APIRequest.post('/api/admin/barcodes', json=payload) if status != 201: return render_template('create_kits.html', @@ -554,13 +545,11 @@ def new_kits(): projects=projects, **build_login_variables()) - # StringIO/BytesIO based off https://stackoverflow.com/a/45111660 buf = io.StringIO() payload = io.BytesIO() - # explicitly expand out the barcode detail kits = pd.DataFrame(result['created']) - for i in range(num_samples): + for i in range(len(kits.columns) - 1): kits['barcode_%d' % (i+1)] = [r['sample_barcodes'][i] for _, r in kits.iterrows()] kits.drop(columns='sample_barcodes', inplace=True) @@ -586,124 +575,117 @@ def new_barcode_kit(): **build_login_variables()) elif request.method == 'POST': - project_id = int(request.form['project_id']) - num_kits = int(request.form['num_kits']) - num_samples = int(request.form['num_samples']) - user_barcode = request.form['user_barcode'] - kit_id = request.form['kit_id'] - generate_barcode_payload = {'number_of_kits': num_kits, - 'number_of_samples': num_samples} - - status, result = APIRequest.post( - '/api/admin/create/barcodes', - json=generate_barcode_payload) - if status == 500: - title = result[5:result.index('\n\n\n')].strip() - raise Exception(f"500 error: {title}") - - for key, file in request.files.items(): - if key == 'upload_csv': - uploaded_csv_contents = file.read().decode('utf-8') - - # If the user is generating more than one barcode - total_barcodes = num_kits * num_samples - if total_barcodes > 1: - # Write the barcodes to a temporary CSV file - with tempfile.NamedTemporaryFile(mode='w', - delete=False, - newline='') as file: - writer = csv.writer(file) - writer.writerow(['Kit IDs', 'Barcode']) - - # To build the barcode, kit id pairs - barcode_pairs = [] - - if uploaded_csv_contents: - uploaded_csv_reader = csv.reader(io.StringIO - (uploaded_csv_contents), - skipinitialspace=True) - check_columns = next(uploaded_csv_reader, None) - - # Check to see if the uploaded csv has only one column - # If so, we know they're just providing kit ids - if len(check_columns) == 1: - for row, barcode in zip(uploaded_csv_reader, result): - row.append(barcode) - writer.writerow(row) - barcode_pairs.append([row[0], row[-1]]) - else: - # If the uploaded csv has two columns, - # we know they're providing barcode, kit id pairs - # We can just use the uploaded csv as is - for row in uploaded_csv_reader: - barcode_pairs.append(row) - - else: - for barcode in result: - writer.writerow([kit_id, barcode]) - barcode_pairs.append([kit_id, barcode]) + kit_ids = [] + barcodes = [] - filename = file.name + if 'kit_ids' in request.form: + kit_ids = request.form['kit_ids'] - csv_payload = { - "barcodes": barcode_pairs, - "kit_id": uploaded_csv_contents, - "project_id": project_id - } + if 'user_barcode' in request.form: + user_barcode = request.form['user_barcode'] + barcodes.append(user_barcode) - status, results = APIRequest.post('/api/admin/insert_barcodes', - json=csv_payload) + if 'generate_barcode_single' in request.form: + generate_barcode_single = request.form['generate_barcode_single'] + else: + generate_barcode_single = None + if 'generate_barcodes_multiple' in request.form: + generate_barcodes_multiple = request.form + ['generate_barcodes_multiple'] + else: + generate_barcodes_multiple = None + + if 'kit_ids' in request.files: + kit_ids_file = request.files['kit_ids'] + kit_ids_content = kit_ids_file.read().decode('utf-8-sig') + kit_ids = [row[0] for row in csv.reader(io.StringIO + (kit_ids_content), + skipinitialspace=True)] + + if 'barcodes_file' in request.files: + barcodes_file = request.files['barcodes_file'] + barcodes_content = barcodes_file.read().decode('utf-8-sig') + barcodes = [row[0] for row in csv.reader(io.StringIO + (barcodes_content), + skipinitialspace=True)] + + if generate_barcode_single or 'user_barcode' in request.form: + if user_barcode == '': + generate_barcode_payload = { + 'action': 'create', + 'kit_ids': kit_ids, + 'generate_barcode_single': generate_barcode_single + } + + status, result = APIRequest.post('/api/admin/barcodes', + json=generate_barcode_payload) if status == 500: - title = results[5:results.index('\n\n\n')].strip() + title = result[5:result.index('\n\n\n')].strip() raise Exception(f"500 error: {title}") + else: + result = barcodes - return send_file(filename, - as_attachment=True, - download_name='barcodes.csv') - - elif user_barcode: - # If the user is providing a single barcode user_barcode_payload = { - "barcodes": [[kit_id, user_barcode]], - "kit_id": kit_id, - "project_id": project_id + "action": "insert", + "barcodes": [result[0]], + "kit_ids": kit_ids } - - status, results = APIRequest.post('/api/admin/insert_barcodes', + status, results = APIRequest.post('/api/admin/barcodes', json=user_barcode_payload) - - # Provide a 500 error if the API request fails - # Most likely due to duplicate barcode if status == 500: title = results[5:results.index('\n\n\n')].strip() raise Exception(f"500 error: {title}") return render_template('add_barcode_to_kit.html', - barcodes=[user_barcode], - kit_id=kit_id, + barcodes=result, + kit_id=kit_ids, **build_login_variables()) - else: - # If the user is only generating a single barcode - single_barcode_generated_payload = { - "barcodes": [[kit_id, result[0]]], - "kit_id": kit_id, - "project_id": project_id - } - - status, results = \ - APIRequest.post('/api/admin/insert_barcodes', - json=single_barcode_generated_payload) + if generate_barcodes_multiple: + generate_barcode_payload = { + 'action': 'create', + 'kit_ids': kit_ids, + 'generate_barcodes_multiple': generate_barcodes_multiple + } + status, result = APIRequest.post('/api/admin/barcodes', + json=generate_barcode_payload) if status == 500: - title = results[5:results.index('\n\n\n')].strip() + title = result[5:result.index('\n\n\n')].strip() raise Exception(f"500 error: {title}") + barcodes = result + if len(kit_ids) != len(barcodes): + error_message = (f'The number of kit IDs ({len(kit_ids)}) ' + f'does not match the number of barcodes ' + f'({len(barcodes)}).') return render_template('add_barcode_to_kit.html', - barcodes=result, - kit_id=kit_id, + error_message=error_message, **build_login_variables()) + csv_payload = { + "action": "insert", + "barcodes": barcodes, + "kit_ids": kit_ids + } + + status, results = APIRequest.post('/api/admin/barcodes', + json=csv_payload) + if status == 500: + title = results[5:results.index('\n\n\n')].strip() + raise Exception(f"500 error: {title}") + + with tempfile.NamedTemporaryFile(mode='w', delete=False, + newline='') as file: + writer = csv.writer(file) + writer.writerow(['Kit IDs', 'Barcode']) + writer.writerows(zip(kit_ids, barcodes)) + filename = file.name + + return send_file(filename, + as_attachment=True, + download_name='barcodes.csv') + def _check_sample_status(extended_barcode_info): warning = None diff --git a/microsetta_admin/templates/add_barcode_to_kit.html b/microsetta_admin/templates/add_barcode_to_kit.html index a86274b..3d395af 100644 --- a/microsetta_admin/templates/add_barcode_to_kit.html +++ b/microsetta_admin/templates/add_barcode_to_kit.html @@ -1,59 +1,48 @@ {% extends "sitebase.html" %} {% block head %} - - {% endblock %} + {% block content %}

    Add Barcode to Kit(s)

    +{% endblock %} +{% block content %} +

    Microsetta Create Kits

    {% if error_message %}

    @@ -77,49 +64,27 @@

    Microsetta Create Kits

    - + - + - - - -
    - {% if search_error %} -

    - {{search_error |e}} -

    - {% endif %} - - -
    -

    Or you can add your barcodes below


    -
    - - - - +

    - +
    -{{blob}} {% endblock %} From c143b03d8f7c8471d6b93cd4248af23174ff4818 Mon Sep 17 00:00:00 2001 From: ayobi Date: Tue, 25 Jun 2024 14:49:42 -0400 Subject: [PATCH 04/13] fixed test --- microsetta_admin/tests/test_routes.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/microsetta_admin/tests/test_routes.py b/microsetta_admin/tests/test_routes.py index 0cfd2ee..1282317 100644 --- a/microsetta_admin/tests/test_routes.py +++ b/microsetta_admin/tests/test_routes.py @@ -360,14 +360,13 @@ def test_create_insert_barcode_success(self): self.mock_post.return_value = DummyResponse(201, {}) response = self.app.post('/add_barcode_to_kit', - data={'project_id': '1', - 'num_kits': '1', - 'kit_id': 'FBGBs', - 'num_samples': '1', - 'user_barcode': 'X11204416'}, + data={'kit_ids': 'FBGBs', + 'user_barcode': 'X64406585', + 'generate_barcode_single': 'off', + 'add_single_barcode': 'Add Barcode'}, follow_redirects=True) self.assertEqual(response.status_code, 200) - self.assertIn(b'You added X11204416 to Kit ID FBGBs', response.data) + self.assertIn(b'You added X64406585 to Kit ID FBGBs', response.data) def test_create_insert_barcode_from_csv(self): self.mock_post.return_value = DummyResponse(201, {}) @@ -378,10 +377,7 @@ def test_create_insert_barcode_from_csv(self): with open(temp_file.name, 'rb') as f: response = self.app.post('/add_barcode_to_kit', - data={'project_id': '1', - 'num_kits': '1', - 'kit_id': 'FBGBs', - 'num_samples': '3', + data={'kit_id': 'FBGBs', 'user_barcode': 'X11204416', 'upload_csv': (f, 'test.csv')}, follow_redirects=True) From 27d0c799b7a31cb50178c53861454e334c08e859 Mon Sep 17 00:00:00 2001 From: ayobi Date: Tue, 6 Aug 2024 00:48:48 -0400 Subject: [PATCH 05/13] changes per suggestions --- microsetta_admin/server.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index 6b2ecd4..0389b61 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -516,6 +516,9 @@ def new_kits(): elif request.method == 'POST': prefix = request.form['prefix'] selected_project_ids = request.form.getlist('project_ids') + num_kits = request.form['num_kits'] + num_samples = request.form['num_samples'] + generate_barcodes = request.form.get('generate_barcodes_1') barcodes = [] @@ -529,7 +532,10 @@ def new_kits(): payload = { 'action': 'create' if not barcodes else 'insert', - 'project_ids': selected_project_ids + 'project_ids': selected_project_ids, + 'num_kits': int(num_kits), + 'num_samples': int(num_samples), + 'generate_barcodes': generate_barcodes } if prefix: @@ -537,7 +543,7 @@ def new_kits(): if barcodes: payload['barcodes'] = barcodes - status, result = APIRequest.post('/api/admin/barcodes', json=payload) + status, result = APIRequest.post('/api/admin/add_barcodes', json=payload) if status != 201: return render_template('create_kits.html', @@ -618,7 +624,7 @@ def new_barcode_kit(): 'generate_barcode_single': generate_barcode_single } - status, result = APIRequest.post('/api/admin/barcodes', + status, result = APIRequest.post('/api/admin/add_barcodes', json=generate_barcode_payload) if status == 500: title = result[5:result.index('\n\n\n')].strip() @@ -631,7 +637,7 @@ def new_barcode_kit(): "barcodes": [result[0]], "kit_ids": kit_ids } - status, results = APIRequest.post('/api/admin/barcodes', + status, results = APIRequest.post('/api/admin/add_barcodes', json=user_barcode_payload) if status == 500: title = results[5:results.index('\n\n\n')].strip() @@ -648,7 +654,7 @@ def new_barcode_kit(): 'kit_ids': kit_ids, 'generate_barcodes_multiple': generate_barcodes_multiple } - status, result = APIRequest.post('/api/admin/barcodes', + status, result = APIRequest.post('/api/admin/add_barcodes', json=generate_barcode_payload) if status == 500: title = result[5:result.index('\n\n\n')].strip() @@ -669,7 +675,7 @@ def new_barcode_kit(): "kit_ids": kit_ids } - status, results = APIRequest.post('/api/admin/barcodes', + status, results = APIRequest.post('/api/admin/add_barcodes', json=csv_payload) if status == 500: title = results[5:results.index('\n\n\n')].strip() From 1e9c6e015175eb9489676c2be986508b9f9c3725 Mon Sep 17 00:00:00 2001 From: ayobi Date: Tue, 6 Aug 2024 12:12:08 -0400 Subject: [PATCH 06/13] lint --- microsetta_admin/server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index 0389b61..88468ca 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -543,7 +543,8 @@ def new_kits(): if barcodes: payload['barcodes'] = barcodes - status, result = APIRequest.post('/api/admin/add_barcodes', json=payload) + status, result = APIRequest.post('/api/admin/add_barcodes', + json=payload) if status != 201: return render_template('create_kits.html', From 8d448fbf646c4104b8c26282e33efb2f9b54495a Mon Sep 17 00:00:00 2001 From: ayobi Date: Wed, 7 Aug 2024 12:49:03 -0400 Subject: [PATCH 07/13] fixed post for create/kits --- microsetta_admin/server.py | 20 ++++++++++++-------- microsetta_admin/templates/create_kits.html | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index 88468ca..515b172 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -516,8 +516,8 @@ def new_kits(): elif request.method == 'POST': prefix = request.form['prefix'] selected_project_ids = request.form.getlist('project_ids') - num_kits = request.form['num_kits'] - num_samples = request.form['num_samples'] + num_kits = request.form['number_of_kits'] + num_samples = request.form['number_of_samples'] generate_barcodes = request.form.get('generate_barcodes_1') barcodes = [] @@ -533,8 +533,8 @@ def new_kits(): payload = { 'action': 'create' if not barcodes else 'insert', 'project_ids': selected_project_ids, - 'num_kits': int(num_kits), - 'num_samples': int(num_samples), + 'number_of_kits': int(num_kits), + 'number_of_samples': int(num_samples), 'generate_barcodes': generate_barcodes } @@ -543,7 +543,7 @@ def new_kits(): if barcodes: payload['barcodes'] = barcodes - status, result = APIRequest.post('/api/admin/add_barcodes', + status, result = APIRequest.post('/api/admin/create/kits', json=payload) if status != 201: @@ -556,9 +556,13 @@ def new_kits(): payload = io.BytesIO() kits = pd.DataFrame(result['created']) - for i in range(len(kits.columns) - 1): - kits['barcode_%d' % (i+1)] = [r['sample_barcodes'][i] - for _, r in kits.iterrows()] + + for kit_index, row in kits.iterrows(): + sample_barcodes = row['sample_barcodes'] + for sample_index in range(len(sample_barcodes)): + kits.at[kit_index, f'barcode_{sample_index + 1}'] = \ + sample_barcodes[sample_index] + kits.drop(columns='sample_barcodes', inplace=True) kits.to_csv(buf, sep=',', index=False, header=True) diff --git a/microsetta_admin/templates/create_kits.html b/microsetta_admin/templates/create_kits.html index dac441b..d3ef36e 100644 --- a/microsetta_admin/templates/create_kits.html +++ b/microsetta_admin/templates/create_kits.html @@ -5,8 +5,8 @@ $(document).ready(function(){ $("form[name='kit_form']").validate({ rules: { - num_kits: "required", - num_samples: "required", + number_of_kits: "required", + number_of_samples: "required", project_ids: "required", submitHandler: function (form) { form.submit(); @@ -14,9 +14,9 @@ } }); - $("#num_samples, #num_kits").on("change", function() { - var numSamples = $("#num_samples").val(); - var numKits = $("#num_kits").val(); + $("#number_of_samples, #number_of_kits").on("change", function() { + var numSamples = $("#number_of_samples").val(); + var numKits = $("#number_of_kits").val(); var totalSamples = numSamples * numKits; var newSections = ""; for (var i = 1; i <= totalSamples; i++) { @@ -32,7 +32,7 @@ $("#sample_sections").html(newSections); }); - $("#num_samples").val(1).trigger('change'); // Default value to 1 on page load + $("#number_of_samples").val(1).trigger('change'); // Default value to 1 on page load });
    {% if error_message %} -

    +

    {{ error_message |e }}

    {% endif %} @@ -132,7 +139,7 @@

    Add Barcode to Kit(s)

    {% if barcodes %} -
      +
        {% for barcode in barcodes %} You added {{ barcode }} to Kit ID {{ kit_id }}
        {% endfor %} diff --git a/microsetta_admin/templates/create_kits.html b/microsetta_admin/templates/create_kits.html index 239d97c..606fecb 100644 --- a/microsetta_admin/templates/create_kits.html +++ b/microsetta_admin/templates/create_kits.html @@ -6,11 +6,19 @@ $("form[name='kit_form']").validate({ rules: { number_of_kits: "required", - number_of_samples: "required", + number_of_samples: { + required: true, + max: 25 + }, project_ids: "required", submitHandler: function (form) { form.submit(); } + }, + messages: { + number_of_samples: { + max: "You cannot add more than 25 samples per kit." + } } }); @@ -63,7 +71,8 @@

        Sample ${j}

        toggleDisableOptions(); }); - $("#number_of_samples").val(1).trigger('change'); // Default value to 1 on page load + $("#number_of_samples").val(1).trigger('change'); + $("#number_of_kits").val(1).trigger('change'); }); +

        Add Barcode(s) to Kit(s)

        {% if error_message %}

        @@ -121,20 +105,53 @@

        Add Barcode to Kit(s)

        @@ -147,24 +164,56 @@

        Add Barcode to Kit(s)

        {% endif %} diff --git a/microsetta_admin/templates/create_kits.html b/microsetta_admin/templates/create_kits.html index 606fecb..becbfeb 100644 --- a/microsetta_admin/templates/create_kits.html +++ b/microsetta_admin/templates/create_kits.html @@ -6,25 +6,17 @@ $("form[name='kit_form']").validate({ rules: { number_of_kits: "required", - number_of_samples: { - required: true, - max: 25 - }, + number_of_samples: "required", project_ids: "required", submitHandler: function (form) { form.submit(); } - }, - messages: { - number_of_samples: { - max: "You cannot add more than 25 samples per kit." - } } }); function adjustContainerHeight() { var numSamples = $("#number_of_samples").val(); - var containerHeight = 400 + (numSamples * 150); + var containerHeight = 400 + (numSamples * 190); $("#kit_container").css("height", containerHeight + "px"); } @@ -59,10 +51,12 @@ newSections += `

        Sample ${j}

        Upload CSV with ${numKits} row(s) of barcode(s) for this sample:

        - + -
        - +
        +
        -- OR --
        +
        +
        `; } diff --git a/microsetta_admin/tests/test_routes.py b/microsetta_admin/tests/test_routes.py index 1c385ab..44c7574 100644 --- a/microsetta_admin/tests/test_routes.py +++ b/microsetta_admin/tests/test_routes.py @@ -401,53 +401,6 @@ def test_create_project_fail(self): self.assertEqual(response.status_code, 200) self.assertIn(b'Unable to create project.', response.data) - def test_insert_barcode_success(self): - self.mock_post.return_value = DummyResponse(201, {}) - - response = self.app.post('/add_barcode_to_kit', - data={'kit_id': 'test', - 'user_barcode': 'X64444485'}, - follow_redirects=True) - self.assertEqual(response.status_code, 201) - - def test_insert_barcode_from_csv(self): - self.mock_post.return_value = DummyResponse(201, {}) - - with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_file: - csv_writer = csv.writer(temp_file) - csv_writer.writerow(['X11204416']) - - with open(temp_file.name, 'rb') as f: - response = self.app.post('/add_barcode_to_kit', - data={'kit_ids': 'test', - 'barcodes_file': (f, 'test.csv')}, - follow_redirects=True) - self.assertEqual(response.status_code, 400) - - def test_insert_barcode_fail_kit_id(self): - self.mock_post.return_value = DummyResponse(404, {}) - - response = self.app.post('/add_barcode_to_kit', - data={'kit_ids': 'alpha9', - 'generate_barcode_single': 'on'}, - follow_redirects=True) - self.assertEqual(response.status_code, 404) - - def test_insert_barcode_fail_csv_mismatch(self): - self.mock_post.return_value = DummyResponse(201, {}) - - with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_file: - csv_writer = csv.writer(temp_file) - csv_writer.writerow(['X11204415']) - csv_writer.writerow(['X11204416']) - - with open(temp_file.name, 'rb') as f: - response = self.app.post('/add_barcode_to_kit', - data={'kit_ids': 'test', - 'barcodes_file': (f, 'test.csv')}, - follow_redirects=True) - self.assertEqual(response.status_code, 400) - def test_update_project_success(self): self.mock_put.return_value = DummyResponse(204, {}) self.mock_get.return_value = DummyResponse(200, self.PROJ_LIST) From 130d4c99c84db5213bb77314793d2842d93585a3 Mon Sep 17 00:00:00 2001 From: Cassidy Symons Date: Sun, 15 Dec 2024 20:44:19 -0800 Subject: [PATCH 13/13] Lint --- microsetta_admin/tests/test_routes.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/microsetta_admin/tests/test_routes.py b/microsetta_admin/tests/test_routes.py index 44c7574..14cc30b 100644 --- a/microsetta_admin/tests/test_routes.py +++ b/microsetta_admin/tests/test_routes.py @@ -1,7 +1,5 @@ -import csv import json from copy import deepcopy -import tempfile from microsetta_admin.tests.base import TestBase