Source code for flip.constants.flip_constants

# Copyright (c) 2026 Guy's and St Thomas' NHS Foundation Trust & King's College London
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#     http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""
FLIP Constants and Configuration.

This module provides:
    - Environment-aware settings (DevSettings, ProdSettings)
    - Enumerations for resource types, model statuses, tasks, and events
"""

from enum import Enum
from typing import Union

from pydantic import HttpUrl, PositiveInt, field_validator
from pydantic_settings import BaseSettings


class _Common(BaseSettings):
    """Base settings shared by both development and production environments."""

    LOCAL_DEV: bool = True  # Defaults to dev mode
    MIN_CLIENTS: PositiveInt = 1


[docs] class DevSettings(_Common): """Development environment configuration. Used when LOCAL_DEV=true. Requires local paths for test data. """
[docs] LOCAL_DEV: bool = True
[docs] DEV_DATAFRAME: str = ""
[docs] DEV_IMAGES_DIR: str = ""
[docs] class ProdSettings(_Common): """Production environment configuration. Used when LOCAL_DEV=false. Settings are grouped by which FL role uses them: - **Server-only** (fl-server on Central Hub): FLIP_API_INTERNAL_URL, INTERNAL_SERVICE_KEY* - **Client-only** (fl-client on trust side): DATA_ACCESS_API_URL, IMAGING_API_URL, TRUST_INTERNAL_SERVICE_KEY* - **Shared**: IMAGES_DIR, NET_ID, UPLOADED_FEDERATED_DATA_BUCKET """
[docs] LOCAL_DEV: bool = False
# -- Server-only: fl-server on Central Hub calls flip-api using these. # FLIP_API_INTERNAL_URL must point at flip-api over the shared Docker network # (e.g. http://flip-api:8000/api), never at the public CloudFront URL — the # CloudFront distribution whitelists only Authorization/Content-Type/Origin # and strips X-Internal-Service-Key at the edge, which would break auth.
[docs] FLIP_API_INTERNAL_URL: HttpUrl = "http://localhost:8000" # type: ignore[assignment]
[docs] INTERNAL_SERVICE_KEY_HEADER: str = "X-Internal-Service-Key"
[docs] INTERNAL_SERVICE_KEY: str = ""
# -- Client-only: fl-client on trust side calls local APIs using these --
[docs] DATA_ACCESS_API_URL: HttpUrl = "http://localhost:8001" # type: ignore[assignment]
[docs] IMAGING_API_URL: HttpUrl = "http://localhost:8002" # type: ignore[assignment]
# Trust-internal service auth — protects imaging-api and data-access-api on the # trust Docker network from unauthenticated callers. The fl-client container is # injected with the per-trust plaintext key in TRUST_INTERNAL_SERVICE_KEY by the # trust compose stack (see trust/compose_trust.*.flower.yml / *.nvflare.yml in # the FLIP repo). The flip package forwards it on every call to imaging-api or # data-access-api; user training code does not deal with the header directly.
[docs] TRUST_INTERNAL_SERVICE_KEY_HEADER: str = "X-Trust-Internal-Service-Key"
[docs] TRUST_INTERNAL_SERVICE_KEY: str = ""
# -- Shared --
[docs] IMAGES_DIR: str = ""
[docs] NET_ID: str = "default"
[docs] UPLOADED_FEDERATED_DATA_BUCKET: str = "s3://default-bucket"
@field_validator("UPLOADED_FEDERATED_DATA_BUCKET") @classmethod def _validate_s3_url(cls, v: str) -> str: if not v.startswith("s3://"): raise ValueError(f"Invalid S3 URL: {v}") return v
_flip_constants_instance: Union[DevSettings, ProdSettings, None] = None
[docs] def get_flip_constants() -> Union[DevSettings, ProdSettings]: """Get FlipConstants singleton instance. Lazy initialization ensures environment variables are only required when the instance is actually used, not at import time. """ global _flip_constants_instance if _flip_constants_instance is None: _flip_constants_instance = ( DevSettings() if _Common().LOCAL_DEV else ProdSettings() # type: ignore[call-arg] ) return _flip_constants_instance
# For backward compatibility, provide FlipConstants as a property-like access # Users should migrate to get_flip_constants() for better lazy loading class _FlipConstantsProxy: """Proxy to provide lazy loading via attribute access.""" def __getattribute__(self, name: str): if name.startswith("_"): return object.__getattribute__(self, name) return getattr(get_flip_constants(), name)
[docs] FlipConstants = _FlipConstantsProxy() # type: ignore[assignment]
[docs] class ResourceType(str, Enum): """Types of imaging resources available in XNAT."""
[docs] DICOM = "DICOM"
[docs] NIFTI = "NIFTI"
[docs] SEGMENTATION = "SEG"
[docs] ALL = "ALL"
[docs] class FlipTasks(str, Enum): """Task names used in FLIP workflows.""" # Common tasks (all job types)
[docs] INIT_TRAINING = "init_training"
[docs] POST_VALIDATION = "post_validation"
[docs] CLEANUP = "cleanup"
# Evaluation-specific tasks
[docs] INIT_TASK = "init_task"
[docs] POST_TASK = "post_task"
[docs] class FlipEvents: """Event names used in FLIP workflows. Note: This is a class with class attributes rather than an Enum because NVFLARE events are string constants. """ # Common events (all job types)
[docs] TRAINING_INITIATED = "_training_initiated"
[docs] RESULTS_UPLOAD_STARTED = "_results_upload_started"
[docs] RESULTS_UPLOAD_COMPLETED = "_results_upload_completed"
[docs] SEND_RESULT = "_send_result"
[docs] LOG_EXCEPTION = "_log_exception"
[docs] ABORTED = "_aborted"
# Evaluation-specific events
[docs] TASK_INITIATED = "_task_initiated"
[docs] class ModelStatus(str, Enum): """Model training status values."""
[docs] PENDING = "PENDING"
[docs] INITIATED = "INITIATED"
[docs] PREPARED = "PREPARED"
[docs] TRAINING_STARTED = "TRAINING_STARTED"
[docs] RESULTS_UPLOADED = "RESULTS_UPLOADED"
[docs] ERROR = "ERROR"
[docs] STOPPED = "STOPPED"
[docs] class FlipMetricsLabel(str, Enum): """Standard metric labels for FLIP metrics reporting."""
[docs] LOSS_FUNCTION = "LOSS_FUNCTION"
[docs] DL_RESULT = "DL_RESULT"
[docs] AVERAGE_SCORE = "AVERAGE_SCORE"
[docs] class FlipMetaKey(str, Enum): """Metadata keys used in FLIP (diffusion model specific)."""
[docs] STAGE = "stage"