TL;DR

  • Providers (LLMs, Cloudinary, Redis clients, etc.) are initialized only when first used.
  • If required envs are missing in dev: we warn and return None so the feature is simply unavailable.
  • In production: missing required envs should be treated as errors.

The rules

  • Env values live in settings (backend/app/config/settings.py).
  • Register providers with @lazy_provider(...) from backend/app/core/lazy_loader.py.
  • Declare required_keys=[...] using values from settings.
  • Choose how to handle missing keys via strategy: ERROR, WARN, WARN_ONCE, SILENT.
  • Call providers.get(name) (sync) or await providers.aget(name) (async) only when you actually need the provider.

Minimal pattern

from app.core.lazy_loader import lazy_provider, providers, MissingKeyStrategy
from app.config.settings import settings

@lazy_provider(
  name="openai",
  required_keys=[settings.OPENAI_API_KEY],
  strategy=MissingKeyStrategy.WARN,  # dev-friendly: no crash if missing
)
def create_openai():
  from openai import OpenAI
  return OpenAI(api_key=settings.OPENAI_API_KEY)

# Use it only where needed (initializes on first access)
client = providers.get("openai")
if client is None:
  # Feature inactive until OPENAI_API_KEY is set
  pass

Global context (config, not an instance)

@lazy_provider(
  name="cloudinary",
  required_keys=[settings.CLOUDINARY_CLOUD_NAME, settings.CLOUDINARY_API_KEY],
  is_global_context=True,
  auto_initialize=True,  # configure early when keys exist
)
def configure_cloudinary():
  import cloudinary
  cloudinary.config(
    cloud_name=settings.CLOUDINARY_CLOUD_NAME,
    api_key=settings.CLOUDINARY_API_KEY,
    api_secret=settings.CLOUDINARY_API_SECRET,
  )

Error behavior (quick mental model)

  • Dev: prefer WARN → feature returns None until you add keys.
  • Prod: prefer ERROR → app raises ConfigurationError on first use if keys are missing/invalid.

References

  • Implementation: backend/app/core/lazy_loader.py
  • Settings (env parsing): backend/app/config/settings.py