============== Sygaldry: Why? ============== Design Philosophy ================= **Composition over inheritance.** Encourage writing code that uses composition over inheritance by making it easy to wire arbitrary pipelines made up of reusable pieces of code. Components are plain Python classes. Configuration is defined by YAML or TOML. Configuration can be nested, and include other configuration files. So users can can compose objects in whatever configuration they want. **Zero modifications to your code.** Sygaldry only needs a dotted import path to instantiate a class or import a callable. Your application code stays exactly as it is. No base classes. No framework coupling. No registration hooks. **Lightweight.** The only runtime dependencies are ``pyyaml`` and ``rich-click``. There is no scheduler, no database, no web server, and no daemon process. **Production-friendly configuration management.** Deep-merge includes, interpolation, ``--set`` / ``--use`` overrides, and the ``interactive`` CLI command make it practical to manage many similar pipelines across environments. Comparison with Existing Libraries ================================== Hydra ----- `Hydra `_ (Meta) is a configuration framework built on OmegaConf. It excels at managing complex configuration hierarchies and parameter sweeps. But it builds trees instead of graphs. Sygaldry builds graphs that allow multiple objects to share the same resolved instance. E.g. a database connection pool used by multiple parts of a pipeline. .. list-table:: :header-rows: 1 :widths: 30 35 35 * - - Hydra - Sygaldry * - Code changes required - Yes -- ``@hydra.main`` decorator, ``DictConfig`` parameters - None -- any class or callable works as-is * - Object instantiation - ``instantiate()`` API with ``_target_`` keys - Automatic bottom-up resolution of the entire object graph * - Composition model - Config groups selected via overrides on the command line - ``_include`` deep-merge and ``_ref`` wiring between components * - Dependencies - ``omegaconf``, ``antlr4-runtime``, and more - ``pyyaml``, ``rich-click`` * - Scope - Configuration management with optional instantiation - Full object-graph assembly from configuration Hydra is a natural fit when you need parameter sweeps or experiment tracking integrations. Sygaldry is a better fit when you want to assemble an object graph declaratively without changing your application code. Dependency Injector =================== `Dependency Injector `_ is a dependency injection framework that uses container classes and provider objects to wire dependencies. .. list-table:: :header-rows: 1 :widths: 30 35 35 * - - Dependency Injector - Sygaldry * - Code changes required - Minimal -- but wiring is defined in Python ``Container`` classes - None -- wiring is defined in YAML or TOML * - Composition model - Python provider objects (``Factory``, ``Singleton``, etc.) - Configuration keys (``_type``, ``_ref``, ``_instance``) * - Configuration format - Python code, optionally reading from ``.ini`` / ``.yaml`` - YAML or TOML as the primary interface * - Reusability - Containers can be nested and overridden in Python - Config files can be included, deep-merged, and overridden Dependency Injector gives you fine-grained programmatic control over instantiation. Sygaldry moves the wiring entirely into configuration, so the same components can be recombined without touching Python. Gin === `Gin `_ (Google) is a lightweight configuration framework that lets you bind function and constructor arguments from a ``.gin`` file using ``@gin.configurable`` decorators. .. list-table:: :header-rows: 1 :widths: 30 35 35 * - - Gin - Sygaldry * - Code changes required - Yes -- functions and classes must be decorated with ``@gin.configurable`` - None -- any class or callable works as-is * - Configuration format - Custom ``.gin`` syntax - Standard YAML or TOML * - Composition model - Parameter binding -- Gin overrides default arguments on decorated callables - Object graph -- ``_type`` instantiates classes, ``_ref`` wires them together * - Object graph support - Limited -- Gin binds parameters but does not assemble or manage an object graph; references between configured objects must be handled manually - First-class -- ``_ref`` declaratively wires objects, with automatic bottom-up resolution and instance caching * - Config inheritance - File-level includes (``import``), no deep-merge - ``_include`` with recursive deep-merge, ``--set`` / ``--use`` overrides * - Dependencies - ``gin-config`` - ``pyyaml``, ``rich-click`` Gin is popular in ML research for its simplicity: decorate a function and bind its arguments from a config file. The trade-off is that your code must opt in via ``@gin.configurable``, and the ``.gin`` format is non-standard. Sygaldry requires no decorators, uses standard file formats, and provides full object-graph assembly with references, caching, and deep-merge config inheritance. Kedro ===== `Kedro `_ (McKinsey QuantumBlack) is an opinionated framework for reproducible data science pipelines. .. list-table:: :header-rows: 1 :widths: 30 35 35 * - - Kedro - Sygaldry * - Code changes required - Yes -- nodes are functions registered in a ``Pipeline``, data is accessed through the ``DataCatalog`` - None * - Composition model - Functional nodes wired by named datasets in a catalog - Object graph assembled from ``_type`` and ``_ref`` entries * - Dependencies - Heavy -- ``kedro`` pulls in ``dynaconf``, ``cookiecutter``, ``pluggy``, ``fsspec``, and many more - ``pyyaml``, ``rich-click`` * - Project structure - Enforced directory layout and ``settings.py`` - No required project structure * - Scope - End-to-end ML pipeline framework with catalog, hooks, and runners - Object-graph assembly -- bring your own pipeline abstraction Kedro shines for ML projects that benefit from its catalog and reproducibility tooling. Sygaldry is a lower-level building block that doesn't impose any project structure or data abstraction. When Sygaldry is the right choice ================================== Sygaldry is a good fit when: * You want to maintain pipelines that leverage (potentially) complex configuration of objects through multiple layers of composition. * You run many similar jobs that share components and you want to **reuse them through configuration** rather than copy-pasting code or subclassing framework base classes. * You want to keep your application code **framework-free** so it stays testable, portable, and easy to reason about. * You need a **lightweight** solution that adds two dependencies, not two hundred. * You manage pipelines across environments and want **config inheritance** (``_include``, ``--set``, ``--use``) to keep the differences minimal and explicit. * You want to **explore and debug** your object graph interactively with ``sygaldry interactive`` before running anything in production. * You already have an orchestrator (or cron) and just need a clean way to **assemble and invoke** the objects it runs.