From cf4291738e1087dd010a1828261ad9fb4e1bba39 Mon Sep 17 00:00:00 2001
From: DerGrumpf
Date: Tue, 16 Sep 2025 16:03:19 +0200
Subject: [PATCH] Finished: Now its a Personal Project
---
jupyterhub/Dockerfile | 3 --
jupyterhub/compose.yml | 3 --
jupyterhub/jupyterhub_config.py | 35 --------------------
jupyterhub/nbgrader/nbgrader_config.py | 30 -----------------
jupyterhub/nbgrader_config.py | 44 -------------------------
jupyterhub/templates/logo.png | Bin 11257 -> 573 bytes
6 files changed, 115 deletions(-)
delete mode 100644 jupyterhub/nbgrader/nbgrader_config.py
delete mode 100644 jupyterhub/nbgrader_config.py
diff --git a/jupyterhub/Dockerfile b/jupyterhub/Dockerfile
index ead7e15..5a37f23 100644
--- a/jupyterhub/Dockerfile
+++ b/jupyterhub/Dockerfile
@@ -23,9 +23,6 @@ RUN pip install --no-cache-dir \
dockerspawner \
jupyterhub-nativeauthenticator \
jupyterhub-dummyauthenticator \
- nbgrader \
- ngshare \
- ngshare-exchange \
psycopg2-binary
RUN mkdir -p /srv/nbgrader \
diff --git a/jupyterhub/compose.yml b/jupyterhub/compose.yml
index 015d6c6..0427655 100644
--- a/jupyterhub/compose.yml
+++ b/jupyterhub/compose.yml
@@ -11,9 +11,6 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
- ./templates:/srv/jupyterhub/templates:ro
- ./jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py
- - ./nbgrader_config.py:/srv/jupyterhub/nbgrader/nbgrader_config.py:ro
- - ../nbgrader/exchange:/srv/nbgrader/exchange
- - ../nbgrader/courses:/srv/nbgrader/courses
# Just the Hacky way to pull images at startup
# It just pulls the image but they wont startup
diff --git a/jupyterhub/jupyterhub_config.py b/jupyterhub/jupyterhub_config.py
index c14bfc6..323002a 100644
--- a/jupyterhub/jupyterhub_config.py
+++ b/jupyterhub/jupyterhub_config.py
@@ -156,38 +156,3 @@ c.JupyterHub.concurrent_spawn_limit = 10
# Allow named servers
c.JupyterHub.allow_named_servers = True
c.JupyterHub.named_server_limit_per_user = 3
-
-# ngshare service configuration
-c.JupyterHub.services.append(
- {
- "name": "ngshare",
- "url": "http://127.0.0.1:10101",
- "command": [
- "python3",
- "-m",
- "ngshare",
- "--admins",
- "admin",
- "--debug" if ds_debug else "",
- ],
- "environment": {
- "JUPYTERHUB_SERVICE_URL": "http://127.0.0.1:10101",
- "JUPYTERHUB_SERVICE_REDIRECT_URL": f"{base_url}services/ngshare/",
- "JUPYTERHUB_BASE_URL": base_url,
- },
- }
-)
-
-# Additional ngshare configuration
-c.JupyterHub.load_roles = [
- {
- "name": "ngshare",
- "scopes": [
- "admin:servers",
- "access:services",
- "list:users",
- "read:users:activity",
- ],
- "services": ["ngshare"],
- }
-]
diff --git a/jupyterhub/nbgrader/nbgrader_config.py b/jupyterhub/nbgrader/nbgrader_config.py
deleted file mode 100644
index 0e8e798..0000000
--- a/jupyterhub/nbgrader/nbgrader_config.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# /srv/nbgrader/nbgrader_config.py
-c = get_config()
-
-# 1. Course Configuration
-c.CourseDirectory.course_id = "intro-to-python" # Change to your course name
-c.CourseDirectory.root = '/srv/nbgrader/courses'
-
-# 2. Exchange Directory (for submitting/collecting assignments)
-c.Exchange.root = '/srv/nbgrader/exchange'
-c.Exchange.path_includes_course = True
-
-# 3. JupyterHub Integration
-#c.NbGrader.hub_url = 'http://jupyterhub:8081/hub/api'
-#c.NbGrader.hubapi_token = 'your-hub-token' # Generate with: openssl rand -hex 32
-
-# 4. Database Configuration
-c.StudentAssignmentNotebook.database_url = 'sqlite:////srv/nbgrader/nbgrader.sqlite'
-
-# 5. Assignment Policies
-c.ExecutePreprocessor.timeout = 300 # 5 minutes timeout per cell
-c.ClearSolutions.code_stub = "# YOUR CODE HERE"
-c.ClearSolutions.text_stub = "YOUR ANSWER HERE"
-
-# 6. Formgrader UI Settings
-c.FormgradeApp.port = 9999
-c.FormgradeApp.authenticator_class = 'nbgrader.auth.hubauth.HubAuth'
-c.FormgradeApp.ip = '0.0.0.0'
-
-# 7. Permissions
-c.CourseDirectory.groupshared = True
diff --git a/jupyterhub/nbgrader_config.py b/jupyterhub/nbgrader_config.py
deleted file mode 100644
index 9ba770b..0000000
--- a/jupyterhub/nbgrader_config.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import os
-
-c = get_config()
-
-# Database configuration - use the same PostgreSQL as JupyterHub
-p_user = os.environ.get("POSTGRES_USER", "")
-p_pass = os.environ.get("POSTGRES_PASSWORD", "")
-p_host = os.environ.get("POSTGRES_HOST", "postgres")
-p_db = os.environ.get("POSTGRES_DB", "jupyterhub")
-
-# NBgrader database URL
-c.CourseDirectory.db_url = f"postgresql://{p_user}:{p_pass}@{p_host}:5432/{p_db}"
-
-# Course configuration
-course_id = os.environ.get("NBGRADER_COURSE_ID", "default_course")
-c.CourseDirectory.course_id = course_id
-c.CourseDirectory.root = "/srv/nbgrader"
-
-# Exchange directory configuration
-exchange_dir = os.environ.get("NBGRADER_EXCHANGE_DIRECTORY", "/srv/nbgrader/exchange")
-c.Exchange.root = exchange_dir
-c.CourseDirectory.course_id = course_id
-
-# Authentication
-c.FormgradeApp.authenticator_plugin_class = "nbgrader.auth.JupyterHubAuthPlugin"
-
-# Logging
-c.Application.log_level = "INFO"
-
-# Formgrader settings
-c.FormgradeApp.ip = "0.0.0.0"
-c.FormgradeApp.port = 9999
-c.FormgradeApp.base_url = "/jupyter/services/nbgrader-formgrader/"
-
-# Enable tornado debug mode for development
-c.FormgradeApp.tornado_settings = {"debug": True}
-
-# Assignment settings
-c.AssignmentListApp.assignment_dir = "/home/jovyan/assignments"
-c.AssignmentListApp.exchange_directory = exchange_dir
-
-# Grader settings
-c.AutogradeApp.force = True
-c.GenerateAssignmentApp.force = True
diff --git a/jupyterhub/templates/logo.png b/jupyterhub/templates/logo.png
index 5d90a034d39f5cbededfa16018c1cb83c1cbb35a..670b7cb73f9ef2faa6d23e156018f08f160fbc84 100644
GIT binary patch
literal 573
zcmV-D0>b@?P))I$%2f)wn*
zUaNw(s7cjSTQx1s$2`W`
z3spRj9FGL24Z%rBSHq?mpT@W3$eUQKcS#3>(xtDqgWhgbHZi-I_ceGIB2vQ0-v8ij
z-5(l;rrVVdoMzipM^Mh
zrQohANUqUXBJhG`fXiY|pX+($%QXDIC935RJRf{oJHTCF=mctMRikHRByy
z29PNk`wt*v9yCudiQ~BESzL#W4+-YaZPhEdlm4*MuQ4siHd
zCF&K40cx{^qc;l8^<)`Z18`Rf)ft8J-Q-zXs{xsUvCIKPhM!W&=`#Cox#Y-arvP%-
zqglEC08~Z=1HHp(A0c{%)6RHa!GMv(+)EmTX?zNoN+w1pbH>;o&KUuYp)*^J00000
LNkvXXu0mjf2I~MK
literal 11257
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
V8C}yFJeUkXT3kV_T;yxO{{kMwH244j