Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web UI profiles #618

Open
wants to merge 58 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
040d446
added fastapi as web ui backend
VukW Jul 11, 2024
97e6bd7
Added cube + benchmark basic listing
VukW Jul 12, 2024
0382684
Adds navigation
VukW Jul 15, 2024
55fe60e
Aded mlcube detailed page
VukW Jul 19, 2024
fb1bca3
Improved mlcubes detailed layout
VukW Jul 19, 2024
64cf53e
Improved mlcube layout
VukW Jul 19, 2024
36611e1
yaml displaying
VukW Jul 19, 2024
56fa5c4
yaml: spinner
VukW Jul 19, 2024
8563887
yaml panel improvement
VukW Jul 19, 2024
07ce4ab
yaml panel layout improvement
VukW Jul 19, 2024
b260401
layout fixes
VukW Jul 19, 2024
b7980a8
Added benchmark detailed page
VukW Jul 19, 2024
ca356cc
added links to mlcube
VukW Jul 19, 2024
6efd724
benchmark page: added owner
VukW Jul 19, 2024
319b1bf
Colors refactoring
VukW Jul 19, 2024
58008f3
Dataset detailed page
VukW Jul 23, 2024
375d89e
Forgot to add js file
VukW Jul 23, 2024
c6d8a56
Unified data format for all data fields automatically
VukW Jul 23, 2024
74f7743
(mlcube-detailed) Display image tarball and additional files always
VukW Jul 24, 2024
b312882
Fixed scrolling and reinvented basic page layout
VukW Jul 24, 2024
0e282cb
Fix navbar is hiding
VukW Jul 24, 2024
6b28ebb
Make templates & static files independent of user's workdir
VukW Jul 29, 2024
881b281
Added error handling
VukW Jul 29, 2024
e28107b
Display invalid entities correctly
VukW Jul 30, 2024
5b718eb
Added invalid entities highlighting + badges
VukW Jul 30, 2024
0f95027
Added benchmark associations
VukW Aug 5, 2024
444786e
Improved association panel style
VukW Aug 5, 2024
e273577
Added association card
VukW Aug 6, 2024
eea1e77
Sorted associations by status / timestamp
VukW Aug 6, 2024
7b68911
Sorted mlcubes and datasets: mine first
VukW Aug 6, 2024
8251c42
Added associations to dataset page
VukW Aug 7, 2024
b669358
Added associations to mlcube page
VukW Aug 7, 2024
039f496
Refactored details page - extracted common styles to the base template
VukW Aug 10, 2024
c225a5e
Refactored association sorting to common util
VukW Aug 10, 2024
ad0451f
Display my benchmarks first
VukW Aug 10, 2024
12ffef2
Hid empty links
VukW Aug 12, 2024
cedad96
Mlcube-as-a-link unified view
VukW Aug 12, 2024
3ac8a74
resources.path cannot return a dir with subdirs for py3.9
VukW Aug 13, 2024
6170b53
Fixed resources path for templates also
VukW Aug 14, 2024
53b557b
linter fix
VukW Aug 14, 2024
2b73c4f
static local resources instead of remote ones
VukW Aug 26, 2024
75d6776
layout fix: align mlcubes vertically
VukW Aug 27, 2024
c47a751
bugfix: add some dependencies for isolated run
VukW Aug 27, 2024
d837837
Merge branch 'main' into web-ui
VukW Aug 27, 2024
c58efd8
Fixes after merging main
VukW Aug 28, 2024
118020c
Resolved confusion between `config.py` and `config_manager.py`
VukW Aug 30, 2024
9b2cffc
Reset config before every test
VukW Sep 2, 2024
4bd5878
Moved UI to the dynamic config
VukW Sep 2, 2024
a9f06a8
UIFactory class is not necessary as it doesn't store any state
VukW Sep 2, 2024
67be01d
Moved comms to the config
VukW Sep 3, 2024
85da36e
Moved auth to config also
VukW Sep 3, 2024
1dc4938
Linter fix
VukW Sep 16, 2024
dfeb040
Linter fix
VukW Sep 16, 2024
3a41d13
Merge branch 'config-refactoring' into web-ui-profiles
VukW Sep 16, 2024
2642fc7
Changing profile successful
VukW Sep 16, 2024
8e73e54
MedperfSchema requires a name field
VukW Sep 17, 2024
a78ef8d
Linter fix
VukW Sep 17, 2024
972b3f1
Merge branch 'web-ui' into web-ui-profiles
VukW Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions cli/medperf/account_management/account_management.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from .token_storage import TokenStore
from medperf.config_management import read_config, write_config
from medperf import config
from medperf.config_management import config
from medperf import settings
from medperf.exceptions import MedperfException


def read_user_account():
config_p = read_config()
if config.credentials_keyword not in config_p.active_profile:
config_p = config.read_config()
if settings.credentials_keyword not in config_p.active_profile:
return

account_info = config_p.active_profile[config.credentials_keyword]
account_info = config_p.active_profile[settings.credentials_keyword]
return account_info


Expand All @@ -23,15 +23,15 @@ def set_credentials(
):
email = id_token_payload["email"]
TokenStore().set_tokens(email, access_token, refresh_token)
config_p = read_config()
config_p = config.read_config()

if login_event:
# Set the time the user logged in, so that we can track the lifetime of
# the refresh token
logged_in_at = token_issued_at
else:
# This means this is a refresh event. Preserve the logged_in_at timestamp.
logged_in_at = config_p.active_profile[config.credentials_keyword][
logged_in_at = config_p.active_profile[settings.credentials_keyword][
"logged_in_at"
]

Expand All @@ -42,8 +42,8 @@ def set_credentials(
"logged_in_at": logged_in_at,
}

config_p.active_profile[config.credentials_keyword] = account_info
write_config(config_p)
config_p.active_profile[settings.credentials_keyword] = account_info
config_p.write_config()


def read_credentials():
Expand All @@ -61,35 +61,35 @@ def read_credentials():


def delete_credentials():
config_p = read_config()
if config.credentials_keyword not in config_p.active_profile:
config_p = config.read_config()
if settings.credentials_keyword not in config_p.active_profile:
raise MedperfException("You are not logged in")

email = config_p.active_profile[config.credentials_keyword]["email"]
email = config_p.active_profile[settings.credentials_keyword]["email"]
TokenStore().delete_tokens(email)

config_p.active_profile.pop(config.credentials_keyword)
write_config(config_p)
config_p.active_profile.pop(settings.credentials_keyword)
config_p.write_config()


def set_medperf_user_data():
"""Get and cache user data from the MedPerf server"""
config_p = read_config()
config_p = config.read_config()
medperf_user = config.comms.get_current_user()

config_p.active_profile[config.credentials_keyword]["medperf_user"] = medperf_user
write_config(config_p)
config_p.active_profile[settings.credentials_keyword]["medperf_user"] = medperf_user
config_p.write_config()

return medperf_user


def get_medperf_user_data():
"""Return cached medperf user data. Get from the server if not found"""
config_p = read_config()
if config.credentials_keyword not in config_p.active_profile:
config_p = config.read_config()
if settings.credentials_keyword not in config_p.active_profile:
raise MedperfException("You are not logged in")

medperf_user = config_p.active_profile[config.credentials_keyword].get(
medperf_user = config_p.active_profile[settings.credentials_keyword].get(
"medperf_user", None
)
if medperf_user is None:
Expand Down
8 changes: 4 additions & 4 deletions cli/medperf/account_management/token_storage/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import base64
import logging
from medperf.utils import remove_path
from medperf import config
from medperf import settings


class FilesystemTokenStore:
def __init__(self):
self.creds_folder = config.creds_folder
self.creds_folder = settings.creds_folder
os.makedirs(self.creds_folder, mode=0o700, exist_ok=True)

def __get_paths(self, account_id):
Expand All @@ -19,9 +19,9 @@ def __get_paths(self, account_id):
account_folder = os.path.join(self.creds_folder, account_id_encoded)
os.makedirs(account_folder, mode=0o700, exist_ok=True)

access_token_file = os.path.join(account_folder, config.access_token_storage_id)
access_token_file = os.path.join(account_folder, settings.access_token_storage_id)
refresh_token_file = os.path.join(
account_folder, config.refresh_token_storage_id
account_folder, settings.refresh_token_storage_id
)

return access_token_file, refresh_token_file
Expand Down
14 changes: 7 additions & 7 deletions cli/medperf/account_management/token_storage/keyring_.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
users who connect to remote machines through passwordless SSH faced some issues."""

import keyring
from medperf import config
from medperf import settings


class KeyringTokenStore:
Expand All @@ -11,33 +11,33 @@ def __init__(self):

def set_tokens(self, account_id, access_token, refresh_token):
keyring.set_password(
config.access_token_storage_id,
settings.access_token_storage_id,
account_id,
access_token,
)
keyring.set_password(
config.refresh_token_storage_id,
settings.refresh_token_storage_id,
account_id,
refresh_token,
)

def read_tokens(self, account_id):
access_token = keyring.get_password(
config.access_token_storage_id,
settings.access_token_storage_id,
account_id,
)
refresh_token = keyring.get_password(
config.refresh_token_storage_id,
settings.refresh_token_storage_id,
account_id,
)
return access_token, refresh_token

def delete_tokens(self, account_id):
keyring.delete_password(
config.access_token_storage_id,
settings.access_token_storage_id,
account_id,
)
keyring.delete_password(
config.refresh_token_storage_id,
settings.refresh_token_storage_id,
account_id,
)
9 changes: 6 additions & 3 deletions cli/medperf/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import logging.handlers

from medperf import __version__
import medperf.config as config
from medperf import settings
from medperf.config_management import config
from medperf.decorators import clean_except, add_inline_parameters
import medperf.commands.result.result as result
from medperf.commands.result.create import BenchmarkExecution
Expand All @@ -17,6 +18,7 @@
import medperf.commands.association.association as association
import medperf.commands.compatibility_test.compatibility_test as compatibility_test
import medperf.commands.storage as storage
import medperf.web_ui.app as web_ui
from medperf.utils import check_for_updates
from medperf.logging.utils import log_machine_details

Expand All @@ -30,6 +32,7 @@
app.add_typer(compatibility_test.app, name="test", help="Manage compatibility tests")
app.add_typer(auth.app, name="auth", help="Authentication")
app.add_typer(storage.app, name="storage", help="Storage management")
app.add_typer(web_ui.app, name="web-ui", help="local web UI to manage medperf entities")


@app.command("run")
Expand Down Expand Up @@ -92,10 +95,10 @@ def main(
# Set inline parameters
inline_args = ctx.params
for param in inline_args:
setattr(config, param, inline_args[param])
setattr(settings, param, inline_args[param])

# Update logging level according to the passed inline params
loglevel = config.loglevel.upper()
loglevel = settings.loglevel.upper()
logging.getLogger().setLevel(loglevel)
logging.getLogger("requests").setLevel(loglevel)

Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/association/approval.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from medperf import config
from medperf.config_management import config
from medperf.exceptions import InvalidArgumentError


Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/association/association.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typer
from typing import Optional

import medperf.config as config
from medperf.config_management import config
from medperf.decorators import clean_except
from medperf.commands.association.list import ListAssociations
from medperf.commands.association.approval import Approval
Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/association/list.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from tabulate import tabulate

from medperf import config
from medperf.config_management import config


class ListAssociations:
Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/association/priority.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from medperf import config
from medperf.config_management import config
from medperf.exceptions import InvalidArgumentError
from medperf.entities.benchmark import Benchmark

Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from medperf.commands.auth.logout import Logout
from medperf.commands.auth.status import Status
from medperf.decorators import clean_except
import medperf.config as config
from medperf.config_management import config
import typer

app = typer.Typer()
Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/auth/login.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import medperf.config as config
from medperf.config_management import config
from medperf.account_management import read_user_account
from medperf.exceptions import InvalidArgumentError, MedperfException
from email_validator import validate_email, EmailNotValidError
Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/auth/logout.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import medperf.config as config
from medperf.config_management import config


class Logout:
Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/auth/status.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import medperf.config as config
from medperf.config_management import config
from medperf.account_management import read_user_account


Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/auth/synapse_login.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import synapseclient
from synapseclient.core.exceptions import SynapseAuthenticationError
from medperf import config
from medperf.config_management import config
from medperf.exceptions import CommunicationAuthenticationError


Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/benchmark/benchmark.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typer
from typing import Optional

import medperf.config as config
from medperf.config_management import config
from medperf.decorators import clean_except
from medperf.entities.benchmark import Benchmark
from medperf.commands.list import EntityList
Expand Down
5 changes: 3 additions & 2 deletions cli/medperf/commands/benchmark/submit.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os

import medperf.config as config
from medperf import settings
from medperf.config_management import config
from medperf.entities.benchmark import Benchmark
from medperf.exceptions import InvalidEntityError
from medperf.utils import remove_path
Expand Down Expand Up @@ -53,7 +54,7 @@ def __init__(
self.no_cache = no_cache
self.skip_data_preparation_step = skip_data_preparation_step
self.bmk.metadata["demo_dataset_already_prepared"] = skip_data_preparation_step
config.tmp_paths.append(self.bmk.path)
settings.tmp_paths.append(self.bmk.path)

def get_extra_information(self):
"""Retrieves information that must be populated automatically,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typer
from typing import Optional

import medperf.config as config
from medperf.config_management import config
from medperf.decorators import clean_except
from medperf.commands.view import EntityView
from medperf.entities.report import TestReport
Expand Down
19 changes: 10 additions & 9 deletions cli/medperf/commands/compatibility_test/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

from medperf.comms.entity_resources import resources
from medperf.entities.cube import Cube
import medperf.config as config
from medperf import settings
from medperf.config_management import config
import os
import yaml
from pathlib import Path
Expand All @@ -26,7 +27,7 @@ def download_demo_data(dset_url, dset_hash):

# It is assumed that all demo datasets contain a file
# which specifies the input of the data preparation step
paths_file = os.path.join(demo_dset_path, config.demo_dset_paths_file)
paths_file = os.path.join(demo_dset_path, settings.demo_dset_paths_file)
with open(paths_file, "r") as f:
paths = yaml.safe_load(f)

Expand All @@ -41,14 +42,14 @@ def download_demo_data(dset_url, dset_hash):

def prepare_local_cube(path):
temp_uid = get_folders_hash([path])
cubes_folder = config.cubes_folder
cubes_folder = settings.cubes_folder
dst = os.path.join(cubes_folder, temp_uid)
os.symlink(path, dst)
logging.info(f"local cube will be linked to path: {dst}")
config.tmp_paths.append(dst)
cube_metadata_file = os.path.join(path, config.cube_metadata_filename)
settings.tmp_paths.append(dst)
cube_metadata_file = os.path.join(path, settings.cube_metadata_filename)
if not os.path.exists(cube_metadata_file):
mlcube_yaml_path = os.path.join(path, config.cube_filename)
mlcube_yaml_path = os.path.join(path, settings.cube_filename)
mlcube_yaml_hash = get_file_hash(mlcube_yaml_path)
temp_metadata = {
"id": None,
Expand All @@ -63,7 +64,7 @@ def prepare_local_cube(path):
metadata = Cube(**temp_metadata).todict()
with open(cube_metadata_file, "w") as f:
yaml.dump(metadata, f)
config.tmp_paths.append(cube_metadata_file)
settings.tmp_paths.append(cube_metadata_file)

return temp_uid

Expand All @@ -90,7 +91,7 @@ def prepare_cube(cube_uid: str):
path = path.resolve()

if os.path.exists(path):
mlcube_yaml_path = os.path.join(path, config.cube_filename)
mlcube_yaml_path = os.path.join(path, settings.cube_filename)
if os.path.exists(mlcube_yaml_path):
logging.info("local path provided. Creating symbolic link")
temp_uid = prepare_local_cube(path)
Expand Down Expand Up @@ -137,7 +138,7 @@ def create_test_dataset(
data_creation.create_dataset_object()
# TODO: existing dataset could make problems
# make some changes since this is a test dataset
config.tmp_paths.remove(data_creation.dataset.path)
settings.tmp_paths.remove(data_creation.dataset.path)
if skip_data_preparation_step:
data_creation.make_dataset_prepared()
dataset = data_creation.dataset
Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/dataset/associate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from medperf import config
from medperf.config_management import config
from medperf.entities.dataset import Dataset
from medperf.entities.benchmark import Benchmark
from medperf.utils import dict_pretty_print, approval_prompt
Expand Down
2 changes: 1 addition & 1 deletion cli/medperf/commands/dataset/dataset.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typer
from typing import Optional

import medperf.config as config
from medperf.config_management import config
from medperf.decorators import clean_except
from medperf.entities.dataset import Dataset
from medperf.commands.list import EntityList
Expand Down
Loading
Loading