Skip to main content

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

Metadata

Release files for app-hub-configurator 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for app-hub-configurator 0.1.1
File Size Uploaded Provenance
app_hub_configurator-0.1.1.tar.gz 23.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for app-hub-configurator 0.1.1
File Interpreter ABI Platform
app_hub_configurator-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 62.4 kB

Release files / app_hub_configurator-0.1.1.tar.gz

Download URL app_hub_configurator-0.1.1.tar.gz
Size 23.6 kB
Tags Source
SHA-256 checksum
How to use checksums
c80753e8674406f13d4558f45f6e58eb7cd683618819dd66f69fe60f2afb09c0
BLAKE2b-256 checksum
How to use checksums
755035aa8637b9c1b0bb5c4715593b000011e42adae81e24dffb0014a2edfbb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 22, 2026.

Transparency log

Release files / app_hub_configurator-0.1.1-py3-none-any.whl

Download URL app_hub_configurator-0.1.1-py3-none-any.whl
Size 38.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2df6d89b7c03e90a6ee841a46f4adf32f0928f990ea01cfbbd22665c52e814ac
BLAKE2b-256 checksum
How to use checksums
801891e2d27682e52dcc497a2a84ba5ea77c88d7366e5a46a91e05c36e72dffa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 22, 2026.

Transparency log

Security for app-hub-configurator 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for app_hub_configurator-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page