From ccbc6017f39c3f01646ef9e161a168a6394278d5 Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Thu, 28 Mar 2024 10:01:34 -0400 Subject: [PATCH 01/20] added schema testing with django models --- ...django_views.yaml => test_django_api.yaml} | 10 +- pycodestyle.cfg | 1 + requirements.txt | 2 +- src/evagram/database/dataset.json | 24 +- src/evagram/database/input_tool.py | 238 ---------------- .../backend/api/migrations/0001_initial.py | 47 ++-- src/evagram/website/backend/api/models.py | 6 +- .../website/backend/api/test_models.py | 74 +++++ .../backend/api/{tests.py => test_views.py} | 1 - .../website/backend/backend/settings.py | 16 +- .../test_database.yaml => test_database.yaml | 0 tests/test_input_tool.py | 261 ------------------ 12 files changed, 120 insertions(+), 560 deletions(-) rename .github/workflows/{test_django_views.yaml => test_django_api.yaml} (75%) delete mode 100644 src/evagram/database/input_tool.py create mode 100644 src/evagram/website/backend/api/test_models.py rename src/evagram/website/backend/api/{tests.py => test_views.py} (99%) rename .github/workflows/test_database.yaml => test_database.yaml (100%) delete mode 100644 tests/test_input_tool.py diff --git a/.github/workflows/test_django_views.yaml b/.github/workflows/test_django_api.yaml similarity index 75% rename from .github/workflows/test_django_views.yaml rename to .github/workflows/test_django_api.yaml index 59e802f..feafb42 100644 --- a/.github/workflows/test_django_views.yaml +++ b/.github/workflows/test_django_api.yaml @@ -1,4 +1,4 @@ -name: Test Django API Views +name: Test Database Tool on: pull_request: types: @@ -35,11 +35,5 @@ jobs: python -m pip install --upgrade pip pip install . -r requirements.txt - - name: Run Test Django API Views - env: - DB_HOST: ${{secrets.DB_HOST}} - DB_PORT: ${{secrets.DB_PORT}} - DB_NAME: ${{secrets.DB_NAME}} - DB_USER: ${{secrets.DB_USER}} - DB_PASSWORD: ${{secrets.DB_PASSWORD}} + - name: Test Django API App run: python ./src/evagram/website/backend/manage.py test api diff --git a/pycodestyle.cfg b/pycodestyle.cfg index 722fa7d..db4875f 100644 --- a/pycodestyle.cfg +++ b/pycodestyle.cfg @@ -9,3 +9,4 @@ max-line-length = 100 indent-size = 4 statistics = True ignore = W503, W504 +exclude = __pycache__, src/evagram/website/backend/api/migrations diff --git a/requirements.txt b/requirements.txt index 17ca94a..c9eb4d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ autopep8==2.0.4 Django==4.2.10 django-cors-headers==4.3.1 djangorestframework==3.14.0 -psycopg2==2.9.9 +psycopg2-binary==2.9.9 pycodestyle>=2.8.0 python-dotenv==1.0.0 pytz==2023.3.post1 diff --git a/src/evagram/database/dataset.json b/src/evagram/database/dataset.json index 455c2a2..2bfef9c 100644 --- a/src/evagram/database/dataset.json +++ b/src/evagram/database/dataset.json @@ -61,38 +61,38 @@ { "plot_id": 121, "plot_file": "brightnessTemperature_4_effectiveerror-vs-gsifinalerror.pkl", - "experiment_id": 12 + "experiment_id": 12, + "observation_name": "amsua_aqua" }, { "plot_id": 322, "plot_file": "brightnessTemperature_10_hofx-vs-gsihofxbc.pkl", - "experiment_id": 12 + "experiment_id": 12, + "observation_name": "amsua_aqua" }, { "plot_id": 323, "plot_file": "brightnessTemperature_8_hofx-vs-gsihofxbc.pkl", - "experiment_id": 3 + "experiment_id": 3, + "observation_name": "amsua_n18" }, { "plot_id": 114, "plot_file": "brightnessTemperature_8_effectiveerror-vs-gsifinalerror.pkl", - "experiment_id": 3 + "experiment_id": 3, + "observation_name": "amsua_n18" }, { "plot_id": 165, "plot_file": "brightnessTemperature_86_effectiveerror-vs-gsifinalerror.pkl", - "experiment_id": 1 + "experiment_id": 1, + "observation_name": "cris-fsr_n20" }, { "plot_id": 966, "plot_file": "windEastward__effectiveerrordiff-vs-gsifinalerror.pkl", - "experiment_id": 96 + "experiment_id": 96, + "observation_name": "satwind" } - ], - "observation_dirs": [ - "amsua_aqua", - "amsua_n18", - "cris-fsr_n20", - "satwind" ] } \ No newline at end of file diff --git a/src/evagram/database/input_tool.py b/src/evagram/database/input_tool.py deleted file mode 100644 index b0b60d5..0000000 --- a/src/evagram/database/input_tool.py +++ /dev/null @@ -1,238 +0,0 @@ -import pickle -import json -import os -import sys -import argparse -from pathlib import Path -import psycopg2 -from dotenv import load_dotenv - -load_dotenv() - -# environment variables for connecting to database -db_host = os.environ.get('DB_HOST') -db_port = os.environ.get('DB_PORT') -db_name = os.environ.get('DB_NAME') -db_user = os.environ.get('DB_USER') -db_password = os.environ.get('DB_PASSWORD') - -# default path configurations -EXPERIMENT_DATA_PATH = './tests/eva' -DATASET_PATH = './src/evagram/database/' -PROCEDURES_PATH = './src/evagram/database/sql' - - -def main(args): - global EXPERIMENT_DATA_PATH - parser = argparse.ArgumentParser() - parser.add_argument("experiment_path") - args = parser.parse_args(args) - experiment_path = Path(args.experiment_path) - if experiment_path.exists(): - EXPERIMENT_DATA_PATH = args.experiment_path - - conn = psycopg2.connect( - host=db_host, - port=db_port, - dbname=db_name, - user=db_user, - password=db_password - ) - cur = conn.cursor() - - create_procedures(cur) - drop_tables(cur) - create_tables(cur) - load_dataset_to_db(cur) - - conn.commit() - cur.close() - conn.close() - - -def create_procedures(cur): - for proc in os.listdir(PROCEDURES_PATH): - proc_file = os.path.join(PROCEDURES_PATH, proc) - if os.path.isfile(proc_file) and proc.startswith("proc_") and proc.endswith(".sql"): - contents = open(proc_file, 'r') - cur.execute(contents.read()) - contents.close() - - -def create_tables(cur): - # Users table - cur.execute("CALL public.create_owners();") - # Experiments table - cur.execute("CALL public.create_experiments();") - # Groups table - cur.execute("CALL public.create_groups();") - # Variables table - cur.execute("CALL public.create_variables();") - # Observations table - cur.execute("CALL public.create_observations();") - # Plots table - cur.execute("CALL public.create_plots();") - - -def drop_tables(cur): - cur.execute("DROP TABLE IF EXISTS owners CASCADE") - cur.execute("DROP TABLE IF EXISTS experiments CASCADE") - cur.execute("DROP TABLE IF EXISTS plots CASCADE") - cur.execute("DROP TABLE IF EXISTS groups CASCADE") - cur.execute("DROP TABLE IF EXISTS observations CASCADE") - cur.execute("DROP TABLE IF EXISTS variables CASCADE") - - -def load_dataset_to_db(cur): - with open(os.path.join(DATASET_PATH, "dataset.json"), 'rb') as dataset: - sample_dataset = json.load(dataset) - for owner in sample_dataset['owners']: - add_user(cur, owner) - for experiment in sample_dataset['experiments']: - add_experiment(cur, experiment) - for plot in (sample_dataset['plots']): - add_plot(cur, plot, sample_dataset['observation_dirs']) - - -def get_observation_name(obs_dirs, filename): - # TODO: resolve duplicate filenames from different observations - for observation in obs_dirs: - obs_dir_path = os.path.join(EXPERIMENT_DATA_PATH, observation) - for plot in os.listdir(obs_dir_path): - if filename == plot: - return observation - return None - - -def insert_table_record(cur, data, table): - cur.execute("SELECT * FROM {} LIMIT 0".format(table)) - colnames = [desc[0] for desc in cur.description] - # filter data to contain only existing columns in table - data = {k: v for (k, v) in data.items() if k in colnames} - - query = "INSERT INTO {} (".format(table) - query += ', '.join(data) - query += ") VALUES (" - query += ', '.join(["%s" for _ in range(len(data))]) - query += ")" - - cur.execute(query, tuple(data.values())) - - -def add_user(cur, user_obj): - # check not null constraints - # TODO: owner_id made optional for user to provide - required = {'owner_id', 'username'} - difference = required.difference(user_obj) - if len(difference) > 0: - print("Missing required columns for owners table: {}".format(difference)) - return 1 - else: - insert_table_record(cur, user_obj, "owners") - return 0 - - -def delete_user(cur, username): - cur.execute("DELETE FROM owners WHERE username=%s", (username,)) - - -def add_experiment(cur, experiment_obj): - # check not null constraints - # TODO: experiment_id made optional for user to provide - required = {'experiment_id', 'owner_id'} - difference = required.difference(experiment_obj) - if len(difference) > 0: - print("Missing required columns for experiment table: {}".format(difference)) - return 1 - else: - insert_table_record(cur, experiment_obj, "experiments") - return 0 - - -def add_plot(cur, plot_obj, observation_dirs): - # check not null constraints - # TODO: plot_id made optional for user to provide - required = {'plot_id', 'plot_file', 'experiment_id'} - difference = required.difference(plot_obj) - if len(difference) > 0: - print("Missing required columns for plots table: {}".format(difference)) - return 1 - - plot_filename = plot_obj['plot_file'] - observation_name = get_observation_name(observation_dirs, plot_filename) - plot_file_path = os.path.join( - EXPERIMENT_DATA_PATH, observation_name, plot_filename) - - with open(plot_file_path, 'rb') as file: - dictionary = pickle.load(file) - - # extract the div and script components - div = dictionary['div'] - script = dictionary['script'] - - # parse filename for components variable name, channel, and group name - filename_no_extension = os.path.splitext(plot_filename)[0] - plot_components = filename_no_extension.split("_") - - var_name = plot_components[0] - channel = plot_components[1] if plot_components[1] != '' else None - group_name = plot_components[2] - - # insert observation, variable, group dynamically if not exist in database - cur.execute("SELECT observation_id FROM observations WHERE observation_name=%s", - (observation_name,)) - new_observation = len(cur.fetchall()) == 0 - cur.execute( - """SELECT variable_id FROM variables WHERE variable_name=%s - AND (channel=%s OR channel IS NULL)""", - (var_name, channel)) - new_variable = len(cur.fetchall()) == 0 - cur.execute("SELECT group_id FROM groups WHERE group_name=%s", (group_name,)) - new_group = len(cur.fetchall()) == 0 - - if new_observation: - observation_obj = { - "observation_name": observation_name, - } - insert_table_record(cur, observation_obj, "observations") - - if new_variable: - variable_obj = { - "variable_name": var_name, - "channel": channel - } - insert_table_record(cur, variable_obj, "variables") - - if new_group: - group_obj = { - "group_name": group_name - } - insert_table_record(cur, group_obj, "groups") - - # get the observation, variable, group ids - cur.execute("SELECT observation_id FROM observations WHERE observation_name=%s", - (observation_name,)) - observation_id = cur.fetchone()[0] - cur.execute( - """SELECT variable_id FROM variables WHERE variable_name=%s - AND (channel=%s OR channel IS NULL)""", - (var_name, channel)) - variable_id = cur.fetchone()[0] - cur.execute("SELECT group_id FROM groups WHERE group_name=%s", (group_name,)) - group_id = cur.fetchone()[0] - - # modify plot object - plot_obj["div"] = div - plot_obj["script"] = script - plot_obj["observation_id"] = observation_id - plot_obj["group_id"] = group_id - plot_obj["variable_id"] = variable_id - - # insert plot to database - insert_table_record(cur, plot_obj, "plots") - - return 0 - - -if __name__ == "__main__": - main(sys.argv[1:]) diff --git a/src/evagram/website/backend/api/migrations/0001_initial.py b/src/evagram/website/backend/api/migrations/0001_initial.py index 8d8b702..1a67d5a 100644 --- a/src/evagram/website/backend/api/migrations/0001_initial.py +++ b/src/evagram/website/backend/api/migrations/0001_initial.py @@ -1,7 +1,7 @@ -# Generated by Django 5.0.1 on 2024-02-07 14:30 +# Generated by Django 4.2.10 on 2024-03-24 02:17 -import django.db.models.deletion from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -36,27 +36,14 @@ class Migration(migrations.Migration): name='Owners', fields=[ ('owner_id', models.AutoField(primary_key=True, serialize=False)), - ('first_name', models.CharField(blank=True, null=True)), - ('last_name', models.CharField(blank=True, null=True)), - ('username', models.CharField(unique=True)), + ('first_name', models.CharField(null=True)), + ('last_name', models.CharField(null=True)), + ('username', models.CharField(default='null', unique=True)), ], options={ 'db_table': 'owners', }, ), - migrations.CreateModel( - name='Experiments', - fields=[ - ('experiment_id', models.AutoField(primary_key=True, serialize=False)), - ('experiment_name', models.CharField(default='null')), - ('owner', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to='api.owners')), - ], - options={ - 'db_table': 'experiments', - 'unique_together': {('experiment_name', 'owner')}, - }, - ), migrations.CreateModel( name='Variables', fields=[ @@ -69,20 +56,28 @@ class Migration(migrations.Migration): 'unique_together': {('variable_name', 'channel')}, }, ), + migrations.CreateModel( + name='Experiments', + fields=[ + ('experiment_id', models.AutoField(primary_key=True, serialize=False)), + ('experiment_name', models.CharField(default='null')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.owners')), + ], + options={ + 'db_table': 'experiments', + 'unique_together': {('experiment_name', 'owner')}, + }, + ), migrations.CreateModel( name='Plots', fields=[ ('plot_id', models.AutoField(primary_key=True, serialize=False)), ('div', models.CharField(blank=True, null=True)), ('script', models.CharField(blank=True, null=True)), - ('experiment', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to='api.experiments')), - ('group', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to='api.groups')), - ('observation', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to='api.observations')), - ('variable', models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to='api.variables')), + ('experiment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.experiments')), + ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.groups')), + ('observation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.observations')), + ('variable', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.variables')), ], options={ 'db_table': 'plots', diff --git a/src/evagram/website/backend/api/models.py b/src/evagram/website/backend/api/models.py index 9f86f42..137d9f1 100644 --- a/src/evagram/website/backend/api/models.py +++ b/src/evagram/website/backend/api/models.py @@ -39,9 +39,9 @@ class Meta: class Owners(models.Model): owner_id = models.AutoField(primary_key=True) - first_name = models.CharField(blank=True, null=True) - last_name = models.CharField(blank=True, null=True) - username = models.CharField(unique=True) + first_name = models.CharField(null=True) + last_name = models.CharField(null=True) + username = models.CharField(null=False, unique=True, default="null") class Meta: db_table = 'owners' diff --git a/src/evagram/website/backend/api/test_models.py b/src/evagram/website/backend/api/test_models.py new file mode 100644 index 0000000..5e9fdba --- /dev/null +++ b/src/evagram/website/backend/api/test_models.py @@ -0,0 +1,74 @@ +from django.test import TestCase +import django.db +from api.models import * + + +class TestModels(TestCase): + fixtures = ["test_data.json"] + + def test_insert_duplicate_owner(self): + with self.assertRaises(django.db.IntegrityError): + Owners.objects.create(username='jdoe') + Owners.objects.create(username='jdoe') + + def test_delete_owner_cascade(self): + owner = Owners.objects.get(pk=1) + owner.delete() + self.assertEqual(0, len(Owners.objects.filter(pk=1))) + self.assertEqual(0, len(Experiments.objects.filter(owner=1))) + + def test_insert_experiment_insufficient_fields(self): + with self.assertRaises(django.db.IntegrityError): + Experiments.objects.create(experiment_name="experiment1") + + def test_insert_experiment_invalid_owner(self): + with self.assertRaises(ValueError): + Experiments.objects.create(experiment_name="experiment1", owner=-1) + + def test_insert_duplicate_experiment(self): + with self.assertRaises(django.db.IntegrityError): + owner = Owners.objects.create(username='jdoe') + experiment1 = Experiments.objects.create(experiment_name="experiment1", owner=owner) + experiment2 = Experiments.objects.create(experiment_name="experiment1", owner=owner) + + def test_delete_experiment_cascade(self): + experiment = Experiments.objects.get(pk=1) + experiment.delete() + self.assertEqual(0, len(Experiments.objects.filter(pk=1))) + self.assertEqual(0, len(Plots.objects.filter(experiment=1))) + + def test_insert_plot_insufficient_fields(self): + # Missing fields: group, variable + with self.assertRaises(django.db.IntegrityError): + experiment = Experiments.objects.get(pk=1) + observation = Observations.objects.get(pk=1) + Plots.objects.create(experiment=experiment, observation=observation) + + def test_insert_plot_invalid_fields(self): + # Invalid fields: experiment, observation + with self.assertRaises(ValueError): + group = Groups.objects.get(pk=1) + variable = Variables.objects.get(pk=1) + Plots.objects.create(experiment=-1, observation=-1, group=group, variable=variable) + + def test_insert_duplicate_observation(self): + with self.assertRaises(django.db.IntegrityError): + Observations.objects.create(observation_name="observation1") + Observations.objects.create(observation_name="observation1") + + def test_query_existing_plots(self): + # get all amsua_n18 plots in experiment "experiment_iv_1" where the user is thamzey + owner = Owners.objects.get(username="thamzey") + experiment = Experiments.objects.get(experiment_name="experiment_iv_1", owner=owner) + observation = Observations.objects.get(observation_name="amsua_n18") + queryset = Plots.objects.filter(experiment=experiment, observation=observation) + self.assertEqual(2, len(queryset)) + self.assertTrue(Plots.objects.get(pk=114) in queryset) + self.assertTrue(Plots.objects.get(pk=323) in queryset) + + def test_query_nonexistent_plots(self): + # get all satwind plots in experiment "experiment_iv_1" + experiment = Experiments.objects.get(experiment_name="experiment_iv_1") + observation = Observations.objects.get(observation_name="satwind") + queryset = Plots.objects.filter(experiment=experiment, observation=observation) + self.assertEqual(0, len(queryset)) diff --git a/src/evagram/website/backend/api/tests.py b/src/evagram/website/backend/api/test_views.py similarity index 99% rename from src/evagram/website/backend/api/tests.py rename to src/evagram/website/backend/api/test_views.py index 5c0ec98..2091d2c 100644 --- a/src/evagram/website/backend/api/tests.py +++ b/src/evagram/website/backend/api/test_views.py @@ -1,5 +1,4 @@ from django.test import TestCase -# from evagram.database import input_tool from api.models import Owners, Plots diff --git a/src/evagram/website/backend/backend/settings.py b/src/evagram/website/backend/backend/settings.py index 16a9547..e125bd2 100644 --- a/src/evagram/website/backend/backend/settings.py +++ b/src/evagram/website/backend/backend/settings.py @@ -15,11 +15,7 @@ import os load_dotenv() -db_host = os.environ.get('DB_HOST') -db_port = os.environ.get('DB_PORT') -db_name = os.environ.get('DB_NAME') -db_user = os.environ.get('DB_USER') -db_password = os.environ.get('DB_PASSWORD') +pg_password = os.environ.get('PG_PASSWORD') # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -92,11 +88,11 @@ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', - 'NAME': db_name, - 'USER': db_user, - 'PASSWORD': db_password, - 'HOST': db_host, - 'PORT': db_port + 'NAME': 'plots', + 'USER': 'postgres', + 'HOST': 'localhost', + 'PORT': 5432, + 'PASSWORD': pg_password } } diff --git a/.github/workflows/test_database.yaml b/test_database.yaml similarity index 100% rename from .github/workflows/test_database.yaml rename to test_database.yaml diff --git a/tests/test_input_tool.py b/tests/test_input_tool.py deleted file mode 100644 index bae0c06..0000000 --- a/tests/test_input_tool.py +++ /dev/null @@ -1,261 +0,0 @@ -from evagram.database import input_tool -import sys -import unittest -import psycopg2 -from dotenv import load_dotenv -import os - -load_dotenv() - -# environment variables for connecting to database -db_host = os.environ.get('DB_HOST') -db_port = os.environ.get('DB_PORT') -db_name = os.environ.get('DB_NAME') -db_user = os.environ.get('DB_USER') -db_password = os.environ.get('DB_PASSWORD') - -conn = psycopg2.connect( - host=db_host, - port=db_port, - dbname=db_name, - user=db_user, - password=db_password -) - - -class TestDatabaseInputTool(unittest.TestCase): - def setUp(self): - self.cur = conn.cursor() - input_tool.main(['tests/eva']) - - self.cur.execute( - """SELECT setval('owners_owner_id_seq', - (SELECT MAX(owner_id) FROM owners)+1)""") - self.cur.execute( - """SELECT setval('experiments_experiment_id_seq', - (SELECT MAX(experiment_id) FROM experiments)+1)""") - self.cur.execute( - """SELECT setval('plots_plot_id_seq', - (SELECT MAX(plot_id) FROM plots)+1)""") - self.cur.execute( - """SELECT setval('observations_observation_id_seq', - (SELECT MAX(observation_id) FROM observations)+1)""") - - def tearDown(self): - conn.rollback() - self.cur.close() - - def test_InsertOwnerExpected(self): - user_obj = { - "username": "jdoe", - "first_name": "John", - "last_name": "Doe" - } - input_tool.insert_table_record(self.cur, user_obj, "owners") - self.cur.execute( - "SELECT (username) FROM owners WHERE username=%s", ("jdoe",)) - assert len(self.cur.fetchall()) == 1 - - def test_InsertSameOwner(self): - with self.assertRaises(psycopg2.errors.UniqueViolation): - user_obj = { - "username": "bzhu", - "first_name": "Brandon", - "last_name": "Zhu" - } - input_tool.insert_table_record(self.cur, user_obj, "owners") - - def test_InsertOwnerNoUsername(self): - with self.assertRaises(psycopg2.errors.NotNullViolation): - user_obj = { - "first_name": "John", - "last_name": "Doe" - } - input_tool.insert_table_record(self.cur, user_obj, "owners") - - def test_DeleteOwnerAndExperiments(self): - self.cur.execute("DELETE FROM owners WHERE owner_id=%s", (1,)) - self.cur.execute( - "SELECT (username) FROM owners WHERE owner_id=%s", (1,)) - assert len(self.cur.fetchall()) == 0 - self.cur.execute( - "SELECT (experiment_id) FROM experiments WHERE owner_id=%s", (1,)) - assert len(self.cur.fetchall()) == 0 - - def test_InsertExperimentExpected(self): - experiment_obj = { - "experiment_name": "control", - "owner_id": 1 - } - input_tool.insert_table_record(self.cur, experiment_obj, "experiments") - self.cur.execute( - "SELECT (experiment_name) FROM experiments WHERE experiment_name=%s AND owner_id=%s", - ("control", 1) - ) - assert len(self.cur.fetchall()) == 1 - - def test_InsertExperimentWithoutOwner(self): - with self.assertRaises(psycopg2.errors.NotNullViolation): - experiment_obj = { - "experiment_name": "control" - } - input_tool.insert_table_record(self.cur, experiment_obj, "experiments") - - def test_InsertExperimentWithOwnerNotFound(self): - with self.assertRaises(psycopg2.errors.ForeignKeyViolation): - experiment_obj = { - "experiment_name": "control", - "owner_id": -1 - } - input_tool.insert_table_record(self.cur, experiment_obj, "experiments") - - def test_InsertExperimentWithSameNameAndOwner(self): - with self.assertRaises(psycopg2.errors.UniqueViolation): - experiment_obj = { - "experiment_name": "experiment_control", - "owner_id": 1 - } - input_tool.insert_table_record(self.cur, experiment_obj, "experiments") - - def test_DeleteExperimentCascades(self): - self.cur.execute( - "DELETE FROM experiments WHERE experiment_id=%s", (12,)) - # find any instance of experiment in 'experiments' - self.cur.execute( - "SELECT (experiment_id) FROM experiments WHERE experiment_id=%s", (12,)) - assert len(self.cur.fetchall()) == 0 - # find any instance of experiment in 'plots' - self.cur.execute( - "SELECT (plot_id) FROM plots WHERE experiment_id=%s", (12,)) - assert len(self.cur.fetchall()) == 0 - - def test_InsertPlotExpected(self): - plot_obj = { - "plot_id": 115, - "experiment_id": 1, - "group_id": 3, - "observation_id": 1, - "variable_id": 2 - } - input_tool.insert_table_record(self.cur, plot_obj, "plots") - self.cur.execute( - "SELECT (plot_id) FROM plots WHERE plot_id=%s", (115,)) - assert len(self.cur.fetchall()) == 1 - - def test_InsertPlotMissingFields(self): - with self.assertRaises(psycopg2.errors.NotNullViolation): - plot_obj = { - "group_id": 1, - "observation_id": 1 - } - input_tool.insert_table_record(self.cur, plot_obj, "plots") - self.tearDown() - self.setUp() - with self.assertRaises(psycopg2.errors.NotNullViolation): - plot_obj = { - "experiment_id": 12, - "observation_id": 1 - } - input_tool.insert_table_record(self.cur, plot_obj, "plots") - self.tearDown() - self.setUp() - with self.assertRaises(psycopg2.errors.NotNullViolation): - plot_obj = { - "experiment_id": 12, - "group_id": 1 - } - input_tool.insert_table_record(self.cur, plot_obj, "plots") - - def test_InsertPlotInvalidFields(self): - plot_obj = { - "experiment_id": 12, - "group_id": 1, - "observation_id": 1, - "variable_id": 1 - } - with self.assertRaises(psycopg2.errors.ForeignKeyViolation): - plot_obj["experiment_id"] = -12 - input_tool.insert_table_record(self.cur, plot_obj, "plots") - self.tearDown() - self.setUp() - with self.assertRaises(psycopg2.errors.ForeignKeyViolation): - plot_obj["experiment_id"] = 12 - plot_obj["group_id"] = -1 - input_tool.insert_table_record(self.cur, plot_obj, "plots") - self.tearDown() - self.setUp() - with self.assertRaises(psycopg2.errors.ForeignKeyViolation): - plot_obj["group_id"] = 1 - plot_obj["observation_id"] = -1 - input_tool.insert_table_record(self.cur, plot_obj, "plots") - self.tearDown() - self.setUp() - with self.assertRaises(psycopg2.errors.ForeignKeyViolation): - plot_obj["observation_id"] = 1 - plot_obj["variable_id"] = -1 - input_tool.insert_table_record(self.cur, plot_obj, "plots") - - def test_InsertObservationExpected(self): - observation_obj = { - "observation_name": "aircraft" - } - input_tool.insert_table_record(self.cur, observation_obj, "observations") - self.cur.execute( - """SELECT (observation_id) FROM observations - WHERE observation_name=%s""", - ("satwind",)) - assert len(self.cur.fetchall()) == 1 - - def test_InsertObservationWithSameName(self): - with self.assertRaises(psycopg2.errors.UniqueViolation): - observation_obj = { - "observation_name": "satwind", - } - input_tool.insert_table_record(self.cur, observation_obj, "observations") - - def test_FetchExistingPlots(self): - # get all amsua_n18 plots in experiment "experiment_iv_1" where the user is thamzey - self.cur.execute("""SELECT plot_id, plots.experiment_id FROM plots - JOIN experiments ON plots.experiment_id = experiments.experiment_id - JOIN observations ON plots.observation_id = observations.observation_id - JOIN variables ON plots.variable_id = variables.variable_id - JOIN owners ON owners.owner_id = experiments.owner_id - WHERE experiments.experiment_name = %s - AND owners.username = %s AND observations.observation_name = %s; """, - ("experiment_iv_1", "thamzey", "amsua_n18")) - plots = self.cur.fetchall() - self.assertTrue(len(plots) == 2) - # checks if plot with plot_id=114 and experiment_id=3 - # and plot_id=323 and experiment_id=3 was found - self.assertTrue((114, 3) in plots) - self.assertTrue((323, 3) in plots) - - def test_FetchNonExistingPlots(self): - # get all satwind plots in experiment "experiment_iv_1" - self.cur.execute("""SELECT plot_id FROM plots - JOIN experiments ON plots.experiment_id = experiments.experiment_id - JOIN observations ON plots.observation_id = observations.observation_id - JOIN variables ON plots.variable_id = variables.variable_id - WHERE experiments.experiment_name = %s - AND observations.observation_name = %s;""", - ("experiment_iv_1", "satwind")) - self.assertTrue(len(self.cur.fetchall()) == 0) - - def test_GroupsRelationWithPlotsAndExperiments(self): - self.cur.execute("""SELECT group_name, plots.plot_id, experiments.experiment_id FROM groups - JOIN plots ON plots.group_id = groups.group_id - JOIN experiments ON experiments.experiment_id = plots.experiment_id - WHERE group_name = %s;""", ("effectiveerror-vs-gsifinalerror",)) - plots, experiments = [], [] - for item in self.cur.fetchall(): - assert len(item) == 3 # sanity checks - assert item[0] == "effectiveerror-vs-gsifinalerror" - plots.append(item[1]) - experiments.append(item[2]) - # check that plots associated with group have unique plot ids (relation) - self.assertEqual(plots, list(set(plots))) - # check that experiments associated with group can be the same (no relation) - self.assertGreaterEqual(len(experiments), len(set(experiments))) - - -unittest.main() From b4aab6c0f29b80e68eddd12d2977113f32762301 Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Thu, 28 Mar 2024 10:20:12 -0400 Subject: [PATCH 02/20] added back env variables in actions --- .github/workflows/test_django_api.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_django_api.yaml b/.github/workflows/test_django_api.yaml index feafb42..364d3e0 100644 --- a/.github/workflows/test_django_api.yaml +++ b/.github/workflows/test_django_api.yaml @@ -35,5 +35,11 @@ jobs: python -m pip install --upgrade pip pip install . -r requirements.txt - - name: Test Django API App + - name: Run Django Model Tests + env: + DB_HOST: ${{secrets.DB_HOST}} + DB_PORT: ${{secrets.DB_PORT}} + DB_NAME: ${{secrets.DB_NAME}} + DB_USER: ${{secrets.DB_USER}} + DB_PASSWORD: ${{secrets.DB_PASSWORD}} run: python ./src/evagram/website/backend/manage.py test api From ec192110b4209d77f553b5ed7a02d5340736269d Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Thu, 28 Mar 2024 13:07:32 -0400 Subject: [PATCH 03/20] fixed actions --- .github/workflows/test_django_api.yaml | 4 ---- src/evagram/website/backend/backend/settings.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/test_django_api.yaml b/.github/workflows/test_django_api.yaml index 364d3e0..db407da 100644 --- a/.github/workflows/test_django_api.yaml +++ b/.github/workflows/test_django_api.yaml @@ -37,9 +37,5 @@ jobs: - name: Run Django Model Tests env: - DB_HOST: ${{secrets.DB_HOST}} - DB_PORT: ${{secrets.DB_PORT}} - DB_NAME: ${{secrets.DB_NAME}} - DB_USER: ${{secrets.DB_USER}} DB_PASSWORD: ${{secrets.DB_PASSWORD}} run: python ./src/evagram/website/backend/manage.py test api diff --git a/src/evagram/website/backend/backend/settings.py b/src/evagram/website/backend/backend/settings.py index e125bd2..34d8343 100644 --- a/src/evagram/website/backend/backend/settings.py +++ b/src/evagram/website/backend/backend/settings.py @@ -15,7 +15,7 @@ import os load_dotenv() -pg_password = os.environ.get('PG_PASSWORD') +pg_password = os.environ.get('DB_PASSWORD') # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent From 6d5fb3cf5b30c502922631809af17f54af810d5a Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Thu, 18 Apr 2024 15:12:25 -0400 Subject: [PATCH 04/20] migrated input tool tests --- .github/workflows/test_django_api.yaml | 4 +- .../website/backend/api/test_input_tool.py | 39 ++++++++++++++++++ .../website/backend/backend/settings.py | 2 +- ...ightnessTemperature_15_hofx-vs-gsihofx.pkl | Bin 0 -> 133068 bytes ...rightnessTemperature_1_hofx-vs-gsihofx.pkl | Bin 0 -> 138223 bytes tests/dummy/invalid/invalid_file.pkl | 2 + 6 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 src/evagram/website/backend/api/test_input_tool.py create mode 100644 tests/dummy/airs_aqua/brightnessTemperature_15_hofx-vs-gsihofx.pkl create mode 100644 tests/dummy/eva/brightnessTemperature_1_hofx-vs-gsihofx.pkl create mode 100644 tests/dummy/invalid/invalid_file.pkl diff --git a/.github/workflows/test_django_api.yaml b/.github/workflows/test_django_api.yaml index db407da..1f54489 100644 --- a/.github/workflows/test_django_api.yaml +++ b/.github/workflows/test_django_api.yaml @@ -35,7 +35,5 @@ jobs: python -m pip install --upgrade pip pip install . -r requirements.txt - - name: Run Django Model Tests - env: - DB_PASSWORD: ${{secrets.DB_PASSWORD}} + - name: Run Django MVC Tests run: python ./src/evagram/website/backend/manage.py test api diff --git a/src/evagram/website/backend/api/test_input_tool.py b/src/evagram/website/backend/api/test_input_tool.py new file mode 100644 index 0000000..999ef75 --- /dev/null +++ b/src/evagram/website/backend/api/test_input_tool.py @@ -0,0 +1,39 @@ +from evagram_input import input_data +from api.models import * +import unittest + + +class TestDatabaseInputTool(unittest.TestCase): + def setUp(self): + input_data(owner="postgres", experiment="experiment1", eva_directory="tests/eva") + + def test_OwnerInSession(self): + queryset = Owners.objects.filter(username="postgres") + self.assertEquals(1, len(queryset)) + + def test_ExperimentInSession(self): + owner = Owners.objects.get(username="postgres") + queryset = Experiments.objects.filter(experiment_name="experiment1", owner=owner) + self.assertEquals(1, len(queryset)) + + def test_WrongRootOwner(self): + with self.assertRaises(Exception): + input_data(owner="test", experiment="experiment1", eva_directory="tests/eva") + + def test_ExperimentPathNotFound(self): + with self.assertRaises(FileNotFoundError): + input_data(owner="postgres", experiment="experiment1", eva_directory="not/a/path") + + def test_RollbackOnException(self): + with self.assertRaises(Exception): + input_data( + owner="postgres", experiment="bad_experiment", eva_directory="tests/dummy") + + owner = Owners.objects.get(username="postgres") + experiments = Experiments.objects.filter(experiment_name="bad_experiment", owner=owner) + self.assertEquals(0, len(experiments)) + observations = Observations.objects.filter(observation_name="airs_aqua").filter(observation_name="eva") + self.assertEquals(0, len(observations)) + +if __name__ == "__main__": + unittest.main() diff --git a/src/evagram/website/backend/backend/settings.py b/src/evagram/website/backend/backend/settings.py index 34d8343..853f503 100644 --- a/src/evagram/website/backend/backend/settings.py +++ b/src/evagram/website/backend/backend/settings.py @@ -90,7 +90,7 @@ 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'plots', 'USER': 'postgres', - 'HOST': 'localhost', + 'HOST': '127.0.0.1', 'PORT': 5432, 'PASSWORD': pg_password } diff --git a/tests/dummy/airs_aqua/brightnessTemperature_15_hofx-vs-gsihofx.pkl b/tests/dummy/airs_aqua/brightnessTemperature_15_hofx-vs-gsihofx.pkl new file mode 100644 index 0000000000000000000000000000000000000000..68cd5949e2cd35b11f7f4929f8489746f5f87798 GIT binary patch literal 133068 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

ni2qdI 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 literal 0 HcmV?d00001 diff --git a/tests/dummy/eva/brightnessTemperature_1_hofx-vs-gsihofx.pkl b/tests/dummy/eva/brightnessTemperature_1_hofx-vs-gsihofx.pkl new file mode 100644 index 0000000000000000000000000000000000000000..88f7ade8dff69342638a7dec900671fb55778210 GIT binary patch literal 138223 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�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

ZH0A1_1%B?Zz~ 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 SZ2XtxFMmzb|1ZB!KL0n`Y*)Yl literal 0 HcmV?d00001 diff --git a/tests/dummy/invalid/invalid_file.pkl b/tests/dummy/invalid/invalid_file.pkl new file mode 100644 index 0000000..139597f --- /dev/null +++ b/tests/dummy/invalid/invalid_file.pkl @@ -0,0 +1,2 @@ + + From f4d79221c54ffbfd59a292d00ba0288bb090d0c3 Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Fri, 19 Apr 2024 16:07:16 -0400 Subject: [PATCH 05/20] created django input app --- .github/workflows/test_django_api.yaml | 8 +++---- .../website/backend/backend/settings.py | 2 +- .../website/backend/input_app/__init__.py | 0 .../website/backend/input_app/admin.py | 3 +++ src/evagram/website/backend/input_app/apps.py | 6 ++++++ .../backend/input_app/migrations/__init__.py | 0 .../website/backend/input_app/models.py | 3 +++ .../{api => input_app}/test_input_tool.py | 21 +++++++++---------- .../website/backend/input_app/views.py | 3 +++ 9 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 src/evagram/website/backend/input_app/__init__.py create mode 100644 src/evagram/website/backend/input_app/admin.py create mode 100644 src/evagram/website/backend/input_app/apps.py create mode 100644 src/evagram/website/backend/input_app/migrations/__init__.py create mode 100644 src/evagram/website/backend/input_app/models.py rename src/evagram/website/backend/{api => input_app}/test_input_tool.py (78%) create mode 100644 src/evagram/website/backend/input_app/views.py diff --git a/.github/workflows/test_django_api.yaml b/.github/workflows/test_django_api.yaml index 1f54489..6074d34 100644 --- a/.github/workflows/test_django_api.yaml +++ b/.github/workflows/test_django_api.yaml @@ -14,8 +14,6 @@ jobs: postgres: image: postgres:latest env: - POSTGRES_DB: ${{secrets.DB_NAME}} - POSTGRES_USER: ${{secrets.DB_USER}} POSTGRES_PASSWORD: ${{secrets.DB_PASSWORD}} ports: - 5432:5432 @@ -35,5 +33,7 @@ jobs: python -m pip install --upgrade pip pip install . -r requirements.txt - - name: Run Django MVC Tests - run: python ./src/evagram/website/backend/manage.py test api + - name: Run Django API Tests + run: python src/evagram/website/backend/manage.py test api + env: + DB_PASSWORD: ${{secrets.DB_PASSWORD}} diff --git a/src/evagram/website/backend/backend/settings.py b/src/evagram/website/backend/backend/settings.py index 853f503..3b02a52 100644 --- a/src/evagram/website/backend/backend/settings.py +++ b/src/evagram/website/backend/backend/settings.py @@ -88,7 +88,7 @@ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'plots', + 'NAME': 'evagram', 'USER': 'postgres', 'HOST': '127.0.0.1', 'PORT': 5432, diff --git a/src/evagram/website/backend/input_app/__init__.py b/src/evagram/website/backend/input_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/evagram/website/backend/input_app/admin.py b/src/evagram/website/backend/input_app/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/src/evagram/website/backend/input_app/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/src/evagram/website/backend/input_app/apps.py b/src/evagram/website/backend/input_app/apps.py new file mode 100644 index 0000000..32922b6 --- /dev/null +++ b/src/evagram/website/backend/input_app/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class InputAppConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'input_app' diff --git a/src/evagram/website/backend/input_app/migrations/__init__.py b/src/evagram/website/backend/input_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/evagram/website/backend/input_app/models.py b/src/evagram/website/backend/input_app/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/src/evagram/website/backend/input_app/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/src/evagram/website/backend/api/test_input_tool.py b/src/evagram/website/backend/input_app/test_input_tool.py similarity index 78% rename from src/evagram/website/backend/api/test_input_tool.py rename to src/evagram/website/backend/input_app/test_input_tool.py index 999ef75..2b7afd8 100644 --- a/src/evagram/website/backend/api/test_input_tool.py +++ b/src/evagram/website/backend/input_app/test_input_tool.py @@ -1,20 +1,21 @@ +from django.test import TestCase from evagram_input import input_data from api.models import * -import unittest -class TestDatabaseInputTool(unittest.TestCase): - def setUp(self): +class TestEvagramInputTool(TestCase): + @classmethod + def setUpTestData(cls): input_data(owner="postgres", experiment="experiment1", eva_directory="tests/eva") - + def test_OwnerInSession(self): queryset = Owners.objects.filter(username="postgres") - self.assertEquals(1, len(queryset)) + self.assertEqual(1, len(queryset)) def test_ExperimentInSession(self): owner = Owners.objects.get(username="postgres") queryset = Experiments.objects.filter(experiment_name="experiment1", owner=owner) - self.assertEquals(1, len(queryset)) + self.assertEqual(1, len(queryset)) def test_WrongRootOwner(self): with self.assertRaises(Exception): @@ -28,12 +29,10 @@ def test_RollbackOnException(self): with self.assertRaises(Exception): input_data( owner="postgres", experiment="bad_experiment", eva_directory="tests/dummy") - + owner = Owners.objects.get(username="postgres") experiments = Experiments.objects.filter(experiment_name="bad_experiment", owner=owner) self.assertEquals(0, len(experiments)) - observations = Observations.objects.filter(observation_name="airs_aqua").filter(observation_name="eva") + observations = Observations.objects.filter( + observation_name="airs_aqua").filter(observation_name="eva") self.assertEquals(0, len(observations)) - -if __name__ == "__main__": - unittest.main() diff --git a/src/evagram/website/backend/input_app/views.py b/src/evagram/website/backend/input_app/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/src/evagram/website/backend/input_app/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. From 0c65a3a37c92836d65d74bd0b92036c0b90a1a67 Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Fri, 19 Apr 2024 16:15:54 -0400 Subject: [PATCH 06/20] fixed input tool testing --- src/evagram/website/backend/input_app/test_input_tool.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/evagram/website/backend/input_app/test_input_tool.py b/src/evagram/website/backend/input_app/test_input_tool.py index 2b7afd8..0cf48a6 100644 --- a/src/evagram/website/backend/input_app/test_input_tool.py +++ b/src/evagram/website/backend/input_app/test_input_tool.py @@ -32,7 +32,7 @@ def test_RollbackOnException(self): owner = Owners.objects.get(username="postgres") experiments = Experiments.objects.filter(experiment_name="bad_experiment", owner=owner) - self.assertEquals(0, len(experiments)) + self.assertEqual(0, len(experiments)) observations = Observations.objects.filter( observation_name="airs_aqua").filter(observation_name="eva") - self.assertEquals(0, len(observations)) + self.assertEqual(0, len(observations)) From 2c3618c739e9c8acf4d1276d8874c040818e04f6 Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Fri, 19 Apr 2024 16:53:01 -0400 Subject: [PATCH 07/20] added actions for evagram input --- ..._django_api.yaml => test_evagram_api.yaml} | 2 +- .github/workflows/test_evagram_input.yaml | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) rename .github/workflows/{test_django_api.yaml => test_evagram_api.yaml} (97%) create mode 100644 .github/workflows/test_evagram_input.yaml diff --git a/.github/workflows/test_django_api.yaml b/.github/workflows/test_evagram_api.yaml similarity index 97% rename from .github/workflows/test_django_api.yaml rename to .github/workflows/test_evagram_api.yaml index 6074d34..2c7831a 100644 --- a/.github/workflows/test_django_api.yaml +++ b/.github/workflows/test_evagram_api.yaml @@ -1,4 +1,4 @@ -name: Test Database Tool +name: Test Evagram API on: pull_request: types: diff --git a/.github/workflows/test_evagram_input.yaml b/.github/workflows/test_evagram_input.yaml new file mode 100644 index 0000000..8b39043 --- /dev/null +++ b/.github/workflows/test_evagram_input.yaml @@ -0,0 +1,45 @@ +name: Test Evagram Input Module +on: + pull_request: + types: + - opened + - synchronize + - reopened + paths: + - src/evagram/website/backend/input_app/** + - src/evagram/website/backend/api/models.py + +jobs: + build: + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:latest + env: + POSTGRES_PASSWORD: ${{secrets.DB_PASSWORD}} + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + steps: + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.x + + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Install Evagram Input Module + run: | + python -m pip install --upgrade pip + pip install evagram_input@git+https://github.com/GEOS-ESM/evagram_input@feature/input_tool --upgrade + + - name: Install Dependencies + run: pip install . -r requirements.txt + + - name: Run Evagram Input Tests + run: python src/evagram/website/backend/manage.py test input_app.test_input_tool + env: + DB_PASSWORD: ${{secrets.DB_PASSWORD}} From 96e4e8df2dad4e73fc011920d82a420f151ee87d Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Thu, 9 May 2024 15:23:25 -0400 Subject: [PATCH 08/20] Created PlotList component to render multiple diagnostics --- .github/workflows/test_evagram_input.yaml | 2 +- .../backend/api/migrations/0001_initial.py | 2 +- src/evagram/website/backend/api/urls.py | 1 + src/evagram/website/backend/api/views.py | 47 ++ src/evagram/website/frontend/.gitignore | 2 + .../website/frontend/src/Components/Plot.js | 60 +-- .../frontend/src/Components/PlotList.js | 40 ++ .../frontend/src/Components/PlotMenu.js | 489 +++++++++--------- .../frontend/src/styles/PlotMenu.module.css | 8 +- test_database.yaml | 54 -- 10 files changed, 373 insertions(+), 332 deletions(-) create mode 100644 src/evagram/website/frontend/src/Components/PlotList.js delete mode 100644 test_database.yaml diff --git a/.github/workflows/test_evagram_input.yaml b/.github/workflows/test_evagram_input.yaml index 8b39043..7823bf0 100644 --- a/.github/workflows/test_evagram_input.yaml +++ b/.github/workflows/test_evagram_input.yaml @@ -34,7 +34,7 @@ jobs: - name: Install Evagram Input Module run: | python -m pip install --upgrade pip - pip install evagram_input@git+https://github.com/GEOS-ESM/evagram_input@feature/input_tool --upgrade + pip install evagram_input@git+https://github.com/GEOS-ESM/evagram_input --upgrade - name: Install Dependencies run: pip install . -r requirements.txt diff --git a/src/evagram/website/backend/api/migrations/0001_initial.py b/src/evagram/website/backend/api/migrations/0001_initial.py index 1a67d5a..e783f98 100644 --- a/src/evagram/website/backend/api/migrations/0001_initial.py +++ b/src/evagram/website/backend/api/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.10 on 2024-03-24 02:17 +# Generated by Django 4.2.10 on 2024-04-30 17:18 from django.db import migrations, models import django.db.models.deletion diff --git a/src/evagram/website/backend/api/urls.py b/src/evagram/website/backend/api/urls.py index 034bd32..420d1c8 100644 --- a/src/evagram/website/backend/api/urls.py +++ b/src/evagram/website/backend/api/urls.py @@ -4,6 +4,7 @@ urlpatterns = [ path("initial-load/", views.initial_load), path("get-plot-components/", views.get_plot_components), + path("get-plots-by-field/", views.get_plots_by_field), path("update-user-option/", views.update_user_option), path("update-experiment-option/", views.update_experiment_option), path("update-observation-option/", views.update_observation_option), diff --git a/src/evagram/website/backend/api/views.py b/src/evagram/website/backend/api/views.py index c6dcf3f..8f8b820 100644 --- a/src/evagram/website/backend/api/views.py +++ b/src/evagram/website/backend/api/views.py @@ -56,6 +56,53 @@ def get_plot_components(request): except ObjectDoesNotExist as e: return Response({"error": str(e)}, status=400) +@api_view(['GET']) +def get_plots_by_field(request): + try: + owner_id = request.GET["owner_id"] + experiment_id = request.GET["experiment_id"] + observation_id = request.GET["observation_id"] + variable_id = request.GET["variable_id"] + group_id = request.GET["group_id"] + + # get plots by owner + if experiment_id == "placeholder": + experiments = Experiments.objects.filter(owner_id=owner_id) + plots = Plots.objects.filter(experiment_id__in=experiments) + + # get plots by experiment + elif observation_id == "placeholder": + plots = Plots.objects.filter(experiment_id=experiment_id) + + # get plots by observation + elif variable_id == "placeholder": + plots = Plots.objects.filter(experiment_id=experiment_id, observation_id=observation_id) + + # get plots by variable + elif group_id == "placeholder": + plots = Plots.objects.filter(experiment_id=experiment_id, observation_id=observation_id, variable_id=variable_id) + + elif group_id != "": + plots = Plots.objects.filter(experiment=experiment_id, + group=group_id, + observation=observation_id, + variable=variable_id) + + else: + return Response() + + serializer = PlotSerializer(plots, many=True) + return Response(serializer.data) + + except ValueError as e: + return Response({"error": str(e)}, status=400) + + except KeyError as e: + error_msg = "Missing request parameter detected: {}".format(str(e)) + return Response({"error": error_msg}, status=400) + + except ObjectDoesNotExist as e: + return Response({"error": str(e)}, status=400) @api_view(['GET']) def update_user_option(request): diff --git a/src/evagram/website/frontend/.gitignore b/src/evagram/website/frontend/.gitignore index 4d29575..e8ea278 100644 --- a/src/evagram/website/frontend/.gitignore +++ b/src/evagram/website/frontend/.gitignore @@ -1,5 +1,7 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +.prettierrc + # dependencies /node_modules /.pnp diff --git a/src/evagram/website/frontend/src/Components/Plot.js b/src/evagram/website/frontend/src/Components/Plot.js index bd68b18..a883b40 100644 --- a/src/evagram/website/frontend/src/Components/Plot.js +++ b/src/evagram/website/frontend/src/Components/Plot.js @@ -1,41 +1,31 @@ -import { useEffect, useState } from "react"; -import axios from "axios"; +import { useEffect, useRef } from "react"; import * as DOMPurify from "dompurify"; -function Plot({ experiment, group, observation, variable }) { - const [divContents, setDivContents] = useState(""); - - useEffect(() => { +function Plot({ div, script }) { const scriptComponent = document.createElement("script"); - if ( - experiment !== "" && - group !== "" && - observation !== "" && - variable !== "" - ) { - axios - .get("http://localhost:8000/api/get-plot-components", { - params: { - experiment_id: experiment, - group_id: group, - observation_id: observation, - variable_id: variable, - }, - }) - .then((response) => { - setDivContents(DOMPurify.sanitize(response.data["div"])); - const scriptContents = DOMPurify.sanitize( - response.data["script"].replace(/(<([^>]+)>)/gi, "") - ); - scriptComponent.innerHTML = scriptContents; - document.body.appendChild(scriptComponent); - }); - return () => { - document.body.removeChild(scriptComponent); - }; - } - }, [experiment, group, observation, variable]); - return
; + const bokehContainerRef = useRef(null); + + useEffect(() => { + if (!bokehContainerRef.current) return; + const divContainer = bokehContainerRef.current; + const divElement = document.createElement("div"); + const divContents = DOMPurify.sanitize(div); + divElement.innerHTML = divContents; + bokehContainerRef.current.appendChild(divElement); + + const scriptContents = DOMPurify.sanitize( + script.replace(/(<([^>]+)>)/gi, "") + ); + scriptComponent.innerHTML = scriptContents; + document.body.appendChild(scriptComponent); + + return () => { + divContainer.removeChild(divElement); + document.body.removeChild(scriptComponent); + }; + }, [div, script]); + + return
; } export default Plot; diff --git a/src/evagram/website/frontend/src/Components/PlotList.js b/src/evagram/website/frontend/src/Components/PlotList.js new file mode 100644 index 0000000..c15a293 --- /dev/null +++ b/src/evagram/website/frontend/src/Components/PlotList.js @@ -0,0 +1,40 @@ +import { useEffect, useState } from "react"; +import axios from "axios"; +import Plot from "./Plot.js"; + +function PlotList({ owner, experiment, group, observation, variable }) { + const [plots, setPlots] = useState([]); + + useEffect(() => { + if ( + owner !== "" && + experiment !== "" && + group !== "" && + observation !== "" && + variable !== "" + ) { + axios + .get("http://localhost:8000/api/get-plots-by-field/", { + params: { + owner_id: owner, + experiment_id: experiment, + group_id: group, + observation_id: observation, + variable_id: variable, + }, + }) + .then((response) => { + setPlots(response.data); + }); + } + }, [owner, experiment, group, observation, variable]); + return ( +
+ {plots.map((plot) => ( + + ))} +
+ ); +} + +export default PlotList; diff --git a/src/evagram/website/frontend/src/Components/PlotMenu.js b/src/evagram/website/frontend/src/Components/PlotMenu.js index 4c8e9ec..d2a66bf 100644 --- a/src/evagram/website/frontend/src/Components/PlotMenu.js +++ b/src/evagram/website/frontend/src/Components/PlotMenu.js @@ -1,257 +1,268 @@ import styles from "../styles/PlotMenu.module.css"; import { useState, useEffect, useRef } from "react"; import axios from "axios"; -import Plot from "./Plot.js"; +import PlotList from "./PlotList.js"; function PlotMenu() { - const [owners, setOwners] = useState([]); - const [groups, setGroups] = useState([]); - const [experiments, setExperiments] = useState([]); - const [observations, setObservations] = useState([]); - const [variables, setVariables] = useState([]); - const [currentOwner, setCurrentOwner] = useState(""); - const [currentExperiment, setCurrentExperiment] = useState(""); - const [currentGroup, setCurrentGroup] = useState(""); - const [currentObservation, setCurrentObservation] = useState(""); - const [currentVariable, setCurrentVariable] = useState(""); + const [owners, setOwners] = useState([]); + const [groups, setGroups] = useState([]); + const [experiments, setExperiments] = useState([]); + const [observations, setObservations] = useState([]); + const [variables, setVariables] = useState([]); + const [currentOwner, setCurrentOwner] = useState(""); + const [currentExperiment, setCurrentExperiment] = useState(""); + const [currentGroup, setCurrentGroup] = useState(""); + const [currentObservation, setCurrentObservation] = useState(""); + const [currentVariable, setCurrentVariable] = useState(""); - const didMount = useRef(false); + const didMount = useRef(false); - useEffect(() => { - axios - .get("http://localhost:8000/api/initial-load/") - .then((response) => { - setOwners(response.data["owners"]); - setExperiments(response.data["experiments"]); - setGroups(response.data["groups"]); - setObservations(response.data["observations"]); - setVariables(response.data["variables"]); - didMount.current = true; - }) - .catch((error) => console.log(error)); - }, []); + useEffect(() => { + axios + .get("http://localhost:8000/api/initial-load/") + .then((response) => { + setOwners(response.data["owners"]); + setExperiments(response.data["experiments"]); + // setGroups(response.data["groups"]); + // setObservations(response.data["observations"]); + // setVariables(response.data["variables"]); + didMount.current = true; + }) + .catch((error) => console.log(error)); + }, []); - useEffect(() => { - if (owners.length > 0) { - setCurrentOwner(owners[0]["owner_id"]); - } - }, [owners]); + const submitForm = (e) => { + setCurrentOwner(document.getElementById("user_menu").value); + setCurrentExperiment(document.getElementById("experiment_menu").value); + setCurrentGroup(document.getElementById("group_menu").value); + setCurrentObservation( + document.getElementById("observation_menu").value + ); + setCurrentVariable(document.getElementById("variable_menu").value); + }; - useEffect(() => { - if (experiments.length > 0) { - setCurrentExperiment(experiments[0]["experiment_id"]); - } - }, [experiments]); + const updateOptionsByUser = (e) => { + // setCurrentExperiment(""); // sets state to empty until all data is fetched + setExperiments([]); + setObservations([]); + setVariables([]); + setGroups([]); + axios + .get("http://localhost:8000/api/update-user-option/", { + params: { + owner_id: e.target.value, + }, + }) + .then((response) => { + setExperiments(response.data["experiments"]); + }) + .catch((error) => console.log(error)); + }; - useEffect(() => { - if (observations.length > 0) { - setCurrentObservation(observations[0]["observation_id"]); - } - }, [observations]); + const updateOptionsByExperiment = (e) => { + if (e.target.value === "placeholder") { + setObservations([]); + setVariables([]); + setGroups([]); + } else { + //setCurrentGroup(""); + axios + .get("http://localhost:8000/api/update-experiment-option/", { + params: { + experiment_id: e.target.value, + }, + }) + .then((response) => { + setObservations(response.data["observations"]); + }) + .catch((error) => console.log(error)); + } + }; - useEffect(() => { - if (variables.length > 0) { - setCurrentVariable(variables[0]["variable_id"]); - } - }, [variables]); + const updateOptionsByObservation = (e) => { + if (e.target.value === "placeholder") { + setVariables([]); + setGroups([]); + } else { + //setCurrentVariable(""); + axios + .get("http://localhost:8000/api/update-observation-option/", { + params: { + observation_id: e.target.value, + }, + }) + .then((response) => { + setVariables(response.data["variables"]); + }) + .catch((error) => console.log(error)); + } + }; - useEffect(() => { - if (groups.length > 0) { - setCurrentGroup(groups[0]["group_id"]); - } - }, [groups]); + const updateOptionsByVariable = (e) => { + if (e.target.value === "placeholder") { + setGroups([]); + } else { + //setCurrentGroup(""); + axios + .get("http://localhost:8000/api/update-variable-option/", { + params: { + variable_id: e.target.value, + }, + }) + .then((response) => { + setGroups(response.data["groups"]); + }) + .catch((error) => console.log(error)); + } + }; - const updateOptionsByUser = (e) => { - setCurrentExperiment(""); // sets state to empty until all data is fetched - axios - .get("http://localhost:8000/api/update-user-option/", { - params: { - owner_id: e.target.value, - }, - }) - .then((response) => { - setExperiments(response.data["experiments"]); - setGroups(response.data["groups"]); - setObservations(response.data["observations"]); - setVariables(response.data["variables"]); - setCurrentOwner(e.target.value); - }) - .catch((error) => console.log(error)); - }; - - const updateOptionsByExperiment = (e) => { - setCurrentGroup(""); - axios - .get("http://localhost:8000/api/update-experiment-option/", { - params: { - experiment_id: e.target.value, - }, - }) - .then((response) => { - setGroups(response.data["groups"]); - setObservations(response.data["observations"]); - setVariables(response.data["variables"]); - setCurrentExperiment(e.target.value); - }) - .catch((error) => console.log(error)); - }; - - const updateOptionsByObservation = (e) => { - setCurrentVariable(""); - axios - .get("http://localhost:8000/api/update-observation-option/", { - params: { - observation_id: e.target.value, - }, - }) - .then((response) => { - setVariables(response.data["variables"]); - setGroups(response.data["groups"]); - setCurrentObservation(e.target.value); - }) - .catch((error) => console.log(error)); - }; - - const updateOptionsByVariable = (e) => { - setCurrentGroup(""); - axios - .get("http://localhost:8000/api/update-variable-option/", { - params: { - variable_id: e.target.value, - }, - }) - .then((response) => { - setGroups(response.data["groups"]); - setCurrentVariable(e.target.value); - }) - .catch((error) => console.log(error)); - }; - - return ( - - ); + + {variables.map((variable) => + variable.variable_id === currentVariable ? ( + variable.channel ? ( + + ) : ( + + ) + ) : variable.channel ? ( + + ) : ( + + ) + )} + + + + +
+
+ +
+ + ); } export default PlotMenu; diff --git a/src/evagram/website/frontend/src/styles/PlotMenu.module.css b/src/evagram/website/frontend/src/styles/PlotMenu.module.css index 1814fc0..228a742 100644 --- a/src/evagram/website/frontend/src/styles/PlotMenu.module.css +++ b/src/evagram/website/frontend/src/styles/PlotMenu.module.css @@ -2,7 +2,7 @@ margin-top: 60px; display: flex; } - + /* Styles for the dropdown menus container */ .dropdown_container { margin-top: 30px; @@ -17,4 +17,8 @@ margin-left: 100px; width: 60%; /* Adjust width as needed */ height: 300px; -} \ No newline at end of file +} + +.submit { + margin-top: 100px; +} diff --git a/test_database.yaml b/test_database.yaml deleted file mode 100644 index ed5015c..0000000 --- a/test_database.yaml +++ /dev/null @@ -1,54 +0,0 @@ -name: Test Database Tool -on: - pull_request: - types: - - opened - - synchronize - - reopened - -jobs: - build: - runs-on: ubuntu-latest - - services: - postgres: - image: postgres:latest - env: - POSTGRES_DB: ${{secrets.DB_NAME}} - POSTGRES_USER: ${{secrets.DB_USER}} - POSTGRES_PASSWORD: ${{secrets.DB_PASSWORD}} - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.x - - - name: Install Dependencies - run: | - python -m pip install --upgrade pip - pip install . -r requirements.txt - - - name: Run Input Tool - env: - DB_HOST: ${{secrets.DB_HOST}} - DB_PORT: ${{secrets.DB_PORT}} - DB_NAME: ${{secrets.DB_NAME}} - DB_USER: ${{secrets.DB_USER}} - DB_PASSWORD: ${{secrets.DB_PASSWORD}} - run: python ./src/evagram/database/input_tool.py ./tests/eva - - - name: Run Test Script - env: - DB_HOST: ${{secrets.DB_HOST}} - DB_PORT: ${{secrets.DB_PORT}} - DB_NAME: ${{secrets.DB_NAME}} - DB_USER: ${{secrets.DB_USER}} - DB_PASSWORD: ${{secrets.DB_PASSWORD}} - run: python ./tests/test_input_tool.py From 968e1795def83d0150fcaf3985dcef98200bc927 Mon Sep 17 00:00:00 2001 From: brandonzhu09 Date: Fri, 17 May 2024 10:39:00 -0400 Subject: [PATCH 09/20] Created dynamic channel dropdown menu --- .gitignore | 4 + .../website/backend/api/serializers.py | 38 ++- src/evagram/website/backend/api/views.py | 56 +++-- .../frontend/src/Components/DropdownList.js | 14 ++ .../website/frontend/src/Components/Plot.js | 2 +- .../frontend/src/Components/PlotList.js | 21 +- .../frontend/src/Components/PlotMenu.js | 238 ++++++------------ .../src/Components/VariableDropdownList.js | 72 ++++++ .../frontend/src/styles/PlotMenu.module.css | 4 +- .../styles/VariableDropdownList.module.css | 3 + 10 files changed, 269 insertions(+), 183 deletions(-) create mode 100644 src/evagram/website/frontend/src/Components/DropdownList.js create mode 100644 src/evagram/website/frontend/src/Components/VariableDropdownList.js create mode 100644 src/evagram/website/frontend/src/styles/VariableDropdownList.module.css diff --git a/.gitignore b/.gitignore index c69d9e6..2bfa03d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ __pycache__/ # C extensions *.so +.prettierrc + # Distribution / packaging .Python build/ @@ -26,6 +28,8 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST +Dockerfile +docker-compose.yml # PyInstaller # Usually these files are written by a python script from a template diff --git a/src/evagram/website/backend/api/serializers.py b/src/evagram/website/backend/api/serializers.py index 6b37ecd..a44a6b8 100644 --- a/src/evagram/website/backend/api/serializers.py +++ b/src/evagram/website/backend/api/serializers.py @@ -1,35 +1,63 @@ from rest_framework import serializers from api.models import * +from django.db import models + class OwnerSerializer(serializers.ModelSerializer): + key = serializers.ModelField(model_field=Owners()._meta.get_field('owner_id')) + value = serializers.ModelField(model_field=Owners()._meta.get_field('owner_id')) + content = serializers.ModelField(model_field=Owners()._meta.get_field('username')) + type = models.CharField(default='owner') + class Meta: model = Owners - fields = ['owner_id', 'first_name', 'last_name', 'username'] + # fields = ['owner_id', 'first_name', 'last_name', 'username'] + fields = ['key', 'value', 'content', 'owner_id', 'username'] class ExperimentSerializer(serializers.ModelSerializer): + key = serializers.ModelField(model_field=Experiments()._meta.get_field('experiment_id')) + value = serializers.ModelField(model_field=Experiments()._meta.get_field('experiment_id')) + content = serializers.ModelField(model_field=Experiments()._meta.get_field('experiment_name')) + type = models.CharField(default='experiment') + class Meta: model = Experiments - fields = ['experiment_id', 'experiment_name'] + fields = ['key', 'value', 'content', 'experiment_id', 'experiment_name'] class ObservationSerializer(serializers.ModelSerializer): + key = serializers.ModelField(model_field=Observations()._meta.get_field('observation_id')) + value = serializers.ModelField(model_field=Observations()._meta.get_field('observation_id')) + content = serializers.ModelField(model_field=Observations()._meta.get_field('observation_name')) + type = models.CharField(default='observation') + class Meta: model = Observations - fields = ['observation_id', 'observation_name'] + fields = ['key', 'value', 'content', 'observation_id', 'observation_name'] class VariableSerializer(serializers.ModelSerializer): + key = serializers.ModelField(model_field=Variables()._meta.get_field('variable_id')) + value = serializers.ModelField(model_field=Variables()._meta.get_field('variable_id')) + content = serializers.ModelField(model_field=Variables()._meta.get_field('variable_name')) + type = models.CharField(default='variable') + class Meta: model = Variables - fields = ['variable_id', 'variable_name', 'channel'] + fields = ['key', 'value', 'content', 'variable_id', 'variable_name', 'channel'] class GroupSerializer(serializers.ModelSerializer): + key = serializers.ModelField(model_field=Groups()._meta.get_field('group_id')) + value = serializers.ModelField(model_field=Groups()._meta.get_field('group_id')) + content = serializers.ModelField(model_field=Groups()._meta.get_field('group_name')) + type = models.CharField(default='group') + class Meta: model = Groups - fields = ['group_id', 'group_name'] + fields = ['key', 'value', 'content', 'group_id', 'group_name'] class PlotSerializer(serializers.ModelSerializer): diff --git a/src/evagram/website/backend/api/views.py b/src/evagram/website/backend/api/views.py index 8f8b820..175e1f8 100644 --- a/src/evagram/website/backend/api/views.py +++ b/src/evagram/website/backend/api/views.py @@ -62,31 +62,35 @@ def get_plots_by_field(request): owner_id = request.GET["owner_id"] experiment_id = request.GET["experiment_id"] observation_id = request.GET["observation_id"] - variable_id = request.GET["variable_id"] + variable_name = request.GET["variable_name"] + channel = request.GET["channel"] group_id = request.GET["group_id"] - # get plots by owner - if experiment_id == "placeholder": + # get plots by owner field + if experiment_id == "null": experiments = Experiments.objects.filter(owner_id=owner_id) plots = Plots.objects.filter(experiment_id__in=experiments) - # get plots by experiment - elif observation_id == "placeholder": + # get plots by experiment field + elif observation_id == "null": plots = Plots.objects.filter(experiment_id=experiment_id) - # get plots by observation - elif variable_id == "placeholder": + # get plots by observation field + elif variable_name == "null": plots = Plots.objects.filter(experiment_id=experiment_id, observation_id=observation_id) - # get plots by variable - elif group_id == "placeholder": + # get plots by variable field + elif group_id == "null": + # lookup variable id by variable name and channel + variable_id = Variables.objects.get(variable_name=variable_name, channel=channel).variable_id plots = Plots.objects.filter(experiment_id=experiment_id, observation_id=observation_id, variable_id=variable_id) elif group_id != "": + variable_id = Variables.objects.get(variable_name=variable_name, channel=channel) plots = Plots.objects.filter(experiment=experiment_id, group=group_id, observation=observation_id, - variable=variable_id) + variable_id=variable_id) else: return Response() @@ -173,9 +177,14 @@ def update_observation_option(request): Observations.objects.get(pk=observation_id) data = { "variables": [], - "groups": [] + "groups": [], + "variablesMap": {} } data["variables"] = get_variables_by_observation(observation_id) + variablesMap = {} + for variable in data["variables"]: + variablesMap[variable['variable_name']] = variablesMap.get(variable['variable_name'], []) + [variable['channel']] + data["variablesMap"] = variablesMap if len(data["variables"]) > 0: data["groups"] = get_groups_by_variable(data["variables"][0]["variable_id"]) return Response(data) @@ -194,10 +203,29 @@ def update_observation_option(request): @api_view(['GET']) def update_variable_option(request): try: - variable_id = request.GET["variable_id"] - Variables.objects.get(pk=variable_id) + variable_name = request.GET["variable_name"] + channel = request.GET["channel"] + variable_id = None + + if channel == "null": + # check if variable does not include a channel by default, + # otherwise it has not been configured yet in the PlotMenu + queryset = Variables.objects.filter(variable_name=variable_name, channel=None) + if len(queryset) == 1: + variable_id = queryset[0].variable_id + # pull the top channel from variable name + else: + queryset = Variables.objects.filter(variable_name=variable_name) + assert len(queryset) > 0 + channel = queryset[0].channel + variable_id = queryset[0].variable_id + # get variable id from variable name and channel + else: + variable_id = Variables.objects.get(variable_name=variable_name, channel=channel).variable_id + data = { - "groups": [] + "groups": [], + "channel": channel } data["groups"] = get_groups_by_variable(variable_id) return Response(data) diff --git a/src/evagram/website/frontend/src/Components/DropdownList.js b/src/evagram/website/frontend/src/Components/DropdownList.js new file mode 100644 index 0000000..a290155 --- /dev/null +++ b/src/evagram/website/frontend/src/Components/DropdownList.js @@ -0,0 +1,14 @@ +function DropdownList({ id, updateOptionCallback, objects }) { + return ( + + ); +} + +export default DropdownList; diff --git a/src/evagram/website/frontend/src/Components/Plot.js b/src/evagram/website/frontend/src/Components/Plot.js index a883b40..dd6bc38 100644 --- a/src/evagram/website/frontend/src/Components/Plot.js +++ b/src/evagram/website/frontend/src/Components/Plot.js @@ -2,11 +2,11 @@ import { useEffect, useRef } from "react"; import * as DOMPurify from "dompurify"; function Plot({ div, script }) { - const scriptComponent = document.createElement("script"); const bokehContainerRef = useRef(null); useEffect(() => { if (!bokehContainerRef.current) return; + const scriptComponent = document.createElement("script"); const divContainer = bokehContainerRef.current; const divElement = document.createElement("div"); const divContents = DOMPurify.sanitize(div); diff --git a/src/evagram/website/frontend/src/Components/PlotList.js b/src/evagram/website/frontend/src/Components/PlotList.js index c15a293..7933877 100644 --- a/src/evagram/website/frontend/src/Components/PlotList.js +++ b/src/evagram/website/frontend/src/Components/PlotList.js @@ -2,32 +2,41 @@ import { useEffect, useState } from "react"; import axios from "axios"; import Plot from "./Plot.js"; -function PlotList({ owner, experiment, group, observation, variable }) { +function PlotList({ + owner, + experiment, + observation, + variableName, + channel, + group, +}) { const [plots, setPlots] = useState([]); useEffect(() => { if ( owner !== "" && experiment !== "" && - group !== "" && observation !== "" && - variable !== "" + variableName !== "" && + channel !== "" && + group !== "" ) { axios .get("http://localhost:8000/api/get-plots-by-field/", { params: { owner_id: owner, experiment_id: experiment, - group_id: group, observation_id: observation, - variable_id: variable, + variable_name: variableName, + channel: channel, + group_id: group, }, }) .then((response) => { setPlots(response.data); }); } - }, [owner, experiment, group, observation, variable]); + }, [owner, experiment, observation, variableName, channel, group]); return (
{plots.map((plot) => ( diff --git a/src/evagram/website/frontend/src/Components/PlotMenu.js b/src/evagram/website/frontend/src/Components/PlotMenu.js index d2a66bf..8297616 100644 --- a/src/evagram/website/frontend/src/Components/PlotMenu.js +++ b/src/evagram/website/frontend/src/Components/PlotMenu.js @@ -2,18 +2,21 @@ import styles from "../styles/PlotMenu.module.css"; import { useState, useEffect, useRef } from "react"; import axios from "axios"; import PlotList from "./PlotList.js"; +import DropdownList from "./DropdownList.js"; +import VariableDropdownList from "./VariableDropdownList.js"; function PlotMenu() { const [owners, setOwners] = useState([]); const [groups, setGroups] = useState([]); const [experiments, setExperiments] = useState([]); const [observations, setObservations] = useState([]); - const [variables, setVariables] = useState([]); + const [variablesMap, setVariablesMap] = useState(new Map()); const [currentOwner, setCurrentOwner] = useState(""); const [currentExperiment, setCurrentExperiment] = useState(""); - const [currentGroup, setCurrentGroup] = useState(""); const [currentObservation, setCurrentObservation] = useState(""); - const [currentVariable, setCurrentVariable] = useState(""); + const [currentVariableName, setCurrentVariableName] = useState(""); + const [currentChannel, setCurrentChannel] = useState("null"); + const [currentGroup, setCurrentGroup] = useState(""); const didMount = useRef(false); @@ -25,7 +28,6 @@ function PlotMenu() { setExperiments(response.data["experiments"]); // setGroups(response.data["groups"]); // setObservations(response.data["observations"]); - // setVariables(response.data["variables"]); didMount.current = true; }) .catch((error) => console.log(error)); @@ -34,35 +36,38 @@ function PlotMenu() { const submitForm = (e) => { setCurrentOwner(document.getElementById("user_menu").value); setCurrentExperiment(document.getElementById("experiment_menu").value); - setCurrentGroup(document.getElementById("group_menu").value); setCurrentObservation( document.getElementById("observation_menu").value ); - setCurrentVariable(document.getElementById("variable_menu").value); + setCurrentVariableName(document.getElementById("variable_menu").value); + setCurrentChannel(document.getElementById("channel_menu").value); + setCurrentGroup(document.getElementById("group_menu").value); }; const updateOptionsByUser = (e) => { // setCurrentExperiment(""); // sets state to empty until all data is fetched setExperiments([]); setObservations([]); - setVariables([]); + setVariablesMap(new Map()); setGroups([]); - axios - .get("http://localhost:8000/api/update-user-option/", { - params: { - owner_id: e.target.value, - }, - }) - .then((response) => { - setExperiments(response.data["experiments"]); - }) - .catch((error) => console.log(error)); + if (e.target.value !== "null") { + axios + .get("http://localhost:8000/api/update-user-option/", { + params: { + owner_id: e.target.value, + }, + }) + .then((response) => { + setExperiments(response.data["experiments"]); + }) + .catch((error) => console.log(error)); + } }; const updateOptionsByExperiment = (e) => { - if (e.target.value === "placeholder") { + if (e.target.value === "null") { setObservations([]); - setVariables([]); + setVariablesMap(new Map()); setGroups([]); } else { //setCurrentGroup(""); @@ -80,11 +85,10 @@ function PlotMenu() { }; const updateOptionsByObservation = (e) => { - if (e.target.value === "placeholder") { - setVariables([]); + if (e.target.value === "null") { + setVariablesMap(new Map()); setGroups([]); } else { - //setCurrentVariable(""); axios .get("http://localhost:8000/api/update-observation-option/", { params: { @@ -92,21 +96,42 @@ function PlotMenu() { }, }) .then((response) => { - setVariables(response.data["variables"]); + setVariablesMap(response.data["variablesMap"]); }) .catch((error) => console.log(error)); } }; - const updateOptionsByVariable = (e) => { - if (e.target.value === "placeholder") { + const updateOptionsByVariableName = (e) => { + if (e.target.value === "null") { setGroups([]); } else { - //setCurrentGroup(""); + // channel has been configured properly axios .get("http://localhost:8000/api/update-variable-option/", { params: { - variable_id: e.target.value, + variable_name: e.target.value, + channel: document.getElementById("channel_menu").value, + }, + }) + .then((response) => { + setGroups(response.data["groups"]); + }) + .catch((error) => console.log(error)); + } + }; + + const updateOptionsByChannel = (e) => { + console.log(e.target.value); + if (e.target.value === "null") { + setGroups([]); + } else { + axios + .get("http://localhost:8000/api/update-variable-option/", { + params: { + variable_name: + document.getElementById("variable_menu").value, + channel: e.target.value, }, }) .then((response) => { @@ -119,136 +144,38 @@ function PlotMenu() { return (
diff --git a/src/evagram/website/frontend/src/Components/VariableDropdownList.js b/src/evagram/website/frontend/src/Components/VariableDropdownList.js new file mode 100644 index 0000000..ac91fc7 --- /dev/null +++ b/src/evagram/website/frontend/src/Components/VariableDropdownList.js @@ -0,0 +1,72 @@ +import { useEffect, useState } from "react"; +import styles from "../styles/VariableDropdownList.module.css"; + +function VariableDropdownList({ + id, + updateOptionsByVariableName, + updateOptionsByChannel, + variablesMap, +}) { + const [variableName, setVariableName] = useState("--"); + + // console.log("Variables Map", variablesMap.size); + + const handleChange = (e) => { + updateOptionsByVariableName(e); + toggleVariableName(); + }; + + const toggleVariableName = () => { + var variableMenu = document.getElementById(id); + setVariableName(variableMenu.options[variableMenu.selectedIndex].text); + }; + + useEffect(() => { + var variableMenu = document.getElementById(id); + setVariableName(variableMenu.options[variableMenu.selectedIndex].text); + }, [variablesMap]); + + return ( +
+ + {variableName !== "--" && Object.keys(variablesMap).length > 0 ? ( + <> +
+ + + )} + +
+ + ) : ( + + )} +
+ ); +} + +export default VariableDropdownList; diff --git a/src/evagram/website/frontend/src/styles/PlotMenu.module.css b/src/evagram/website/frontend/src/styles/PlotMenu.module.css index 228a742..1de475d 100644 --- a/src/evagram/website/frontend/src/styles/PlotMenu.module.css +++ b/src/evagram/website/frontend/src/styles/PlotMenu.module.css @@ -19,6 +19,6 @@ height: 300px; } -.submit { - margin-top: 100px; +button { + margin-top: 20px; } diff --git a/src/evagram/website/frontend/src/styles/VariableDropdownList.module.css b/src/evagram/website/frontend/src/styles/VariableDropdownList.module.css new file mode 100644 index 0000000..a9ce81c --- /dev/null +++ b/src/evagram/website/frontend/src/styles/VariableDropdownList.module.css @@ -0,0 +1,3 @@ +.variable_dropdown { + display: flex; +} From 658092437479d8c67010b986dc80ebbfd3737ed0 Mon Sep 17 00:00:00 2001 From: Brandon Zhu Date: Fri, 17 May 2024 15:48:53 -0400 Subject: [PATCH 10/20] Simplified channel toggling logic --- src/evagram/website/backend/api/views.py | 4 +++ .../frontend/src/Components/DropdownList.js | 4 ++- .../frontend/src/Components/PlotList.js | 3 +- .../frontend/src/Components/PlotMenu.js | 16 +++++++++-- .../src/Components/VariableDropdownList.js | 28 ++++++++----------- 5 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/evagram/website/backend/api/views.py b/src/evagram/website/backend/api/views.py index 175e1f8..c04b894 100644 --- a/src/evagram/website/backend/api/views.py +++ b/src/evagram/website/backend/api/views.py @@ -82,10 +82,14 @@ def get_plots_by_field(request): # get plots by variable field elif group_id == "null": # lookup variable id by variable name and channel + if channel == "null": + channel = None variable_id = Variables.objects.get(variable_name=variable_name, channel=channel).variable_id plots = Plots.objects.filter(experiment_id=experiment_id, observation_id=observation_id, variable_id=variable_id) elif group_id != "": + if channel == "null": + channel = None variable_id = Variables.objects.get(variable_name=variable_name, channel=channel) plots = Plots.objects.filter(experiment=experiment_id, group=group_id, diff --git a/src/evagram/website/frontend/src/Components/DropdownList.js b/src/evagram/website/frontend/src/Components/DropdownList.js index a290155..9f19a42 100644 --- a/src/evagram/website/frontend/src/Components/DropdownList.js +++ b/src/evagram/website/frontend/src/Components/DropdownList.js @@ -1,3 +1,5 @@ +import React from "react"; + function DropdownList({ id, updateOptionCallback, objects }) { return ( - {variableName !== "--" && Object.keys(variablesMap).length > 0 ? ( + {toggleChannel && variablesMap[variableName][0] !== null ? ( <>
@@ -46,19 +48,11 @@ function VariableDropdownList({ id="channel_menu" onChange={updateOptionsByChannel} > - {variableName in variablesMap ? ( - variablesMap[variableName].map((channel) => ( - - )) - ) : ( - - )} + {variablesMap[variableName].map((channel) => ( + + ))}
@@ -69,4 +63,4 @@ function VariableDropdownList({ ); } -export default VariableDropdownList; +export default React.memo(VariableDropdownList); From c509ec97b1f389a312e3e1c8be54b8f306e84897 Mon Sep 17 00:00:00 2001 From: Brandon Zhu Date: Mon, 20 May 2024 16:19:17 -0400 Subject: [PATCH 11/20] Fixed behavior for updating options --- src/evagram/website/backend/api/views.py | 14 +++++--- .../website/frontend/public/index.html | 1 + .../frontend/src/Components/PlotMenu.js | 32 ++++++++----------- .../src/Components/VariableDropdownList.js | 2 +- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/evagram/website/backend/api/views.py b/src/evagram/website/backend/api/views.py index c04b894..82ef5df 100644 --- a/src/evagram/website/backend/api/views.py +++ b/src/evagram/website/backend/api/views.py @@ -66,8 +66,15 @@ def get_plots_by_field(request): channel = request.GET["channel"] group_id = request.GET["group_id"] + plots = Plots.objects.none() + + # invalid input + if owner_id == "null": + serializer = PlotSerializer(plots, many=True) + return Response(serializer.data) + # get plots by owner field - if experiment_id == "null": + elif experiment_id == "null": experiments = Experiments.objects.filter(owner_id=owner_id) plots = Plots.objects.filter(experiment_id__in=experiments) @@ -95,10 +102,7 @@ def get_plots_by_field(request): group=group_id, observation=observation_id, variable_id=variable_id) - - else: - return Response() - + serializer = PlotSerializer(plots, many=True) return Response(serializer.data) diff --git a/src/evagram/website/frontend/public/index.html b/src/evagram/website/frontend/public/index.html index 020e4ac..6954687 100644 --- a/src/evagram/website/frontend/public/index.html +++ b/src/evagram/website/frontend/public/index.html @@ -11,6 +11,7 @@ /> +