From db648c698dd7c47028ded9cc47e9461aa844a792 Mon Sep 17 00:00:00 2001 From: Adam Lewis <23342526+Adam-D-Lewis@users.noreply.github.com> Date: Tue, 17 Dec 2024 13:10:17 -0600 Subject: [PATCH] updates --- jhub_apps/config_utils.py | 3 +++ jhub_apps/hub_client/hub_client.py | 13 +++++++--- jhub_apps/service/app.py | 40 ++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/jhub_apps/config_utils.py b/jhub_apps/config_utils.py index 1fcd1e1c..76b1bd4e 100644 --- a/jhub_apps/config_utils.py +++ b/jhub_apps/config_utils.py @@ -64,6 +64,8 @@ class JAppsConfig(SingletonConfigurable): startup_apps = List( trait=Any, # TODO: Change this, use Instance() maybe or define a new type - https://traitlets.readthedocs.io/en/stable/defining_traits.html + description="only add a server if it is not already created or edit an existing one to match the config, won't delete any servers", + # This class should be a ServerCreation class + user + thumbnail default_value=[{ 'display_name': 'Adam\'s App', @@ -84,6 +86,7 @@ class JAppsConfig(SingletonConfigurable): {'users': ['alice', 'john', 'admin'], 'groups': ['alpha', 'beta']}, 'servername': 'my-server', + 'username': 'alice', }], help="List of apps to start on JHub Apps Launcher startup", ).tag(config=True) diff --git a/jhub_apps/hub_client/hub_client.py b/jhub_apps/hub_client/hub_client.py index 66f19bc2..88e63694 100644 --- a/jhub_apps/hub_client/hub_client.py +++ b/jhub_apps/hub_client/hub_client.py @@ -122,7 +122,7 @@ def get_user(self, user=None): return user @requires_user_token - def get_server(self, username, servername): + def get_server(self, username, servername=None): users = self.get_users() filter_given_user = [user for user in users if user["name"] == username] if not filter_given_user: @@ -130,9 +130,14 @@ def get_server(self, username, servername): return else: given_user = filter_given_user[0] - for name, server in given_user["servers"].items(): - if name == servername: - return server + + if servername: + for name, server in given_user["servers"].items(): + if name == servername: + return server + else: + # return all user servers + return given_user["servers"] def normalize_server_name(self, servername): # Convert text to lowercase diff --git a/jhub_apps/service/app.py b/jhub_apps/service/app.py index 80607d79..9355cd1f 100644 --- a/jhub_apps/service/app.py +++ b/jhub_apps/service/app.py @@ -3,6 +3,8 @@ import os from pathlib import Path import pprint +from itertools import groupby +from operator import itemgetter from fastapi import FastAPI from fastapi.staticfiles import StaticFiles @@ -16,6 +18,9 @@ from jhub_apps.service.routes import router from jhub_apps.service.utils import get_jupyterhub_config from jhub_apps.version import get_version +import structlog + +logger = structlog.get_logger(__name__) ### When managed by Jupyterhub, the actual endpoints ### will be served out prefixed by /services/:name. @@ -28,22 +33,37 @@ async def lifespan(app: FastAPI): config = get_jupyterhub_config() user_options_list = config['JAppsConfig']['startup_apps'] - instantiate_startup_apps(user_options_list, username='alice') + # group user options by username + + grouped_user_options_list = groupby(user_options_list, itemgetter('username')) + for username, user_options_list in grouped_user_options_list: + instantiate_startup_apps(user_options_list, username=username) yield def instantiate_startup_apps(server_creation_list: list[dict[str, Any]], username: str): - # instantiate custom apps + hub_client = HubClient(username=username) + + existing_servers = hub_client.get_server(username=username) + for server_creation_dict in server_creation_list: - print(f"Instantiating app with user_options: {pprint.pformat(server_creation_dict)}") # TODO: Remove user_options = UserOptions(**server_creation_dict) - hub_client = HubClient(username=username) - hub_client.create_server( - username=username, - servername=server_creation_dict['servername'], - # servername=None, # throws an error - user_options=user_options, - ) + servername = server_creation_dict['servername'] + if server_creation_dict['servername'] in existing_servers: + # update the server + logger.info(f"{'='*50}Updating server: {server_creation_dict['servername']}") + hub_client.edit_server(username, servername, user_options) + else: + # create the server + logger.info(f"{'='*50}Instantiating app with user_options: {pprint.pformat(server_creation_dict)}") # TODO: Remove + # user_options = UserOptions(**server_creation_dict) + + hub_client.create_server( + username=username, + servername=servername, + user_options=user_options, + ) + logger.info('Done instantiating apps') app = FastAPI( title="JApps Service",