Skip to main content

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 apps
  • BaseRemoteDesktopProfile → web-based desktop apps
  • BaseJupyterLabProfile → 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_limit
  • cpu_guarantee
  • mem_limit
  • mem_guarantee
  • image
  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

app_hub_configurator-0.1.1.tar.gz (23.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

app_hub_configurator-0.1.1-py3-none-any.whl (38.7 kB view details)

Uploaded Python 3

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

Hashes for app_hub_configurator-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c80753e8674406f13d4558f45f6e58eb7cd683618819dd66f69fe60f2afb09c0
MD5 9465c3affb562f3790622fde58d60762
BLAKE2b-256 755035aa8637b9c1b0bb5c4715593b000011e42adae81e24dffb0014a2edfbb7

See more details on using hashes here.

Provenance

The following attestation bundles were made for app_hub_configurator-0.1.1.tar.gz:

Publisher: package.yaml on EOEPCA/app-hub-configurator

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file app_hub_configurator-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for app_hub_configurator-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2df6d89b7c03e90a6ee841a46f4adf32f0928f990ea01cfbbd22665c52e814ac
MD5 739b924434ee4351878a9448c48b9b80
BLAKE2b-256 801891e2d27682e52dcc497a2a84ba5ea77c88d7366e5a46a91e05c36e72dffa

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page