configurator for the Application Hub
Project description
Configurator – Application Hub Profile Generator
configurator is a framework and CLI tool to define, compose, and export application profiles (Code Server, GPU Code Server, Remote Desktop, …) into a single YAML configuration consumable by an Application Hub (e.g. JupyterHub + KubeSpawner).
The design focuses on:
- explicit configuration (no magic)
- strong typing (Pydantic)
- extensible base classes
- deterministic profile selection
- deployment-time overrides via CLI
Core Concepts
Profile
A Profile represents a runnable application configuration:
- container image
- CPU / memory limits
- node selector
- volumes
- environment variables
- config maps
- init containers
- optional default URL
Profiles are serialized into a YAML file via the Config model.
BaseAppProfile
BaseAppProfile is the foundation for all applications.
It implements:
- profile construction (
build()) - resource wiring
- config map handling
- init containers
- volume merging
- node selector handling
- default URL propagation
Concrete profiles never override build().
App Families
Profiles are grouped by base app classes:
BaseCoderProfile→ code / notebook / CWL appsBaseRemoteDesktopProfile→ web-based desktop appsBaseJupyterLabProfile→ JupyterLab apps
Each family defines sane defaults for:
- image
- resources
- volumes
- environment
Profile Registry
Profiles are registered explicitly in a central registry.
- Each profile has a unique slug
- Deployments select profiles by slug
- No auto-discovery or hidden imports
This makes profile selection deterministic and debuggable.
Repository Structure
configurator/
cli/
commands.py # Click command definitions
options.py # Shared CLI options
describe/
profile.py # Human-readable profile output
io/
yaml_writer.py # YAML serialization
overrides/
apply.py # Override application
parser.py # Override parsing
plugins/
loader.py # Builtin/external profile loading
apps/
base.py # BaseAppProfile
registry.py # ProfileRegistry
coder/
base_coder.py # BaseCoderProfile
coder_profiles.py # CoderProfile, GpuCoderProfile
__init__.py # re-exports + registration
remote_desktop/
base_remote_desktop.py # BaseRemoteDesktopProfile
remote_desktop_profiles.py
__init__.py # re-exports + registration
jupyterlab/
base_jupyterlab.py # BaseJupyterLabProfile
jupyterlab_profiles.py # JupyterLab profiles
models.py # Pydantic models
main.py # click-based CLI entrypoint
Defining Profiles
Example: Base coder profile
class BaseCoderProfile(BaseAppProfile):
image = "ghcr.io/eoepca/pde-code-server:latest-dev"
cpu_guarantee = 1
cpu_limit = 2
mem_guarantee = "4G"
mem_limit = "6G"
Example: Concrete coder profile
class CoderProfile(BaseCoderProfile):
display_name = "Code Server"
description = "Code Server for development"
slug = "coder_app"
Example: GPU coder profile
class GpuCoderProfile(BaseCoderProfile):
display_name = "GPU Code Server"
description = "Code Server with GPU acceleration"
slug = "gpu_coder_app"
cpu_limit = 8
mem_limit = "32G"
def get_extra_resource_limits(self):
return {"nvidia.com/gpu": 1}
Example: Remote desktop base profile
class BaseRemoteDesktopProfile(BaseAppProfile):
image = "ghcr.io/eoepca/iga-remote-desktop:1.2.0"
default_url = "/desktop"
Registering Profiles
Profiles are registered explicitly in their package init.py:
from configurator.apps import profile_registry
from .coder_profiles import CoderProfile, GpuCoderProfile, DaskGatewayCoderProfile
profile_registry.register(CoderProfile)
profile_registry.register(GpuCoderProfile)
profile_registry.register(DaskGatewayCoderProfile)
Only concrete profiles are registered.
Base classes are never registered.
CLI: dump-config
The CLI is implemented using Click.
dump-config --help
Options
Option Description --profiles Comma-separated list of profile slugs --groups Comma-separated list of groups --node-selector Per-profile node selector override --override Per-profile attribute override --output Output YAML file
Environment variables can be used as defaults.
Selecting Profiles
dump-config \
--profiles coder_app,gpu_coder_app,remote_desktop
Profiles are selected by slug, in order.
Groups
dump-config \
--profiles coder_app \
--groups developers,ml-users
Groups are deployment-level policy and apply to all selected profiles.
Node Selector Overrides (per slug)
Syntax
--node-selector <slug>:<key>=<value>
Example
dump-config \
--profiles coder_app,gpu_coder_app \
--node-selector gpu_coder_app:nodepool=gpu
Result (excerpt)
profiles:
- id: profile_gpu_coder_app
node_selector:
nodepool: gpu
Resource & Image Overrides (per slug)
Syntax
--override <slug>:<field>=<value>
Supported fields include:
cpu_limitcpu_guaranteemem_limitmem_guaranteeimage- any other profile attribute
Example: CPU & memory
dump-config \
--profiles coder_app \
--override coder_app:cpu_limit=4 \
--override coder_app:mem_limit=8G
Example: image override
dump-config \
--profiles coder_app \
--override coder_app:image=ghcr.io/eoepca/pde-code-server:2024.11
Combined Example
dump-config \
--profiles coder_app,gpu_coder_app,remote_desktop \
--groups developers,ml-users \
--node-selector gpu_coder_app:nodepool=gpu \
--override coder_app:cpu_limit=4 \
--override gpu_coder_app:mem_limit=32G \
--output config.yaml
Output
The CLI generates a single YAML file:
profiles:
- id: profile_coder_app
groups:
- developers
- ml-users
definition:
display_name: Code Server
slug: coder_app
kubespawner_override:
cpu_limit: 4
mem_limit: 6G
image: ghcr.io/eoepca/pde-code-server:latest-dev
Serialization uses:
config.model_dump(exclude_none=True)
No Python-specific YAML tags are emitted.
Design Rules (Important)
- Profiles define defaults, not deployment policy
- Deployment overrides happen only via the CLI
- Selection is by slug, not by class name
- Concrete profiles never override build()
- Base classes define shared behavior
- CLI remains the single control plane
Why This Architecture Scales
This design supports, without refactoring:
- new app families
- cluster-specific overrides
- GPU / non-GPU deployments
- multiple environments
- CI-generated configs
- Helm / GitOps workflows
License
Usage examples
dump-config \
--profiles coder_app,gpu_coder_app,remote_desktop,qgis_remote_desktop,jupyterlab_small \
--override coder_app:image=ghcr.io/eoepca/pde-code-server:2024.11 \
--groups group-a,group-b,group-c
dump-config \
--profiles coder_app,gpu_coder_app,remote_desktop,qgis_remote_desktop,jupyterlab_small \
--override coder_app:image=ghcr.io/eoepca/pde-code-server:2024.11 \
--groups group-a,group-b,group-c \
--override gpu_coder_app:groups=ml-users,gpu-users
dump-config \
--profiles-dir ./data/work/extra-profiles \
--profiles coder_app,training_how_to_app,mlflow_coder_app \
--groups group-a,group-b \
--output config.yaml
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file app_hub_configurator-0.1.1.tar.gz.
File metadata
- Download URL: app_hub_configurator-0.1.1.tar.gz
- Upload date:
- Size: 23.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c80753e8674406f13d4558f45f6e58eb7cd683618819dd66f69fe60f2afb09c0
|
|
| MD5 |
9465c3affb562f3790622fde58d60762
|
|
| BLAKE2b-256 |
755035aa8637b9c1b0bb5c4715593b000011e42adae81e24dffb0014a2edfbb7
|
Provenance
The following attestation bundles were made for app_hub_configurator-0.1.1.tar.gz:
Publisher:
package.yaml on EOEPCA/app-hub-configurator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
app_hub_configurator-0.1.1.tar.gz -
Subject digest:
c80753e8674406f13d4558f45f6e58eb7cd683618819dd66f69fe60f2afb09c0 - Sigstore transparency entry: 1356799311
- Sigstore integration time:
-
Permalink:
EOEPCA/app-hub-configurator@7faab9ca3c4ccbec3b825d9fbd69e12bfadb8aaa -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/EOEPCA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
package.yaml@7faab9ca3c4ccbec3b825d9fbd69e12bfadb8aaa -
Trigger Event:
push
-
Statement type:
File details
Details for the file app_hub_configurator-0.1.1-py3-none-any.whl.
File metadata
- Download URL: app_hub_configurator-0.1.1-py3-none-any.whl
- Upload date:
- Size: 38.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2df6d89b7c03e90a6ee841a46f4adf32f0928f990ea01cfbbd22665c52e814ac
|
|
| MD5 |
739b924434ee4351878a9448c48b9b80
|
|
| BLAKE2b-256 |
801891e2d27682e52dcc497a2a84ba5ea77c88d7366e5a46a91e05c36e72dffa
|
Provenance
The following attestation bundles were made for app_hub_configurator-0.1.1-py3-none-any.whl:
Publisher:
package.yaml on EOEPCA/app-hub-configurator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
app_hub_configurator-0.1.1-py3-none-any.whl -
Subject digest:
2df6d89b7c03e90a6ee841a46f4adf32f0928f990ea01cfbbd22665c52e814ac - Sigstore transparency entry: 1356799317
- Sigstore integration time:
-
Permalink:
EOEPCA/app-hub-configurator@7faab9ca3c4ccbec3b825d9fbd69e12bfadb8aaa -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/EOEPCA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
package.yaml@7faab9ca3c4ccbec3b825d9fbd69e12bfadb8aaa -
Trigger Event:
push
-
Statement type: